diff options
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 | } |