projview 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -3
- package/docs/reference/api.md +32 -1
- package/package.json +1 -1
- package/public/comments.js +4 -4
- package/public/editor.js +306 -0
- package/public/history.js +162 -0
- package/public/index.html +20 -10
- package/public/live.js +7 -1
- package/public/main.js +7 -1
- package/public/mermaid.js +17 -10
- package/public/store.js +3 -1
- package/public/style.css +318 -125
- package/public/theme.js +52 -0
- package/public/toc.js +13 -5
- package/public/tree.js +2 -1
- package/public/viewer.js +14 -3
- package/src/render.js +24 -2
- package/src/search.js +15 -5
- package/src/server.js +130 -18
- package/src/store.js +88 -3
package/public/main.js
CHANGED
|
@@ -8,9 +8,11 @@ import { connectEvents } from './live.js';
|
|
|
8
8
|
// side-effect modules: each attaches its own listeners on import
|
|
9
9
|
import './links.js';
|
|
10
10
|
import './toc.js';
|
|
11
|
-
import './mermaid.js';
|
|
11
|
+
import { runMermaid } from './mermaid.js';
|
|
12
|
+
import { onThemeChange } from './theme.js';
|
|
12
13
|
import './search.js';
|
|
13
14
|
import './comments.js';
|
|
15
|
+
import './editor.js';
|
|
14
16
|
|
|
15
17
|
// browser back / forward
|
|
16
18
|
window.addEventListener('hashchange', () => {
|
|
@@ -18,6 +20,10 @@ window.addEventListener('hashchange', () => {
|
|
|
18
20
|
if (p && p !== state.currentPath) openFile(p); // guard prevents self-trigger loop
|
|
19
21
|
});
|
|
20
22
|
|
|
23
|
+
// light/dark flip: CSS follows on its own; diagrams are baked SVG, so redraw them
|
|
24
|
+
// in place (no re-fetch, no scroll jump, an open editor is left alone)
|
|
25
|
+
onThemeChange(() => runMermaid({ rerender: true }));
|
|
26
|
+
|
|
21
27
|
async function boot() {
|
|
22
28
|
await loadTree();
|
|
23
29
|
const hash = decodeURIComponent(location.hash.slice(1));
|
package/public/mermaid.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/* mermaid rendering (per-diagram, with error cards) + zoom overlay */
|
|
2
2
|
|
|
3
3
|
import { $, esc } from './dom.js';
|
|
4
|
+
import { currentTheme } from './theme.js';
|
|
4
5
|
|
|
5
6
|
const mermaid = window.mermaid; // UMD global, loaded via classic <script> before this module
|
|
6
7
|
const contentEl = $('content');
|
|
@@ -9,27 +10,33 @@ const zoomInnerEl = $('zoom-inner');
|
|
|
9
10
|
|
|
10
11
|
let mermaidSeq = 0; // unique id source for mermaid.render
|
|
11
12
|
|
|
12
|
-
mermaid.initialize({
|
|
13
|
-
startOnLoad: false,
|
|
14
|
-
theme: 'dark',
|
|
15
|
-
securityLevel: 'loose',
|
|
16
|
-
suppressErrorRendering: true // we render our own error card; don't inject the default bomb
|
|
17
|
-
});
|
|
18
|
-
|
|
19
13
|
// Render each .mermaid block individually so one bad diagram can't kill the rest.
|
|
20
|
-
|
|
14
|
+
// A block keeps its source in data-src, so it can be re-rendered in place (theme
|
|
15
|
+
// flip) - otherwise blocks that are already rendered are left alone.
|
|
16
|
+
export async function runMermaid({ rerender = false } = {}) {
|
|
17
|
+
mermaid.initialize({
|
|
18
|
+
startOnLoad: false,
|
|
19
|
+
theme: currentTheme() === 'light' ? 'neutral' : 'dark', // read per render: themes can flip mid-session
|
|
20
|
+
securityLevel: 'loose',
|
|
21
|
+
suppressErrorRendering: true // we render our own error card; don't inject the default bomb
|
|
22
|
+
});
|
|
21
23
|
const nodes = [...contentEl.querySelectorAll('.mermaid')];
|
|
22
24
|
for (const node of nodes) {
|
|
23
|
-
|
|
25
|
+
if (!node.dataset.src) node.dataset.src = node.textContent.trim();
|
|
26
|
+
else if (!rerender) continue;
|
|
27
|
+
const src = node.dataset.src;
|
|
28
|
+
node.classList.remove('rendered', 'mermaid-error');
|
|
24
29
|
try {
|
|
25
30
|
const { svg, bindFunctions } = await mermaid.render(`pv-mmd-${++mermaidSeq}`, src);
|
|
26
31
|
node.innerHTML = svg;
|
|
27
32
|
bindFunctions?.(node);
|
|
28
33
|
node.classList.add('rendered');
|
|
29
34
|
node.title = 'click to zoom';
|
|
30
|
-
node.
|
|
35
|
+
node.onclick = () => openZoom(node.querySelector('svg')?.outerHTML || '');
|
|
31
36
|
} catch (err) {
|
|
32
37
|
node.classList.add('mermaid-error');
|
|
38
|
+
node.onclick = null;
|
|
39
|
+
node.title = '';
|
|
33
40
|
node.innerHTML =
|
|
34
41
|
`<div class="diagram-error"><strong>⚠ diagram failed to render</strong>` +
|
|
35
42
|
`<pre class="err-msg">${esc(String(err && err.message ? err.message : err))}</pre>` +
|
package/public/store.js
CHANGED
|
@@ -5,5 +5,7 @@ export const state = {
|
|
|
5
5
|
expanded: new Set(), // dir paths the user has opened
|
|
6
6
|
treeData: [], // last tree payload from the server
|
|
7
7
|
rootName: 'projview', // indexed root's display name
|
|
8
|
-
writable: false
|
|
8
|
+
writable: false, // can this client create/edit comments + files? (loopback only)
|
|
9
|
+
view: 'rendered', // md / mmd: 'rendered' or 'raw' - sticks while browsing
|
|
10
|
+
persistent: false // does the store keep comments + versions across runs?
|
|
9
11
|
};
|