aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorHsieh Chin Fan <pham@topo.tw>2024-09-29 14:12:07 +0800
committerHsieh Chin Fan <pham@topo.tw>2024-09-29 15:06:28 +0800
commit88201b62764931868f0bc3cae978edb3fd307485 (patch)
tree84300275f6e9a56ac47f5adcc287cfcbf5050504 /src
parentc3f47cff4a7fb897f802558f85ac79e10297b95b (diff)
feat(mapclay): add callback to indicate rendering progress
Diffstat (limited to 'src')
-rw-r--r--src/css/dumbymap.css42
-rw-r--r--src/dumbymap.mjs42
2 files changed, 74 insertions, 10 deletions
diff --git a/src/css/dumbymap.css b/src/css/dumbymap.css
index 7b7f393..c6782fc 100644
--- a/src/css/dumbymap.css
+++ b/src/css/dumbymap.css
@@ -52,6 +52,8 @@ root {
52 position: relative; 52 position: relative;
53 transform-origin: top left; 53 transform-origin: top left;
54 54
55 transition: flex-basis 300ms ease-in-out;
56
55 &.focus::after { 57 &.focus::after {
56 content: 'Map-ID: ' attr(id); 58 content: 'Map-ID: ' attr(id);
57 padding: 0.3rem 0.5rem; 59 padding: 0.3rem 0.5rem;
@@ -75,18 +77,52 @@ root {
75 opacity: 0; 77 opacity: 0;
76 animation: 1.5s forwards fade-out cubic-bezier(0.44, 0.18, 0.86, -0.21); 78 animation: 1.5s forwards fade-out cubic-bezier(0.44, 0.18, 0.86, -0.21);
77 } 79 }
80
81 &[data-report*='/'] {
82 &::after {
83 content: attr(data-report);
84 padding: 0.3rem 0.5rem;
85
86 position: absolute;
87 left: 50%;
88 top: 50%;
89 z-index: 9999;
90
91 border: solid transparent;
92 border-radius: 5px;
93
94 background: gray;
95
96 color: white;
97 font-size: 1.5rem;
98 font-weight: bold;
99 line-height: 1.2;
100
101 transform: translate(-50%, -50%);
102 }
103
104 &[data-render='fulfilled'][data-report$="\20"]::after {
105 content: '\2714 ' attr(data-report);
106 animation: 1.5s forwards fade-out cubic-bezier(0.44, 0.18, 0.86, -0.21);
107 }
108
109 &[data-render='unfulfilled'][data-report$="\20"]::after {
110 content: '\2716 ' attr(data-report);
111 animation: 2.5s forwards fade-out cubic-bezier(0.44, 0.18, 0.86, -0.21);
112 }
113 }
78} 114}
79 115
80.with-leader-line:not(:has(> *)) { 116.with-leader-line:not(:has(> *)) {
81 display: inline-block; 117 display: inline-block;
118 padding-right: 15px;
119 padding-left: 6px;
82 120
83 background-image: url('data:image/svg+xml;charset=utf-8;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0Ij48cG9seWdvbiBwb2ludHM9IjI0LDAgMCw4IDgsMTEgMCwxOSA1LDI0IDEzLDE2IDE2LDI0IiBmaWxsPSJjb3JhbCIvPjwvc3ZnPg=='); 121 background-image: url('data:image/svg+xml;charset=utf-8;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0Ij48cG9seWdvbiBwb2ludHM9IjI0LDAgMCw4IDgsMTEgMCwxOSA1LDI0IDEzLDE2IDE2LDI0IiBmaWxsPSJjb3JhbCIvPjwvc3ZnPg==');
84 background-repeat: no-repeat; 122 background-repeat: no-repeat;
85 background-position: right 2px top 2px; 123 background-position: right 2px top 2px;
86 124
87 color: #555; 125 color: #555;
88 padding-right: 15px;
89 padding-left: 6px;
90 background-size: 12px 12px; 126 background-size: 12px 12px;
91 127
92 &.geolink { 128 &.geolink {
@@ -219,9 +255,9 @@ root {
219.SemanticHtml { 255.SemanticHtml {
220 display: flex; 256 display: flex;
221 flex-direction: column; 257 flex-direction: column;
258 justify-content: flex-start;
222 height: 100%; 259 height: 100%;
223 gap: 1rem; 260 gap: 1rem;
224 justify-content: flex-start;
225 overflow-y: auto; 261 overflow-y: auto;
226 262
227 /* Trivial: gray out text not focused */ 263 /* Trivial: gray out text not focused */
diff --git a/src/dumbymap.mjs b/src/dumbymap.mjs
index cb029de..241c6b9 100644
--- a/src/dumbymap.mjs
+++ b/src/dumbymap.mjs
@@ -426,19 +426,47 @@ export const generateMaps = (container, { delay, mapCallback }) => {
426 426
427 // Render each code block with "language-map" class 427 // Render each code block with "language-map" class
428 const elementsWithMapConfig = Array.from( 428 const elementsWithMapConfig = Array.from(
429 container.querySelectorAll("pre:has(.language-map)") ?? [], 429 container.querySelectorAll('pre:has(.language-map)') ?? []
430 ); 430 )
431 // Add default aliases into each config 431 /**
432 * updateAttributeByStep.
433 *
434 * @param {Object} -- renderer which is running steps
435 */
436 const updateAttributeByStep = ({ results, target, steps }) => {
437 let passNum = results
438 .filter(r => r.type === 'step' && r.state.match(/success|skip/))
439 .length
440 const total = steps.length;
441 passNum += `/${total}`;
442 if (results.filter(r=>r.type === 'step').length === total) {
443 passNum += '\u0020'
444 }
445
446 // FIXME HACK use MutationObserver for animation
447 if (!target.animations) target.animations = Promise.resolve();
448 target.animations = target.animations.then(async () => {
449 await new Promise(resolve => setTimeout(resolve, 150));
450 target.setAttribute('data-report', passNum);
451 });
452 }
453 /**
454 * config converter for mapclay.renderWith()
455 *
456 * @param {Object} config
457 * @return {Object} -- converted config
458 */
432 const configConverter = config => ({ 459 const configConverter = config => ({
433 use: config.use ?? "Leaflet", 460 use: config.use ?? 'Leaflet',
434 width: "100%", 461 width: '100%',
435 ...config, 462 ...config,
436 aliases: { 463 aliases: {
437 ...defaultAliases, 464 ...defaultAliases,
438 ...(config.aliases ?? {}), 465 ...(config.aliases ?? {}),
439 }, 466 },
440 }); 467 stepCallback: updateAttributeByStep,
441 const render = renderWith(configConverter); 468 })
469 const render = renderWith(configConverter)
442 elementsWithMapConfig.forEach(target => { 470 elementsWithMapConfig.forEach(target => {
443 // Get text in code block starts with markdown text '```map' 471 // Get text in code block starts with markdown text '```map'
444 const configText = target 472 const configText = target