diff options
author | Guilhem Moulin <guilhem@fripost.org> | 2025-10-17 00:26:39 +0200 |
---|---|---|
committer | Guilhem Moulin <guilhem@fripost.org> | 2025-10-18 14:10:14 +0200 |
commit | 354e8aa6abfcc37452c8bcf8bab2d481612bb750 (patch) | |
tree | f72d8f2e9fe57283c4373122311771e9e361dcac | |
parent | 7f74020caf44589bcd68a07378823848c6daea03 (diff) |
Add an help modal with instructions how to use the map.
-rw-r--r-- | index.html | 143 | ||||
-rw-r--r-- | main.js | 521 | ||||
-rw-r--r-- | style.css | 66 |
3 files changed, 510 insertions, 220 deletions
@@ -53,6 +53,149 @@ </div> </div> </div> + <div class="modal" id="help-modal" tabindex="-1" aria-hidden="true"> + <div class="modal-dialog modal-dialog-centered modal-dialog-scrollable modal-lg"> + <div class="modal-content"> + <div class="modal-header"> + <button type="button" class="btn-close" data-bs-dismiss="modal" title="Stäng" aria-label="Stäng"></button> + </div> + <div id="help-body" class="modal-body"> + <h3>Navigering</h3> + <p>Kartan är interaktiv och kontrolleras med musen. Tryck ner på + musens första knapp och dra kartan för att byta koordinater.</p> + <p>Zoomnivån kan styras med musens rullhjul, eller alternativt med + knapparna och skjutreglaget längst upp till vänster. Den aktuella + skalan visas längst ner till vänster på kartan.</p> + <p>Både koordinater och zoomnivå sparas i URL:en, så om du delar + URL:en med någon annan eller sparar den i din webbläsares bokmärken + kommer senare besök att landa på samma plats samt zoomnivå på + kartan.</p> + <p>Klickar du på ett objekt på kartan – exempelvis ett + undersökningstillstånd eller ett naturreservat (läs mer om lagerval + nedan) – så visar det valda objektet med en cyanfärgad kantlinje + samt dyker ett fönster upp med information om just det objektet. + Både informationen och geometrier kommer från ansvarig myndighet. + I fall det finns flera objekt i närheten av just platsen du klickade + på, så antalet träffar visas högst upp på informationsfönstret + (exempelvis ”<span class="fst-italic text-muted">Träff 1 av 3</span>”) och du + kan välja mellan dem genom att klicka på pilarna + <span class="popover-header"> + <button class="popover-button popover-button-prev text-muted help-button"></button>/<button class="popover-button popover-button-next text-muted help-button"></button> + </span> bredvid. + Informationsfönstret kan flyttas runt om det står i vägen, samt att + det förstoras om rutan är för liten.</p> + + <h3>Funktionsknappar</h3> + <p>Det finns ett antal funktionsknappar längst upp till + höger på kartan. Om du låter muspekaren vila på varje + knapp, dyker en hjälptext upp.</p> + + <ol id='help-describe-functions'> + <li data-for-button='layer-selection-button'> + <p>Här kan du välja mellan olika lager att ha på kartan. + Det finns massor med lager, och de grupperas ihop så att + det är enkelt att välja hela gruppen på en gång. Klickar + du på pilen + <span class="accordion"><span class="accordion-button collapsed help-button text-muted"></span></span> + kan du istället välja ett specifikt lager.</p> + <p>Längst ned finns knappar där du kan välja att se + administrativa gränser, samt välja mellan nedtonad eller färgad + bakgrundskarta.</p> + <p>Lager, precis som koordinater och zoomnivå, sparas i URL:en. + Så om du delar URL:en med någon annan eller sparar den i din + webbläsares bokmärken kommer senare besök att landa på samma vy + (eventuellt med uppdaterat underlag).</p> + </li> + + <li data-for-button='map-legend-button'> + <p>Här ser du symboler för alla lager som valts ut.</p> + </li> + + <li data-for-button='measure-button'> + <p>Med det här verktyget kan du rita direkt på kartan och mäta + distanser eller ytor. Till exempel kan du lätt mäta avståndet + mellan en viss exploatering och ett skyddat område eller + kommungräns.</p> + </li> + + <li data-for-button='age-filter-button'> + <p>Med det här verktyget kan du filtrera bort gamla + exploateringar, vilket underlättar övervakning. Det är bra att + kunna fokusera på nya exploateringen, då det annars snabbt kan + kännas överväldigande.</p> + + <p>Om filtret är aktivt så blir knappen svart. Filterparametrar + sparas i URL:en, så en övervaknings-URL till ett specifik område + kan enkelt delas med andra eller bokmärkas.</p> + </li> + + <li data-for-button='fullscreen-toggle'> + <p>Genom att klicka på knappen kan du aktivera eller inaktivera + helskärmsläget.</p> + <li> + + <li data-for-button='export-to-image'> + <p>Genom att klicka på knappen kan du ladda ner den aktuella + kartvyn som en bild. Bilden kan då användas i en rapport eller + ett yttrande.</p> + </li> + + <li data-for-button='info-button'> + <p>Här kan du se källor och licensvillkor för varje lager samt + själva kartverktyget. + För de flesta lager finns det också en produktlänk till den + ansvariga myndighetens webbplats.</p> + <p>Bredvid varje källa kan du se när den senast hämtades av + kartverktyget, samt när skikten generades på kartan (det vill + säga hur gammalt underlaget är på kartan). + Nedladdning samt uppdatering av underlag för kartan sker + automatiskt varje dag.</p> + </li> + + <li data-for-button='help-button'> + <p>Om du klickar på den här knappen ser du det här + hjälpfönstret.</p> + </li> + </ol> + + <h3>Målgrupp och syftet</h3> + <p class="mb-2">Kartan kan användas som en hjälp i att välja vilka + exploateringar som är viktigast att bekämpa. Målgruppen för kartan + är individer och organisationer som vill:</p> + <ol> + <li>se kumulativa effekter av olika exploateringar i + norr</li> + <li>se var en viss exploatering ligger i förhållande + till ett område av intresse (ex formellt skydd, höga + naturvärden, riksintresse med flera)</li> + <li>övervaka de senaste exploateringarna i ett visst + område.</li> + </ol> + + <p>Viktigt att komma ihåg är att allt underlag i kartan + kommer från olika myndigheter (Bergsstaten, Skogsstyrelsen, + Länsstyrelsen, Naturvårdsverket med flera) och ingen modell + finns för att assistera i själva avvägningen. + Med andra ord så samlar kartan in befintliga underlag från + olika myndigheter istället för att själv presentera något + nytt, och den data kartan presenterar är därmed information + som kan ingå i rapporter och yttranden (och ingen kan hävda + att underlaget är påhittat).</p> + + <p>Underlagen för kartan uppdateras automatiskt varje dag. + Se ovan för detaljer om hur gammalt varje underlag är.</p> + + <h3>Buggrapporter och feedback</h3> + <p>Tveka inte att skicka ett + <a href="mailto:Z3VpbGhlbQ __AT__ ZnJpcG9zdA __DOT__ b3Jn" target="_blank" class="link-secondary email-address-b64">mejl + <i class="bi bi-envelope-at"></i></a> + med önskemål, buggrapporter, förslag till + förbättring med flera. + Kartverktyget samt tillhörande verktyg är alla fri programvara.</p> + </div> + </div> + </div> + </div> <script type="module" src="./main.js"></script> <noscript>Den här sidan kräver JavaScript men din webbläsare stöder inte det (eller så är skript blockerade).</noscript> </body> @@ -168,11 +168,16 @@ const CONTAINER_STOPEVENT = MAP.getViewport().getElementsByClassName('ol-overlay CONTAINER_STOPEVENT.appendChild(document.getElementById('zoom-control')); CONTAINER_STOPEVENT.appendChild(CONTAINER_MAP); CONTAINER_STOPEVENT.appendChild(document.getElementById('info-modal')); + CONTAINER_STOPEVENT.appendChild(document.getElementById('help-modal')); const info_backdrop = document.createElement('div'); CONTAINER_STOPEVENT.appendChild(info_backdrop); info_backdrop.id = 'info-modal-backdrop'; + const help_backdrop = document.createElement('div'); + CONTAINER_STOPEVENT.appendChild(help_backdrop); + help_backdrop.id = 'help-modal-backdrop'; + const age_filter = document.createElement('div'); age_filter.id = 'age-filter-modal'; age_filter.classList.add('modal'); @@ -340,6 +345,7 @@ if (window.location === window.parent.location) { btn.classList.add('btn', classInactive); btn.setAttribute('aria-label', btn.title); MAP.addControl(control); + control.element.id = 'fullscreen-toggle'; /* for the help dialog */ control.addEventListener('enterfullscreen', function() { /* dispose popover as entering fullscreen messes up its position */ @@ -423,260 +429,341 @@ if (window.location === window.parent.location) { }; } -const decodeEmailAddress = function(element) { - const MAILTO = 'mailto:'; - const CLASSNAME = 'email-address-b64'; - for (const a of element.getElementsByClassName(CLASSNAME)) { - if (a.tagName.toLowerCase() === 'a' && a.href.toLowerCase().startsWith(MAILTO)) { - let href = MAILTO; - for (const part of a.href.substr(MAILTO.length).split(/\s+/)) { - switch (part) { - case '__AT__': - href += '@'; - break; - case '__DOT__': - href += '.'; - break; - default: - href += atob(part); - } - } - a.href = href; - a.classList.remove(CLASSNAME); - } - } -}; - -/* info button */ +/* info and help buttons */ (function() { - const div = document.createElement('div'); - MENU.appendChild(div); - div.id = 'info-button'; - div.classList.add('ol-unselectable', 'ol-control'); + const add_button = function(x) { + const div = document.createElement('div'); + MENU.appendChild(div); + div.id = x.id + '-button'; + div.classList.add('ol-unselectable', 'ol-control'); - const btn = document.createElement('button'); - div.appendChild(btn); - btn.type = 'button'; - btn.setAttribute('aria-expanded', 'false'); - btn.title = 'Källor och licensinformation'; - btn.setAttribute('aria-label', btn.title); - btn.classList.add('btn', 'btn-light'); + const btn = document.createElement('button'); + div.appendChild(btn); + btn.type = 'button'; + btn.setAttribute('aria-expanded', 'false'); + btn.title = x.title; + btn.setAttribute('aria-label', btn.title); + btn.classList.add('btn', 'btn-light'); - const i = document.createElement('i'); - btn.appendChild(i); - i.classList.add('bi', 'bi-info-lg'); + const i = document.createElement('i'); + btn.appendChild(i); + i.classList.add('bi', 'bi-' + x.bi); - const panel = document.getElementById('info-modal'); - const modal = new Modal(panel, { - backdrop: false, - }); - decodeEmailAddress(panel); + const panel = document.getElementById(x.id + '-modal'); + const modal = new Modal(panel, { + backdrop: false, + }); - const backdrop = document.getElementById('info-modal-backdrop'); - backdrop.onclick = function() { - modal.hide(); - }; + const backdrop = document.getElementById(x.id + '-modal-backdrop'); + backdrop.onclick = function() { + modal.hide(); + }; - panel.addEventListener('show.bs.modal', function() { - backdrop.classList.add('modal-backdrop', 'show'); - btn.setAttribute('aria-expanded', 'true'); - btn.classList.replace('btn-light', 'btn-dark'); - }); - panel.addEventListener('hide.bs.modal', function() { - /* XXX workaround for https://github.com/twbs/bootstrap/issues/41005#issuecomment-2585390544 */ - const activeElement = document.activeElement; - if (activeElement instanceof HTMLElement) { - activeElement.blur(); - } - }); - panel.addEventListener('hidden.bs.modal', function() { - btn.classList.replace('btn-dark', 'btn-light'); - btn.setAttribute('aria-expanded', 'false'); - backdrop.classList.remove('modal-backdrop', 'show'); - infoMetadataAccordions.forEach(function(x, idx) { - /* collapse all accordions */ - const body = x.element.parentNode.parentNode; - const name = 'info-accordion-collapse-' + idx; - if (body.id === name) { - body.classList.remove('show'); + panel.addEventListener('show.bs.modal', function() { + backdrop.classList.add('modal-backdrop', 'show'); + btn.setAttribute('aria-expanded', 'true'); + btn.classList.replace('btn-light', 'btn-dark'); + }); + panel.addEventListener('hide.bs.modal', function() { + /* XXX workaround for https://github.com/twbs/bootstrap/issues/41005#issuecomment-2585390544 */ + const activeElement = document.activeElement; + if (activeElement instanceof HTMLElement) { + activeElement.blur(); } - if (body.parentNode !== null) { - const headers = body.parentNode.getElementsByClassName('accordion-header'); - for (let i = 0; i < headers.length; i++) { - const buttons = headers[i].getElementsByClassName('accordion-button'); - for (let j = 0; j < buttons.length; j++) { - const btn = buttons[j]; - if (btn.getAttribute('data-bs-target') === '#' + name) { - btn.setAttribute('aria-expanded', 'false'); - btn.classList.add('collapsed'); - } + }); + + panel.addEventListener('hidden.bs.modal', function() { + btn.classList.replace('btn-dark', 'btn-light'); + btn.setAttribute('aria-expanded', 'false'); + backdrop.classList.remove('modal-backdrop', 'show'); + }); + + btn.onclick = function() { + modal.show(); + }; + + /* de-obfuscate email address */ + const MAILTO = 'mailto:'; + const CLASSNAME = 'email-address-b64'; + for (const a of panel.getElementsByClassName(CLASSNAME)) { + if (a.tagName.toLowerCase() === 'a' && a.href.toLowerCase().startsWith(MAILTO)) { + let href = MAILTO; + for (const part of a.href.substr(MAILTO.length).split(/\s+/)) { + switch (part) { + case '__AT__': + href += '@'; + break; + case '__DOT__': + href += '.'; + break; + default: + href += atob(part); } } + a.href = href; + a.classList.remove(CLASSNAME); } + } + + return [panel, btn, modal]; + }; + + /* info button */ + (function() { + const [panel, btn, modal] = add_button({ + id: 'info', + title: 'Källor och licensinformation', + bi: 'info-lg', }); - }); - const dateFormatter = new Intl.DateTimeFormat(LOCALE); - btn.onclick = function() { - infoMetadataAccordions.forEach((x) => x.element.replaceChildren()); - modal.show(); - Promise.allSettled(Object.entries(mapLayers).map(function([grp,lyr]) { - const baseurl = lyr?.getSource?.()?.get?.('baseurl'); - if (baseurl == null) { - return new Promise(() => { throw new Error(`Unknown source for "${grp}"`); }); - } - return fetch(new URL('metadata.json', baseurl)) - .then(function(resp0) { - if (resp0.status === 200) { - return resp0.json().then((x) => [grp,x]); - } else { - throw new Error(`${resp0.url} [${resp0.status}]`); - } - }); - })) - .then(function(rs) { - const metadata = Object.fromEntries(rs.filter(function(r) { - if (r.status === 'fulfilled') { - return true; - } else if (r.status === 'rejected') { - console.log(r.reason); - } - return false; - }).map((r) => r.value)); - - infoMetadataAccordions.forEach(function(x) { - const ul = x.element; - const groupnames = new Set(); - const last_updated = []; - x.items.forEach(function([groupname]) { - const layer_group = metadata[groupname]; - if (layer_group == null) { - return; - } - if (!groupnames.has(groupname)) { - groupnames.add(groupname); - if (layer_group.last_updated != null) { - last_updated.push(layer_group.last_updated); + panel.addEventListener('hidden.bs.modal', function() { + infoMetadataAccordions.forEach(function(x, idx) { + /* collapse all accordions */ + const body = x.element.parentNode.parentNode; + const name = 'info-accordion-collapse-' + idx; + if (body.id === name) { + body.classList.remove('show'); + } + if (body.parentNode !== null) { + const headers = body.parentNode.getElementsByClassName('accordion-header'); + for (let i = 0; i < headers.length; i++) { + const buttons = headers[i].getElementsByClassName('accordion-button'); + for (let j = 0; j < buttons.length; j++) { + const btn = buttons[j]; + if (btn.getAttribute('data-bs-target') === '#' + name) { + btn.setAttribute('aria-expanded', 'false'); + btn.classList.add('collapsed'); } } - }); - if (last_updated.length > 0) { - /* show creation time of the MVT layers */ - const li = document.createElement('li'); - li.classList.add('list-group-item', 'text-muted'); - ul.appendChild(li); - const i = document.createElement('i'); - i.classList.add('bi', 'bi-map'); - li.appendChild(i); - const t = document.createTextNode( - ' Lokalt skikt (vectiler) genererades ' + - last_updated - .sort() - .map((ts) => dateFormatter.format(new Date(ts))) - .join('; ') + '.' - ); - li.appendChild(t); } + } + }); + }); - const source_files = new Set(); - x.items.forEach(function([groupname, layername]) { - /* for each source file associated with the accordion header, show copyright, license and timing information */ - const layer_group = metadata[groupname]; - if (layer_group?.layers == null || layer_group?.source_files == null) { - return; + const dateFormatter = new Intl.DateTimeFormat(LOCALE); + btn.onclick = function() { + infoMetadataAccordions.forEach((x) => x.element.replaceChildren()); + modal.show(); + Promise.allSettled(Object.entries(mapLayers).map(function([grp,lyr]) { + const baseurl = lyr?.getSource?.()?.get?.('baseurl'); + if (baseurl == null) { + return new Promise(() => { throw new Error(`Unknown source for "${grp}"`); }); + } + return fetch(new URL('metadata.json', baseurl)) + .then(function(resp0) { + if (resp0.status === 200) { + return resp0.json().then((x) => [grp,x]); + } else { + throw new Error(`${resp0.url} [${resp0.status}]`); } - const def = layer_group.layers[layername]; - if (def?.source_files == null) { - return; + }); + })) + .then(function(rs) { + const metadata = Object.fromEntries(rs.filter(function(r) { + if (r.status === 'fulfilled') { + return true; + } else if (r.status === 'rejected') { + console.log(r.reason); } - def.source_files.forEach(function(source_file) { - if (source_files.has(source_file)) { + return false; + }).map((r) => r.value)); + + infoMetadataAccordions.forEach(function(x) { + const ul = x.element; + const groupnames = new Set(); + const last_updated = []; + x.items.forEach(function([groupname]) { + const layer_group = metadata[groupname]; + if (layer_group == null) { return; } - const x = layer_group.source_files[source_file]; - source_files.add(source_file); - + if (!groupnames.has(groupname)) { + groupnames.add(groupname); + if (layer_group.last_updated != null) { + last_updated.push(layer_group.last_updated); + } + } + }); + if (last_updated.length > 0) { + /* show creation time of the MVT layers */ const li = document.createElement('li'); - li.classList.add('list-group-item'); + li.classList.add('list-group-item', 'text-muted'); ul.appendChild(li); - const h = document.createElement('h6'); - li.appendChild(h); - if (x.description != null) { - const t = document.createTextNode(x.description); - h.appendChild(t); - } + const i = document.createElement('i'); + i.classList.add('bi', 'bi-map'); + li.appendChild(i); + const t = document.createTextNode( + ' Lokalt skikt (vectiler) genererades ' + + last_updated + .sort() + .map((ts) => dateFormatter.format(new Date(ts))) + .join('; ') + '.' + ); + li.appendChild(t); + } - if (x.copyright != null) { - const p = document.createElement('p'); - li.appendChild(p); - const t = document.createTextNode(x.copyright); - p.appendChild(t); + const source_files = new Set(); + x.items.forEach(function([groupname, layername]) { + /* for each source file associated with the accordion header, show copyright, license and timing information */ + const layer_group = metadata[groupname]; + if (layer_group?.layers == null || layer_group?.source_files == null) { + return; } + const def = layer_group.layers[layername]; + if (def?.source_files == null) { + return; + } + def.source_files.forEach(function(source_file) { + if (source_files.has(source_file)) { + return; + } + const x = layer_group.source_files[source_file]; + source_files.add(source_file); + + const li = document.createElement('li'); + li.classList.add('list-group-item'); + ul.appendChild(li); + const h = document.createElement('h6'); + li.appendChild(h); + if (x.description != null) { + const t = document.createTextNode(x.description); + h.appendChild(t); + } - if (x.license != null) { - const p = document.createElement('p'); - li.appendChild(p); - p.appendChild(document.createTextNode('Licensvillkor: ')); - const t = document.createTextNode(x.license.name); - if (x.license.url == null) { + if (x.copyright != null) { + const p = document.createElement('p'); + li.appendChild(p); + const t = document.createTextNode(x.copyright); p.appendChild(t); - } else { + } + + if (x.license != null) { + const p = document.createElement('p'); + li.appendChild(p); + p.appendChild(document.createTextNode('Licensvillkor: ')); + const t = document.createTextNode(x.license.name); + if (x.license.url == null) { + p.appendChild(t); + } else { + const a = document.createElement('a'); + a.href = x.license.url; + a.target = '_blank'; + a.appendChild(t); + p.appendChild(a); + } + } + + if (x.product_url != null) { + const p = document.createElement('p'); + li.appendChild(p); + const t = document.createTextNode('Produktlänk '); + const i = document.createElement('i'); + i.classList.add('bi', 'bi-box-arrow-up-right'); const a = document.createElement('a'); - a.href = x.license.url; + a.href = x.product_url; a.target = '_blank'; a.appendChild(t); + a.appendChild(i); p.appendChild(a); } - } - - if (x.product_url != null) { - const p = document.createElement('p'); - li.appendChild(p); - const t = document.createTextNode('Produktlänk '); - const i = document.createElement('i'); - i.classList.add('bi', 'bi-box-arrow-up-right'); - const a = document.createElement('a'); - a.href = x.product_url; - a.target = '_blank'; - a.appendChild(t); - a.appendChild(i); - p.appendChild(a); - } - if (x.last_modified != null) { - const p = document.createElement('p'); - p.classList.add('small', 'text-muted'); - li.appendChild(p); - const i = document.createElement('i'); - i.classList.add('bi', 'bi-file-earmark-code'); - p.appendChild(i); - p.appendChild(document.createTextNode(' ')); - const t0 = document.createTextNode('Källfil'); - if (x.url == null) { - p.appendChild(t0); - } else { - const a = document.createElement('a'); - p.appendChild(a); + if (x.last_modified != null) { + const p = document.createElement('p'); + p.classList.add('small', 'text-muted'); + li.appendChild(p); const i = document.createElement('i'); - i.classList.add('bi', 'bi-box-arrow-up-right'); - a.appendChild(t0); - a.appendChild(document.createTextNode(' ')); - a.appendChild(i); - a.href = x.url; - a.target = '_blank'; + i.classList.add('bi', 'bi-file-earmark-code'); + p.appendChild(i); + p.appendChild(document.createTextNode(' ')); + const t0 = document.createTextNode('Källfil'); + if (x.url == null) { + p.appendChild(t0); + } else { + const a = document.createElement('a'); + p.appendChild(a); + const i = document.createElement('i'); + i.classList.add('bi', 'bi-box-arrow-up-right'); + a.appendChild(t0); + a.appendChild(document.createTextNode(' ')); + a.appendChild(i); + a.href = x.url; + a.target = '_blank'; + } + const t1 = document.createTextNode(' ändrades senast '); + p.appendChild(t1); + const td = document.createTextNode(dateFormatter.format(new Date(x.last_modified))); + p.appendChild(td); + const t2 = document.createTextNode('.'); + p.appendChild(t2); } - const t1 = document.createTextNode(' ändrades senast '); - p.appendChild(t1); - const td = document.createTextNode(dateFormatter.format(new Date(x.last_modified))); - p.appendChild(td); - const t2 = document.createTextNode('.'); - p.appendChild(t2); - } + }); }); }); }); - }); - }; + }; + })(); + + /* help button */ + (function() { + const [panel] = add_button({ + id: 'help', + title: 'Hjälp med att använda kartan', + bi: 'question-circle', + }); + + /* Use the text from the .html file but ensure that buttons are + * listed in the same order as the menu, and spell titles out. This + * avoids duplication and avoids that things would get out of sync */ + const button_map = {}; + const ol = panel.querySelector('#help-describe-functions'); + if (ol != null && ol.tagName.toLowerCase() === 'ol') { + for (const li of ol.children) { + const id = li.getAttribute('data-for-button'); + if (id == null || id === '') { + continue; + } + button_map[id] = li; + } + } + + for (const node of MENU.children) { + if (node.id == null || node.id === '') { + continue + } + const btn = node.getElementsByTagName('button')[0]; + if (btn == null || btn.tagName.toLowerCase() !== 'button') { + continue; + } + const btn2 = btn.cloneNode(true); + const title = btn2.title; + btn2.id = btn2.title = ''; + for (const attr of btn.attributes) { + if (attr.name.toLowerCase().startsWith('aria-') || attr.name === 'id' || attr.name === 'title') { + btn2.removeAttribute(attr.name); + } + } + + const h = document.createElement('h6'); + h.classList.add('help-button-description'); + h.appendChild(btn2); + if (title != null && title != '') { + const t = document.createTextNode(title) + h.appendChild(t); + } + btn2.classList.add('help-button'); + + ol.insertAdjacentElement('beforebegin', h); + + const li = button_map[node.id]; + if (li != null) { + /* move <li>'s children (paragraphs) to the main text */ + while (li.children.length > 0) { + ol.insertAdjacentElement('beforebegin', li.firstElementChild); + } + } + } + ol.remove(); + })(); })(); /* we're all set, show the control container now */ @@ -157,7 +157,7 @@ body.inprogress { border: none; outline: none; /* eslint-disable-line css/use-baseline */ } -.ol-control button.btn { +.ol-control button.btn, #help-body button.btn.help-button { --bs-btn-padding-x: 0.5rem; --bs-btn-padding-y: 0.5rem; display: block; @@ -299,7 +299,7 @@ body.inprogress { --bs-btn-padding-y: 0.4rem; } } -#info-modal { +#info-modal, #help-modal { /* close the modal when clicking the backdrop */ pointer-events: none; -webkit-user-select: text; @@ -310,7 +310,12 @@ body.inprogress { --modal-info-padding-y: .5rem; --modal-info-bg-light: rgba(0, 0, 0, .08); } -#info-modal .modal-header { +#help-modal { + --modal-info-padding-x: 1rem; + --modal-info-padding-y: 1rem; +} +#info-modal .modal-header, +#help-modal .modal-header { padding: var(--modal-info-padding-y) var(--modal-info-padding-x); } #info-modal .list-group-item, @@ -383,6 +388,61 @@ body.inprogress { padding: var(--modal-info-padding-y) var(--modal-info-padding-x) 0 var(--modal-info-padding-x); margin: 0; } +#help-body { + padding: var(--modal-info-padding-y) var(--modal-info-padding-x); + hyphens: auto; /* eslint-disable-line css/use-baseline */ +} +#help-body .popover-header { + -webkit-user-select: inherit; + -moz-user-select: inherit; + user-select: inherit; /* eslint-disable-line css/use-baseline */ + border: none; + margin: 0; + padding: 0; +} +#help-body .popover-header .popover-button { + height: var(--bs-body-font-size); + width: var(--bs-body-font-size); + padding: 0; + border: none; + vertical-align: middle; +} +#help-body button.btn.help-button { + --bs-btn-padding-x: .1rem; + --bs-btn-padding-y: .1rem; + width: 1.75rem; + height: 1.75rem; + display: inline-block; + font-size: var(--bs-body-font-size); + font-weight: var(--bs-body-font-weight); + line-height: var(--bs-body-line-height); + margin: 0; +} +#help-body .help-button { + pointer-events: none; +} +#help-body .accordion .accordion-button { + display: inline; + padding: 0; + opacity: .75; +} +#help-body .accordion .accordion-button::after { + display: inline-block; + margin: 0; + height: 1rem; + vertical-align: middle; +} +#help-body .help-button-description > button.btn.help-button { + margin-right: .5rem; +} +#help-body p:last-child { + margin-bottom: 0; +} +@media (min-width: 992px) { + #help-body { + text-align: justify; + } +} .ol-overlaycontainer-stopevent .modal-backdrop.show { pointer-events: auto; |