-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: extracting some file to reduce pressure on minifier
Signed-off-by: Vincent Boutour <[email protected]>
- Loading branch information
Showing
10 changed files
with
646 additions
and
635 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -64,7 +64,7 @@ func newConfig() (configuration, error) { | |
logger: logger.Flags(fs, "logger"), | ||
tracer: tracer.Flags(fs, "tracer"), | ||
prometheus: prometheus.Flags(fs, "prometheus", flags.NewOverride("Gzip", false)), | ||
owasp: owasp.Flags(fs, "", flags.NewOverride("FrameOptions", "SAMEORIGIN"), flags.NewOverride("Csp", "default-src 'self'; base-uri 'self'; script-src 'self' 'httputils-nonce' unpkg.com/[email protected]/dist-cjs/ unpkg.com/[email protected]/dist/ unpkg.com/[email protected]/; style-src 'httputils-nonce' unpkg.com/[email protected]/dist/ unpkg.com/[email protected]/; img-src 'self' data: a.tile.openstreetmap.org b.tile.openstreetmap.org c.tile.openstreetmap.org")), | ||
owasp: owasp.Flags(fs, "", flags.NewOverride("FrameOptions", "SAMEORIGIN"), flags.NewOverride("Csp", "default-src 'self'; base-uri 'self'; script-src 'self' 'httputils-nonce' unpkg.com/[email protected]/dist-cjs/ unpkg.com/[email protected]/dist/ unpkg.com/[email protected]/; style-src 'self' 'httputils-nonce' unpkg.com/[email protected]/dist/ unpkg.com/[email protected]/; img-src 'self' data: a.tile.openstreetmap.org b.tile.openstreetmap.org c.tile.openstreetmap.org")), | ||
basic: basicMemory.Flags(fs, "auth", flags.NewOverride("Profiles", "1:admin")), | ||
crud: crud.Flags(fs, ""), | ||
share: share.Flags(fs, "share"), | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
// from https://developers.google.com/speed/webp/faq#how_can_i_detect_browser_support_for_webp | ||
function isWebPCompatible() { | ||
const animatedImage = | ||
'UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA'; | ||
|
||
return new Promise((resolve, reject) => { | ||
const image = new Image(); | ||
image.onload = () => { | ||
if (image.width > 0 && image.height > 0) { | ||
resolve(); | ||
} else { | ||
reject(); | ||
} | ||
}; | ||
|
||
image.onerror = reject.bind(null, true); | ||
image.src = `data:image/webp;base64,${animatedImage}`; | ||
}); | ||
} | ||
|
||
// From https://developer.mozilla.org/en-US/docs/Web/API/ReadableStreamDefaultReader/read#example_2_-_handling_text_line_by_line | ||
async function* readLineByLine(response) { | ||
const utf8Decoder = new TextDecoder('utf-8'); | ||
const reader = response.body.getReader(); | ||
let { value: chunk, done: readerDone } = await reader.read(); | ||
chunk = chunk ? utf8Decoder.decode(chunk, { stream: true }) : ''; | ||
|
||
let re = /\r\n|\n|\r/gm; | ||
let startIndex = 0; | ||
|
||
for (;;) { | ||
const result = re.exec(chunk); | ||
if (!result) { | ||
if (readerDone) { | ||
break; | ||
} | ||
|
||
const remainder = chunk.substr(startIndex); | ||
({ value: chunk, done: readerDone } = await reader.read()); | ||
chunk = | ||
remainder + (chunk ? utf8Decoder.decode(chunk, { stream: true }) : ''); | ||
startIndex = re.lastIndex = 0; | ||
continue; | ||
} | ||
|
||
yield chunk.substring(startIndex, result.index); | ||
startIndex = re.lastIndex; | ||
} | ||
|
||
if (startIndex < chunk.length) { | ||
yield chunk.substr(startIndex); | ||
} | ||
} | ||
|
||
/** | ||
* Async image loading | ||
*/ | ||
async function fetchThumbnail() { | ||
let fetchURL = document.location.search; | ||
if (fetchURL.includes('?')) { | ||
if (!fetchURL.endsWith('&')) { | ||
fetchURL += '&'; | ||
} | ||
fetchURL += 'thumbnail'; | ||
} else { | ||
fetchURL += '?thumbnail'; | ||
} | ||
|
||
const response = await fetch(fetchURL, { credentials: 'same-origin' }); | ||
|
||
if (response.status >= 400) { | ||
throw new Error('unable to load thumbnails'); | ||
} | ||
|
||
for await (let line of readLineByLine(response)) { | ||
const parts = line.split(','); | ||
if (parts.length != 2) { | ||
console.error('invalid line for thumbnail:', line); | ||
continue; | ||
} | ||
|
||
const picture = document.getElementById(`picture-${parts[0]}`); | ||
if (!picture) { | ||
continue; | ||
} | ||
|
||
const img = new Image(); | ||
img.src = `data:image/webp;base64,${parts[1]}`; | ||
img.alt = picture.dataset.alt; | ||
img.dataset.src = picture.dataset.src; | ||
img.classList.add('thumbnail', 'full', 'block'); | ||
|
||
replaceContent(picture, img); | ||
} | ||
} | ||
|
||
window.addEventListener( | ||
'load', | ||
async () => { | ||
const thumbnailsElem = document.querySelectorAll('[data-thumbnail]'); | ||
if (!thumbnailsElem) { | ||
return; | ||
} | ||
|
||
thumbnailsElem.forEach((picture) => { | ||
replaceContent(picture, generateThrobber(['throbber-white'])); | ||
}); | ||
|
||
try { | ||
await fetchThumbnail(); | ||
} catch (e) { | ||
console.error(e); | ||
} | ||
|
||
try { | ||
await isWebPCompatible(); | ||
} catch (e) { | ||
await resolveScript( | ||
'https://unpkg.com/[email protected]/dist-cjs/webp-hero.bundle.js', | ||
'sha512-DA6h9H5Sqn55/uVn4JI4aSPFnAWoCQYYDXUnvjOAMNVx11///hX4QaFbQt5yWsrIm9hSI5fLJYfRWt3KXneSXQ==', | ||
'anonymous', | ||
); | ||
|
||
const webpMachine = new webpHero.WebpMachine(); | ||
webpMachine.polyfillDocument(); | ||
webpMachine.clearCache(); | ||
} | ||
|
||
window.dispatchEvent(new Event('thumbnail-done')); | ||
}, | ||
false, | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
async function fetchGeoJSON(geoURL) { | ||
const response = await fetch(geoURL, { credentials: 'same-origin' }); | ||
|
||
if (response.status >= 400) { | ||
throw new Error('unable to load geojson'); | ||
} | ||
|
||
if (response.status === 204) { | ||
return null; | ||
} | ||
|
||
return response.json(); | ||
} | ||
|
||
async function addStyle(src, integrity, crossorigin) { | ||
return new Promise((resolve) => { | ||
const style = document.createElement('link'); | ||
style.rel = 'stylesheet'; | ||
style.href = src; | ||
style.onload = resolve; | ||
|
||
if (integrity) { | ||
style.integrity = integrity; | ||
style.crossOrigin = crossorigin; | ||
} | ||
|
||
document.querySelector('head').appendChild(style); | ||
}); | ||
} | ||
|
||
async function loadLeaflet() { | ||
const leafletVersion = '1.9.2'; | ||
|
||
await addStyle( | ||
`https://unpkg.com/leaflet@${leafletVersion}/dist/leaflet.css`, | ||
'sha512-UkezATkM8unVC0R/Z9Kmq4gorjNoFwLMAWR/1yZpINW08I79jEKx/c8NlLSvvimcu7SL8pgeOnynxfRpe+5QpA==', | ||
'anonymous', | ||
); | ||
await addStyle( | ||
'https://unpkg.com/[email protected]/dist/MarkerCluster.Default.css', | ||
'sha512-6ZCLMiYwTeli2rVh3XAPxy3YoR5fVxGdH/pz+KMCzRY2M65Emgkw00Yqmhh8qLGeYQ3LbVZGdmOX9KUjSKr0TA==', | ||
'anonymous', | ||
); | ||
await resolveScript( | ||
`https://unpkg.com/leaflet@${leafletVersion}/dist/leaflet.js`, | ||
'sha512-KMraOVM0qMVE0U1OULTpYO4gg5MZgazwPAPyMQWfOkEshpwlLQFCHZ/0lBXyviDNVL+pBGwmeXQnuvGK8Fscvg==', | ||
'anonymous', | ||
); | ||
await resolveScript( | ||
'https://unpkg.com/[email protected]/dist/leaflet.markercluster.js', | ||
'sha512-+Zr0llcuE/Ho6wXRYtlWypMyWSEMxrWJxrYgeAMDRSf1FF46gQ3PAVOVp5RHdxdzikZXuHZ0soHpqRkkPkI3KA==', | ||
'anonymous', | ||
); | ||
} | ||
|
||
let map; | ||
async function renderMap(geoURL) { | ||
if (map) { | ||
map.invalidateSize(); // force re-render | ||
return; | ||
} | ||
|
||
const container = document.getElementById('map-container'); | ||
const throbber = generateThrobber(['map-throbber', 'throbber-white']); | ||
if (container) { | ||
container.appendChild(throbber); | ||
} | ||
|
||
await loadLeaflet(); | ||
|
||
// create Leaflet map | ||
map = L.map('map-container', { | ||
center: [46.227638, 2.213749], // France 🇫🇷 | ||
zoom: 5, | ||
}); | ||
|
||
// add the OpenStreetMap tiles | ||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { | ||
maxZoom: 19, | ||
attribution: | ||
'© <a href="https://openstreetmap.org/copyright">OpenStreetMap contributors</a>', | ||
}).addTo(map); | ||
|
||
const geojson = await fetchGeoJSON(geoURL); | ||
if (!geojson || !geojson.features) { | ||
return; | ||
} | ||
|
||
const markers = L.markerClusterGroup({ | ||
zoomToBoundsOnClick: false, | ||
}); | ||
|
||
const bounds = []; | ||
geojson.features.map((f) => { | ||
const coord = L.GeoJSON.coordsToLatLng(f.geometry.coordinates); | ||
|
||
bounds.push(coord); | ||
markers.addLayer( | ||
L.circleMarker(coord).bindPopup( | ||
`<a href="${f.properties.url}?browser"> | ||
<img src="${f.properties.url}?thumbnail" alt="Image thumbnail" class="thumbnail-img"> | ||
</a> | ||
<br> | ||
<span>${f.properties.date}</span>`, | ||
{ | ||
maxWidth: 'auto', | ||
closeButton: false, | ||
className: 'thumbnail-popup', | ||
}, | ||
), | ||
); | ||
}); | ||
|
||
markers.on('clusterclick', (a) => { | ||
map.fitBounds(a.layer.getAllChildMarkers().map((m) => m.getLatLng())); | ||
}); | ||
|
||
// fit bounds of map | ||
if (bounds.length) { | ||
map.once('zoomend', () => { | ||
container.removeChild(throbber); | ||
}); | ||
map.fitBounds(bounds); | ||
} else { | ||
container.removeChild(throbber); | ||
} | ||
|
||
map.addLayer(markers); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/** | ||
* Async loading of a script | ||
* @param {String} src URL of script | ||
* @param {String} integrity Integrity of script | ||
* @param {String} crossorigin Crossorigin of script | ||
* @return Promise when script is either loaded or on error | ||
*/ | ||
function resolveScript(src, integrity, crossorigin) { | ||
return new Promise((resolve, reject) => { | ||
const script = document.createElement('script'); | ||
script.type = 'text/javascript'; | ||
script.src = src; | ||
script.async = true; | ||
script.onload = resolve.bind(null, true); | ||
script.onerror = reject.bind(null, true); | ||
|
||
if (integrity) { | ||
script.integrity = integrity; | ||
script.crossOrigin = crossorigin; | ||
} | ||
|
||
document.querySelector('head').appendChild(script); | ||
}); | ||
} | ||
|
||
/** | ||
* Handle Previous/next. | ||
*/ | ||
window.onkeyup = (e) => { | ||
switch (e.key) { | ||
case 'ArrowLeft': | ||
goToPrevious(); | ||
break; | ||
|
||
case 'ArrowRight': | ||
goToNext(); | ||
break; | ||
|
||
case 'Escape': | ||
if (typeof abort === 'function') { | ||
abort(e); | ||
} else { | ||
goBack(); | ||
} | ||
break; | ||
} | ||
}; | ||
|
||
/** | ||
* Remove all child and append given one. | ||
* @param {Element} element Element to clear | ||
* @param {Element} newContent Element to put in place | ||
*/ | ||
function replaceContent(element, newContent) { | ||
while (element.firstChild) { | ||
element.removeChild(element.firstChild); | ||
} | ||
|
||
if (newContent) { | ||
element.appendChild(newContent); | ||
} | ||
} |
Oops, something went wrong.