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/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
- export async function runMermaid() {
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
- const src = node.textContent.trim();
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.addEventListener('click', () => openZoom(node.querySelector('svg')?.outerHTML || ''));
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 // can this client create/edit comments? (loopback only)
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
  };