|
1 | 1 | (function initializeMarkmap() {
|
2 | 2 | const transformer = new markmap.Transformer();
|
| 3 | + const preloadAssets = transformer.getPreloadScripts(); |
3 | 4 | const assets = transformer.getAssets();
|
4 | 5 | const loading = Promise.all([
|
5 | 6 | assets.styles && markmap.loadCSS(assets.styles),
|
6 |
| - assets.scripts && markmap.loadJS(assets.scripts), |
| 7 | + markmap.loadJS([...preloadAssets.scripts, ...assets.scripts]), |
7 | 8 | ]);
|
8 | 9 |
|
9 | 10 | function parseData(content) {
|
10 | 11 | const { root, frontmatter } = transformer.transform(content);
|
11 | 12 | let options = markmap.deriveOptions(frontmatter?.markmap);
|
12 |
| - options = Object.assign({ |
13 |
| - fitRatio: 0.85, |
14 |
| - }, options); |
| 13 | + options = Object.assign( |
| 14 | + { |
| 15 | + fitRatio: 0.85, |
| 16 | + }, |
| 17 | + options |
| 18 | + ); |
15 | 19 | return { root, options };
|
16 | 20 | }
|
17 | 21 |
|
18 | 22 | function resetMarkmap(m, el) {
|
19 |
| - const { minX, maxX, minY, maxY } = m.state; |
20 |
| - const height = el.clientWidth * (maxX - minX) / (maxY - minY); |
| 23 | + if (!m.state.rect) return; |
| 24 | + const { x1, y1, x2, y2 } = m.state.rect; |
| 25 | + const height = (el.offsetWidth / (x2 - x1)) * (y2 - y1); |
21 | 26 | el.style.height = height + "px";
|
22 | 27 | m.fit();
|
23 | 28 | }
|
24 | 29 |
|
| 30 | + function decodeBase64(encoded) { |
| 31 | + const binary = atob(encoded); |
| 32 | + const bytes = new Uint8Array(binary.length); |
| 33 | + for (let i = 0; i < bytes.length; i++) { |
| 34 | + bytes[i] = binary.charCodeAt(i); |
| 35 | + } |
| 36 | + return new TextDecoder().decode(bytes); |
| 37 | + } |
| 38 | + |
25 | 39 | function renderMarkmap(el) {
|
26 |
| - let svg = el.querySelector('svg'); |
27 |
| - if (svg) return; |
28 |
| - const content = el.textContent; |
29 |
| - el.innerHTML = '<svg>'; |
| 40 | + const dataEl = el.querySelector("markmap-data"); |
| 41 | + if (!dataEl) return; |
| 42 | + let content = el.textContent; |
| 43 | + if (dataEl.getAttribute("encoding") === "base64") { |
| 44 | + content = decodeBase64(content); |
| 45 | + } |
| 46 | + el.innerHTML = "<svg>"; |
30 | 47 | svg = el.firstChild;
|
31 | 48 | const { root, options } = parseData(content);
|
32 |
| - const m = markmap.Markmap.create(svg, options, root); |
33 |
| - resetMarkmap(m, el); |
34 |
| - transformer.hooks.retransform.tap(() => { |
35 |
| - const { root, options } = parseData(content); |
36 |
| - m.setData(root, options); |
| 49 | + const m = markmap.Markmap.create(svg, options); |
| 50 | + m.setData(root); |
| 51 | + requestAnimationFrame(() => { |
37 | 52 | resetMarkmap(m, el);
|
38 | 53 | });
|
39 | 54 | }
|
40 | 55 |
|
41 | 56 | function updateMarkmaps(node) {
|
42 |
| - for (const el of node.querySelectorAll('.mkdocs-markmap')) { |
| 57 | + for (const el of node.querySelectorAll(".mkdocs-markmap")) { |
43 | 58 | renderMarkmap(el);
|
44 | 59 | }
|
45 | 60 | }
|
46 | 61 |
|
47 | 62 | loading.then(() => {
|
48 | 63 | const observer = new MutationObserver((mutationList) => {
|
49 | 64 | for (const mutation of mutationList) {
|
50 |
| - if (mutation.type === 'childList') { |
| 65 | + if (mutation.type === "childList") { |
51 | 66 | for (const node of mutation.addedNodes) {
|
52 | 67 | updateMarkmaps(node);
|
53 | 68 | }
|
|
0 commit comments