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