diff options
| author | Hsieh Chin Fan <pham@topo.tw> | 2024-09-12 11:36:50 +0800 |
|---|---|---|
| committer | Hsieh Chin Fan <pham@topo.tw> | 2024-09-12 16:28:56 +0800 |
| commit | 6fad3f93ec8a92e71138853e36e0fd2526cc2942 (patch) | |
| tree | abae0ef526e0217e1c241c44d483ff38cca8733f /src | |
| parent | 9cdc8b1e6b4f57bb2d6ec5d756bcd5e348afcd96 (diff) | |
feat: export method createGeoLinks()
Diffstat (limited to 'src')
| -rw-r--r-- | src/dumbymap.mjs | 69 |
1 files changed, 37 insertions, 32 deletions
diff --git a/src/dumbymap.mjs b/src/dumbymap.mjs index a896d0d..f5cab8e 100644 --- a/src/dumbymap.mjs +++ b/src/dumbymap.mjs | |||
| @@ -25,7 +25,7 @@ const onRemove = (element, callback) => { | |||
| 25 | obs.observe(parent, { childList: true, }); | 25 | obs.observe(parent, { childList: true, }); |
| 26 | } | 26 | } |
| 27 | // }}} | 27 | // }}} |
| 28 | // FUNCTION: Get DocLinks from normal special anchor element {{{ | 28 | // FUNCTION: Get DocLinks from special anchor element {{{ |
| 29 | 29 | ||
| 30 | const docLinkSelector = 'a[href^="#"][title^="=>"]' | 30 | const docLinkSelector = 'a[href^="#"][title^="=>"]' |
| 31 | export const createDocLinks = (container) => Array.from(container.querySelectorAll(docLinkSelector)) | 31 | export const createDocLinks = (container) => Array.from(container.querySelectorAll(docLinkSelector)) |
| @@ -60,6 +60,30 @@ export const createDocLinks = (container) => Array.from(container.querySelectorA | |||
| 60 | return link | 60 | return link |
| 61 | }) | 61 | }) |
| 62 | // }}} | 62 | // }}} |
| 63 | // FUNCTION: Get GeoLinks from special anchor element {{{ | ||
| 64 | // Links points to map by geo schema and id | ||
| 65 | const geoLinkSelector = 'a[href^="geo:"]' | ||
| 66 | export const createGeoLinks = (container, callback) => Array.from(container.querySelectorAll(geoLinkSelector)) | ||
| 67 | .filter(link => { | ||
| 68 | const url = new URL(link.href) | ||
| 69 | const xy = url?.href?.match(/^geo:([0-9.,]+)/)?.at(1)?.split(',')?.reverse()?.map(Number) | ||
| 70 | |||
| 71 | if (!xy || isNaN(xy[0]) || isNaN(xy[1])) return false | ||
| 72 | |||
| 73 | // Geo information in link | ||
| 74 | link.url = url | ||
| 75 | link.xy = xy | ||
| 76 | link.classList.add('with-leader-line', 'geolink') | ||
| 77 | link.targets = link.url.searchParams.get('id')?.split(',') ?? null | ||
| 78 | |||
| 79 | // LeaderLine | ||
| 80 | link.lines = [] | ||
| 81 | callback(link) | ||
| 82 | |||
| 83 | return true | ||
| 84 | }) | ||
| 85 | |||
| 86 | // }}} | ||
| 63 | export const markdown2HTML = (container, mdContent) => { | 87 | export const markdown2HTML = (container, mdContent) => { |
| 64 | // Render: Markdown -> HTML {{{ | 88 | // Render: Markdown -> HTML {{{ |
| 65 | Array.from(container.children).map(e => e.remove()) | 89 | Array.from(container.children).map(e => e.remove()) |
| @@ -119,6 +143,18 @@ export const generateMaps = async (container) => { | |||
| 119 | // Get anchors with "geo:" scheme | 143 | // Get anchors with "geo:" scheme |
| 120 | const htmlHolder = container.querySelector('.SemanticHtml') ?? container | 144 | const htmlHolder = container.querySelector('.SemanticHtml') ?? container |
| 121 | htmlHolder.anchors = [] | 145 | htmlHolder.anchors = [] |
| 146 | const geoLinks = createGeoLinks(htmlHolder, (link) => { | ||
| 147 | link.onmouseover = () => addLeaderLines(link) | ||
| 148 | link.onmouseout = () => removeLeaderLines(link) | ||
| 149 | link.onclick = (event) => { | ||
| 150 | event.preventDefault() | ||
| 151 | htmlHolder.anchors | ||
| 152 | .filter(isAnchorPointedBy(link)) | ||
| 153 | .forEach(updateMapByMarker(link.xy)) | ||
| 154 | // TODO Just hide leader line and show it again | ||
| 155 | removeLeaderLines(link) | ||
| 156 | } | ||
| 157 | }) | ||
| 122 | 158 | ||
| 123 | // Set focusArea | 159 | // Set focusArea |
| 124 | const showcase = document.createElement('div') | 160 | const showcase = document.createElement('div') |
| @@ -128,36 +164,6 @@ export const generateMaps = async (container) => { | |||
| 128 | mapPlaceholder.id = 'mapPlaceholder' | 164 | mapPlaceholder.id = 'mapPlaceholder' |
| 129 | showcase.appendChild(mapPlaceholder) | 165 | showcase.appendChild(mapPlaceholder) |
| 130 | 166 | ||
| 131 | // Links points to map by geo schema and id | ||
| 132 | const geoLinks = Array.from(htmlHolder.querySelectorAll('a[href^="geo:"]')) | ||
| 133 | .filter(link => { | ||
| 134 | const url = new URL(link.href) | ||
| 135 | const xy = url?.href?.match(/^geo:([0-9.,]+)/)?.at(1)?.split(',')?.reverse()?.map(Number) | ||
| 136 | |||
| 137 | if (!xy || isNaN(xy[0]) || isNaN(xy[1])) return false | ||
| 138 | |||
| 139 | // Geo information in link | ||
| 140 | link.url = url | ||
| 141 | link.xy = xy | ||
| 142 | link.classList.add('with-leader-line', 'geolink') | ||
| 143 | link.targets = link.url.searchParams.get('id')?.split(',') ?? null | ||
| 144 | |||
| 145 | // LeaderLine | ||
| 146 | link.lines = [] | ||
| 147 | link.onmouseover = () => addLeaderLines(link) | ||
| 148 | link.onmouseout = () => removeLeaderLines(link) | ||
| 149 | link.onclick = (event) => { | ||
| 150 | event.preventDefault() | ||
| 151 | htmlHolder.anchors | ||
| 152 | .filter(isAnchorPointedBy(link)) | ||
| 153 | .forEach(updateMapByMarker(xy)) | ||
| 154 | // TODO Just hide leader line and show it again | ||
| 155 | removeLeaderLines(link) | ||
| 156 | } | ||
| 157 | |||
| 158 | return true | ||
| 159 | }) | ||
| 160 | |||
| 161 | const isAnchorPointedBy = (link) => (anchor) => { | 167 | const isAnchorPointedBy = (link) => (anchor) => { |
| 162 | const mapContainer = anchor.closest('.map-container') | 168 | const mapContainer = anchor.closest('.map-container') |
| 163 | const isTarget = !link.targets || link.targets.includes(mapContainer.id) | 169 | const isTarget = !link.targets || link.targets.includes(mapContainer.id) |
| @@ -276,7 +282,6 @@ export const generateMaps = async (container) => { | |||
| 276 | Object.assign(result, { markers: markersFromLinks }) | 282 | Object.assign(result, { markers: markersFromLinks }) |
| 277 | return result | 283 | return result |
| 278 | }) | 284 | }) |
| 279 | /* eslint-disable no-unused-vars */ | ||
| 280 | } catch (_) { | 285 | } catch (_) { |
| 281 | console.warn('Fail to parse yaml config for element', target) | 286 | console.warn('Fail to parse yaml config for element', target) |
| 282 | } | 287 | } |