diff options
Diffstat (limited to 'src/dumbymap.mjs')
-rw-r--r-- | src/dumbymap.mjs | 174 |
1 files changed, 88 insertions, 86 deletions
diff --git a/src/dumbymap.mjs b/src/dumbymap.mjs index 241c6b9..dc22021 100644 --- a/src/dumbymap.mjs +++ b/src/dumbymap.mjs | |||
@@ -1,21 +1,21 @@ | |||
1 | import MarkdownIt from "markdown-it"; | 1 | import MarkdownIt from 'markdown-it'; |
2 | import MarkdownItAnchor from "markdown-it-anchor"; | 2 | import MarkdownItAnchor from 'markdown-it-anchor'; |
3 | import MarkdownItFootnote from "markdown-it-footnote"; | 3 | import MarkdownItFootnote from 'markdown-it-footnote'; |
4 | import MarkdownItFrontMatter from "markdown-it-front-matter"; | 4 | import MarkdownItFrontMatter from 'markdown-it-front-matter'; |
5 | import MarkdownItTocDoneRight from "markdown-it-toc-done-right"; | 5 | import MarkdownItTocDoneRight from 'markdown-it-toc-done-right'; |
6 | import LeaderLine from "leader-line"; | 6 | import LeaderLine from 'leader-line'; |
7 | import { renderWith, defaultAliases, parseConfigsFromYaml } from "mapclay"; | 7 | import { renderWith, defaultAliases, parseConfigsFromYaml } from 'mapclay'; |
8 | import { onRemove, animateRectTransition, throttle } from "./utils"; | 8 | import { onRemove, animateRectTransition, throttle } from './utils'; |
9 | import { Layout, SideBySide, Overlay } from "./Layout"; | 9 | import { Layout, SideBySide, Overlay } from './Layout'; |
10 | import * as utils from "./dumbyUtils"; | 10 | import * as utils from './dumbyUtils'; |
11 | 11 | ||
12 | const docLinkSelector = 'a[href^="#"][title^="=>"]'; | 12 | const docLinkSelector = 'a[href^="#"][title^="=>"]'; |
13 | const geoLinkSelector = 'a[href^="geo:"]'; | 13 | const geoLinkSelector = 'a[href^="geo:"]'; |
14 | 14 | ||
15 | const layouts = [ | 15 | const layouts = [ |
16 | new Layout({ name: "normal" }), | 16 | new Layout({ name: 'normal' }), |
17 | new SideBySide({ name: "side-by-side" }), | 17 | new SideBySide({ name: 'side-by-side' }), |
18 | new Overlay({ name: "overlay" }), | 18 | new Overlay({ name: 'overlay' }), |
19 | ]; | 19 | ]; |
20 | const mapCache = {}; | 20 | const mapCache = {}; |
21 | 21 | ||
@@ -26,12 +26,12 @@ const mapCache = {}; | |||
26 | * @param {HTMLElement} Elements contains anchor elements for doclinks | 26 | * @param {HTMLElement} Elements contains anchor elements for doclinks |
27 | */ | 27 | */ |
28 | export const createDocLink = link => { | 28 | export const createDocLink = link => { |
29 | link.classList.add("with-leader-line", "doclink"); | 29 | link.classList.add('with-leader-line', 'doclink'); |
30 | link.lines = []; | 30 | link.lines = []; |
31 | 31 | ||
32 | link.onmouseover = () => { | 32 | link.onmouseover = () => { |
33 | const label = decodeURIComponent(link.href.split("#")[1]); | 33 | const label = decodeURIComponent(link.href.split('#')[1]); |
34 | const selector = link.title.split("=>")[1] ?? "#" + label; | 34 | const selector = link.title.split('=>')[1] ?? '#' + label; |
35 | const target = document.querySelector(selector); | 35 | const target = document.querySelector(selector); |
36 | if (!target?.checkVisibility()) return; | 36 | if (!target?.checkVisibility()) return; |
37 | 37 | ||
@@ -40,13 +40,13 @@ export const createDocLink = link => { | |||
40 | end: target, | 40 | end: target, |
41 | middleLabel: LeaderLine.pathLabel({ | 41 | middleLabel: LeaderLine.pathLabel({ |
42 | text: label, | 42 | text: label, |
43 | fontWeight: "bold", | 43 | fontWeight: 'bold', |
44 | }), | 44 | }), |
45 | hide: true, | 45 | hide: true, |
46 | path: "magnet", | 46 | path: 'magnet', |
47 | }); | 47 | }); |
48 | link.lines.push(line); | 48 | link.lines.push(line); |
49 | line.show("draw", { duration: 300 }); | 49 | line.show('draw', { duration: 300 }); |
50 | }; | 50 | }; |
51 | link.onmouseout = () => { | 51 | link.onmouseout = () => { |
52 | link.lines.forEach(line => line.remove()); | 52 | link.lines.forEach(line => line.remove()); |
@@ -63,13 +63,13 @@ export const createDocLink = link => { | |||
63 | */ | 63 | */ |
64 | export const createGeoLink = (link, callback = null) => { | 64 | export const createGeoLink = (link, callback = null) => { |
65 | const url = new URL(link.href); | 65 | const url = new URL(link.href); |
66 | const xyInParams = url.searchParams.get("xy"); | 66 | const xyInParams = url.searchParams.get('xy'); |
67 | const xy = xyInParams | 67 | const xy = xyInParams |
68 | ? xyInParams.split(",")?.map(Number) | 68 | ? xyInParams.split(',')?.map(Number) |
69 | : url?.href | 69 | : url?.href |
70 | ?.match(/^geo:([0-9.,]+)/) | 70 | ?.match(/^geo:([0-9.,]+)/) |
71 | ?.at(1) | 71 | ?.at(1) |
72 | ?.split(",") | 72 | ?.split(',') |
73 | ?.reverse() | 73 | ?.reverse() |
74 | ?.map(Number); | 74 | ?.map(Number); |
75 | 75 | ||
@@ -78,8 +78,8 @@ export const createGeoLink = (link, callback = null) => { | |||
78 | // Geo information in link | 78 | // Geo information in link |
79 | link.url = url; | 79 | link.url = url; |
80 | link.xy = xy; | 80 | link.xy = xy; |
81 | link.classList.add("with-leader-line", "geolink"); | 81 | link.classList.add('with-leader-line', 'geolink'); |
82 | link.targets = link.url.searchParams.get("id")?.split(",") ?? null; | 82 | link.targets = link.url.searchParams.get('id')?.split(',') ?? null; |
83 | 83 | ||
84 | // LeaderLine | 84 | // LeaderLine |
85 | link.lines = []; | 85 | link.lines = []; |
@@ -94,7 +94,7 @@ export const markdown2HTML = (container, mdContent) => { | |||
94 | Array.from(container.children).map(e => e.remove()); | 94 | Array.from(container.children).map(e => e.remove()); |
95 | 95 | ||
96 | container.innerHTML = '<div class="SemanticHtml"></div>'; | 96 | container.innerHTML = '<div class="SemanticHtml"></div>'; |
97 | const htmlHolder = container.querySelector(".SemanticHtml"); | 97 | const htmlHolder = container.querySelector('.SemanticHtml'); |
98 | 98 | ||
99 | const md = MarkdownIt({ | 99 | const md = MarkdownIt({ |
100 | html: true, | 100 | html: true, |
@@ -102,7 +102,7 @@ export const markdown2HTML = (container, mdContent) => { | |||
102 | }) | 102 | }) |
103 | .use(MarkdownItAnchor, { | 103 | .use(MarkdownItAnchor, { |
104 | permalink: MarkdownItAnchor.permalink.linkInsideHeader({ | 104 | permalink: MarkdownItAnchor.permalink.linkInsideHeader({ |
105 | placement: "before", | 105 | placement: 'before', |
106 | }), | 106 | }), |
107 | }) | 107 | }) |
108 | .use(MarkdownItFootnote) | 108 | .use(MarkdownItFootnote) |
@@ -110,49 +110,49 @@ export const markdown2HTML = (container, mdContent) => { | |||
110 | .use(MarkdownItTocDoneRight); | 110 | .use(MarkdownItTocDoneRight); |
111 | 111 | ||
112 | // FIXME A better way to generate blocks | 112 | // FIXME A better way to generate blocks |
113 | md.renderer.rules.dumby_block_open = () => "<div>"; | 113 | md.renderer.rules.dumby_block_open = () => '<div>'; |
114 | md.renderer.rules.dumby_block_close = () => "</div>"; | 114 | md.renderer.rules.dumby_block_close = () => '</div>'; |
115 | 115 | ||
116 | md.core.ruler.before("block", "dumby_block", state => { | 116 | md.core.ruler.before('block', 'dumby_block', state => { |
117 | state.tokens.push(new state.Token("dumby_block_open", "", 1)); | 117 | state.tokens.push(new state.Token('dumby_block_open', '', 1)); |
118 | }); | 118 | }); |
119 | 119 | ||
120 | // Add close tag for block with more than 2 empty lines | 120 | // Add close tag for block with more than 2 empty lines |
121 | md.block.ruler.before("table", "dumby_block", (state, startLine) => { | 121 | md.block.ruler.before('table', 'dumby_block', (state, startLine) => { |
122 | if ( | 122 | if ( |
123 | state.src[state.bMarks[startLine - 1]] === "\n" && | 123 | state.src[state.bMarks[startLine - 1]] === '\n' && |
124 | state.src[state.bMarks[startLine - 2]] === "\n" && | 124 | state.src[state.bMarks[startLine - 2]] === '\n' && |
125 | state.tokens.at(-1).type !== "list_item_open" // Quick hack for not adding tag after "::marker" for <li> | 125 | state.tokens.at(-1).type !== 'list_item_open' // Quick hack for not adding tag after "::marker" for <li> |
126 | ) { | 126 | ) { |
127 | state.push("dumby_block_close", "", -1); | 127 | state.push('dumby_block_close', '', -1); |
128 | state.push("dumby_block_open", "", 1); | 128 | state.push('dumby_block_open', '', 1); |
129 | } | 129 | } |
130 | }); | 130 | }); |
131 | 131 | ||
132 | md.core.ruler.after("block", "dumby_block", state => { | 132 | md.core.ruler.after('block', 'dumby_block', state => { |
133 | state.tokens.push(new state.Token("dumby_block_close", "", -1)); | 133 | state.tokens.push(new state.Token('dumby_block_close', '', -1)); |
134 | }); | 134 | }); |
135 | 135 | ||
136 | const contentWithToc = "${toc}\n\n\n" + mdContent; | 136 | const contentWithToc = '${toc}\n\n\n' + mdContent; |
137 | htmlHolder.innerHTML = md.render(contentWithToc); | 137 | htmlHolder.innerHTML = md.render(contentWithToc); |
138 | 138 | ||
139 | // TODO Do this in markdown-it | 139 | // TODO Do this in markdown-it |
140 | const blocks = htmlHolder.querySelectorAll(":scope > div:not(:has(nav))"); | 140 | const blocks = htmlHolder.querySelectorAll(':scope > div:not(:has(nav))'); |
141 | blocks.forEach(b => { | 141 | blocks.forEach(b => { |
142 | b.classList.add("dumby-block"); | 142 | b.classList.add('dumby-block'); |
143 | b.setAttribute("data-total", blocks.length); | 143 | b.setAttribute('data-total', blocks.length); |
144 | }); | 144 | }); |
145 | 145 | ||
146 | return container; | 146 | return container; |
147 | //}}} | 147 | //}}} |
148 | }; | 148 | }; |
149 | export const generateMaps = (container, { delay, mapCallback }) => { | 149 | export const generateMaps = (container, { delay, mapCallback }) => { |
150 | container.classList.add("Dumby"); | 150 | container.classList.add('Dumby'); |
151 | const htmlHolder = container.querySelector(".SemanticHtml") ?? container; | 151 | const htmlHolder = container.querySelector('.SemanticHtml') ?? container; |
152 | const blocks = Array.from(htmlHolder.querySelectorAll(".dumby-block")); | 152 | const blocks = Array.from(htmlHolder.querySelectorAll('.dumby-block')); |
153 | const showcase = document.createElement("div"); | 153 | const showcase = document.createElement('div'); |
154 | container.appendChild(showcase); | 154 | container.appendChild(showcase); |
155 | showcase.classList.add("Showcase"); | 155 | showcase.classList.add('Showcase'); |
156 | const renderMaps = []; | 156 | const renderMaps = []; |
157 | 157 | ||
158 | const dumbymap = { | 158 | const dumbymap = { |
@@ -196,13 +196,13 @@ export const generateMaps = (container, { delay, mapCallback }) => { | |||
196 | ).filter(l => createGeoLink(l, geoLinkCallback)); | 196 | ).filter(l => createGeoLink(l, geoLinkCallback)); |
197 | 197 | ||
198 | const isAnchorPointedBy = link => anchor => { | 198 | const isAnchorPointedBy = link => anchor => { |
199 | const mapContainer = anchor.closest(".mapclay"); | 199 | const mapContainer = anchor.closest('.mapclay'); |
200 | const isTarget = !link.targets || link.targets.includes(mapContainer.id); | 200 | const isTarget = !link.targets || link.targets.includes(mapContainer.id); |
201 | return anchor.title === link.url.pathname && isTarget; | 201 | return anchor.title === link.url.pathname && isTarget; |
202 | }; | 202 | }; |
203 | 203 | ||
204 | const isAnchorVisible = anchor => { | 204 | const isAnchorVisible = anchor => { |
205 | const mapContainer = anchor.closest(".mapclay"); | 205 | const mapContainer = anchor.closest('.mapclay'); |
206 | return insideWindow(anchor) && insideParent(anchor, mapContainer); | 206 | return insideWindow(anchor) && insideParent(anchor, mapContainer); |
207 | }; | 207 | }; |
208 | 208 | ||
@@ -211,10 +211,10 @@ export const generateMaps = (container, { delay, mapCallback }) => { | |||
211 | start: link, | 211 | start: link, |
212 | end: anchor, | 212 | end: anchor, |
213 | hide: true, | 213 | hide: true, |
214 | middleLabel: link.url.searchParams.get("text"), | 214 | middleLabel: link.url.searchParams.get('text'), |
215 | path: "magnet", | 215 | path: 'magnet', |
216 | }); | 216 | }); |
217 | line.show("draw", { duration: 300 }); | 217 | line.show('draw', { duration: 300 }); |
218 | return line; | 218 | return line; |
219 | }; | 219 | }; |
220 | 220 | ||
@@ -232,7 +232,7 @@ export const generateMaps = (container, { delay, mapCallback }) => { | |||
232 | }; | 232 | }; |
233 | 233 | ||
234 | const updateMapByMarker = xy => marker => { | 234 | const updateMapByMarker = xy => marker => { |
235 | const renderer = marker.closest(".mapclay")?.renderer; | 235 | const renderer = marker.closest('.mapclay')?.renderer; |
236 | renderer.updateCamera({ center: xy }, true); | 236 | renderer.updateCamera({ center: xy }, true); |
237 | }; | 237 | }; |
238 | 238 | ||
@@ -273,7 +273,7 @@ export const generateMaps = (container, { delay, mapCallback }) => { | |||
273 | const target = mutation.target; | 273 | const target = mutation.target; |
274 | const focus = target | 274 | const focus = target |
275 | .getAttribute(mutation.attributeName) | 275 | .getAttribute(mutation.attributeName) |
276 | .includes("focus"); | 276 | .includes('focus'); |
277 | const shouldBeInShowcase = | 277 | const shouldBeInShowcase = |
278 | focus && | 278 | focus && |
279 | showcase.checkVisibility({ | 279 | showcase.checkVisibility({ |
@@ -287,8 +287,8 @@ export const generateMaps = (container, { delay, mapCallback }) => { | |||
287 | 287 | ||
288 | // Placeholder for map in Showcase, it should has the same DOMRect | 288 | // Placeholder for map in Showcase, it should has the same DOMRect |
289 | const placeholder = target.cloneNode(true); | 289 | const placeholder = target.cloneNode(true); |
290 | placeholder.removeAttribute("id"); | 290 | placeholder.removeAttribute('id'); |
291 | placeholder.classList.remove("mapclay", "focus"); | 291 | placeholder.classList.remove('mapclay', 'focus'); |
292 | target.parentElement.replaceChild(placeholder, target); | 292 | target.parentElement.replaceChild(placeholder, target); |
293 | 293 | ||
294 | // FIXME Maybe use @start-style for CSS | 294 | // FIXME Maybe use @start-style for CSS |
@@ -297,10 +297,10 @@ export const generateMaps = (container, { delay, mapCallback }) => { | |||
297 | // To make sure the original height of placeholder is applied, DOM changes seems needed | 297 | // To make sure the original height of placeholder is applied, DOM changes seems needed |
298 | // then set data-attribute for CSS selector to change height to 0 | 298 | // then set data-attribute for CSS selector to change height to 0 |
299 | placeholder.getBoundingClientRect(); | 299 | placeholder.getBoundingClientRect(); |
300 | placeholder.setAttribute("data-placeholder", target.id); | 300 | placeholder.setAttribute('data-placeholder', target.id); |
301 | 301 | ||
302 | // To fit showcase, remove all inline style | 302 | // To fit showcase, remove all inline style |
303 | target.removeAttribute("style"); | 303 | target.removeAttribute('style'); |
304 | showcase.appendChild(target); | 304 | showcase.appendChild(target); |
305 | 305 | ||
306 | // Resume rect from Semantic HTML to Showcase, with animation | 306 | // Resume rect from Semantic HTML to Showcase, with animation |
@@ -333,7 +333,7 @@ export const generateMaps = (container, { delay, mapCallback }) => { | |||
333 | // Layout {{{ | 333 | // Layout {{{ |
334 | // press key to switch layout | 334 | // press key to switch layout |
335 | const defaultLayout = layouts[0]; | 335 | const defaultLayout = layouts[0]; |
336 | container.setAttribute("data-layout", defaultLayout.name); | 336 | container.setAttribute('data-layout', defaultLayout.name); |
337 | 337 | ||
338 | // observe layout change | 338 | // observe layout change |
339 | const layoutObserver = new MutationObserver(mutations => { | 339 | const layoutObserver = new MutationObserver(mutations => { |
@@ -351,7 +351,7 @@ export const generateMaps = (container, { delay, mapCallback }) => { | |||
351 | Object.values(dumbymap) | 351 | Object.values(dumbymap) |
352 | .flat() | 352 | .flat() |
353 | .filter(ele => ele instanceof HTMLElement) | 353 | .filter(ele => ele instanceof HTMLElement) |
354 | .forEach(ele => ele.removeAttribute("style")); | 354 | .forEach(ele => ele.removeAttribute('style')); |
355 | 355 | ||
356 | if (newLayout) { | 356 | if (newLayout) { |
357 | layouts | 357 | layouts |
@@ -362,13 +362,13 @@ export const generateMaps = (container, { delay, mapCallback }) => { | |||
362 | // Since layout change may show/hide showcase, the current focused map should do something | 362 | // Since layout change may show/hide showcase, the current focused map should do something |
363 | // Reset attribute triggers MutationObserver which is observing it | 363 | // Reset attribute triggers MutationObserver which is observing it |
364 | const focusMap = | 364 | const focusMap = |
365 | container.querySelector(".mapclay.focus") ?? | 365 | container.querySelector('.mapclay.focus') ?? |
366 | container.querySelector(".mapclay"); | 366 | container.querySelector('.mapclay'); |
367 | focusMap?.classList?.add("focus"); | 367 | focusMap?.classList?.add('focus'); |
368 | }); | 368 | }); |
369 | layoutObserver.observe(container, { | 369 | layoutObserver.observe(container, { |
370 | attributes: true, | 370 | attributes: true, |
371 | attributeFilter: ["data-layout"], | 371 | attributeFilter: ['data-layout'], |
372 | attributeOldValue: true, | 372 | attributeOldValue: true, |
373 | characterDataOldValue: true, | 373 | characterDataOldValue: true, |
374 | }); | 374 | }); |
@@ -380,8 +380,10 @@ export const generateMaps = (container, { delay, mapCallback }) => { | |||
380 | 380 | ||
381 | const afterMapRendered = renderer => { | 381 | const afterMapRendered = renderer => { |
382 | const mapElement = renderer.target; | 382 | const mapElement = renderer.target; |
383 | mapElement.setAttribute("tabindex", "-1"); | 383 | //FIXME |
384 | if (mapElement.getAttribute("data-render") === "fulfilled") { | 384 | mapElement.renderer = renderer; |
385 | mapElement.setAttribute('tabindex', '-1'); | ||
386 | if (mapElement.getAttribute('data-render') === 'fulfilled') { | ||
385 | mapCache[mapElement.id] = renderer; | 387 | mapCache[mapElement.id] = renderer; |
386 | } | 388 | } |
387 | 389 | ||
@@ -394,14 +396,14 @@ export const generateMaps = (container, { delay, mapCallback }) => { | |||
394 | // Add markers with Geolinks | 396 | // Add markers with Geolinks |
395 | renderer.addMarkers(markers); | 397 | renderer.addMarkers(markers); |
396 | mapElement | 398 | mapElement |
397 | .querySelectorAll(".marker") | 399 | .querySelectorAll('.marker') |
398 | .forEach(marker => htmlHolder.anchors.push(marker)); | 400 | .forEach(marker => htmlHolder.anchors.push(marker)); |
399 | 401 | ||
400 | // Work with Mutation Observer | 402 | // Work with Mutation Observer |
401 | const observer = mapFocusObserver(); | 403 | const observer = mapFocusObserver(); |
402 | mapFocusObserver().observe(mapElement, { | 404 | mapFocusObserver().observe(mapElement, { |
403 | attributes: true, | 405 | attributes: true, |
404 | attributeFilter: ["class"], | 406 | attributeFilter: ['class'], |
405 | attributeOldValue: true, | 407 | attributeOldValue: true, |
406 | }); | 408 | }); |
407 | onRemove(mapElement, () => observer.disconnect()); | 409 | onRemove(mapElement, () => observer.disconnect()); |
@@ -412,10 +414,10 @@ export const generateMaps = (container, { delay, mapCallback }) => { | |||
412 | const assignMapId = config => { | 414 | const assignMapId = config => { |
413 | let mapId = config.id; | 415 | let mapId = config.id; |
414 | if (!mapId) { | 416 | if (!mapId) { |
415 | mapId = config.use?.split("/")?.at(-1); | 417 | mapId = config.use?.split('/')?.at(-1); |
416 | let counter = 1; | 418 | let counter = 1; |
417 | while (!mapId || mapIdList.includes(mapId)) { | 419 | while (!mapId || mapIdList.includes(mapId)) { |
418 | mapId = `${config.use ?? "unnamed"}-${counter}`; | 420 | mapId = `${config.use ?? 'unnamed'}-${counter}`; |
419 | counter++; | 421 | counter++; |
420 | } | 422 | } |
421 | config.id = mapId; | 423 | config.id = mapId; |
@@ -426,21 +428,21 @@ export const generateMaps = (container, { delay, mapCallback }) => { | |||
426 | 428 | ||
427 | // Render each code block with "language-map" class | 429 | // Render each code block with "language-map" class |
428 | const elementsWithMapConfig = Array.from( | 430 | const elementsWithMapConfig = Array.from( |
429 | container.querySelectorAll('pre:has(.language-map)') ?? [] | 431 | container.querySelectorAll('pre:has(.language-map)') ?? [], |
430 | ) | 432 | ); |
431 | /** | 433 | /** |
432 | * updateAttributeByStep. | 434 | * updateAttributeByStep. |
433 | * | 435 | * |
434 | * @param {Object} -- renderer which is running steps | 436 | * @param {Object} -- renderer which is running steps |
435 | */ | 437 | */ |
436 | const updateAttributeByStep = ({ results, target, steps }) => { | 438 | const updateAttributeByStep = ({ results, target, steps }) => { |
437 | let passNum = results | 439 | let passNum = results.filter( |
438 | .filter(r => r.type === 'step' && r.state.match(/success|skip/)) | 440 | r => r.type === 'step' && r.state.match(/success|skip/), |
439 | .length | 441 | ).length; |
440 | const total = steps.length; | 442 | const total = steps.length; |
441 | passNum += `/${total}`; | 443 | passNum += `/${total}`; |
442 | if (results.filter(r=>r.type === 'step').length === total) { | 444 | if (results.filter(r => r.type === 'step').length === total) { |
443 | passNum += '\u0020' | 445 | passNum += '\u0020'; |
444 | } | 446 | } |
445 | 447 | ||
446 | // FIXME HACK use MutationObserver for animation | 448 | // FIXME HACK use MutationObserver for animation |
@@ -449,7 +451,7 @@ export const generateMaps = (container, { delay, mapCallback }) => { | |||
449 | await new Promise(resolve => setTimeout(resolve, 150)); | 451 | await new Promise(resolve => setTimeout(resolve, 150)); |
450 | target.setAttribute('data-report', passNum); | 452 | target.setAttribute('data-report', passNum); |
451 | }); | 453 | }); |
452 | } | 454 | }; |
453 | /** | 455 | /** |
454 | * config converter for mapclay.renderWith() | 456 | * config converter for mapclay.renderWith() |
455 | * | 457 | * |
@@ -465,21 +467,21 @@ export const generateMaps = (container, { delay, mapCallback }) => { | |||
465 | ...(config.aliases ?? {}), | 467 | ...(config.aliases ?? {}), |
466 | }, | 468 | }, |
467 | stepCallback: updateAttributeByStep, | 469 | stepCallback: updateAttributeByStep, |
468 | }) | 470 | }); |
469 | const render = renderWith(configConverter) | 471 | const render = renderWith(configConverter); |
470 | elementsWithMapConfig.forEach(target => { | 472 | elementsWithMapConfig.forEach(target => { |
471 | // Get text in code block starts with markdown text '```map' | 473 | // Get text in code block starts with markdown text '```map' |
472 | const configText = target | 474 | const configText = target |
473 | .querySelector(".language-map") | 475 | .querySelector('.language-map') |
474 | .textContent // BE CAREFUL!!! 0xa0 char is "non-breaking spaces" in HTML text content | 476 | .textContent // BE CAREFUL!!! 0xa0 char is "non-breaking spaces" in HTML text content |
475 | // replace it by normal space | 477 | // replace it by normal space |
476 | .replace(/\u00A0/g, "\u0020"); | 478 | .replace(/\u00A0/g, '\u0020'); |
477 | 479 | ||
478 | let configList = []; | 480 | let configList = []; |
479 | try { | 481 | try { |
480 | configList = parseConfigsFromYaml(configText).map(assignMapId); | 482 | configList = parseConfigsFromYaml(configText).map(assignMapId); |
481 | } catch (_) { | 483 | } catch (_) { |
482 | console.warn("Fail to parse yaml config for element", target); | 484 | console.warn('Fail to parse yaml config for element', target); |
483 | return; | 485 | return; |
484 | } | 486 | } |
485 | 487 | ||
@@ -494,9 +496,9 @@ export const generateMaps = (container, { delay, mapCallback }) => { | |||
494 | }); | 496 | }); |
495 | 497 | ||
496 | // trivial: if map cache is applied, do not show yaml text | 498 | // trivial: if map cache is applied, do not show yaml text |
497 | if (target.querySelector(".mapclay")) { | 499 | if (target.querySelector('.mapclay')) { |
498 | target | 500 | target |
499 | .querySelectorAll(":scope > :not([data-render=fulfilled])") | 501 | .querySelectorAll(':scope > :not([data-render=fulfilled])') |
500 | .forEach(e => e.remove()); | 502 | .forEach(e => e.remove()); |
501 | } | 503 | } |
502 | 504 | ||