@diagrammo/dgmo 0.44.1 → 0.46.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/dist/advanced.cjs +33 -27
- package/dist/advanced.js +33 -27
- package/dist/auto.cjs +502 -343
- package/dist/auto.css +342 -159
- package/dist/auto.d.cts +10 -8
- package/dist/auto.d.ts +10 -8
- package/dist/auto.js +373 -265
- package/dist/auto.mjs +502 -343
- package/dist/block.cjs +70208 -0
- package/dist/block.css +290 -0
- package/dist/block.d.cts +115 -0
- package/dist/block.d.ts +115 -0
- package/dist/block.js +70204 -0
- package/dist/cli.cjs +110 -110
- package/dist/element.cjs +494 -327
- package/dist/element.js +367 -259
- package/dist/element.mjs +494 -327
- package/dist/highlight.cjs +31 -0
- package/dist/highlight.d.cts +10 -1
- package/dist/highlight.d.ts +10 -1
- package/dist/highlight.js +30 -0
- package/dist/index.cjs +33 -27
- package/dist/index.js +33 -27
- package/package.json +13 -2
- package/src/auto/index.ts +55 -57
- package/src/auto/shared.ts +142 -142
- package/src/auto/styles.ts +44 -199
- package/src/c4/renderer.ts +2 -2
- package/src/editor/highlight-api.ts +34 -0
- package/src/element/index.ts +29 -21
- package/src/embed/css.ts +312 -0
- package/src/embed/escape.ts +15 -0
- package/src/embed/index.ts +280 -0
- package/src/event-line/renderer.ts +3 -3
- package/src/infra/renderer.ts +1 -1
- package/src/render.ts +34 -14
- package/src/sitemap/renderer.ts +1 -1
- package/src/swimlane/renderer.ts +1 -0
- package/src/timeline/renderer.ts +1 -1
- package/src/utils/hover-styles.ts +6 -1
- package/src/utils/legend-d3.ts +1 -4
- package/src/utils/legend-svg.ts +1 -1
package/src/render.ts
CHANGED
|
@@ -24,11 +24,29 @@ const DOM_GLOBALS = [
|
|
|
24
24
|
'HTMLElement',
|
|
25
25
|
'SVGElement',
|
|
26
26
|
] as const;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
// The ref-count state lives on `globalThis` under a well-known symbol rather
|
|
28
|
+
// than in module state: dist/index and dist/block are each self-contained
|
|
29
|
+
// bundles, so a host importing both gets two copies of this module. With
|
|
30
|
+
// per-copy state, each copy keeps its own ref-count over the SAME
|
|
31
|
+
// `globalThis.document` — one copy's release tears down globals mid-render of
|
|
32
|
+
// the other. `Symbol.for` puts every copy on one shared count.
|
|
33
|
+
interface DomGlobalsState {
|
|
34
|
+
refCount: number;
|
|
35
|
+
installPromise: Promise<void> | null;
|
|
36
|
+
installedByUs: boolean;
|
|
37
|
+
}
|
|
38
|
+
const DOM_STATE_KEY = Symbol.for('diagrammo.dgmo.dom-globals');
|
|
39
|
+
|
|
40
|
+
function domState(): DomGlobalsState {
|
|
41
|
+
const g = globalThis as { [DOM_STATE_KEY]?: DomGlobalsState };
|
|
42
|
+
return (g[DOM_STATE_KEY] ??= {
|
|
43
|
+
refCount: 0,
|
|
44
|
+
installPromise: null,
|
|
45
|
+
installedByUs: false,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
30
48
|
|
|
31
|
-
async function installDom(): Promise<void> {
|
|
49
|
+
async function installDom(state: DomGlobalsState): Promise<void> {
|
|
32
50
|
const { JSDOM } = await loadJsdom();
|
|
33
51
|
// Concrete URL → non-opaque origin, so host code that touches
|
|
34
52
|
// window.localStorage during a same-process render doesn't throw.
|
|
@@ -49,7 +67,7 @@ async function installDom(): Promise<void> {
|
|
|
49
67
|
configurable: true,
|
|
50
68
|
});
|
|
51
69
|
}
|
|
52
|
-
|
|
70
|
+
state.installedByUs = true;
|
|
53
71
|
}
|
|
54
72
|
|
|
55
73
|
/**
|
|
@@ -58,22 +76,24 @@ async function installDom(): Promise<void> {
|
|
|
58
76
|
* we did not install). Pair every successful call with `releaseDom()`.
|
|
59
77
|
*/
|
|
60
78
|
async function acquireDom(): Promise<void> {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
79
|
+
const state = domState();
|
|
80
|
+
if (typeof document !== 'undefined' && !state.installedByUs) return;
|
|
81
|
+
state.refCount++;
|
|
82
|
+
if (!state.installPromise) state.installPromise = installDom(state);
|
|
83
|
+
await state.installPromise;
|
|
65
84
|
}
|
|
66
85
|
|
|
67
86
|
/** Tear down the jsdom globals once no render is in flight. */
|
|
68
87
|
function releaseDom(): void {
|
|
69
|
-
|
|
70
|
-
if (
|
|
88
|
+
const state = domState();
|
|
89
|
+
if (!state.installedByUs) return;
|
|
90
|
+
if (--state.refCount > 0) return;
|
|
71
91
|
for (const key of DOM_GLOBALS) {
|
|
72
92
|
delete (globalThis as Record<string, unknown>)[key];
|
|
73
93
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
94
|
+
state.installedByUs = false;
|
|
95
|
+
state.installPromise = null;
|
|
96
|
+
state.refCount = 0;
|
|
77
97
|
}
|
|
78
98
|
|
|
79
99
|
/**
|
package/src/sitemap/renderer.ts
CHANGED
|
@@ -663,7 +663,7 @@ export function renderSitemap(
|
|
|
663
663
|
.attr('class', 'sitemap-legend-fixed')
|
|
664
664
|
.attr('transform', `translate(0, ${sDiagramPadding + fixedTitleH})`);
|
|
665
665
|
if (activeTagGroup) {
|
|
666
|
-
legendParent.attr('data-legend-active', activeTagGroup
|
|
666
|
+
legendParent.attr('data-legend-active', tagAttrKey(activeTagGroup));
|
|
667
667
|
}
|
|
668
668
|
renderLegend(
|
|
669
669
|
legendParent,
|
package/src/swimlane/renderer.ts
CHANGED
|
@@ -153,6 +153,7 @@ export function renderSwimlaneForExport(
|
|
|
153
153
|
.attr('width', width)
|
|
154
154
|
.attr('height', height)
|
|
155
155
|
.attr('viewBox', `0 0 ${width} ${height}`)
|
|
156
|
+
.attr('preserveAspectRatio', 'xMidYMin meet')
|
|
156
157
|
.style('font-family', FONT_FAMILY) as unknown as D3Svg;
|
|
157
158
|
|
|
158
159
|
const defs = svg.append('defs');
|
package/src/timeline/renderer.ts
CHANGED
|
@@ -25,6 +25,8 @@
|
|
|
25
25
|
// there is no opacity double-up. `render({ bakeHover: false })` opts out.
|
|
26
26
|
// ============================================================
|
|
27
27
|
|
|
28
|
+
import { tagAttrKey } from './tag-groups';
|
|
29
|
+
|
|
28
30
|
/** How a chart's cross-highlight rules are shaped. `self` = self-emphasis only
|
|
29
31
|
* (no cross-highlight — single-series / non-relational charts). */
|
|
30
32
|
export type HoverStrategy = 'enumerated' | 'structural' | 'connection' | 'self';
|
|
@@ -599,7 +601,10 @@ function deriveFromSvg(svg: string, spec: HoverSpec): HoverDerived {
|
|
|
599
601
|
.querySelector('[data-legend-active]')
|
|
600
602
|
?.getAttribute('data-legend-active');
|
|
601
603
|
if (slug) {
|
|
602
|
-
|
|
604
|
+
// Defensive re-slug: legacy SVGs (pre-0.46) carried the raw lowercased
|
|
605
|
+
// group name here, which is not a valid attribute name when the group
|
|
606
|
+
// name contains spaces/parens — querySelectorAll would throw.
|
|
607
|
+
groupAttr = `data-tag-${tagAttrKey(slug)}`;
|
|
603
608
|
} else {
|
|
604
609
|
// Fallback for charts with no legend-active marker (e.g. mindmap): if
|
|
605
610
|
// the marks carry exactly ONE distinct `data-tag-*` group, use it.
|
package/src/utils/legend-d3.ts
CHANGED
|
@@ -74,10 +74,7 @@ export function renderLegendD3(
|
|
|
74
74
|
|
|
75
75
|
// Set active attribute on container
|
|
76
76
|
if (currentState.activeGroup) {
|
|
77
|
-
legendG.attr(
|
|
78
|
-
'data-legend-active',
|
|
79
|
-
currentState.activeGroup.toLowerCase()
|
|
80
|
-
);
|
|
77
|
+
legendG.attr('data-legend-active', tagAttrKey(currentState.activeGroup));
|
|
81
78
|
} else {
|
|
82
79
|
legendG.attr('data-legend-active', null);
|
|
83
80
|
}
|
package/src/utils/legend-svg.ts
CHANGED
|
@@ -180,7 +180,7 @@ export function renderLegendSvg(
|
|
|
180
180
|
|
|
181
181
|
const classAttr = className ? ` class="${esc(className)}"` : '';
|
|
182
182
|
const activeAttr = activeGroup
|
|
183
|
-
? ` data-legend-active="${esc(activeGroup
|
|
183
|
+
? ` data-legend-active="${esc(tagAttrKey(activeGroup))}"`
|
|
184
184
|
: '';
|
|
185
185
|
const svg = `<g${classAttr}${activeAttr}>${parts.join('')}</g>`;
|
|
186
186
|
|