mirror of
https://github.com/backnotprop/plannotator.git
synced 2026-09-14 14:17:26 +08:00
0b167cc478
Bundle-weight optimization of @plannotator/ui for multi-chunk hosts, requested by Workspaces: the Mermaid runtime and Graphviz engine load inside the render effect, the username dictionary sits behind a synchronous identity generator slot, and KaTeX sits behind a math renderer slot with a loader seam on configurePlannotatorUI. Plannotator's own apps import eager entries (math, identity, and Mermaid for the plan editor) so their behavior is unchanged: single-file builds within noise of main, math typeset on first paint, identities from the full dictionary, and the share portal keeps Mermaid in its entry chunk so its failure surface matches main. Built-HTML registration markers guard the eager imports. Hosts that omit the eager entries get the lazy paths, a one-shot automatic re-attempt, and a Retry affordance on the diagram error panel; the module-map limitation of in-page retries is documented. AI-assisted (Claude) under maintainer direction.
72 lines
2.9 KiB
TypeScript
72 lines
2.9 KiB
TypeScript
import { describe, expect, test } from 'bun:test';
|
|
import { normalizeMermaidSvgMarkup } from './mermaidSvg';
|
|
import { MERMAID_CONFIG } from './MermaidBlock';
|
|
|
|
describe('MERMAID_CONFIG', () => {
|
|
// Deliberate security pin: the config is applied on first diagram (the
|
|
// runtime is imported lazily), so a drift here would only show up in the
|
|
// browser as arbitrary HTML/JS in a document-supplied diagram.
|
|
test('keeps securityLevel strict and startOnLoad off', () => {
|
|
expect(MERMAID_CONFIG.securityLevel).toBe('strict');
|
|
expect(MERMAID_CONFIG.startOnLoad).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('normalizeMermaidSvgMarkup', () => {
|
|
test('replaces natural max-width with max-width:none', () => {
|
|
const input = '<svg style="max-width: 85.125px;" viewBox="0 0 346 278" width="100%"><g/></svg>';
|
|
const expected =
|
|
'<svg style="max-width: none" viewBox="0 0 346 278" width="100%" preserveAspectRatio="xMidYMid meet" height="100%"><g/></svg>';
|
|
|
|
expect(normalizeMermaidSvgMarkup(input)).toBe(expected);
|
|
});
|
|
|
|
test('adds preserveAspectRatio when missing', () => {
|
|
const input = '<svg viewBox="0 0 1 1"></svg>';
|
|
const expected =
|
|
'<svg viewBox="0 0 1 1" style="max-width: none" preserveAspectRatio="xMidYMid meet" height="100%"></svg>';
|
|
|
|
expect(normalizeMermaidSvgMarkup(input)).toBe(expected);
|
|
});
|
|
|
|
test('adds height=100% when missing', () => {
|
|
const input = '<svg viewBox="0 0 1 1" preserveAspectRatio="none"></svg>';
|
|
const expected =
|
|
'<svg viewBox="0 0 1 1" preserveAspectRatio="none" style="max-width: none" height="100%"></svg>';
|
|
|
|
expect(normalizeMermaidSvgMarkup(input)).toBe(expected);
|
|
});
|
|
|
|
test('preserves existing preserveAspectRatio and height', () => {
|
|
const input = '<svg viewBox="0 0 1 1" preserveAspectRatio="none" height="200"></svg>';
|
|
const expected =
|
|
'<svg viewBox="0 0 1 1" preserveAspectRatio="none" height="200" style="max-width: none"></svg>';
|
|
|
|
expect(normalizeMermaidSvgMarkup(input)).toBe(expected);
|
|
});
|
|
|
|
test('injects style attribute when mermaid omits one', () => {
|
|
const input = '<svg viewBox="0 0 1 1" width="100%"></svg>';
|
|
const expected =
|
|
'<svg viewBox="0 0 1 1" width="100%" style="max-width: none" preserveAspectRatio="xMidYMid meet" height="100%"></svg>';
|
|
|
|
expect(normalizeMermaidSvgMarkup(input)).toBe(expected);
|
|
});
|
|
|
|
test('only normalizes the root <svg> tag', () => {
|
|
const input =
|
|
'<svg style="max-width: 100px;" viewBox="0 0 1 1"><defs><marker><svg viewBox="0 0 5 5"/></marker></defs></svg>';
|
|
const expected =
|
|
'<svg style="max-width: none" viewBox="0 0 1 1" preserveAspectRatio="xMidYMid meet" height="100%"><defs><marker><svg viewBox="0 0 5 5"/></marker></defs></svg>';
|
|
|
|
expect(normalizeMermaidSvgMarkup(input)).toBe(expected);
|
|
});
|
|
|
|
test('leaves non-svg input unchanged', () => {
|
|
const input = 'plain text';
|
|
const expected = 'plain text';
|
|
|
|
expect(normalizeMermaidSvgMarkup(input)).toBe(expected);
|
|
});
|
|
});
|