@diagrammo/dgmo 0.45.0 → 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 +31 -25
- package/dist/advanced.js +31 -25
- package/dist/auto.cjs +500 -341
- 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 +500 -341
- package/dist/block.cjs +31 -25
- package/dist/block.js +31 -25
- package/dist/cli.cjs +112 -112
- package/dist/element.cjs +492 -325
- package/dist/element.js +367 -259
- package/dist/element.mjs +492 -325
- package/dist/index.cjs +31 -25
- package/dist/index.js +31 -25
- package/package.json +1 -1
- 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/element/index.ts +29 -21
- package/src/infra/renderer.ts +1 -1
- package/src/render.ts +34 -14
- package/src/sitemap/renderer.ts +1 -1
- 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/dist/auto.cjs
CHANGED
|
@@ -5052,10 +5052,7 @@ function renderLegendD3(container, config, state, palette, isDark, callbacks, co
|
|
|
5052
5052
|
legendG.selectAll("*").remove();
|
|
5053
5053
|
if (currentLayout.height === 0) return;
|
|
5054
5054
|
if (currentState.activeGroup) {
|
|
5055
|
-
legendG.attr(
|
|
5056
|
-
"data-legend-active",
|
|
5057
|
-
currentState.activeGroup.toLowerCase()
|
|
5058
|
-
);
|
|
5055
|
+
legendG.attr("data-legend-active", tagAttrKey(currentState.activeGroup));
|
|
5059
5056
|
} else {
|
|
5060
5057
|
legendG.attr("data-legend-active", null);
|
|
5061
5058
|
}
|
|
@@ -5862,7 +5859,7 @@ function renderTimelineTagLegendOverlay(container, parsed, palette, isDark, setu
|
|
|
5862
5859
|
if (currentActiveGroup) {
|
|
5863
5860
|
legendContainer.attr(
|
|
5864
5861
|
"data-legend-active",
|
|
5865
|
-
currentActiveGroup
|
|
5862
|
+
tagAttrKey(currentActiveGroup)
|
|
5866
5863
|
);
|
|
5867
5864
|
}
|
|
5868
5865
|
const iconAddon = viewMode ? 0 : LG_ICON_W;
|
|
@@ -25559,7 +25556,7 @@ function renderLegendSvg(groups, options) {
|
|
|
25559
25556
|
track(pill.x, pill.y, pill.width, pill.height);
|
|
25560
25557
|
}
|
|
25561
25558
|
const classAttr = className ? ` class="${esc(className)}"` : "";
|
|
25562
|
-
const activeAttr = activeGroup ? ` data-legend-active="${esc(activeGroup
|
|
25559
|
+
const activeAttr = activeGroup ? ` data-legend-active="${esc(tagAttrKey(activeGroup))}"` : "";
|
|
25563
25560
|
const svg = `<g${classAttr}${activeAttr}>${parts.join("")}</g>`;
|
|
25564
25561
|
return {
|
|
25565
25562
|
svg,
|
|
@@ -30874,7 +30871,7 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
|
|
|
30874
30871
|
if (fixedLegend) {
|
|
30875
30872
|
const legendParent = svg.append("g").attr("class", "sitemap-legend-fixed").attr("transform", `translate(0, ${sDiagramPadding + fixedTitleH})`);
|
|
30876
30873
|
if (activeTagGroup) {
|
|
30877
|
-
legendParent.attr("data-legend-active", activeTagGroup
|
|
30874
|
+
legendParent.attr("data-legend-active", tagAttrKey(activeTagGroup));
|
|
30878
30875
|
}
|
|
30879
30876
|
renderLegend(
|
|
30880
30877
|
legendParent,
|
|
@@ -41296,7 +41293,7 @@ function renderC4Context(container, parsed, layout, palette, isDark, onClickItem
|
|
|
41296
41293
|
if (hasLegend) {
|
|
41297
41294
|
const legendParent = fixedLegend ? svg.append("g").attr("class", "c4-legend-fixed").attr("transform", `translate(0, ${DIAGRAM_PADDING8 + titleHeight})`) : contentG.append("g").attr("class", "c4-legend");
|
|
41298
41295
|
if (activeTagGroup) {
|
|
41299
|
-
legendParent.attr("data-legend-active", activeTagGroup
|
|
41296
|
+
legendParent.attr("data-legend-active", tagAttrKey(activeTagGroup));
|
|
41300
41297
|
}
|
|
41301
41298
|
renderLegend2(
|
|
41302
41299
|
legendParent,
|
|
@@ -41911,7 +41908,7 @@ function renderC4Containers(container, parsed, layout, palette, isDark, onClickI
|
|
|
41911
41908
|
if (hasLegend) {
|
|
41912
41909
|
const legendParent = fixedLegend ? svg.append("g").attr("class", "c4-legend-fixed").attr("transform", `translate(0, ${DIAGRAM_PADDING8 + titleHeight})`) : contentG.append("g").attr("class", "c4-legend");
|
|
41913
41910
|
if (activeTagGroup) {
|
|
41914
|
-
legendParent.attr("data-legend-active", activeTagGroup
|
|
41911
|
+
legendParent.attr("data-legend-active", tagAttrKey(activeTagGroup));
|
|
41915
41912
|
}
|
|
41916
41913
|
renderLegend2(
|
|
41917
41914
|
legendParent,
|
|
@@ -45584,7 +45581,7 @@ function renderLegend3(rootSvg, legendGroups, totalWidth, legendY, palette, isDa
|
|
|
45584
45581
|
const appHostedPlayback = controlsHost === "app" && !!playback;
|
|
45585
45582
|
const legendG = rootSvg.append("g").attr("transform", `translate(0, ${legendY})`);
|
|
45586
45583
|
if (activeGroup) {
|
|
45587
|
-
legendG.attr("data-legend-active", activeGroup
|
|
45584
|
+
legendG.attr("data-legend-active", tagAttrKey(activeGroup));
|
|
45588
45585
|
}
|
|
45589
45586
|
const allGroups = legendGroups.map((g) => ({
|
|
45590
45587
|
name: g.name,
|
|
@@ -68658,6 +68655,7 @@ async function exportVisualization(ctx) {
|
|
|
68658
68655
|
init_charts_d3();
|
|
68659
68656
|
|
|
68660
68657
|
// src/utils/hover-styles.ts
|
|
68658
|
+
init_tag_groups();
|
|
68661
68659
|
var MAX_HOVER_GROUPS = 40;
|
|
68662
68660
|
var DEFAULT_DIM_OPACITY = 0.4;
|
|
68663
68661
|
var LIFT_DECL = "filter:saturate(1.4) brightness(1.06)";
|
|
@@ -69052,7 +69050,7 @@ function deriveFromSvg(svg, spec) {
|
|
|
69052
69050
|
if (spec.groupAttrMode === "tag-active") {
|
|
69053
69051
|
const slug = root.querySelector("[data-legend-active]")?.getAttribute("data-legend-active");
|
|
69054
69052
|
if (slug) {
|
|
69055
|
-
groupAttr = `data-tag-${slug}`;
|
|
69053
|
+
groupAttr = `data-tag-${tagAttrKey(slug)}`;
|
|
69056
69054
|
} else {
|
|
69057
69055
|
const names = /* @__PURE__ */ new Set();
|
|
69058
69056
|
root.querySelectorAll(spec.markSelector).forEach((el) => {
|
|
@@ -69107,10 +69105,16 @@ var DOM_GLOBALS = [
|
|
|
69107
69105
|
"HTMLElement",
|
|
69108
69106
|
"SVGElement"
|
|
69109
69107
|
];
|
|
69110
|
-
var
|
|
69111
|
-
|
|
69112
|
-
|
|
69113
|
-
|
|
69108
|
+
var DOM_STATE_KEY = /* @__PURE__ */ Symbol.for("diagrammo.dgmo.dom-globals");
|
|
69109
|
+
function domState() {
|
|
69110
|
+
const g = globalThis;
|
|
69111
|
+
return g[DOM_STATE_KEY] ??= {
|
|
69112
|
+
refCount: 0,
|
|
69113
|
+
installPromise: null,
|
|
69114
|
+
installedByUs: false
|
|
69115
|
+
};
|
|
69116
|
+
}
|
|
69117
|
+
async function installDom(state) {
|
|
69114
69118
|
const { JSDOM } = await loadJsdom();
|
|
69115
69119
|
const dom = new JSDOM("<!DOCTYPE html><html><body></body></html>", {
|
|
69116
69120
|
url: "http://localhost/"
|
|
@@ -69129,23 +69133,25 @@ async function installDom() {
|
|
|
69129
69133
|
configurable: true
|
|
69130
69134
|
});
|
|
69131
69135
|
}
|
|
69132
|
-
|
|
69136
|
+
state.installedByUs = true;
|
|
69133
69137
|
}
|
|
69134
69138
|
async function acquireDom() {
|
|
69135
|
-
|
|
69136
|
-
|
|
69137
|
-
|
|
69138
|
-
|
|
69139
|
+
const state = domState();
|
|
69140
|
+
if (typeof document !== "undefined" && !state.installedByUs) return;
|
|
69141
|
+
state.refCount++;
|
|
69142
|
+
if (!state.installPromise) state.installPromise = installDom(state);
|
|
69143
|
+
await state.installPromise;
|
|
69139
69144
|
}
|
|
69140
69145
|
function releaseDom() {
|
|
69141
|
-
|
|
69142
|
-
if (
|
|
69146
|
+
const state = domState();
|
|
69147
|
+
if (!state.installedByUs) return;
|
|
69148
|
+
if (--state.refCount > 0) return;
|
|
69143
69149
|
for (const key of DOM_GLOBALS) {
|
|
69144
69150
|
delete globalThis[key];
|
|
69145
69151
|
}
|
|
69146
|
-
|
|
69147
|
-
|
|
69148
|
-
|
|
69152
|
+
state.installedByUs = false;
|
|
69153
|
+
state.installPromise = null;
|
|
69154
|
+
state.refCount = 0;
|
|
69149
69155
|
}
|
|
69150
69156
|
async function loadJsdom() {
|
|
69151
69157
|
const spec = ["js", "dom"].join("");
|
|
@@ -69270,6 +69276,9 @@ function encodeDiagramUrl(dsl, options) {
|
|
|
69270
69276
|
return { url: `${baseUrl}?${hash}#${hash}` };
|
|
69271
69277
|
}
|
|
69272
69278
|
|
|
69279
|
+
// src/embed/index.ts
|
|
69280
|
+
init_palettes();
|
|
69281
|
+
|
|
69273
69282
|
// src/editor/dgmo.grammar.js
|
|
69274
69283
|
var import_lr = require("@lezer/lr");
|
|
69275
69284
|
|
|
@@ -69652,230 +69661,426 @@ function markTokensInRange(tokens, from, to, role) {
|
|
|
69652
69661
|
}
|
|
69653
69662
|
}
|
|
69654
69663
|
|
|
69655
|
-
// src/
|
|
69656
|
-
var
|
|
69657
|
-
|
|
69658
|
-
|
|
69659
|
-
|
|
69660
|
-
|
|
69661
|
-
|
|
69664
|
+
// src/embed/escape.ts
|
|
69665
|
+
var HTML_ENTITIES = {
|
|
69666
|
+
"&": "&",
|
|
69667
|
+
"<": "<",
|
|
69668
|
+
">": ">",
|
|
69669
|
+
'"': """,
|
|
69670
|
+
"'": "'"
|
|
69671
|
+
};
|
|
69672
|
+
function escapeHtml3(s) {
|
|
69673
|
+
return s.replace(/[&<>"']/g, (ch) => HTML_ENTITIES[ch] ?? ch);
|
|
69662
69674
|
}
|
|
69663
|
-
|
|
69664
|
-
.
|
|
69665
|
-
visibility: visible !important;
|
|
69675
|
+
function escapeAttr(s) {
|
|
69676
|
+
return s.replace(/[&<>"']/g, (ch) => HTML_ENTITIES[ch] ?? ch);
|
|
69666
69677
|
}
|
|
69667
69678
|
|
|
69668
|
-
.
|
|
69679
|
+
// src/embed/css.ts
|
|
69680
|
+
var BLOCK_CSS = `
|
|
69681
|
+
/* @diagrammo/dgmo block \u2014 standard embed chrome.
|
|
69682
|
+
* Override the [data-theme="dark"] selectors if your site uses .dark or
|
|
69683
|
+
* another color-mode convention. */
|
|
69684
|
+
|
|
69685
|
+
/* === Color-mode visibility (dual-render) === */
|
|
69686
|
+
.dgmo-dark {
|
|
69687
|
+
display: none;
|
|
69688
|
+
}
|
|
69689
|
+
[data-theme="dark"] .dgmo-light {
|
|
69690
|
+
display: none;
|
|
69691
|
+
}
|
|
69692
|
+
[data-theme="dark"] .dgmo-dark {
|
|
69669
69693
|
display: block;
|
|
69670
|
-
position: relative;
|
|
69671
|
-
margin: 1em 0;
|
|
69672
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
|
|
69673
|
-
Oxygen, Ubuntu, Cantarell, sans-serif;
|
|
69674
|
-
font-size: 14px;
|
|
69675
|
-
line-height: 1.4;
|
|
69676
|
-
color-scheme: light dark;
|
|
69677
69694
|
}
|
|
69678
|
-
|
|
69695
|
+
|
|
69696
|
+
/* === Diagram sizing ===
|
|
69697
|
+
* SVGs are emitted with viewBox only (no fixed width/height). Force them to
|
|
69698
|
+
* fill their wrapper so light and dark variants render at identical sizes. */
|
|
69699
|
+
.dgmo-light > svg,
|
|
69700
|
+
.dgmo-dark > svg,
|
|
69701
|
+
.dgmo-svg > svg {
|
|
69679
69702
|
display: block;
|
|
69680
|
-
|
|
69703
|
+
width: 100%;
|
|
69681
69704
|
height: auto;
|
|
69705
|
+
max-width: 100%;
|
|
69682
69706
|
}
|
|
69683
69707
|
|
|
69684
|
-
|
|
69685
|
-
|
|
69686
|
-
|
|
69708
|
+
/* === Toolbar ===
|
|
69709
|
+
* The diagram is the star: the toolbar is a slim reserved row below the SVG
|
|
69710
|
+
* (height always in flow \u2014 no layout shift) that stays fully transparent
|
|
69711
|
+
* until the block is hovered or focused, or the source panel is open. It is
|
|
69712
|
+
* the <summary> of the source <details>, so toggling works without any JS.
|
|
69713
|
+
* No text labels, no disclosure triangle \u2014 three wordless icon buttons. */
|
|
69714
|
+
.dgmo-source-wrap {
|
|
69715
|
+
margin: 0;
|
|
69716
|
+
}
|
|
69717
|
+
.dgmo-toolbar {
|
|
69718
|
+
display: flex;
|
|
69719
|
+
align-items: center;
|
|
69720
|
+
justify-content: flex-end;
|
|
69721
|
+
gap: 0.25em;
|
|
69722
|
+
min-height: 1.9em;
|
|
69723
|
+
padding: 0.15em 0;
|
|
69724
|
+
opacity: 0;
|
|
69725
|
+
transition: opacity 0.15s ease;
|
|
69726
|
+
cursor: pointer;
|
|
69727
|
+
list-style: none;
|
|
69728
|
+
user-select: none;
|
|
69729
|
+
color: rgba(127, 127, 127, 0.9);
|
|
69730
|
+
}
|
|
69731
|
+
.dgmo-toolbar::-webkit-details-marker {
|
|
69732
|
+
display: none;
|
|
69733
|
+
}
|
|
69734
|
+
/* Reveal is keyed to the diagram IMAGE (the svg wrappers), not the whole
|
|
69735
|
+
* figure \u2014 hovering the open code panel keeps the page quiet. The toolbar's
|
|
69736
|
+
* own :hover keeps it alive while the pointer travels down from the image
|
|
69737
|
+
* (they're adjacent, so there's no dead gap). focus-within covers keyboard
|
|
69738
|
+
* and touch-tap. */
|
|
69739
|
+
.dgmo-light:hover ~ .dgmo-source-wrap > .dgmo-toolbar,
|
|
69740
|
+
.dgmo-dark:hover ~ .dgmo-source-wrap > .dgmo-toolbar,
|
|
69741
|
+
.dgmo-svg:hover ~ .dgmo-source-wrap > .dgmo-toolbar,
|
|
69742
|
+
.dgmo-toolbar:hover,
|
|
69743
|
+
.dgmo:focus-within .dgmo-toolbar {
|
|
69744
|
+
opacity: 1;
|
|
69745
|
+
}
|
|
69746
|
+
/* Touch devices have no hover: keep the icons faintly visible so the
|
|
69747
|
+
* affordance is discoverable at all. */
|
|
69748
|
+
@media (hover: none) {
|
|
69749
|
+
.dgmo-toolbar {
|
|
69750
|
+
opacity: 0.5;
|
|
69751
|
+
}
|
|
69687
69752
|
}
|
|
69688
69753
|
|
|
69689
|
-
.dgmo-
|
|
69754
|
+
.dgmo-toggle,
|
|
69755
|
+
.dgmo-toolbar-btn {
|
|
69690
69756
|
display: inline-flex;
|
|
69691
69757
|
align-items: center;
|
|
69692
|
-
|
|
69693
|
-
|
|
69694
|
-
|
|
69695
|
-
|
|
69696
|
-
|
|
69697
|
-
padding: 4px 6px;
|
|
69698
|
-
background: transparent;
|
|
69758
|
+
justify-content: center;
|
|
69759
|
+
width: 1.9em;
|
|
69760
|
+
height: 1.9em;
|
|
69761
|
+
border-radius: 0.35em;
|
|
69762
|
+
background: none;
|
|
69699
69763
|
border: 0;
|
|
69700
|
-
|
|
69701
|
-
font-size: 11px;
|
|
69702
|
-
font-weight: 500;
|
|
69703
|
-
letter-spacing: 0.02em;
|
|
69704
|
-
text-align: left;
|
|
69705
|
-
cursor: pointer;
|
|
69764
|
+
padding: 0;
|
|
69706
69765
|
color: inherit;
|
|
69707
|
-
|
|
69708
|
-
|
|
69709
|
-
transition:
|
|
69710
|
-
|
|
69711
|
-
|
|
69712
|
-
opacity: 0.85;
|
|
69713
|
-
background: rgba(127, 127, 127, 0.08);
|
|
69766
|
+
cursor: pointer;
|
|
69767
|
+
opacity: 0.75;
|
|
69768
|
+
transition:
|
|
69769
|
+
opacity 0.15s ease,
|
|
69770
|
+
background-color 0.15s ease;
|
|
69714
69771
|
}
|
|
69715
|
-
.dgmo-
|
|
69772
|
+
.dgmo-toggle:hover,
|
|
69773
|
+
.dgmo-toolbar-btn:hover {
|
|
69716
69774
|
opacity: 1;
|
|
69717
|
-
|
|
69718
|
-
outline-offset: 1px;
|
|
69775
|
+
background: rgba(127, 127, 127, 0.12);
|
|
69719
69776
|
}
|
|
69720
|
-
.dgmo-
|
|
69721
|
-
|
|
69777
|
+
.dgmo-toggle svg,
|
|
69778
|
+
.dgmo-toolbar-btn svg {
|
|
69779
|
+
width: 1em;
|
|
69780
|
+
height: 1em;
|
|
69722
69781
|
}
|
|
69723
|
-
|
|
69724
|
-
|
|
69725
|
-
|
|
69726
|
-
|
|
69727
|
-
font-size: 8px;
|
|
69728
|
-
line-height: 1;
|
|
69729
|
-
transition: transform 150ms ease-out;
|
|
69782
|
+
/* Active state while the source panel is open. */
|
|
69783
|
+
.dgmo-source-wrap[open] > .dgmo-toolbar .dgmo-toggle {
|
|
69784
|
+
opacity: 1;
|
|
69785
|
+
background: rgba(127, 127, 127, 0.15);
|
|
69730
69786
|
}
|
|
69731
|
-
.dgmo-
|
|
69732
|
-
|
|
69787
|
+
.dgmo-copy--success {
|
|
69788
|
+
color: #5cba7a;
|
|
69789
|
+
opacity: 1;
|
|
69733
69790
|
}
|
|
69734
|
-
|
|
69735
|
-
|
|
69736
|
-
|
|
69737
|
-
|
|
69738
|
-
|
|
69739
|
-
|
|
69740
|
-
|
|
69791
|
+
|
|
69792
|
+
/* === Open state: frame the whole block ===
|
|
69793
|
+
* When the source panel is open, diagram + toolbar + code get one shared
|
|
69794
|
+
* border so the code visibly belongs to the chart above it, not to the
|
|
69795
|
+
* surrounding prose. Closed blocks stay frameless. */
|
|
69796
|
+
.dgmo:has(> .dgmo-source-wrap[open]) {
|
|
69797
|
+
border: 1px solid rgba(127, 127, 127, 0.3);
|
|
69798
|
+
border-radius: 0.6em;
|
|
69799
|
+
padding: 0.75em 0.75em 0.5em;
|
|
69741
69800
|
}
|
|
69742
69801
|
|
|
69743
|
-
|
|
69802
|
+
/* === Source panel (hidden until toggled) === */
|
|
69803
|
+
.dgmo-source-inner {
|
|
69804
|
+
border-top: 1px solid rgba(127, 127, 127, 0.25);
|
|
69805
|
+
background: rgba(127, 127, 127, 0.06);
|
|
69744
69806
|
overflow: hidden;
|
|
69745
|
-
|
|
69746
|
-
|
|
69747
|
-
|
|
69807
|
+
margin: 0 -0.75em -0.5em;
|
|
69808
|
+
border-radius: 0 0 0.6em 0.6em;
|
|
69809
|
+
}
|
|
69810
|
+
.dgmo-pre {
|
|
69811
|
+
white-space: pre;
|
|
69812
|
+
overflow-x: auto;
|
|
69813
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
69814
|
+
font-size: 0.85em;
|
|
69815
|
+
line-height: 1.5;
|
|
69816
|
+
margin: 0;
|
|
69817
|
+
padding: 1em;
|
|
69748
69818
|
}
|
|
69749
|
-
.dgmo-
|
|
69750
|
-
|
|
69751
|
-
overflow: auto;
|
|
69752
|
-
margin-top: 2px;
|
|
69753
|
-
border-radius: 4px;
|
|
69754
|
-
background: rgba(127, 127, 127, 0.04);
|
|
69819
|
+
.dgmo-code {
|
|
69820
|
+
display: block;
|
|
69755
69821
|
}
|
|
69756
|
-
|
|
69757
|
-
|
|
69822
|
+
|
|
69823
|
+
/* === Error card === */
|
|
69824
|
+
.dgmo--error {
|
|
69825
|
+
border: 1px solid rgba(220, 80, 80, 0.5);
|
|
69826
|
+
border-radius: 0.5em;
|
|
69827
|
+
padding: 0.75em 1em;
|
|
69758
69828
|
}
|
|
69759
|
-
.dgmo
|
|
69760
|
-
margin: 0;
|
|
69761
|
-
/* Right padding leaves room for the floating action icons. */
|
|
69762
|
-
padding: 10px 56px 10px 14px;
|
|
69763
|
-
font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
|
|
69764
|
-
font-size: 12px;
|
|
69765
|
-
line-height: 1.45;
|
|
69829
|
+
.dgmo--error pre {
|
|
69766
69830
|
white-space: pre;
|
|
69767
|
-
overflow: auto;
|
|
69768
|
-
|
|
69769
|
-
|
|
69831
|
+
overflow-x: auto;
|
|
69832
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
69833
|
+
font-size: 0.85em;
|
|
69834
|
+
margin: 0.5em 0 0;
|
|
69770
69835
|
}
|
|
69771
69836
|
|
|
69772
|
-
|
|
69773
|
-
|
|
69774
|
-
|
|
69775
|
-
|
|
69776
|
-
|
|
69777
|
-
|
|
69778
|
-
/* Inherit visibility:hidden when collapsed; pointer-events:none keeps
|
|
69779
|
-
them off the tab order until the panel opens. */
|
|
69780
|
-
pointer-events: none;
|
|
69837
|
+
/* === Source highlight roles ===
|
|
69838
|
+
* Light values mirror LIGHT_ROLE_STYLES; dark overrides mirror
|
|
69839
|
+
* NORD_ROLE_STYLES. Guarded by the parity test in tests/block.test.ts. */
|
|
69840
|
+
.dgmo-tok-keyword {
|
|
69841
|
+
color: #3b6ea5;
|
|
69842
|
+
font-weight: bold;
|
|
69781
69843
|
}
|
|
69782
|
-
.dgmo-
|
|
69783
|
-
|
|
69844
|
+
.dgmo-tok-controlKeyword {
|
|
69845
|
+
color: #7d5ba6;
|
|
69846
|
+
font-weight: bold;
|
|
69784
69847
|
}
|
|
69785
|
-
.dgmo-
|
|
69786
|
-
|
|
69787
|
-
|
|
69788
|
-
justify-content: center;
|
|
69789
|
-
width: 26px;
|
|
69790
|
-
height: 26px;
|
|
69791
|
-
padding: 0;
|
|
69792
|
-
background: transparent;
|
|
69793
|
-
color: inherit;
|
|
69794
|
-
border: 0;
|
|
69795
|
-
border-radius: 3px;
|
|
69796
|
-
cursor: pointer;
|
|
69797
|
-
text-decoration: none;
|
|
69798
|
-
opacity: 0.4;
|
|
69799
|
-
transition: opacity 120ms ease, background 120ms ease, color 120ms ease;
|
|
69848
|
+
.dgmo-tok-definitionKeyword {
|
|
69849
|
+
color: #2f5a86;
|
|
69850
|
+
font-weight: bold;
|
|
69800
69851
|
}
|
|
69801
|
-
.dgmo-
|
|
69802
|
-
|
|
69803
|
-
background: rgba(127, 127, 127, 0.15);
|
|
69852
|
+
.dgmo-tok-modifier {
|
|
69853
|
+
color: #7d5ba6;
|
|
69804
69854
|
}
|
|
69805
|
-
.dgmo-
|
|
69806
|
-
|
|
69807
|
-
|
|
69808
|
-
outline-offset: 1px;
|
|
69855
|
+
.dgmo-tok-chartType {
|
|
69856
|
+
color: #b8691f;
|
|
69857
|
+
font-weight: bold;
|
|
69809
69858
|
}
|
|
69810
|
-
.dgmo-
|
|
69811
|
-
|
|
69812
|
-
|
|
69859
|
+
.dgmo-tok-operator {
|
|
69860
|
+
color: #c0504d;
|
|
69861
|
+
font-weight: bold;
|
|
69813
69862
|
}
|
|
69814
|
-
.dgmo-
|
|
69815
|
-
|
|
69863
|
+
.dgmo-tok-number {
|
|
69864
|
+
color: #7d5ba6;
|
|
69816
69865
|
}
|
|
69817
|
-
.dgmo-
|
|
69818
|
-
|
|
69819
|
-
|
|
69866
|
+
.dgmo-tok-comment {
|
|
69867
|
+
color: #677483;
|
|
69868
|
+
font-style: italic;
|
|
69820
69869
|
}
|
|
69821
|
-
.dgmo-
|
|
69822
|
-
|
|
69823
|
-
|
|
69824
|
-
|
|
69870
|
+
.dgmo-tok-heading {
|
|
69871
|
+
color: #b8691f;
|
|
69872
|
+
font-weight: bold;
|
|
69873
|
+
}
|
|
69874
|
+
.dgmo-tok-bracket {
|
|
69875
|
+
color: #5b6672;
|
|
69876
|
+
}
|
|
69877
|
+
.dgmo-tok-separator {
|
|
69878
|
+
color: #2d7268;
|
|
69879
|
+
}
|
|
69880
|
+
.dgmo-tok-deprecatedSyntax {
|
|
69881
|
+
color: #c0504d;
|
|
69882
|
+
text-decoration: line-through;
|
|
69883
|
+
}
|
|
69884
|
+
.dgmo-tok-url {
|
|
69885
|
+
color: #3b6ea5;
|
|
69886
|
+
text-decoration: underline;
|
|
69887
|
+
}
|
|
69888
|
+
.dgmo-tok-colorAnnotation {
|
|
69889
|
+
color: #b8691f;
|
|
69890
|
+
font-style: italic;
|
|
69891
|
+
}
|
|
69892
|
+
.dgmo-tok-punctuation {
|
|
69893
|
+
color: #677483;
|
|
69894
|
+
}
|
|
69895
|
+
.dgmo-tok-propertyName {
|
|
69896
|
+
color: #2d7268;
|
|
69897
|
+
}
|
|
69898
|
+
.dgmo-tok-string {
|
|
69899
|
+
color: #3f7a3b;
|
|
69900
|
+
}
|
|
69901
|
+
.dgmo-tok-noteContent {
|
|
69902
|
+
color: #677483;
|
|
69903
|
+
font-style: italic;
|
|
69904
|
+
}
|
|
69905
|
+
|
|
69906
|
+
[data-theme="dark"] .dgmo-tok-keyword {
|
|
69907
|
+
color: #81a1c1;
|
|
69908
|
+
font-weight: bold;
|
|
69909
|
+
}
|
|
69910
|
+
[data-theme="dark"] .dgmo-tok-controlKeyword {
|
|
69911
|
+
color: #b48ead;
|
|
69912
|
+
font-weight: bold;
|
|
69913
|
+
}
|
|
69914
|
+
[data-theme="dark"] .dgmo-tok-definitionKeyword {
|
|
69915
|
+
color: #5e81ac;
|
|
69916
|
+
font-weight: bold;
|
|
69917
|
+
}
|
|
69918
|
+
[data-theme="dark"] .dgmo-tok-modifier {
|
|
69919
|
+
color: #b48ead;
|
|
69920
|
+
}
|
|
69921
|
+
[data-theme="dark"] .dgmo-tok-chartType {
|
|
69922
|
+
color: #d08770;
|
|
69923
|
+
font-weight: bold;
|
|
69924
|
+
}
|
|
69925
|
+
[data-theme="dark"] .dgmo-tok-operator {
|
|
69926
|
+
color: #bf616a;
|
|
69927
|
+
font-weight: bold;
|
|
69928
|
+
}
|
|
69929
|
+
[data-theme="dark"] .dgmo-tok-number {
|
|
69930
|
+
color: #b48ead;
|
|
69931
|
+
}
|
|
69932
|
+
[data-theme="dark"] .dgmo-tok-comment {
|
|
69933
|
+
color: #616e88;
|
|
69934
|
+
font-style: italic;
|
|
69935
|
+
}
|
|
69936
|
+
[data-theme="dark"] .dgmo-tok-heading {
|
|
69937
|
+
color: #d08770;
|
|
69938
|
+
font-weight: bold;
|
|
69939
|
+
}
|
|
69940
|
+
[data-theme="dark"] .dgmo-tok-bracket {
|
|
69941
|
+
color: #5e81ac;
|
|
69942
|
+
}
|
|
69943
|
+
[data-theme="dark"] .dgmo-tok-separator {
|
|
69944
|
+
color: #88c0d0;
|
|
69945
|
+
}
|
|
69946
|
+
[data-theme="dark"] .dgmo-tok-deprecatedSyntax {
|
|
69947
|
+
color: #bf616a;
|
|
69948
|
+
text-decoration: line-through;
|
|
69949
|
+
}
|
|
69950
|
+
[data-theme="dark"] .dgmo-tok-url {
|
|
69951
|
+
color: #88c0d0;
|
|
69952
|
+
text-decoration: underline;
|
|
69953
|
+
}
|
|
69954
|
+
[data-theme="dark"] .dgmo-tok-colorAnnotation {
|
|
69955
|
+
color: #d08770;
|
|
69956
|
+
font-style: italic;
|
|
69957
|
+
}
|
|
69958
|
+
[data-theme="dark"] .dgmo-tok-punctuation {
|
|
69959
|
+
color: #616e88;
|
|
69960
|
+
}
|
|
69961
|
+
[data-theme="dark"] .dgmo-tok-propertyName {
|
|
69962
|
+
color: #88c0d0;
|
|
69963
|
+
}
|
|
69964
|
+
[data-theme="dark"] .dgmo-tok-string {
|
|
69965
|
+
color: #a3be8c;
|
|
69966
|
+
}
|
|
69967
|
+
[data-theme="dark"] .dgmo-tok-noteContent {
|
|
69968
|
+
color: #616e88;
|
|
69969
|
+
font-style: italic;
|
|
69970
|
+
}
|
|
69971
|
+
`;
|
|
69972
|
+
|
|
69973
|
+
// src/embed/index.ts
|
|
69974
|
+
var EDITOR_BASE_URL = "https://online.diagrammo.app";
|
|
69975
|
+
function resolveBlockOptions(opts) {
|
|
69976
|
+
const mode = opts.mode ?? "diagram";
|
|
69977
|
+
const showcase = mode === "showcase";
|
|
69978
|
+
return {
|
|
69979
|
+
mode,
|
|
69980
|
+
palette: opts.palette ?? "slate",
|
|
69981
|
+
colorMode: opts.colorMode ?? "auto",
|
|
69982
|
+
showSource: opts.showSource ?? showcase,
|
|
69983
|
+
showCopy: opts.showCopy ?? showcase,
|
|
69984
|
+
showOpenInEditor: opts.showOpenInEditor ?? showcase,
|
|
69985
|
+
editorBaseUrl: opts.editorBaseUrl ?? EDITOR_BASE_URL,
|
|
69986
|
+
wrapper: opts.wrapper ?? "figure",
|
|
69987
|
+
className: opts.className ?? "dgmo",
|
|
69988
|
+
legacyClassNames: opts.legacyClassNames ?? [],
|
|
69989
|
+
title: opts.title,
|
|
69990
|
+
onWarn: opts.onWarn ?? ((message) => console.warn(message))
|
|
69991
|
+
};
|
|
69992
|
+
}
|
|
69993
|
+
function buildDgmoBlockHtml(source, svgsHtml, options = {}) {
|
|
69994
|
+
return assembleBlock(source.trim(), svgsHtml, resolveBlockOptions(options));
|
|
69995
|
+
}
|
|
69996
|
+
function errorBlockHtml(err, source, options = {}) {
|
|
69997
|
+
const msg = err instanceof Error ? err.message : "Failed to render dgmo block.";
|
|
69998
|
+
const base = options.className ?? "dgmo";
|
|
69999
|
+
const legacy = (options.legacyClassNames ?? []).join(" ");
|
|
70000
|
+
const cls = legacy ? `${base} ${legacy} ${base}--error` : `${base} ${base}--error`;
|
|
70001
|
+
return `<div class="${escapeAttr(cls)}" role="alert"><strong>dgmo render error:</strong> ${escapeHtml3(msg)}<pre>${escapeHtml3(source)}</pre></div>`;
|
|
70002
|
+
}
|
|
70003
|
+
function wrapperClasses(opts, variant) {
|
|
70004
|
+
const base = `${opts.className} ${opts.className}--${variant}`;
|
|
70005
|
+
const legacy = opts.legacyClassNames.join(" ");
|
|
70006
|
+
return legacy ? `${base} ${legacy}` : base;
|
|
70007
|
+
}
|
|
70008
|
+
function assembleBlock(source, svgsHtml, opts) {
|
|
70009
|
+
const Wrapper = opts.wrapper;
|
|
70010
|
+
const showcase = opts.mode === "showcase";
|
|
70011
|
+
const variant = showcase ? "showcase" : "diagram";
|
|
70012
|
+
const ariaAttr = opts.title ? ` aria-label="${escapeAttr(opts.title)}"` : "";
|
|
70013
|
+
const sourceHtml = showcase ? sourceDisclosure(source, opts) : "";
|
|
70014
|
+
return `<${Wrapper} class="${escapeAttr(wrapperClasses(opts, variant))}"${ariaAttr}>` + svgsHtml + sourceHtml + `</${Wrapper}>`;
|
|
70015
|
+
}
|
|
70016
|
+
var CODE_ICON = `<svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m10 4.5 4 3.5-4 3.5"/><path d="m6 4.5-4 3.5 4 3.5"/></svg>`;
|
|
70017
|
+
var COPY_ICON = `<svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="5.5" y="5.5" width="8" height="8" rx="1.5"/><path d="M10.5 5.5V3a1.5 1.5 0 0 0-1.5-1.5H3A1.5 1.5 0 0 0 1.5 3v6A1.5 1.5 0 0 0 3 10.5h2.5"/></svg>`;
|
|
70018
|
+
var EXTERNAL_ICON = `<svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9.5 2.5h4v4"/><path d="M13.5 2.5 7 9"/><path d="M12.5 9.5v3a1 1 0 0 1-1 1h-8a1 1 0 0 1-1-1v-8a1 1 0 0 1 1-1h3"/></svg>`;
|
|
70019
|
+
function sourceDisclosure(source, opts) {
|
|
70020
|
+
if (!opts.showSource) return "";
|
|
70021
|
+
const toggle = `<span class="dgmo-toggle" title="View DGMO source">${CODE_ICON}</span>`;
|
|
70022
|
+
const copyButton = opts.showCopy ? `<button type="button" class="dgmo-toolbar-btn dgmo-copy" aria-label="Copy DGMO source" title="Copy source" data-dgmo-source="${escapeAttr(source)}">${COPY_ICON}</button>` : "";
|
|
70023
|
+
let openButton = "";
|
|
70024
|
+
if (opts.showOpenInEditor) {
|
|
70025
|
+
const encoded = encodeDiagramUrl(source, { baseUrl: opts.editorBaseUrl });
|
|
70026
|
+
if (encoded.url) {
|
|
70027
|
+
openButton = `<a href="${escapeAttr(encoded.url)}" target="_blank" rel="noopener noreferrer" class="dgmo-toolbar-btn dgmo-open" aria-label="Open in online editor" title="Open in online editor">${EXTERNAL_ICON}</a>`;
|
|
70028
|
+
}
|
|
70029
|
+
}
|
|
70030
|
+
const sourceHtml = highlightedSource(source);
|
|
70031
|
+
return `<details class="dgmo-source-wrap"><summary class="dgmo-toolbar" aria-label="View DGMO source">${toggle}${copyButton}${openButton}</summary><div class="dgmo-source-inner">${sourceHtml}</div></details>`;
|
|
70032
|
+
}
|
|
70033
|
+
function highlightedSource(source) {
|
|
70034
|
+
const tokens = highlightDgmo(source);
|
|
70035
|
+
const inner = tokens.map((t) => {
|
|
70036
|
+
const text = escapeHtml3(t.text);
|
|
70037
|
+
if (!t.role || t.role === "default") return text;
|
|
70038
|
+
return `<span class="dgmo-tok-${escapeAttr(t.role)}">${text}</span>`;
|
|
70039
|
+
}).join("");
|
|
70040
|
+
return `<pre class="dgmo-pre"><span class="dgmo-code">${inner}</span></pre>`;
|
|
70041
|
+
}
|
|
70042
|
+
|
|
70043
|
+
// src/auto/styles.ts
|
|
70044
|
+
var AUTO_BASE_CSS = `
|
|
70045
|
+
/* anti-flash: hide source elements until either render swaps them out
|
|
70046
|
+
or the error path replaces them with the standard error card */
|
|
70047
|
+
pre.dgmo, code.language-dgmo, pre > code.language-dgmo,
|
|
70048
|
+
.dgmo:not(svg *):not(.dgmo-rendered):not(.dgmo-rendered *):not(.dgmo--error):not(.dgmo--error *) {
|
|
70049
|
+
visibility: hidden;
|
|
70050
|
+
}
|
|
70051
|
+
.dgmo-rendered, .dgmo-rendered *,
|
|
70052
|
+
.dgmo--error, .dgmo--error * {
|
|
70053
|
+
visibility: visible !important;
|
|
69825
70054
|
}
|
|
69826
70055
|
|
|
69827
|
-
.dgmo-
|
|
70056
|
+
.dgmo-rendered {
|
|
69828
70057
|
display: block;
|
|
69829
|
-
|
|
69830
|
-
|
|
69831
|
-
|
|
69832
|
-
|
|
69833
|
-
font-
|
|
69834
|
-
font-size: 13px;
|
|
70058
|
+
position: relative;
|
|
70059
|
+
margin: 1em 0;
|
|
70060
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
|
|
70061
|
+
Oxygen, Ubuntu, Cantarell, sans-serif;
|
|
70062
|
+
font-size: 14px;
|
|
69835
70063
|
line-height: 1.4;
|
|
69836
|
-
color:
|
|
69837
|
-
border-radius: 0 4px 4px 0;
|
|
69838
|
-
}
|
|
69839
|
-
.dgmo-error-banner-title {
|
|
69840
|
-
font-weight: 600;
|
|
69841
|
-
margin-bottom: 2px;
|
|
70064
|
+
color-scheme: light dark;
|
|
69842
70065
|
}
|
|
69843
|
-
|
|
69844
|
-
|
|
70066
|
+
|
|
70067
|
+
.dgmo--loading {
|
|
70068
|
+
opacity: 0.6;
|
|
69845
70069
|
font-size: 12px;
|
|
69846
70070
|
font-family: ui-monospace, monospace;
|
|
69847
70071
|
}
|
|
69848
|
-
|
|
69849
|
-
/* Token roles \u2014 fallback colors used when theme classes don't override */
|
|
69850
|
-
.dgmo-source-pre .dgmo-tok-keyword { color: #5e81ac; font-weight: 600; }
|
|
69851
|
-
.dgmo-source-pre .dgmo-tok-controlKeyword { color: #b48ead; font-weight: 600; }
|
|
69852
|
-
.dgmo-source-pre .dgmo-tok-definitionKeyword { color: #5e81ac; font-weight: 600; }
|
|
69853
|
-
.dgmo-source-pre .dgmo-tok-modifier { color: #b48ead; }
|
|
69854
|
-
.dgmo-source-pre .dgmo-tok-chartType { color: #d08770; font-weight: 600; }
|
|
69855
|
-
.dgmo-source-pre .dgmo-tok-operator { color: #bf616a; font-weight: 600; }
|
|
69856
|
-
.dgmo-source-pre .dgmo-tok-number { color: #b48ead; }
|
|
69857
|
-
.dgmo-source-pre .dgmo-tok-comment { color: #6c7a96; font-style: italic; }
|
|
69858
|
-
.dgmo-source-pre .dgmo-tok-heading { color: #d08770; font-weight: 600; }
|
|
69859
|
-
.dgmo-source-pre .dgmo-tok-bracket { color: #5e81ac; }
|
|
69860
|
-
.dgmo-source-pre .dgmo-tok-separator { color: #88c0d0; }
|
|
69861
|
-
.dgmo-source-pre .dgmo-tok-url { color: #88c0d0; text-decoration: underline; }
|
|
69862
|
-
.dgmo-source-pre .dgmo-tok-colorAnnotation { color: #d08770; font-style: italic; }
|
|
69863
|
-
.dgmo-source-pre .dgmo-tok-punctuation { color: #6c7a96; }
|
|
69864
|
-
.dgmo-source-pre .dgmo-tok-noteContent { color: #6c7a96; font-style: italic; }
|
|
69865
|
-
|
|
69866
|
-
.dgmo-rendered.dgmo-theme-dark .dgmo-source-pre .dgmo-tok-keyword,
|
|
69867
|
-
.dgmo-rendered.dgmo-theme-dark .dgmo-source-pre .dgmo-tok-definitionKeyword { color: #81a1c1; }
|
|
69868
|
-
.dgmo-rendered.dgmo-theme-dark .dgmo-source-pre .dgmo-tok-comment,
|
|
69869
|
-
.dgmo-rendered.dgmo-theme-dark .dgmo-source-pre .dgmo-tok-noteContent,
|
|
69870
|
-
.dgmo-rendered.dgmo-theme-dark .dgmo-source-pre .dgmo-tok-punctuation { color: #616e88; }
|
|
69871
70072
|
`;
|
|
70073
|
+
function darkScopedBlockCss(css) {
|
|
70074
|
+
const rules = css.match(/\[data-theme="dark"\][^{]*\{[^}]*\}/g) ?? [];
|
|
70075
|
+
return rules.map((rule) => rule.replace(/\[data-theme="dark"\]/g, ".dgmo-theme-dark")).join("\n");
|
|
70076
|
+
}
|
|
70077
|
+
var CSS = AUTO_BASE_CSS + "\n" + BLOCK_CSS + "\n" + darkScopedBlockCss(BLOCK_CSS) + "\n";
|
|
69872
70078
|
|
|
69873
70079
|
// src/auto/shared.ts
|
|
69874
70080
|
init_safe_href();
|
|
69875
|
-
var VERSION = "0.
|
|
69876
|
-
var EDITOR_BASE_URL = "https://online.diagrammo.app";
|
|
70081
|
+
var VERSION = "0.46.0";
|
|
69877
70082
|
var ARIA_LABEL_MAX = 200;
|
|
69878
|
-
var COPIED_INTERACTION_MS =
|
|
70083
|
+
var COPIED_INTERACTION_MS = 1500;
|
|
69879
70084
|
var LOG_PREFIX = "[dgmo]";
|
|
69880
70085
|
var ARIA_STRIP_RE = /[\x00-\x1F--]/g;
|
|
69881
70086
|
var STYLE_FLAG = "dgmoAutoStyles";
|
|
@@ -69944,139 +70149,98 @@ function deriveAriaLabel(source) {
|
|
|
69944
70149
|
if (!firstLine) return "DGMO diagram";
|
|
69945
70150
|
return firstLine.replace(ARIA_STRIP_RE, "").slice(0, ARIA_LABEL_MAX);
|
|
69946
70151
|
}
|
|
69947
|
-
function
|
|
69948
|
-
const
|
|
69949
|
-
|
|
69950
|
-
|
|
69951
|
-
|
|
69952
|
-
|
|
69953
|
-
|
|
69954
|
-
return frag;
|
|
69955
|
-
}
|
|
69956
|
-
for (const tok of tokens) {
|
|
69957
|
-
if (!tok.text) continue;
|
|
69958
|
-
const span = document.createElement("span");
|
|
69959
|
-
span.className = `dgmo-tok-${tok.role}`;
|
|
69960
|
-
span.textContent = tok.text;
|
|
69961
|
-
frag.appendChild(span);
|
|
69962
|
-
}
|
|
69963
|
-
return frag;
|
|
69964
|
-
}
|
|
69965
|
-
var COPY_ICON_SVG = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="5.5" y="5.5" width="8" height="8" rx="1.5"/><path d="M10.5 5.5V3a1.5 1.5 0 0 0-1.5-1.5H3A1.5 1.5 0 0 0 1.5 3v6A1.5 1.5 0 0 0 3 10.5h2.5"/></svg>';
|
|
69966
|
-
var CHECK_ICON_SVG = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="3 8.5 6.5 12 13 4.5"/></svg>';
|
|
69967
|
-
var EXTERNAL_ICON_SVG = '<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9 2h5v5"/><path d="M14 2L7 9"/><path d="M13 9v4a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h4"/></svg>';
|
|
69968
|
-
function setIcon(el, svg) {
|
|
69969
|
-
el.innerHTML = svg;
|
|
69970
|
-
}
|
|
69971
|
-
function buildSourcePanel(source, shareUrl, showEditorLink) {
|
|
69972
|
-
const panel = document.createElement("div");
|
|
69973
|
-
panel.className = "dgmo-source-panel";
|
|
69974
|
-
const toggle = document.createElement("button");
|
|
69975
|
-
toggle.type = "button";
|
|
69976
|
-
toggle.className = "dgmo-source-toggle";
|
|
69977
|
-
toggle.setAttribute("aria-expanded", "false");
|
|
69978
|
-
const chevron = document.createElement("span");
|
|
69979
|
-
chevron.className = "dgmo-chevron";
|
|
69980
|
-
chevron.setAttribute("aria-hidden", "true");
|
|
69981
|
-
chevron.textContent = "\u25B8";
|
|
69982
|
-
toggle.appendChild(chevron);
|
|
69983
|
-
const label = document.createElement("span");
|
|
69984
|
-
label.textContent = "DGMO source";
|
|
69985
|
-
toggle.appendChild(label);
|
|
69986
|
-
const body = document.createElement("div");
|
|
69987
|
-
body.className = "dgmo-source-body";
|
|
69988
|
-
const pre = document.createElement("pre");
|
|
69989
|
-
pre.className = "dgmo-source-pre";
|
|
69990
|
-
pre.appendChild(buildHighlightedSource(source));
|
|
69991
|
-
body.appendChild(pre);
|
|
69992
|
-
const actions = document.createElement("div");
|
|
69993
|
-
actions.className = "dgmo-source-actions";
|
|
69994
|
-
const copyBtn = document.createElement("button");
|
|
69995
|
-
copyBtn.type = "button";
|
|
69996
|
-
copyBtn.className = "dgmo-btn dgmo-btn-copy";
|
|
69997
|
-
copyBtn.setAttribute("aria-label", "Copy DGMO source");
|
|
69998
|
-
copyBtn.title = "Copy source";
|
|
69999
|
-
setIcon(copyBtn, COPY_ICON_SVG);
|
|
70000
|
-
copyBtn.addEventListener("click", () => {
|
|
70001
|
-
void copySource(source, copyBtn);
|
|
70152
|
+
function buildRenderedBlock(opts) {
|
|
70153
|
+
const html = buildDgmoBlockHtml(opts.source, '<div class="dgmo-svg"></div>', {
|
|
70154
|
+
mode: opts.showSource ? "showcase" : "diagram",
|
|
70155
|
+
showOpenInEditor: opts.showSource && opts.showEditorLink,
|
|
70156
|
+
// Keep the legacy `.dgmo-rendered` + theme hooks so the anti-flash CSS,
|
|
70157
|
+
// idempotency filters, and theme-scoped token colors keep working.
|
|
70158
|
+
legacyClassNames: ["dgmo-rendered", opts.themeClass]
|
|
70002
70159
|
});
|
|
70003
|
-
|
|
70004
|
-
|
|
70005
|
-
|
|
70006
|
-
|
|
70007
|
-
|
|
70008
|
-
|
|
70009
|
-
|
|
70010
|
-
|
|
70011
|
-
|
|
70012
|
-
|
|
70013
|
-
|
|
70014
|
-
|
|
70015
|
-
|
|
70016
|
-
|
|
70017
|
-
|
|
70018
|
-
}
|
|
70019
|
-
actions.appendChild(editorBtn);
|
|
70020
|
-
}
|
|
70021
|
-
body.appendChild(actions);
|
|
70022
|
-
panel.appendChild(toggle);
|
|
70023
|
-
panel.appendChild(body);
|
|
70024
|
-
toggle.addEventListener("click", () => {
|
|
70025
|
-
const open = body.classList.toggle("dgmo-open");
|
|
70026
|
-
toggle.setAttribute("aria-expanded", open ? "true" : "false");
|
|
70160
|
+
const holder = document.createElement("div");
|
|
70161
|
+
holder.innerHTML = html;
|
|
70162
|
+
const wrapper = holder.firstElementChild;
|
|
70163
|
+
wrapper.querySelector(".dgmo-svg")?.appendChild(opts.svgEl);
|
|
70164
|
+
const open = wrapper.querySelector("a.dgmo-open");
|
|
70165
|
+
if (open) {
|
|
70166
|
+
if (opts.shareUrl) open.href = opts.shareUrl;
|
|
70167
|
+
else open.remove();
|
|
70168
|
+
}
|
|
70169
|
+
bindBlockToolbar(wrapper);
|
|
70170
|
+
return wrapper;
|
|
70171
|
+
}
|
|
70172
|
+
function bindBlockToolbar(wrapper) {
|
|
70173
|
+
wrapper.addEventListener("click", (e) => {
|
|
70174
|
+
void handleToolbarClick(e);
|
|
70027
70175
|
});
|
|
70028
|
-
return panel;
|
|
70029
70176
|
}
|
|
70030
|
-
async function
|
|
70031
|
-
|
|
70177
|
+
async function handleToolbarClick(e) {
|
|
70178
|
+
const target = e.target;
|
|
70179
|
+
if (!target || typeof target.closest !== "function") return;
|
|
70180
|
+
const btn = target.closest(".dgmo-toolbar-btn");
|
|
70181
|
+
if (!btn) return;
|
|
70182
|
+
const insideSummary = !!btn.closest("summary");
|
|
70183
|
+
if (insideSummary) e.preventDefault();
|
|
70184
|
+
if (btn.matches("button.dgmo-copy")) {
|
|
70185
|
+
const copied = await copyText(btn.dataset["dgmoSource"] ?? "");
|
|
70186
|
+
if (copied) {
|
|
70187
|
+
btn.classList.add("dgmo-copy--success");
|
|
70188
|
+
setTimeout(
|
|
70189
|
+
() => btn.classList.remove("dgmo-copy--success"),
|
|
70190
|
+
COPIED_INTERACTION_MS
|
|
70191
|
+
);
|
|
70192
|
+
} else {
|
|
70193
|
+
sharedWarn("clipboard write failed");
|
|
70194
|
+
}
|
|
70195
|
+
return;
|
|
70196
|
+
}
|
|
70197
|
+
if (insideSummary && btn.matches("a.dgmo-open")) {
|
|
70198
|
+
const anchor = btn;
|
|
70199
|
+
if (anchor.href) {
|
|
70200
|
+
window.open(
|
|
70201
|
+
anchor.href,
|
|
70202
|
+
anchor.target || "_blank",
|
|
70203
|
+
"noopener,noreferrer"
|
|
70204
|
+
);
|
|
70205
|
+
}
|
|
70206
|
+
}
|
|
70207
|
+
}
|
|
70208
|
+
async function copyText(text) {
|
|
70032
70209
|
try {
|
|
70033
70210
|
if (navigator?.clipboard?.writeText) {
|
|
70034
|
-
await navigator.clipboard.writeText(
|
|
70035
|
-
|
|
70211
|
+
await navigator.clipboard.writeText(text);
|
|
70212
|
+
return true;
|
|
70036
70213
|
}
|
|
70037
70214
|
} catch {
|
|
70038
70215
|
}
|
|
70039
|
-
if (
|
|
70216
|
+
if (typeof document !== "undefined") {
|
|
70040
70217
|
try {
|
|
70041
70218
|
const ta = document.createElement("textarea");
|
|
70042
|
-
ta.value =
|
|
70219
|
+
ta.value = text;
|
|
70043
70220
|
ta.setAttribute("readonly", "");
|
|
70044
70221
|
ta.style.position = "absolute";
|
|
70045
70222
|
ta.style.left = "-9999px";
|
|
70046
70223
|
document.body.appendChild(ta);
|
|
70047
70224
|
ta.select();
|
|
70048
|
-
copied = document.execCommand("copy");
|
|
70225
|
+
const copied = document.execCommand("copy");
|
|
70049
70226
|
document.body.removeChild(ta);
|
|
70227
|
+
return copied;
|
|
70050
70228
|
} catch {
|
|
70051
|
-
|
|
70229
|
+
return false;
|
|
70052
70230
|
}
|
|
70053
70231
|
}
|
|
70054
|
-
|
|
70055
|
-
setIcon(btn, CHECK_ICON_SVG);
|
|
70056
|
-
btn.classList.add("dgmo-btn-copied");
|
|
70057
|
-
setTimeout(() => {
|
|
70058
|
-
setIcon(btn, COPY_ICON_SVG);
|
|
70059
|
-
btn.classList.remove("dgmo-btn-copied");
|
|
70060
|
-
}, COPIED_INTERACTION_MS);
|
|
70061
|
-
} else {
|
|
70062
|
-
sharedWarn("clipboard write failed");
|
|
70063
|
-
}
|
|
70232
|
+
return false;
|
|
70064
70233
|
}
|
|
70065
|
-
function
|
|
70066
|
-
|
|
70067
|
-
banner.className = "dgmo-error-banner";
|
|
70068
|
-
banner.setAttribute("role", "alert");
|
|
70069
|
-
const title = document.createElement("div");
|
|
70070
|
-
title.className = "dgmo-error-banner-title";
|
|
70071
|
-
title.textContent = `${opts.severity ?? "error"}: ${opts.message}`;
|
|
70072
|
-
banner.appendChild(title);
|
|
70234
|
+
function buildErrorBlock(opts) {
|
|
70235
|
+
let message = opts.severity && opts.severity !== "error" ? `${opts.severity}: ${opts.message}` : opts.message;
|
|
70073
70236
|
if (opts.line !== void 0 && opts.line > 0) {
|
|
70074
|
-
|
|
70075
|
-
loc.className = "dgmo-error-banner-loc";
|
|
70076
|
-
loc.textContent = opts.column !== void 0 ? `at ${opts.line}:${opts.column}` : `at line ${opts.line}`;
|
|
70077
|
-
banner.appendChild(loc);
|
|
70237
|
+
message += opts.column !== void 0 ? ` (at ${opts.line}:${opts.column})` : ` (at line ${opts.line})`;
|
|
70078
70238
|
}
|
|
70079
|
-
|
|
70239
|
+
const holder = document.createElement("div");
|
|
70240
|
+
holder.innerHTML = errorBlockHtml(new Error(message), opts.source);
|
|
70241
|
+
const card = holder.firstElementChild;
|
|
70242
|
+
card.setAttribute("data-dgmo-processed", "true");
|
|
70243
|
+
return card;
|
|
70080
70244
|
}
|
|
70081
70245
|
function buildShareUrl(source, opts) {
|
|
70082
70246
|
const result = encodeDiagramUrl(source, {
|
|
@@ -70216,6 +70380,10 @@ function determineReplaceTarget(matched) {
|
|
|
70216
70380
|
}
|
|
70217
70381
|
return matched;
|
|
70218
70382
|
}
|
|
70383
|
+
function replaceWithErrorCard(el, source, opts) {
|
|
70384
|
+
const card = buildErrorBlock({ ...opts, source });
|
|
70385
|
+
determineReplaceTarget(el).replaceWith(card);
|
|
70386
|
+
}
|
|
70219
70387
|
async function processElement(el) {
|
|
70220
70388
|
if (!(el instanceof HTMLElement)) return {};
|
|
70221
70389
|
if (el.dataset["dgmoProcessed"] === "true") return {};
|
|
@@ -70223,12 +70391,10 @@ async function processElement(el) {
|
|
|
70223
70391
|
const source = el.textContent || "";
|
|
70224
70392
|
const sourceBytes = new TextEncoder().encode(source).byteLength;
|
|
70225
70393
|
if (sourceBytes > SOURCE_BYTE_CAP) {
|
|
70226
|
-
el
|
|
70227
|
-
const banner = buildErrorBanner({
|
|
70394
|
+
replaceWithErrorCard(el, source, {
|
|
70228
70395
|
message: `DGMO source too large to render \u2014 ${SOURCE_BYTE_CAP / 1024} KB max`,
|
|
70229
70396
|
severity: "error"
|
|
70230
70397
|
});
|
|
70231
|
-
el.parentElement?.insertBefore(banner, el);
|
|
70232
70398
|
warn("source exceeds 256 KB cap");
|
|
70233
70399
|
return {};
|
|
70234
70400
|
}
|
|
@@ -70254,69 +70420,62 @@ async function processElement(el) {
|
|
|
70254
70420
|
palette: cfg.palette
|
|
70255
70421
|
});
|
|
70256
70422
|
} catch (err) {
|
|
70257
|
-
el.style.visibility = "";
|
|
70258
70423
|
const message = err instanceof Error ? err.message : "Render failed unexpectedly";
|
|
70259
|
-
|
|
70260
|
-
el.parentElement?.insertBefore(banner, el);
|
|
70424
|
+
replaceWithErrorCard(el, source, { message, severity: "error" });
|
|
70261
70425
|
warn("render() rejected:", err);
|
|
70262
70426
|
return {};
|
|
70263
70427
|
}
|
|
70264
70428
|
if (result.diagnostics && result.diagnostics.length > 0) {
|
|
70265
|
-
el.style.visibility = "";
|
|
70266
70429
|
const d = result.diagnostics[0];
|
|
70267
|
-
|
|
70430
|
+
replaceWithErrorCard(el, source, {
|
|
70268
70431
|
message: d.message,
|
|
70269
70432
|
severity: d.severity,
|
|
70270
70433
|
line: d.line,
|
|
70271
70434
|
...d.column !== void 0 && { column: d.column }
|
|
70272
70435
|
});
|
|
70273
|
-
el.parentElement?.insertBefore(banner, el);
|
|
70274
70436
|
warn("diagnostic:", d.message, d.line, d.column);
|
|
70275
70437
|
return {};
|
|
70276
70438
|
}
|
|
70277
70439
|
if (!result.svg) {
|
|
70278
|
-
el
|
|
70279
|
-
const banner = buildErrorBanner({
|
|
70440
|
+
replaceWithErrorCard(el, source, {
|
|
70280
70441
|
message: "Empty SVG returned from renderer",
|
|
70281
70442
|
severity: "error"
|
|
70282
70443
|
});
|
|
70283
|
-
el.parentElement?.insertBefore(banner, el);
|
|
70284
70444
|
return {};
|
|
70285
70445
|
}
|
|
70286
|
-
const wrapper = document.createElement("div");
|
|
70287
70446
|
const themeClass = resolvedTheme === "dark" ? "dgmo-theme-dark" : resolvedTheme === "transparent" ? "dgmo-theme-transparent" : "dgmo-theme-light";
|
|
70288
|
-
wrapper.className = `dgmo-rendered ${themeClass}`;
|
|
70289
|
-
wrapper.dataset["dgmoProcessed"] = "true";
|
|
70290
70447
|
const svgHolder = document.createElement("div");
|
|
70291
70448
|
svgHolder.innerHTML = result.svg;
|
|
70292
70449
|
const svgEl = svgHolder.querySelector("svg");
|
|
70293
70450
|
if (!svgEl) {
|
|
70294
|
-
el
|
|
70295
|
-
const banner = buildErrorBanner({
|
|
70451
|
+
replaceWithErrorCard(el, source, {
|
|
70296
70452
|
message: "Empty SVG returned from renderer",
|
|
70297
70453
|
severity: "error"
|
|
70298
70454
|
});
|
|
70299
|
-
el.parentElement?.insertBefore(banner, el);
|
|
70300
70455
|
return {};
|
|
70301
70456
|
}
|
|
70302
70457
|
sanitizeSvgInPlace(svgEl);
|
|
70303
70458
|
svgEl.setAttribute("role", "img");
|
|
70304
70459
|
svgEl.setAttribute("aria-label", ariaLabel);
|
|
70305
|
-
|
|
70306
|
-
if (showSource) {
|
|
70307
|
-
|
|
70308
|
-
|
|
70309
|
-
|
|
70310
|
-
|
|
70311
|
-
|
|
70312
|
-
|
|
70313
|
-
|
|
70314
|
-
utmSource: "auto-embed"
|
|
70315
|
-
});
|
|
70316
|
-
}
|
|
70317
|
-
const panel = buildSourcePanel(source, shareUrl, cfg.showEditorLink);
|
|
70318
|
-
wrapper.appendChild(panel);
|
|
70460
|
+
let shareUrl = null;
|
|
70461
|
+
if (showSource && cfg.showEditorLink) {
|
|
70462
|
+
shareUrl = buildShareUrl(source, {
|
|
70463
|
+
palette: cfg.palette,
|
|
70464
|
+
theme: resolvedTheme === "dark" ? "dark" : "light",
|
|
70465
|
+
editorBase: EDITOR_BASE_URL,
|
|
70466
|
+
campaign: VERSION,
|
|
70467
|
+
utmSource: "auto-embed"
|
|
70468
|
+
});
|
|
70319
70469
|
}
|
|
70470
|
+
const wrapper = buildRenderedBlock({
|
|
70471
|
+
source,
|
|
70472
|
+
svgEl,
|
|
70473
|
+
themeClass,
|
|
70474
|
+
showSource,
|
|
70475
|
+
showEditorLink: cfg.showEditorLink,
|
|
70476
|
+
shareUrl
|
|
70477
|
+
});
|
|
70478
|
+
wrapper.dataset["dgmoProcessed"] = "true";
|
|
70320
70479
|
const trackedShowSource = perElementShowSource === "true" ? true : perElementShowSource === "false" ? false : null;
|
|
70321
70480
|
const tracked = {
|
|
70322
70481
|
wrapper,
|