@markdy/renderer-dom 1.0.17 → 1.0.19
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/README.md +10 -10
- package/dist/index.d.ts +2 -2
- package/dist/index.js +140 -136
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ Web Animations API renderer for [MarkdyScript](../../docs/SYNTAX.md) scenes. Tra
|
|
|
13
13
|
- **Seek-safe** — manual `currentTime` control enables reliable `seek()` in any direction
|
|
14
14
|
- **Playback-rate controls** — set normalized timeline speed to slow down or speed up diagrams without rebuilding animations
|
|
15
15
|
- **Interactive viewport** — opt into wheel zoom and drag pan while click-to-pause stays available
|
|
16
|
-
- **Embed controls** — opt into
|
|
16
|
+
- **Embed controls** — opt into only the playback, timeline, viewport, export, and sharing controls a scene needs
|
|
17
17
|
- **Semantic themes** — `paper`, `editorial`, `nebula`, `midnight`, `blueprint`, and `graphite`, with per-role node and edge colors
|
|
18
18
|
- **Single dependency** — only `@markdy/core`
|
|
19
19
|
|
|
@@ -70,21 +70,21 @@ diagram.destroy(); // clean up DOM + cancel animations
|
|
|
70
70
|
|---|---|---|---|
|
|
71
71
|
| `container` | `HTMLElement` | *(required)* | DOM element to mount the scene into |
|
|
72
72
|
| `code` | `string` | *(required)* | MarkdyScript source code |
|
|
73
|
-
| `autoplay` | `boolean` | `
|
|
74
|
-
| `loop` | `boolean` | `
|
|
75
|
-
| `copyright` | `boolean` | `
|
|
73
|
+
| `autoplay` | `boolean` | `player.playback.autoplay ?? true` | Override whether playback starts immediately |
|
|
74
|
+
| `loop` | `boolean` | `player.playback.loop ?? true` | Override whether playback loops at the end |
|
|
75
|
+
| `copyright` | `boolean` | `player.chrome.badge ?? true` | Show the linked badge at the footer's right edge |
|
|
76
76
|
| `progressBar` | `boolean \| string` | `true` | Deprecated compatibility flag for the scene-boundary progress bar |
|
|
77
|
-
| `sceneBoundaryProgress` | `boolean \| string` | `
|
|
78
|
-
| `progressColor` | `string` | `
|
|
79
|
-
| `playbackRate` | `number` | `
|
|
80
|
-
| `interactiveViewport` | `boolean` | `
|
|
81
|
-
| `controls` | `boolean` | `player.controls` |
|
|
77
|
+
| `sceneBoundaryProgress` | `boolean \| string` | `player.chrome.progress` | Override boundary progress, or pass a custom color/gradient |
|
|
78
|
+
| `progressColor` | `string` | `player.chrome.color` or rainbow | Override the progress color or gradient |
|
|
79
|
+
| `playbackRate` | `number` | `player.playback.rate ?? 1` | Override the initial timeline multiplier |
|
|
80
|
+
| `interactiveViewport` | `boolean` | `player.interaction` | `true` supplies default gestures; `false` suppresses script gestures |
|
|
81
|
+
| `controls` | `boolean` | `player.controls` | `true` supplies legacy toolbar defaults; `false` suppresses script controls |
|
|
82
82
|
| `shareUrl` | `string` | Markdy playground | Base URL used by the Share control when building `#code=` links |
|
|
83
83
|
| `onWarning` | `(warning: Diagnostic) => void` | `console.warn` | Called for each soft parse warning |
|
|
84
84
|
| `onTimeUpdate` | `(seconds: number, durationSeconds: number) => void` | — | Called whenever playback or seek changes the current time |
|
|
85
85
|
| `onPlayStateChange` | `(playing: boolean) => void` | — | Called when playback starts or pauses |
|
|
86
86
|
|
|
87
|
-
> **Note:**
|
|
87
|
+
> **Note:** Prefer grouped `player:` configuration in MarkdyScript. Omitted host options preserve it; host `false` suppresses controls or interaction, while host `true` supplies legacy defaults for leaves the script does not set. A speed selector renders only with at least two distinct positive `speeds` values.
|
|
88
88
|
|
|
89
89
|
### `Diagram`
|
|
90
90
|
|
package/dist/index.d.ts
CHANGED
|
@@ -26,11 +26,11 @@ interface DiagramOptions {
|
|
|
26
26
|
progressBarColor?: string;
|
|
27
27
|
/** Playback speed multiplier. Defaults to 1, where 1 is Markdy's normal pace. */
|
|
28
28
|
playbackRate?: number;
|
|
29
|
-
/**
|
|
29
|
+
/** Host interaction override. `true` enables default gestures; `false` suppresses script interaction. */
|
|
30
30
|
interactiveViewport?: boolean;
|
|
31
31
|
/** Base URL for the Share control. Defaults to the Markdy playground. */
|
|
32
32
|
shareUrl?: string;
|
|
33
|
-
/**
|
|
33
|
+
/** Host controls override. `true` enables the legacy default set; `false` suppresses script controls. */
|
|
34
34
|
controls?: boolean;
|
|
35
35
|
onWarning?: (warning: Diagnostic) => void;
|
|
36
36
|
onTimeUpdate?: (seconds: number, durationSeconds: number) => void;
|
package/dist/index.js
CHANGED
|
@@ -2511,6 +2511,7 @@ function ensureSceneStyles(doc) {
|
|
|
2511
2511
|
justify-content: space-between;
|
|
2512
2512
|
gap: 8px;
|
|
2513
2513
|
padding: 6px 12px;
|
|
2514
|
+
color: var(--md-text, #f8fafc);
|
|
2514
2515
|
background: var(--md-footer-bg, rgba(15, 23, 42, 0.85));
|
|
2515
2516
|
backdrop-filter: blur(16px);
|
|
2516
2517
|
-webkit-backdrop-filter: blur(16px);
|
|
@@ -2521,7 +2522,9 @@ function ensureSceneStyles(doc) {
|
|
|
2521
2522
|
display: flex;
|
|
2522
2523
|
align-items: center;
|
|
2523
2524
|
justify-content: flex-start;
|
|
2524
|
-
|
|
2525
|
+
flex: 1 1 auto;
|
|
2526
|
+
width: auto;
|
|
2527
|
+
min-width: 0;
|
|
2525
2528
|
gap: 8px;
|
|
2526
2529
|
max-width: 100%;
|
|
2527
2530
|
overflow-x: auto;
|
|
@@ -2555,7 +2558,6 @@ function ensureSceneStyles(doc) {
|
|
|
2555
2558
|
align-items: center;
|
|
2556
2559
|
gap: 4px;
|
|
2557
2560
|
flex-shrink: 0;
|
|
2558
|
-
margin-left: auto;
|
|
2559
2561
|
}
|
|
2560
2562
|
.markdy-control-divider {
|
|
2561
2563
|
width: 1px;
|
|
@@ -2628,26 +2630,22 @@ function ensureSceneStyles(doc) {
|
|
|
2628
2630
|
.markdy-badge {
|
|
2629
2631
|
display: inline-flex;
|
|
2630
2632
|
align-items: center;
|
|
2631
|
-
|
|
2632
|
-
font-family:
|
|
2633
|
-
font-size:
|
|
2634
|
-
font-weight:
|
|
2633
|
+
text-align: right;
|
|
2634
|
+
font-family: system-ui, sans-serif;
|
|
2635
|
+
font-size: 10px;
|
|
2636
|
+
font-weight: 400;
|
|
2635
2637
|
color: var(--md-control-text, #94a3b8);
|
|
2636
2638
|
text-decoration: none;
|
|
2637
|
-
padding:
|
|
2638
|
-
|
|
2639
|
-
background: var(--md-control-bg, rgba(255, 255, 255, 0.05));
|
|
2640
|
-
border: 1px solid var(--md-control-border, rgba(148, 163, 184, 0.18));
|
|
2639
|
+
padding: 0;
|
|
2640
|
+
opacity: 0.7;
|
|
2641
2641
|
margin-left: auto;
|
|
2642
2642
|
flex-shrink: 0;
|
|
2643
|
-
transition:
|
|
2643
|
+
transition: opacity 0.15s ease, color 0.15s ease;
|
|
2644
2644
|
white-space: nowrap;
|
|
2645
2645
|
}
|
|
2646
2646
|
.markdy-badge:hover {
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
border-color: var(--accent, #10b981);
|
|
2650
|
-
transform: translateY(-1px);
|
|
2647
|
+
opacity: 1;
|
|
2648
|
+
color: var(--md-text, #f8fafc);
|
|
2651
2649
|
}
|
|
2652
2650
|
.markdy-speed-group {
|
|
2653
2651
|
display: inline-flex;
|
|
@@ -2680,57 +2678,6 @@ function ensureSceneStyles(doc) {
|
|
|
2680
2678
|
color: #ffffff !important;
|
|
2681
2679
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25) !important;
|
|
2682
2680
|
}
|
|
2683
|
-
.markdy-control-seek {
|
|
2684
|
-
appearance: none;
|
|
2685
|
-
-webkit-appearance: none;
|
|
2686
|
-
width: 100%;
|
|
2687
|
-
height: 5px;
|
|
2688
|
-
border-radius: 999px;
|
|
2689
|
-
background: linear-gradient(
|
|
2690
|
-
to right,
|
|
2691
|
-
var(--accent, #10b981) 0%,
|
|
2692
|
-
var(--accent, #10b981) var(--seek-pct, 0%),
|
|
2693
|
-
rgba(148, 163, 184, 0.22) var(--seek-pct, 0%),
|
|
2694
|
-
rgba(148, 163, 184, 0.22) 100%
|
|
2695
|
-
);
|
|
2696
|
-
outline: none;
|
|
2697
|
-
cursor: pointer;
|
|
2698
|
-
margin: 0;
|
|
2699
|
-
transition: height 0.15s ease;
|
|
2700
|
-
}
|
|
2701
|
-
.markdy-control-seek:hover {
|
|
2702
|
-
height: 7px;
|
|
2703
|
-
}
|
|
2704
|
-
.markdy-control-seek::-webkit-slider-thumb {
|
|
2705
|
-
appearance: none;
|
|
2706
|
-
-webkit-appearance: none;
|
|
2707
|
-
width: 12px;
|
|
2708
|
-
height: 12px;
|
|
2709
|
-
border-radius: 50%;
|
|
2710
|
-
background: #ffffff;
|
|
2711
|
-
border: 2px solid var(--accent, #10b981);
|
|
2712
|
-
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
|
|
2713
|
-
cursor: pointer;
|
|
2714
|
-
transition: transform 0.15s ease, box-shadow 0.15s ease;
|
|
2715
|
-
}
|
|
2716
|
-
.markdy-control-seek:hover::-webkit-slider-thumb {
|
|
2717
|
-
transform: scale(1.25);
|
|
2718
|
-
box-shadow: 0 0 8px var(--accent-glow, rgba(16, 185, 129, 0.6));
|
|
2719
|
-
}
|
|
2720
|
-
.markdy-control-seek::-moz-range-thumb {
|
|
2721
|
-
width: 12px;
|
|
2722
|
-
height: 12px;
|
|
2723
|
-
border-radius: 50%;
|
|
2724
|
-
background: #ffffff;
|
|
2725
|
-
border: 2px solid var(--accent, #10b981);
|
|
2726
|
-
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
|
|
2727
|
-
cursor: pointer;
|
|
2728
|
-
transition: transform 0.15s ease, box-shadow 0.15s ease;
|
|
2729
|
-
}
|
|
2730
|
-
.markdy-control-seek:hover::-moz-range-thumb {
|
|
2731
|
-
transform: scale(1.25);
|
|
2732
|
-
box-shadow: 0 0 8px var(--accent-glow, rgba(16, 185, 129, 0.6));
|
|
2733
|
-
}
|
|
2734
2681
|
.markdy-control-time {
|
|
2735
2682
|
font-family: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
|
2736
2683
|
font-size: 10px;
|
|
@@ -2916,44 +2863,61 @@ function ensureSceneStyles(doc) {
|
|
|
2916
2863
|
.markdy-control-seek::-webkit-slider-runnable-track {
|
|
2917
2864
|
width: 100%;
|
|
2918
2865
|
height: 4.5px;
|
|
2919
|
-
background:
|
|
2866
|
+
background: linear-gradient(
|
|
2867
|
+
to right,
|
|
2868
|
+
var(--accent, #10b981) 0%,
|
|
2869
|
+
var(--accent, #10b981) var(--seek-pct, 0%),
|
|
2870
|
+
rgba(148, 163, 184, 0.35) var(--seek-pct, 0%),
|
|
2871
|
+
rgba(148, 163, 184, 0.35) 100%
|
|
2872
|
+
);
|
|
2920
2873
|
border-radius: 9999px;
|
|
2921
|
-
transition: background 0.15s ease;
|
|
2922
|
-
}
|
|
2923
|
-
.markdy-control-seek:hover::-webkit-slider-runnable-track {
|
|
2924
|
-
background: rgba(148, 163, 184, 0.55);
|
|
2925
2874
|
}
|
|
2926
2875
|
.markdy-control-seek::-webkit-slider-thumb {
|
|
2876
|
+
appearance: none;
|
|
2927
2877
|
-webkit-appearance: none;
|
|
2928
2878
|
height: 13px;
|
|
2929
2879
|
width: 13px;
|
|
2930
2880
|
border-radius: 50%;
|
|
2931
|
-
background: #
|
|
2881
|
+
background: var(--accent, #10b981);
|
|
2932
2882
|
border: 2px solid #ffffff;
|
|
2933
2883
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
|
2934
2884
|
margin-top: -4.25px;
|
|
2935
2885
|
cursor: grab;
|
|
2936
|
-
transition: transform 0.1s ease,
|
|
2886
|
+
transition: transform 0.1s ease, box-shadow 0.15s ease;
|
|
2887
|
+
}
|
|
2888
|
+
.markdy-control-seek:hover::-webkit-slider-thumb {
|
|
2889
|
+
transform: scale(1.2);
|
|
2890
|
+
box-shadow: 0 0 8px var(--accent-glow, rgba(16, 185, 129, 0.6));
|
|
2937
2891
|
}
|
|
2938
2892
|
.markdy-control-seek:active::-webkit-slider-thumb {
|
|
2939
2893
|
cursor: grabbing;
|
|
2940
2894
|
transform: scale(1.2);
|
|
2941
|
-
background: #1d4ed8;
|
|
2942
2895
|
}
|
|
2943
2896
|
.markdy-control-seek::-moz-range-track {
|
|
2944
2897
|
width: 100%;
|
|
2945
2898
|
height: 4.5px;
|
|
2946
|
-
background:
|
|
2899
|
+
background: linear-gradient(
|
|
2900
|
+
to right,
|
|
2901
|
+
var(--accent, #10b981) 0%,
|
|
2902
|
+
var(--accent, #10b981) var(--seek-pct, 0%),
|
|
2903
|
+
rgba(148, 163, 184, 0.35) var(--seek-pct, 0%),
|
|
2904
|
+
rgba(148, 163, 184, 0.35) 100%
|
|
2905
|
+
);
|
|
2947
2906
|
border-radius: 9999px;
|
|
2948
2907
|
}
|
|
2949
2908
|
.markdy-control-seek::-moz-range-thumb {
|
|
2950
2909
|
height: 13px;
|
|
2951
2910
|
width: 13px;
|
|
2952
2911
|
border-radius: 50%;
|
|
2953
|
-
background: #
|
|
2912
|
+
background: var(--accent, #10b981);
|
|
2954
2913
|
border: 2px solid #ffffff;
|
|
2955
2914
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
|
2956
2915
|
cursor: grab;
|
|
2916
|
+
transition: transform 0.1s ease, box-shadow 0.15s ease;
|
|
2917
|
+
}
|
|
2918
|
+
.markdy-control-seek:hover::-moz-range-thumb {
|
|
2919
|
+
transform: scale(1.2);
|
|
2920
|
+
box-shadow: 0 0 8px var(--accent-glow, rgba(16, 185, 129, 0.6));
|
|
2957
2921
|
}
|
|
2958
2922
|
|
|
2959
2923
|
[data-markdy-theme="midnight"] .markdy-controls button,
|
|
@@ -2974,9 +2938,9 @@ function ensureSceneStyles(doc) {
|
|
|
2974
2938
|
[data-markdy-theme="nebula"] .markdy-controls button:hover:not([aria-pressed="true"]),
|
|
2975
2939
|
:root[data-theme="dark"] .markdy-controls button:hover:not([aria-pressed="true"]),
|
|
2976
2940
|
.theme-dark .markdy-controls button:hover:not([aria-pressed="true"]) {
|
|
2977
|
-
background: rgba(51, 65, 85, 0.95);
|
|
2978
|
-
color: #f8fafc;
|
|
2979
|
-
border-color: #94a3b8;
|
|
2941
|
+
background: var(--md-control-hover-bg, rgba(51, 65, 85, 0.95));
|
|
2942
|
+
color: var(--md-control-hover-text, #f8fafc);
|
|
2943
|
+
border-color: var(--md-control-hover-border, #94a3b8);
|
|
2980
2944
|
}
|
|
2981
2945
|
[data-markdy-theme="midnight"] .markdy-controls button[aria-pressed="true"],
|
|
2982
2946
|
[data-markdy-theme="blueprint"] .markdy-controls button[aria-pressed="true"],
|
|
@@ -2985,10 +2949,10 @@ function ensureSceneStyles(doc) {
|
|
|
2985
2949
|
[data-markdy-theme="nebula"] .markdy-controls button[aria-pressed="true"],
|
|
2986
2950
|
:root[data-theme="dark"] .markdy-controls button[aria-pressed="true"],
|
|
2987
2951
|
.theme-dark .markdy-controls button[aria-pressed="true"] {
|
|
2988
|
-
background: #3b82f6 !important;
|
|
2952
|
+
background: var(--accent, #3b82f6) !important;
|
|
2989
2953
|
color: #ffffff !important;
|
|
2990
|
-
border-color: #3b82f6 !important;
|
|
2991
|
-
box-shadow: 0 0 10px rgba(59, 130, 246, 0.5) !important;
|
|
2954
|
+
border-color: var(--accent, #3b82f6) !important;
|
|
2955
|
+
box-shadow: 0 0 10px var(--accent-glow, rgba(59, 130, 246, 0.5)) !important;
|
|
2992
2956
|
}
|
|
2993
2957
|
.markdy-footer a {
|
|
2994
2958
|
transition: opacity 0.15s ease, color 0.15s ease;
|
|
@@ -3082,41 +3046,56 @@ function ensureSceneStyles(doc) {
|
|
|
3082
3046
|
`;
|
|
3083
3047
|
doc.head.appendChild(style);
|
|
3084
3048
|
}
|
|
3085
|
-
function
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
if (theme.
|
|
3104
|
-
if (theme.
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3049
|
+
function applyThemeVariables(element, theme) {
|
|
3050
|
+
element.style.setProperty("--md-canvas", theme.canvas);
|
|
3051
|
+
element.style.setProperty("--md-surface", theme.surface);
|
|
3052
|
+
element.style.setProperty("--md-surface-raised", theme.surfaceRaised);
|
|
3053
|
+
element.style.setProperty("--md-border", theme.border);
|
|
3054
|
+
element.style.setProperty("--md-text", theme.text);
|
|
3055
|
+
element.style.setProperty("--md-text-muted", theme.textMuted);
|
|
3056
|
+
element.style.setProperty("--md-paper", theme.paper ?? theme.canvas);
|
|
3057
|
+
element.style.setProperty("--md-ink", theme.ink ?? theme.text);
|
|
3058
|
+
element.style.setProperty("--md-muted", theme.muted ?? theme.textMuted);
|
|
3059
|
+
element.style.setProperty("--md-rule", theme.rule ?? theme.border);
|
|
3060
|
+
element.style.setProperty("--md-grid-minor", theme.gridMinor);
|
|
3061
|
+
element.style.setProperty("--md-grid-major", theme.gridMajor);
|
|
3062
|
+
element.style.setProperty("--md-vignette", theme.vignette);
|
|
3063
|
+
element.style.setProperty("--md-accent", theme.accent);
|
|
3064
|
+
element.style.setProperty("--accent", theme.accent);
|
|
3065
|
+
element.style.setProperty("--accent-glow", `color-mix(in srgb, ${theme.accent} 40%, transparent)`);
|
|
3066
|
+
element.style.setProperty("--accent-light", theme.accentTint ?? `color-mix(in srgb, ${theme.accent} 15%, transparent)`);
|
|
3067
|
+
if (theme.link) element.style.setProperty("--md-link", theme.link);
|
|
3068
|
+
if (theme.soft) element.style.setProperty("--md-soft", theme.soft);
|
|
3069
|
+
if (theme.accentTint) element.style.setProperty("--md-accent-tint", theme.accentTint);
|
|
3070
|
+
element.style.setProperty("--md-node-surface", theme.nodeSurface ?? theme.surface);
|
|
3071
|
+
element.style.setProperty("--md-node-surface-raised", theme.nodeSurfaceRaised ?? theme.surfaceRaised);
|
|
3072
|
+
element.style.setProperty("--md-hairline", theme.hairline ?? `color-mix(in srgb, ${theme.border} 50%, transparent)`);
|
|
3073
|
+
element.style.setProperty("--md-shadow", theme.shadow ?? "rgba(2, 6, 23, 0.55)");
|
|
3074
|
+
element.style.setProperty("--md-footer-bg", `color-mix(in srgb, ${theme.surface} 92%, transparent)`);
|
|
3075
|
+
element.style.setProperty("--md-footer-border", theme.border);
|
|
3076
|
+
element.style.setProperty("--md-control-bg", theme.surfaceRaised);
|
|
3077
|
+
element.style.setProperty("--md-control-border", theme.border);
|
|
3078
|
+
element.style.setProperty("--md-control-text", theme.textMuted);
|
|
3079
|
+
element.style.setProperty("--md-control-hover-bg", theme.canvas);
|
|
3080
|
+
element.style.setProperty("--md-control-hover-text", theme.text);
|
|
3081
|
+
element.style.setProperty("--md-control-hover-border", theme.accent);
|
|
3082
|
+
element.style.setProperty("--md-divider", theme.border);
|
|
3083
|
+
if (theme.fonts?.title) element.style.setProperty("--md-font-title", theme.fonts.title);
|
|
3084
|
+
if (theme.fonts?.nodeName) element.style.setProperty("--md-font-node", theme.fonts.nodeName);
|
|
3085
|
+
if (theme.fonts?.mono) element.style.setProperty("--md-font-mono", theme.fonts.mono);
|
|
3086
|
+
if (theme.radiusMd) element.style.setProperty("--md-radius-md", `${theme.radiusMd}px`);
|
|
3113
3087
|
if (theme.spacing) {
|
|
3114
3088
|
for (const [key, value] of Object.entries(theme.spacing)) {
|
|
3115
|
-
|
|
3089
|
+
element.style.setProperty(`--md-space-${key}`, `${value}px`);
|
|
3116
3090
|
}
|
|
3117
3091
|
}
|
|
3118
|
-
|
|
3119
|
-
if (theme.flatCards)
|
|
3092
|
+
element.dataset.markdyTheme = theme.name;
|
|
3093
|
+
if (theme.flatCards) element.dataset.flat = "1";
|
|
3094
|
+
}
|
|
3095
|
+
function applyThemeToScene(scene, theme) {
|
|
3096
|
+
applyThemeVariables(scene, theme);
|
|
3097
|
+
scene.style.background = theme.canvas;
|
|
3098
|
+
scene.style.color = theme.text;
|
|
3120
3099
|
}
|
|
3121
3100
|
|
|
3122
3101
|
// src/diagram.ts
|
|
@@ -3287,11 +3266,12 @@ function createDiagram(opts) {
|
|
|
3287
3266
|
if (footer) return footer;
|
|
3288
3267
|
footer = document.createElement("div");
|
|
3289
3268
|
footer.className = "markdy-footer";
|
|
3269
|
+
applyThemeVariables(footer, plan.theme);
|
|
3290
3270
|
Object.assign(footer.style, {
|
|
3291
3271
|
display: "flex",
|
|
3292
3272
|
alignItems: "center",
|
|
3293
3273
|
justifyContent: "space-between",
|
|
3294
|
-
flexWrap: "
|
|
3274
|
+
flexWrap: "nowrap",
|
|
3295
3275
|
gap: "6px",
|
|
3296
3276
|
width: "100%",
|
|
3297
3277
|
boxSizing: "border-box",
|
|
@@ -3309,9 +3289,12 @@ function createDiagram(opts) {
|
|
|
3309
3289
|
badge.target = "_blank";
|
|
3310
3290
|
badge.rel = "noopener noreferrer";
|
|
3311
3291
|
badge.title = "Open and edit in Markdy Playground";
|
|
3312
|
-
badge.
|
|
3313
|
-
badge.innerHTML = `<span style="opacity:0.9">\u26A1</span> Markdy`;
|
|
3292
|
+
badge.textContent = "Powered by Markdy";
|
|
3314
3293
|
ensureFooter().appendChild(badge);
|
|
3294
|
+
const badgeLink = badge;
|
|
3295
|
+
void compressMarkdyToUrlHash(code).then((hash) => {
|
|
3296
|
+
badgeLink.href = `${MARKDY_PLAYGROUND_URL}#code=${hash}`;
|
|
3297
|
+
}).catch(() => void 0);
|
|
3315
3298
|
}
|
|
3316
3299
|
ensureSceneStyles(document);
|
|
3317
3300
|
ensureNodeStyles(document);
|
|
@@ -3540,6 +3523,7 @@ function createDiagram(opts) {
|
|
|
3540
3523
|
let controlsSeekBar = null;
|
|
3541
3524
|
let controlsTimeEl = null;
|
|
3542
3525
|
let controlsFitButton = null;
|
|
3526
|
+
let closeCodePanel = null;
|
|
3543
3527
|
let fitViewActive = false;
|
|
3544
3528
|
const ICONS2 = {
|
|
3545
3529
|
play: '<svg class="markdy-icon" width="12" height="12" viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>',
|
|
@@ -3759,8 +3743,9 @@ function createDiagram(opts) {
|
|
|
3759
3743
|
for (const anim of allAnims) anim.cancel();
|
|
3760
3744
|
resizeObserver?.disconnect();
|
|
3761
3745
|
removeFullscreenListeners?.();
|
|
3746
|
+
closeCodePanel?.();
|
|
3747
|
+
closeCodePanel = null;
|
|
3762
3748
|
if (progressEl?.parentNode === viewport) viewport.removeChild(progressEl);
|
|
3763
|
-
if (badge?.parentNode) badge.parentNode.removeChild(badge);
|
|
3764
3749
|
if (footer?.parentNode) footer.parentNode.removeChild(footer);
|
|
3765
3750
|
if (viewport.parentNode === container) container.removeChild(viewport);
|
|
3766
3751
|
}
|
|
@@ -3927,19 +3912,33 @@ function createDiagram(opts) {
|
|
|
3927
3912
|
}
|
|
3928
3913
|
function tintCode(raw) {
|
|
3929
3914
|
return raw.split("\n").map((line) => {
|
|
3930
|
-
if (/^\s*\/\//.test(line)) {
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
line = line.replace(/(->|<-|~>|--|<~)/g, '<span class="t-edge">$1</span>');
|
|
3934
|
-
line = line.replace(/"([^"]*)"/g, '"<span class="t-string">$1</span>"');
|
|
3935
|
-
line = line.replace(
|
|
3936
|
-
/^(\s*)(scene|beat|group|player|show|frame|glow|focus|layout|edge|annotation|start|end|decision|service|browser|gateway|database|cache|queue|worker|function|pod|user|client|hub|station|metric|mobile)\b/,
|
|
3937
|
-
'$1<span class="t-keyword">$2</span>'
|
|
3915
|
+
if (/^\s*\/\//.test(line)) return `<span class="t-comment">${escHtml(line)}</span>`;
|
|
3916
|
+
const keyword = line.match(
|
|
3917
|
+
/^(\s*)(scene|beat|group|player|show|frame|glow|focus|layout|edge|annotation|start|end|decision|service|browser|gateway|database|cache|queue|worker|function|pod|user|client|hub|station|metric|mobile)\b/
|
|
3938
3918
|
);
|
|
3939
|
-
|
|
3940
|
-
return line;
|
|
3919
|
+
const prefix = keyword ? `${escHtml(keyword[1])}<span class="t-keyword">${keyword[2]}</span>` : "";
|
|
3920
|
+
return prefix + tintInlineCode(line.slice(keyword?.[0].length ?? 0));
|
|
3941
3921
|
}).join("\n");
|
|
3942
3922
|
}
|
|
3923
|
+
function tintInlineCode(raw) {
|
|
3924
|
+
const tokenPattern = /"[^"]*"|->|<-|~>|--|<~|\b\d[\d.]*(?:ms|px|s)?\b/g;
|
|
3925
|
+
let output = "";
|
|
3926
|
+
let cursor = 0;
|
|
3927
|
+
for (const match of raw.matchAll(tokenPattern)) {
|
|
3928
|
+
const token = match[0];
|
|
3929
|
+
const index = match.index ?? 0;
|
|
3930
|
+
output += escHtml(raw.slice(cursor, index));
|
|
3931
|
+
if (token.startsWith('"')) {
|
|
3932
|
+
output += `"<span class="t-string">${escHtml(token.slice(1, -1))}</span>"`;
|
|
3933
|
+
} else if (/^\d/.test(token)) {
|
|
3934
|
+
output += `<span class="t-number">${token}</span>`;
|
|
3935
|
+
} else {
|
|
3936
|
+
output += `<span class="t-edge">${escHtml(token)}</span>`;
|
|
3937
|
+
}
|
|
3938
|
+
cursor = index + token.length;
|
|
3939
|
+
}
|
|
3940
|
+
return output + escHtml(raw.slice(cursor));
|
|
3941
|
+
}
|
|
3943
3942
|
function escHtml(str) {
|
|
3944
3943
|
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
3945
3944
|
}
|
|
@@ -3949,6 +3948,7 @@ function createDiagram(opts) {
|
|
|
3949
3948
|
button.className = "markdy-control-code";
|
|
3950
3949
|
button.setAttribute("aria-haspopup", "dialog");
|
|
3951
3950
|
button.addEventListener("click", () => {
|
|
3951
|
+
closeCodePanel?.();
|
|
3952
3952
|
const overlay = document.createElement("div");
|
|
3953
3953
|
overlay.className = "markdy-code-panel-overlay";
|
|
3954
3954
|
overlay.setAttribute("role", "dialog");
|
|
@@ -4006,24 +4006,28 @@ function createDiagram(opts) {
|
|
|
4006
4006
|
overlay.appendChild(panel);
|
|
4007
4007
|
document.body.appendChild(overlay);
|
|
4008
4008
|
closeBtn.focus();
|
|
4009
|
+
let closing = false;
|
|
4010
|
+
function removePanel() {
|
|
4011
|
+
document.removeEventListener("keydown", handleEscape);
|
|
4012
|
+
overlay.remove();
|
|
4013
|
+
if (closeCodePanel === removePanel) closeCodePanel = null;
|
|
4014
|
+
}
|
|
4009
4015
|
function closePanel() {
|
|
4016
|
+
if (closing) return;
|
|
4017
|
+
closing = true;
|
|
4010
4018
|
overlay.dataset.closing = "1";
|
|
4011
|
-
|
|
4019
|
+
document.removeEventListener("keydown", handleEscape);
|
|
4020
|
+
overlay.addEventListener("animationend", removePanel, { once: true });
|
|
4012
4021
|
}
|
|
4013
4022
|
closeBtn.addEventListener("click", closePanel);
|
|
4014
4023
|
overlay.addEventListener("click", (e) => {
|
|
4015
4024
|
if (e.target === overlay) closePanel();
|
|
4016
4025
|
});
|
|
4017
4026
|
function handleEscape(e) {
|
|
4018
|
-
if (e.key === "Escape")
|
|
4019
|
-
closePanel();
|
|
4020
|
-
document.removeEventListener("keydown", handleEscape);
|
|
4021
|
-
}
|
|
4027
|
+
if (e.key === "Escape") closePanel();
|
|
4022
4028
|
}
|
|
4023
4029
|
document.addEventListener("keydown", handleEscape);
|
|
4024
|
-
|
|
4025
|
-
if (overlay.dataset.closing === "1") document.removeEventListener("keydown", handleEscape);
|
|
4026
|
-
}, { once: true });
|
|
4030
|
+
closeCodePanel = removePanel;
|
|
4027
4031
|
});
|
|
4028
4032
|
toolbar.appendChild(button);
|
|
4029
4033
|
}
|
|
@@ -4230,7 +4234,7 @@ function createDiagram(opts) {
|
|
|
4230
4234
|
mountCodeControl(toolsGroup);
|
|
4231
4235
|
}
|
|
4232
4236
|
if (toolsGroup.children.length > 0) toolbar.appendChild(toolsGroup);
|
|
4233
|
-
ensureFooter().insertBefore(toolbar, badge
|
|
4237
|
+
ensureFooter().insertBefore(toolbar, badge);
|
|
4234
4238
|
syncControls();
|
|
4235
4239
|
}
|
|
4236
4240
|
viewport.style.cursor = interactiveViewport ? "grab" : "pointer";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markdy/renderer-dom",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.19",
|
|
4
4
|
"description": "Browser renderer for diagram-native animated MarkdyScript architecture diagrams, built on the Web Animations API.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -45,14 +45,14 @@
|
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"html2canvas": "^1.4.1",
|
|
48
|
-
"@markdy/core": "1.0.
|
|
48
|
+
"@markdy/core": "1.0.19"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"jsdom": "^29.1.1",
|
|
52
52
|
"tsup": "^8.5.1",
|
|
53
53
|
"typescript": "^5.9.3",
|
|
54
54
|
"vitest": "^4.1.7",
|
|
55
|
-
"@markdy/stdlib-systems": "1.0.
|
|
55
|
+
"@markdy/stdlib-systems": "1.0.19"
|
|
56
56
|
},
|
|
57
57
|
"scripts": {
|
|
58
58
|
"build": "tsup",
|