Native surfaces migration — evolve the extension onto VS Code's native review surfaces (9-task plan, spec v0.2.1) (#72)

This commit was merged in pull request #72.
This commit is contained in:
2026-07-02 23:09:37 +00:00
parent 93eeaf13b8
commit 935fcc35ee
54 changed files with 3689 additions and 1995 deletions
+57
View File
@@ -0,0 +1,57 @@
/**
* Task 7 (Q4 mermaid check, D3/D21): the built-in VS Code Markdown preview does
* not render mermaid fences on its own — `previewAnnotations.ts`'s
* `cowritingMarkdownItPlugin` teaches ```mermaid fences to render as
* `<pre class="mermaid">SRC</pre>` (via `options.highlight`, the same
* extension point the built-in preview's own fence rule already calls); this
* script (contributed via `markdown.previewScripts`) is what actually turns
* those into diagrams — mermaid needs a DOM, so it runs here, in the preview's
* webview, never in the extension host. Bundled by esbuild as a standalone
* IIFE → out/media/preview-mermaid.js, so mermaid never enters the host
* bundle (matching the sealed webview's `media/preview.ts` precedent).
*
* Contributed preview scripts are reloaded on every content change (VS Code
* docs), so running at module top-level is sufficient; the
* `vscode.markdown.updateContent` listener is added defensively to also cover
* in-place content updates that don't reload the script (mirrors the proven
* `bierner.markdown-mermaid` extension's own approach).
*
* RESOLVED SCOPE NOTE (Q4 finding, migration plan Task 7 Step 2.6; wired in a
* cross-task review follow-up): this script itself only turns `pre.mermaid`
* nodes into diagrams — it never sees a diff. The intra-diagram diff/legend
* augmentation (F7.1, INV-29..31) happens one step earlier, source-side,
* where it CAN be unit-tested without a DOM: `previewAnnotations.ts`'s
* `cowritingMarkdownItPlugin` re-emits a CHANGED mermaid fence's source
* through `mermaidDiff.ts` (`buildMermaidQueue`, block-level `diffBlocks`
* pairing against the F6/F7 baseline) before this script ever runs, so the
* `pre.mermaid` node this script hands to `mermaid.run` already carries the
* `classDef`/`class`/`linkStyle` styling directives — this script needn't (and
* can't, DOM-less-ly) know a diagram changed at all. Basic mermaid rendering
* (this file) is exercised by the same proven pattern as the real
* `bierner.markdown-mermaid` extension; the augmentation upstream is exercised
* by pure unit tests (`test/previewAnnotations.test.ts`).
*/
import mermaid from "mermaid";
function theme(): "dark" | "default" {
return document.body.classList.contains("vscode-dark") || document.body.classList.contains("vscode-high-contrast")
? "dark"
: "default";
}
async function run(): Promise<void> {
const nodes = Array.from(document.querySelectorAll<HTMLElement>("pre.mermaid"));
if (nodes.length === 0) return;
mermaid.initialize({ startOnLoad: false, theme: theme(), securityLevel: "strict" });
try {
await mermaid.run({ nodes });
} catch {
// mermaid.run already marks failed nodes; ensure a visible chip per failure.
for (const n of nodes) {
if (!n.querySelector("svg")) n.setAttribute("data-cw-error", "true");
}
}
}
window.addEventListener("vscode.markdown.updateContent", () => void run());
void run();