sketchmark 1.1.1 → 1.1.3
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/animation/index.d.ts +5 -0
- package/dist/animation/index.d.ts.map +1 -1
- package/dist/index.cjs +213 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +213 -19
- package/dist/index.js.map +1 -1
- package/dist/sketchmark.iife.js +213 -19
- package/dist/ui/editor.d.ts +4 -0
- package/dist/ui/editor.d.ts.map +1 -1
- package/package.json +71 -72
|
@@ -20,6 +20,7 @@ export declare class AnimationController {
|
|
|
20
20
|
private _config?;
|
|
21
21
|
private _step;
|
|
22
22
|
private _pendingStepTimers;
|
|
23
|
+
private _pendingNarrationTimers;
|
|
23
24
|
private _transforms;
|
|
24
25
|
private _listeners;
|
|
25
26
|
readonly drawTargetEdges: Set<string>;
|
|
@@ -34,6 +35,7 @@ export declare class AnimationController {
|
|
|
34
35
|
private readonly _groupDescendantIds;
|
|
35
36
|
private _captionEl;
|
|
36
37
|
private _captionTextEl;
|
|
38
|
+
private _narrationRunId;
|
|
37
39
|
private _annotationLayer;
|
|
38
40
|
private _annotations;
|
|
39
41
|
private _pointerEl;
|
|
@@ -67,7 +69,10 @@ export declare class AnimationController {
|
|
|
67
69
|
prev(): boolean;
|
|
68
70
|
play(msPerStep?: number): Promise<void>;
|
|
69
71
|
goTo(index: number): void;
|
|
72
|
+
private _clearTimerBucket;
|
|
70
73
|
private _clearPendingStepTimers;
|
|
74
|
+
private _cancelNarrationTyping;
|
|
75
|
+
private _scheduleTimer;
|
|
71
76
|
private _scheduleStep;
|
|
72
77
|
private _stepWaitMs;
|
|
73
78
|
private _playbackWaitMs;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/animation/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAoB,WAAW,EAAE,MAAM,cAAc,CAAC;AAGlE,MAAM,MAAM,kBAAkB,GAC1B,aAAa,GACb,eAAe,GACf,iBAAiB,GACjB,iBAAiB,GACjB,eAAe,CAAC;AACpB,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,kBAAkB,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AACD,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,EAAE,cAAc,KAAK,IAAI,CAAC;AAoZ5D,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAQtE;AACD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAOtE;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAOvE;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAOtE;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAOvE;AAsKD,qBAAa,mBAAmB;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/animation/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.cjs
CHANGED
|
@@ -9248,11 +9248,13 @@ class AnimationController {
|
|
|
9248
9248
|
this._config = _config;
|
|
9249
9249
|
this._step = -1;
|
|
9250
9250
|
this._pendingStepTimers = new Set();
|
|
9251
|
+
this._pendingNarrationTimers = new Set();
|
|
9251
9252
|
this._transforms = new Map();
|
|
9252
9253
|
this._listeners = [];
|
|
9253
9254
|
// ── Narration caption ──
|
|
9254
9255
|
this._captionEl = null;
|
|
9255
9256
|
this._captionTextEl = null;
|
|
9257
|
+
this._narrationRunId = 0;
|
|
9256
9258
|
// ── Annotations ──
|
|
9257
9259
|
this._annotationLayer = null;
|
|
9258
9260
|
this._annotations = [];
|
|
@@ -9515,20 +9517,30 @@ class AnimationController {
|
|
|
9515
9517
|
}
|
|
9516
9518
|
this.emit("step-change");
|
|
9517
9519
|
}
|
|
9520
|
+
_clearTimerBucket(bucket) {
|
|
9521
|
+
bucket.forEach((id) => window.clearTimeout(id));
|
|
9522
|
+
bucket.clear();
|
|
9523
|
+
}
|
|
9518
9524
|
_clearPendingStepTimers() {
|
|
9519
|
-
this.
|
|
9520
|
-
this._pendingStepTimers.clear();
|
|
9525
|
+
this._clearTimerBucket(this._pendingStepTimers);
|
|
9521
9526
|
}
|
|
9522
|
-
|
|
9527
|
+
_cancelNarrationTyping() {
|
|
9528
|
+
this._narrationRunId += 1;
|
|
9529
|
+
this._clearTimerBucket(this._pendingNarrationTimers);
|
|
9530
|
+
}
|
|
9531
|
+
_scheduleTimer(fn, delayMs, bucket = this._pendingStepTimers) {
|
|
9523
9532
|
if (delayMs <= 0) {
|
|
9524
9533
|
fn();
|
|
9525
9534
|
return;
|
|
9526
9535
|
}
|
|
9527
9536
|
const id = window.setTimeout(() => {
|
|
9528
|
-
|
|
9537
|
+
bucket.delete(id);
|
|
9529
9538
|
fn();
|
|
9530
9539
|
}, delayMs);
|
|
9531
|
-
|
|
9540
|
+
bucket.add(id);
|
|
9541
|
+
}
|
|
9542
|
+
_scheduleStep(fn, delayMs) {
|
|
9543
|
+
this._scheduleTimer(fn, delayMs, this._pendingStepTimers);
|
|
9532
9544
|
}
|
|
9533
9545
|
_stepWaitMs(step, fallbackMs) {
|
|
9534
9546
|
const delay = Math.max(0, step.delay ?? 0);
|
|
@@ -9572,6 +9584,7 @@ class AnimationController {
|
|
|
9572
9584
|
}
|
|
9573
9585
|
_clearAll() {
|
|
9574
9586
|
this._clearPendingStepTimers();
|
|
9587
|
+
this._cancelNarrationTyping();
|
|
9575
9588
|
this._cancelSpeech();
|
|
9576
9589
|
this._transforms.clear();
|
|
9577
9590
|
// Nodes
|
|
@@ -10126,6 +10139,7 @@ class AnimationController {
|
|
|
10126
10139
|
_doNarrate(text, silent) {
|
|
10127
10140
|
if (!this._captionEl || !this._captionTextEl)
|
|
10128
10141
|
return;
|
|
10142
|
+
this._cancelNarrationTyping();
|
|
10129
10143
|
this._captionEl.style.opacity = "1";
|
|
10130
10144
|
if (silent || !text) {
|
|
10131
10145
|
this._captionTextEl.textContent = text;
|
|
@@ -10136,12 +10150,16 @@ class AnimationController {
|
|
|
10136
10150
|
this._speak(text);
|
|
10137
10151
|
// Typing effect
|
|
10138
10152
|
this._captionTextEl.textContent = "";
|
|
10153
|
+
const narrationRunId = this._narrationRunId;
|
|
10139
10154
|
let charIdx = 0;
|
|
10140
10155
|
const typeNext = () => {
|
|
10156
|
+
if (this._narrationRunId !== narrationRunId || !this._captionTextEl)
|
|
10157
|
+
return;
|
|
10141
10158
|
if (charIdx < text.length) {
|
|
10142
10159
|
this._captionTextEl.textContent += text[charIdx++];
|
|
10143
|
-
|
|
10144
|
-
|
|
10160
|
+
if (charIdx < text.length) {
|
|
10161
|
+
this._scheduleTimer(typeNext, ANIMATION.narrationTypeMs, this._pendingNarrationTimers);
|
|
10162
|
+
}
|
|
10145
10163
|
}
|
|
10146
10164
|
};
|
|
10147
10165
|
typeNext();
|
|
@@ -10251,12 +10269,11 @@ class AnimationController {
|
|
|
10251
10269
|
requestAnimationFrame(animate);
|
|
10252
10270
|
}
|
|
10253
10271
|
// After guide finishes: reveal rough.js element, remove guide
|
|
10254
|
-
|
|
10272
|
+
this._scheduleTimer(() => {
|
|
10255
10273
|
roughEl.style.transition = `opacity 120ms ease`;
|
|
10256
10274
|
roughEl.style.opacity = "1";
|
|
10257
10275
|
guide.remove();
|
|
10258
10276
|
}, dur + 30);
|
|
10259
|
-
this._pendingStepTimers.add(id);
|
|
10260
10277
|
}));
|
|
10261
10278
|
}
|
|
10262
10279
|
_doAnnotationCircle(target, silent) {
|
|
@@ -10567,13 +10584,13 @@ function exportHTML(svg, dslSource, opts = {}) {
|
|
|
10567
10584
|
</head>
|
|
10568
10585
|
<body>
|
|
10569
10586
|
<div class="diagram">${svgStr}</div>
|
|
10570
|
-
<details class="dsl"><summary style="cursor:pointer;color:#f0c96a">DSL source</summary><pre>${escapeHtml(dslSource)}</pre></details>
|
|
10587
|
+
<details class="dsl"><summary style="cursor:pointer;color:#f0c96a">DSL source</summary><pre>${escapeHtml$1(dslSource)}</pre></details>
|
|
10571
10588
|
</body>
|
|
10572
10589
|
</html>`;
|
|
10573
10590
|
const blob = new Blob([html], { type: 'text/html;charset=utf-8' });
|
|
10574
10591
|
download(blob, opts.filename ?? 'diagram.html');
|
|
10575
10592
|
}
|
|
10576
|
-
function escapeHtml(s) {
|
|
10593
|
+
function escapeHtml$1(s) {
|
|
10577
10594
|
return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
10578
10595
|
}
|
|
10579
10596
|
// ── GIF stub (requires gifshot or gif.js at runtime) ──────
|
|
@@ -10799,7 +10816,7 @@ const CANVAS_CSS = `
|
|
|
10799
10816
|
.skm-canvas__viewport.is-panning{cursor:grabbing}
|
|
10800
10817
|
.skm-canvas--dark .skm-canvas__viewport{background:#12100a}
|
|
10801
10818
|
.skm-canvas__grid{position:absolute;inset:0;width:100%;height:100%;pointer-events:none}
|
|
10802
|
-
.skm-canvas__world{position:absolute;top:0;left:0;transform-origin:0 0;
|
|
10819
|
+
.skm-canvas__world{position:absolute;top:0;left:0;transform-origin:0 0;}
|
|
10803
10820
|
.skm-canvas__controls{position:absolute;right:14px;bottom:14px;display:flex;flex-direction:column;align-items:center;gap:4px;z-index:2}
|
|
10804
10821
|
.skm-canvas__zoom{min-width:40px;text-align:center;color:#8a6040;font-size:10px}
|
|
10805
10822
|
.skm-canvas__minimap{position:absolute;left:14px;bottom:14px;width:120px;height:80px;background:rgba(255,248,234,.94);border:1px solid #caba98;border-radius:6px;overflow:hidden;z-index:2}
|
|
@@ -11449,20 +11466,44 @@ const EDITOR_CSS = `
|
|
|
11449
11466
|
color: #fff;
|
|
11450
11467
|
}
|
|
11451
11468
|
|
|
11452
|
-
.skm-
|
|
11469
|
+
.skm-editor__surface {
|
|
11470
|
+
position: relative;
|
|
11453
11471
|
flex: 1;
|
|
11454
|
-
width: 100%;
|
|
11455
11472
|
min-height: 0;
|
|
11456
|
-
border: 0;
|
|
11457
|
-
outline: 0;
|
|
11458
|
-
resize: none;
|
|
11459
11473
|
background: #1c1608;
|
|
11460
|
-
|
|
11474
|
+
overflow: hidden;
|
|
11475
|
+
}
|
|
11476
|
+
|
|
11477
|
+
.skm-editor__highlight,
|
|
11478
|
+
.skm-editor__input {
|
|
11479
|
+
position: absolute;
|
|
11480
|
+
inset: 0;
|
|
11481
|
+
width: 100%;
|
|
11482
|
+
height: 100%;
|
|
11461
11483
|
padding: 12px 14px;
|
|
11462
11484
|
font: inherit;
|
|
11463
11485
|
font-size: 12px;
|
|
11464
11486
|
line-height: 1.7;
|
|
11465
11487
|
tab-size: 2;
|
|
11488
|
+
white-space: pre-wrap;
|
|
11489
|
+
overflow: auto;
|
|
11490
|
+
}
|
|
11491
|
+
|
|
11492
|
+
.skm-editor__highlight {
|
|
11493
|
+
margin: 0;
|
|
11494
|
+
border: 0;
|
|
11495
|
+
background: #1c1608;
|
|
11496
|
+
color: #e0c898;
|
|
11497
|
+
pointer-events: none;
|
|
11498
|
+
word-break: break-word;
|
|
11499
|
+
}
|
|
11500
|
+
|
|
11501
|
+
.skm-editor__input {
|
|
11502
|
+
border: 0;
|
|
11503
|
+
outline: 0;
|
|
11504
|
+
resize: none;
|
|
11505
|
+
background: transparent;
|
|
11506
|
+
color: transparent;
|
|
11466
11507
|
caret-color: #f0c96a;
|
|
11467
11508
|
}
|
|
11468
11509
|
|
|
@@ -11470,6 +11511,40 @@ const EDITOR_CSS = `
|
|
|
11470
11511
|
color: #80633b;
|
|
11471
11512
|
}
|
|
11472
11513
|
|
|
11514
|
+
.skm-editor__input::selection {
|
|
11515
|
+
background: rgba(240, 201, 106, 0.22);
|
|
11516
|
+
}
|
|
11517
|
+
|
|
11518
|
+
.skm-editor__token--keyword {
|
|
11519
|
+
color: #e07040;
|
|
11520
|
+
}
|
|
11521
|
+
|
|
11522
|
+
.skm-editor__token--property {
|
|
11523
|
+
color: #70a8d0;
|
|
11524
|
+
}
|
|
11525
|
+
|
|
11526
|
+
.skm-editor__token--string {
|
|
11527
|
+
color: #8db870;
|
|
11528
|
+
}
|
|
11529
|
+
|
|
11530
|
+
.skm-editor__token--number {
|
|
11531
|
+
color: #d4a020;
|
|
11532
|
+
}
|
|
11533
|
+
|
|
11534
|
+
.skm-editor__token--comment {
|
|
11535
|
+
color: #6a5a3a;
|
|
11536
|
+
}
|
|
11537
|
+
|
|
11538
|
+
.skm-editor__token--connector {
|
|
11539
|
+
color: #c8b070;
|
|
11540
|
+
}
|
|
11541
|
+
|
|
11542
|
+
.skm-editor__token--color {
|
|
11543
|
+
color: var(--skm-editor-color, #f0c96a);
|
|
11544
|
+
box-shadow: inset 0 -1px 0 rgba(255, 255, 255, 0.08);
|
|
11545
|
+
font-weight: 600;
|
|
11546
|
+
}
|
|
11547
|
+
|
|
11473
11548
|
.skm-editor__error {
|
|
11474
11549
|
display: none;
|
|
11475
11550
|
flex-shrink: 0;
|
|
@@ -11486,12 +11561,112 @@ const EDITOR_CSS = `
|
|
|
11486
11561
|
display: block;
|
|
11487
11562
|
}
|
|
11488
11563
|
`;
|
|
11564
|
+
const CONNECTORS = ["<-->", "<->", "-->", "<--", "---", "--", "->", "<-"];
|
|
11565
|
+
const HEX_COLOR_RE = /#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})\b/g;
|
|
11489
11566
|
function defaultFormatter(value) {
|
|
11490
11567
|
return normalizeNewlines(value)
|
|
11491
11568
|
.split("\n")
|
|
11492
11569
|
.map((line) => line.replace(/[ \t]+$/g, ""))
|
|
11493
11570
|
.join("\n");
|
|
11494
11571
|
}
|
|
11572
|
+
function escapeHtml(value) {
|
|
11573
|
+
return value
|
|
11574
|
+
.replace(/&/g, "&")
|
|
11575
|
+
.replace(/</g, "<")
|
|
11576
|
+
.replace(/>/g, ">")
|
|
11577
|
+
.replace(/"/g, """);
|
|
11578
|
+
}
|
|
11579
|
+
function wrapToken(kind, value) {
|
|
11580
|
+
return `<span class="skm-editor__token skm-editor__token--${kind}">${escapeHtml(value)}</span>`;
|
|
11581
|
+
}
|
|
11582
|
+
function renderColorLiteral(value) {
|
|
11583
|
+
return `<span class="skm-editor__token skm-editor__token--color" style="--skm-editor-color:${value}">${escapeHtml(value)}</span>`;
|
|
11584
|
+
}
|
|
11585
|
+
function renderStringToken(value) {
|
|
11586
|
+
HEX_COLOR_RE.lastIndex = 0;
|
|
11587
|
+
if (!HEX_COLOR_RE.test(value)) {
|
|
11588
|
+
return wrapToken("string", value);
|
|
11589
|
+
}
|
|
11590
|
+
HEX_COLOR_RE.lastIndex = 0;
|
|
11591
|
+
let html = "";
|
|
11592
|
+
let lastIndex = 0;
|
|
11593
|
+
let match = null;
|
|
11594
|
+
while ((match = HEX_COLOR_RE.exec(value))) {
|
|
11595
|
+
if (match.index > lastIndex) {
|
|
11596
|
+
html += wrapToken("string", value.slice(lastIndex, match.index));
|
|
11597
|
+
}
|
|
11598
|
+
html += renderColorLiteral(match[0]);
|
|
11599
|
+
lastIndex = match.index + match[0].length;
|
|
11600
|
+
}
|
|
11601
|
+
if (lastIndex < value.length) {
|
|
11602
|
+
html += wrapToken("string", value.slice(lastIndex));
|
|
11603
|
+
}
|
|
11604
|
+
return html;
|
|
11605
|
+
}
|
|
11606
|
+
function renderPlainToken(value, nextChar) {
|
|
11607
|
+
if (/^-?\d/.test(value)) {
|
|
11608
|
+
return wrapToken("number", value);
|
|
11609
|
+
}
|
|
11610
|
+
if (nextChar === "=") {
|
|
11611
|
+
return wrapToken("property", value);
|
|
11612
|
+
}
|
|
11613
|
+
if (KEYWORDS.has(value)) {
|
|
11614
|
+
return wrapToken("keyword", value);
|
|
11615
|
+
}
|
|
11616
|
+
return escapeHtml(value);
|
|
11617
|
+
}
|
|
11618
|
+
function highlightLine(line) {
|
|
11619
|
+
let html = "";
|
|
11620
|
+
let index = 0;
|
|
11621
|
+
while (index < line.length) {
|
|
11622
|
+
const rest = line.slice(index);
|
|
11623
|
+
if (rest.startsWith("//") || rest.startsWith("#")) {
|
|
11624
|
+
html += wrapToken("comment", rest);
|
|
11625
|
+
break;
|
|
11626
|
+
}
|
|
11627
|
+
if (line[index] === "\"") {
|
|
11628
|
+
let end = index + 1;
|
|
11629
|
+
while (end < line.length) {
|
|
11630
|
+
if (line[end] === "\"" && line[end - 1] !== "\\") {
|
|
11631
|
+
end += 1;
|
|
11632
|
+
break;
|
|
11633
|
+
}
|
|
11634
|
+
end += 1;
|
|
11635
|
+
}
|
|
11636
|
+
html += renderStringToken(line.slice(index, end));
|
|
11637
|
+
index = end;
|
|
11638
|
+
continue;
|
|
11639
|
+
}
|
|
11640
|
+
const connector = CONNECTORS.find((candidate) => line.startsWith(candidate, index));
|
|
11641
|
+
if (connector) {
|
|
11642
|
+
html += wrapToken("connector", connector);
|
|
11643
|
+
index += connector.length;
|
|
11644
|
+
continue;
|
|
11645
|
+
}
|
|
11646
|
+
const wordMatch = /^[A-Za-z_][A-Za-z0-9_-]*/.exec(rest);
|
|
11647
|
+
if (wordMatch) {
|
|
11648
|
+
const word = wordMatch[0];
|
|
11649
|
+
const nextChar = line[index + word.length] ?? "";
|
|
11650
|
+
html += renderPlainToken(word, nextChar);
|
|
11651
|
+
index += word.length;
|
|
11652
|
+
continue;
|
|
11653
|
+
}
|
|
11654
|
+
const numberMatch = /^-?\d+(?:\.\d+)?/.exec(rest);
|
|
11655
|
+
if (numberMatch) {
|
|
11656
|
+
html += wrapToken("number", numberMatch[0]);
|
|
11657
|
+
index += numberMatch[0].length;
|
|
11658
|
+
continue;
|
|
11659
|
+
}
|
|
11660
|
+
html += escapeHtml(line[index]);
|
|
11661
|
+
index += 1;
|
|
11662
|
+
}
|
|
11663
|
+
return html;
|
|
11664
|
+
}
|
|
11665
|
+
function renderHighlightedValue(value) {
|
|
11666
|
+
const normalized = normalizeNewlines(value);
|
|
11667
|
+
const html = normalized.split("\n").map(highlightLine).join("\n");
|
|
11668
|
+
return html || " ";
|
|
11669
|
+
}
|
|
11495
11670
|
class SketchmarkEditor {
|
|
11496
11671
|
constructor(options) {
|
|
11497
11672
|
this.emitter = new EventEmitter();
|
|
@@ -11528,16 +11703,23 @@ class SketchmarkEditor {
|
|
|
11528
11703
|
if (options.showClearButton !== false)
|
|
11529
11704
|
this.toolbar.appendChild(clearButton);
|
|
11530
11705
|
this.toolbar.appendChild(hint);
|
|
11706
|
+
this.surface = document.createElement("div");
|
|
11707
|
+
this.surface.className = "skm-editor__surface";
|
|
11708
|
+
this.highlightElement = document.createElement("pre");
|
|
11709
|
+
this.highlightElement.className = "skm-editor__highlight";
|
|
11710
|
+
this.highlightElement.setAttribute("aria-hidden", "true");
|
|
11531
11711
|
this.textarea = document.createElement("textarea");
|
|
11532
11712
|
this.textarea.className = "skm-editor__input";
|
|
11533
11713
|
this.textarea.spellcheck = false;
|
|
11534
11714
|
this.textarea.placeholder = options.placeholder ?? "diagram\nbox a label=\"Hello\"\nend";
|
|
11535
11715
|
this.textarea.value = normalizeNewlines(options.value ?? DEFAULT_CLEAR_VALUE);
|
|
11536
11716
|
this.textarea.addEventListener("input", () => {
|
|
11717
|
+
this.syncHighlight();
|
|
11537
11718
|
const payload = { value: this.getValue(), editor: this };
|
|
11538
11719
|
options.onChange?.(payload.value, this);
|
|
11539
11720
|
this.emitter.emit("change", payload);
|
|
11540
11721
|
});
|
|
11722
|
+
this.textarea.addEventListener("scroll", () => this.syncScroll());
|
|
11541
11723
|
this.textarea.addEventListener("keydown", (event) => {
|
|
11542
11724
|
if ((event.ctrlKey || event.metaKey) && event.key === "Enter") {
|
|
11543
11725
|
event.preventDefault();
|
|
@@ -11549,9 +11731,12 @@ class SketchmarkEditor {
|
|
|
11549
11731
|
if (options.showToolbar !== false) {
|
|
11550
11732
|
this.root.appendChild(this.toolbar);
|
|
11551
11733
|
}
|
|
11552
|
-
this.
|
|
11734
|
+
this.surface.appendChild(this.highlightElement);
|
|
11735
|
+
this.surface.appendChild(this.textarea);
|
|
11736
|
+
this.root.appendChild(this.surface);
|
|
11553
11737
|
this.root.appendChild(this.errorElement);
|
|
11554
11738
|
host.appendChild(this.root);
|
|
11739
|
+
this.syncHighlight();
|
|
11555
11740
|
if (options.autoFocus) {
|
|
11556
11741
|
this.focus();
|
|
11557
11742
|
}
|
|
@@ -11561,6 +11746,7 @@ class SketchmarkEditor {
|
|
|
11561
11746
|
}
|
|
11562
11747
|
setValue(value, emitChange = false) {
|
|
11563
11748
|
this.textarea.value = normalizeNewlines(value);
|
|
11749
|
+
this.syncHighlight();
|
|
11564
11750
|
if (emitChange) {
|
|
11565
11751
|
const payload = { value: this.getValue(), editor: this };
|
|
11566
11752
|
this.options.onChange?.(payload.value, this);
|
|
@@ -11602,6 +11788,14 @@ class SketchmarkEditor {
|
|
|
11602
11788
|
destroy() {
|
|
11603
11789
|
this.root.remove();
|
|
11604
11790
|
}
|
|
11791
|
+
syncHighlight() {
|
|
11792
|
+
this.highlightElement.innerHTML = renderHighlightedValue(this.textarea.value);
|
|
11793
|
+
this.syncScroll();
|
|
11794
|
+
}
|
|
11795
|
+
syncScroll() {
|
|
11796
|
+
this.highlightElement.scrollTop = this.textarea.scrollTop;
|
|
11797
|
+
this.highlightElement.scrollLeft = this.textarea.scrollLeft;
|
|
11798
|
+
}
|
|
11605
11799
|
}
|
|
11606
11800
|
|
|
11607
11801
|
const EMBED_STYLE_ID = "sketchmark-embed-ui";
|