UNPKG

mermaid

Version:

Markdown-ish syntax for generating flowcharts, mindmaps, sequence diagrams, class diagrams, gantt charts, git graphs and more.

8 lines (7 loc) 6.56 kB
{ "version": 3, "sources": ["../../../src/rendering-util/layout-algorithms/ddlt/sizeCapture.ts"], "sourcesContent": ["import type { Selection } from 'd3';\nimport type { LayoutData } from '../../types.js';\nimport { DDLT_SIZE_CAPTURE_VERSION } from './captureContract.js';\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// DDLT size capture (dev / test tooling \u2014 NOT part of production rendering)\n//\n// This module is dynamically imported by createGraphWithElements ONLY when\n// `window.mermaidCaptureSizes` is set, so it is never bundled into a production\n// render path (it lands in a lazily-loaded chunk instead).\n//\n// When enabled, it records the measured bounding-box dimensions of every leaf\n// node and edge-label dummy node, matching the `.sizes.json` fixture format used\n// by DOM-Decoupled Layout Testing (see\n// cypress/platform/dev-diagrams/layout-tests/*.sizes.json).\n//\n// Toggle from the browser devtools:\n//\n// window.mermaidCaptureSizes = true; // enable\n// window.mermaidCaptureSizes = false; // disable\n//\n// Each diagram rendered while enabled updates `window.mermaidLastCapturedSizes`\n// and is also appended to `window.mermaidCapturedSizes` (an array) for\n// programmatic access from dev-explorer or test tooling.\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ntype D3Selection<T extends SVGElement = SVGElement> = Selection<\n T,\n unknown,\n Element | null,\n unknown\n>;\n\ninterface CapturedNodeSize {\n id: string;\n width: number;\n height: number;\n}\n\ninterface CapturedSizesMetadata {\n captureVersion: number;\n capturedAt: string;\n capturedFrom: string;\n}\n\ninterface CapturedSizes {\n nodes: CapturedNodeSize[];\n metadata: CapturedSizesMetadata;\n}\n\ninterface CapturedEntry {\n svgId: string;\n sizes: CapturedSizes;\n}\n\ninterface CaptureGlobal {\n mermaidCaptureSizes?: boolean;\n mermaidCapturedSizes?: CapturedEntry[];\n mermaidLastCapturedSizes?: CapturedEntry;\n}\n\nfunction getCaptureGlobal(): CaptureGlobal | undefined {\n if (typeof globalThis === 'undefined') {\n return undefined;\n }\n return globalThis as unknown as CaptureGlobal;\n}\n\n/**\n * Whether DDLT size capture is enabled. Kept here so callers can avoid importing\n * this module at all in production \u2014 the createGraph guard reads the raw\n * `globalThis.mermaidCaptureSizes` flag directly and only dynamically imports\n * this module when it is truthy.\n */\nexport function shouldCaptureSizes(): boolean {\n return Boolean(getCaptureGlobal()?.mermaidCaptureSizes);\n}\n\nfunction capturedFromLocation(): string {\n if (typeof location === 'undefined') {\n return 'browser-dev';\n }\n return `${location.pathname}${location.search}`;\n}\n\nfunction emitCapturedSizes(captured: CapturedSizes, element: D3Selection): void {\n const g = getCaptureGlobal();\n if (!g) {\n return;\n }\n\n // Identify the owning SVG so captures can be told apart when a page\n // renders many diagrams (e.g. knsv3.html).\n const domNode = element.node();\n const ownerSvg =\n (domNode && 'ownerSVGElement' in domNode ? domNode.ownerSVGElement : null) ?? domNode;\n const svgId = ownerSvg?.id ?? '(unknown)';\n\n // `mermaidCapturedSizes` accumulates one entry per captured render and is never\n // trimmed; in a long dev session, `delete window.mermaidCapturedSizes` to reset it.\n g.mermaidCapturedSizes ??= [];\n const entry = { svgId, sizes: captured };\n g.mermaidCapturedSizes.push(entry);\n g.mermaidLastCapturedSizes = entry;\n}\n\n/**\n * Record the measured sizes of every leaf + edge-label node from an\n * already-laid-out {@link LayoutData} into `window.mermaidCapturedSizes`.\n *\n * Reads `node.width`/`node.height` set by createGraphWithElements during\n * measurement, so the capture lives entirely outside the production render path.\n *\n * @param element - The container the diagram was rendered into.\n * @param data4Layout - Layout data whose nodes have been measured.\n */\nexport function captureNodeSizes(element: D3Selection, data4Layout: LayoutData): void {\n const nodes: CapturedNodeSize[] = [];\n for (const node of data4Layout.nodes) {\n if (node.isGroup) {\n continue;\n }\n nodes.push({ id: node.id, width: node.width ?? 0, height: node.height ?? 0 });\n }\n if (nodes.length === 0) {\n return;\n }\n emitCapturedSizes(\n {\n metadata: {\n captureVersion: DDLT_SIZE_CAPTURE_VERSION,\n capturedAt: new Date().toISOString(),\n capturedFrom: capturedFromLocation(),\n },\n nodes,\n },\n element\n );\n}\n"], "mappings": "yCA6DA,SAASA,GAA8C,CACrD,GAAI,SAAO,WAAe,KAG1B,OAAO,UACT,CALSC,EAAAD,EAAA,oBAaF,SAASE,GAA8B,CAC5C,MAAO,EAAQF,EAAiB,GAAG,mBACrC,CAFgBC,EAAAC,EAAA,sBAIhB,SAASC,GAA+B,CACtC,OAAI,OAAO,SAAa,IACf,cAEF,GAAG,SAAS,QAAQ,GAAG,SAAS,MAAM,EAC/C,CALSF,EAAAE,EAAA,wBAOT,SAASC,EAAkBC,EAAyBC,EAA4B,CAC9E,IAAMC,EAAIP,EAAiB,EAC3B,GAAI,CAACO,EACH,OAKF,IAAMC,EAAUF,EAAQ,KAAK,EAGvBG,IADHD,GAAW,oBAAqBA,EAAUA,EAAQ,gBAAkB,OAASA,IACxD,IAAM,YAI9BD,EAAE,uBAAyB,CAAC,EAC5B,IAAMG,EAAQ,CAAE,MAAAD,EAAO,MAAOJ,CAAS,EACvCE,EAAE,qBAAqB,KAAKG,CAAK,EACjCH,EAAE,yBAA2BG,CAC/B,CAnBST,EAAAG,EAAA,qBA+BF,SAASO,EAAiBL,EAAsBM,EAA+B,CACpF,IAAMC,EAA4B,CAAC,EACnC,QAAWC,KAAQF,EAAY,MACzBE,EAAK,SAGTD,EAAM,KAAK,CAAE,GAAIC,EAAK,GAAI,MAAOA,EAAK,OAAS,EAAG,OAAQA,EAAK,QAAU,CAAE,CAAC,EAE1ED,EAAM,SAAW,GAGrBT,EACE,CACE,SAAU,CACR,eAAgB,EAChB,WAAY,IAAI,KAAK,EAAE,YAAY,EACnC,aAAcD,EAAqB,CACrC,EACA,MAAAU,CACF,EACAP,CACF,CACF,CAtBgBL,EAAAU,EAAA", "names": ["getCaptureGlobal", "__name", "shouldCaptureSizes", "capturedFromLocation", "emitCapturedSizes", "captured", "element", "g", "domNode", "svgId", "entry", "captureNodeSizes", "data4Layout", "nodes", "node"] }