@blankdotpage/cake 0.1.2 → 0.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/cake/core/runtime.d.ts +50 -13
- package/dist/cake/engine/cake-engine.d.ts +14 -0
- package/dist/cake/engine/selection/selection-layout-dom.d.ts +7 -0
- package/dist/cake/extensions/blockquote/blockquote.d.ts +1 -2
- package/dist/cake/extensions/bold/bold.d.ts +1 -2
- package/dist/cake/extensions/combined-emphasis/combined-emphasis.d.ts +1 -2
- package/dist/cake/extensions/heading/heading.d.ts +1 -2
- package/dist/cake/extensions/image/image.d.ts +1 -2
- package/dist/cake/extensions/index.d.ts +1 -0
- package/dist/cake/extensions/italic/italic.d.ts +1 -2
- package/dist/cake/extensions/link/link-popover.d.ts +6 -0
- package/dist/cake/extensions/link/link.d.ts +15 -2
- package/dist/cake/extensions/list/list.d.ts +11 -2
- package/dist/cake/extensions/pipe-link/pipe-link.d.ts +1 -2
- package/dist/cake/extensions/scrollbar/index.d.ts +1 -2
- package/dist/cake/extensions/strikethrough/strikethrough.d.ts +1 -2
- package/dist/cake/react/CakeEditor.d.ts +2 -0
- package/dist/cake/test/harness.d.ts +12 -0
- package/dist/index.cjs +652 -176
- package/dist/index.js +652 -176
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -999,15 +999,36 @@ class CursorSourceBuilder {
|
|
|
999
999
|
if (!text) {
|
|
1000
1000
|
return;
|
|
1001
1001
|
}
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1002
|
+
let isAllAscii = true;
|
|
1003
|
+
for (let i = 0; i < text.length; i++) {
|
|
1004
|
+
if (text.charCodeAt(i) >= 128) {
|
|
1005
|
+
isAllAscii = false;
|
|
1006
|
+
break;
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
if (isAllAscii) {
|
|
1010
|
+
for (let i = 0; i < text.length; i++) {
|
|
1011
|
+
const char = text[i];
|
|
1012
|
+
this.sourceParts.push(char);
|
|
1013
|
+
this.sourceLengthValue += 1;
|
|
1014
|
+
const sourceLength = this.sourceLengthValue;
|
|
1015
|
+
this.cursorLength += 1;
|
|
1016
|
+
this.boundaries.push({
|
|
1017
|
+
sourceBackward: sourceLength,
|
|
1018
|
+
sourceForward: sourceLength
|
|
1019
|
+
});
|
|
1020
|
+
}
|
|
1021
|
+
} else {
|
|
1022
|
+
for (const segment of graphemeSegments(text)) {
|
|
1023
|
+
this.sourceParts.push(segment.segment);
|
|
1024
|
+
this.sourceLengthValue += segment.segment.length;
|
|
1025
|
+
const sourceLength = this.sourceLengthValue;
|
|
1026
|
+
this.cursorLength += 1;
|
|
1027
|
+
this.boundaries.push({
|
|
1028
|
+
sourceBackward: sourceLength,
|
|
1029
|
+
sourceForward: sourceLength
|
|
1030
|
+
});
|
|
1031
|
+
}
|
|
1011
1032
|
}
|
|
1012
1033
|
}
|
|
1013
1034
|
appendCursorAtom(sourceText, cursorUnits = 1) {
|
|
@@ -1057,6 +1078,15 @@ class CursorSourceBuilder {
|
|
|
1057
1078
|
};
|
|
1058
1079
|
}
|
|
1059
1080
|
}
|
|
1081
|
+
function isStructuralEdit(command) {
|
|
1082
|
+
return command.type === "insert" || command.type === "delete-backward" || command.type === "delete-forward" || command.type === "insert-line-break" || command.type === "exit-block-wrapper";
|
|
1083
|
+
}
|
|
1084
|
+
function isApplyEditCommand(command) {
|
|
1085
|
+
return command.type === "insert" || command.type === "insert-line-break" || command.type === "delete-backward" || command.type === "delete-forward";
|
|
1086
|
+
}
|
|
1087
|
+
function defineExtension(extension) {
|
|
1088
|
+
return extension;
|
|
1089
|
+
}
|
|
1060
1090
|
const defaultSelection$1 = { start: 0, end: 0, affinity: "forward" };
|
|
1061
1091
|
function createRuntime(extensions) {
|
|
1062
1092
|
const toggleMarkerToKind = /* @__PURE__ */ new Map();
|
|
@@ -1298,7 +1328,7 @@ function createRuntime(extensions) {
|
|
|
1298
1328
|
}
|
|
1299
1329
|
}
|
|
1300
1330
|
const selection = normalizeSelection$1(state2.selection);
|
|
1301
|
-
if (command
|
|
1331
|
+
if (isStructuralEdit(command)) {
|
|
1302
1332
|
const structural = applyStructuralEdit(command, state2.doc, selection);
|
|
1303
1333
|
if (!structural) {
|
|
1304
1334
|
if (command.type === "delete-backward" || command.type === "delete-forward") {
|
|
@@ -1340,6 +1370,39 @@ function createRuntime(extensions) {
|
|
|
1340
1370
|
}
|
|
1341
1371
|
};
|
|
1342
1372
|
}
|
|
1373
|
+
if (command.type === "insert" || command.type === "insert-line-break") {
|
|
1374
|
+
const cursorLength = state2.map.cursorLength;
|
|
1375
|
+
const cursorStart = Math.max(
|
|
1376
|
+
0,
|
|
1377
|
+
Math.min(cursorLength, Math.min(selection.start, selection.end))
|
|
1378
|
+
);
|
|
1379
|
+
const cursorEnd = Math.max(
|
|
1380
|
+
0,
|
|
1381
|
+
Math.min(cursorLength, Math.max(selection.start, selection.end))
|
|
1382
|
+
);
|
|
1383
|
+
const range = { start: cursorStart, end: cursorEnd };
|
|
1384
|
+
const fullDocReplace = range.start === 0 && range.end === cursorLength;
|
|
1385
|
+
const from = fullDocReplace ? 0 : state2.map.cursorToSource(range.start, "backward");
|
|
1386
|
+
const to = fullDocReplace ? state2.source.length : state2.map.cursorToSource(range.end, "forward");
|
|
1387
|
+
const fromClamped = Math.max(0, Math.min(from, state2.source.length));
|
|
1388
|
+
const toClamped = Math.max(
|
|
1389
|
+
fromClamped,
|
|
1390
|
+
Math.min(to, state2.source.length)
|
|
1391
|
+
);
|
|
1392
|
+
const insertText = command.type === "insert" ? command.text : "\n";
|
|
1393
|
+
const nextSource = state2.source.slice(0, fromClamped) + insertText + state2.source.slice(toClamped);
|
|
1394
|
+
const next2 = createState(nextSource);
|
|
1395
|
+
const caretSource2 = fromClamped + insertText.length;
|
|
1396
|
+
const caretCursor2 = next2.map.sourceToCursor(caretSource2, "forward");
|
|
1397
|
+
return {
|
|
1398
|
+
...next2,
|
|
1399
|
+
selection: {
|
|
1400
|
+
start: caretCursor2.cursorOffset,
|
|
1401
|
+
end: caretCursor2.cursorOffset,
|
|
1402
|
+
affinity: caretCursor2.affinity
|
|
1403
|
+
}
|
|
1404
|
+
};
|
|
1405
|
+
}
|
|
1343
1406
|
return state2;
|
|
1344
1407
|
}
|
|
1345
1408
|
const interim = createStateFromDoc(structural.doc);
|
|
@@ -2582,7 +2645,20 @@ function parseLiteralBlock(source, start, context) {
|
|
|
2582
2645
|
return { block: { type: "paragraph", content }, nextPos: end };
|
|
2583
2646
|
}
|
|
2584
2647
|
function parseLiteralInline(source, start, end) {
|
|
2585
|
-
const
|
|
2648
|
+
const code = source.charCodeAt(start);
|
|
2649
|
+
if (code < 128) {
|
|
2650
|
+
const text2 = source[start] ?? "";
|
|
2651
|
+
return { inline: { type: "text", text: text2 }, nextPos: start + 1 };
|
|
2652
|
+
}
|
|
2653
|
+
if (code >= 55296 && code <= 56319) {
|
|
2654
|
+
const lowCode = source.charCodeAt(start + 1);
|
|
2655
|
+
if (lowCode >= 56320 && lowCode <= 57343) {
|
|
2656
|
+
const segment2 = graphemeSegments(source.slice(start, Math.min(start + 10, end)))[0];
|
|
2657
|
+
const text2 = segment2 ? segment2.segment : source.slice(start, start + 2);
|
|
2658
|
+
return { inline: { type: "text", text: text2 }, nextPos: start + text2.length };
|
|
2659
|
+
}
|
|
2660
|
+
}
|
|
2661
|
+
const segment = graphemeSegments(source.slice(start, Math.min(start + 10, end)))[0];
|
|
2586
2662
|
const text = segment ? segment.segment : source[start] ?? "";
|
|
2587
2663
|
return { inline: { type: "text", text }, nextPos: start + text.length };
|
|
2588
2664
|
}
|
|
@@ -2625,29 +2701,66 @@ function normalizeSelection$1(selection) {
|
|
|
2625
2701
|
affinity: isRange ? "backward" : selection.affinity
|
|
2626
2702
|
};
|
|
2627
2703
|
}
|
|
2704
|
+
const graphemeCache = /* @__PURE__ */ new WeakMap();
|
|
2628
2705
|
function createTextRun(node, cursorStart) {
|
|
2629
|
-
const
|
|
2706
|
+
const data = node.data;
|
|
2707
|
+
const cached = graphemeCache.get(node);
|
|
2708
|
+
if (cached && cached.data === data) {
|
|
2709
|
+
const segmentCount = Math.max(0, cached.boundaryOffsets.length - 1);
|
|
2710
|
+
return {
|
|
2711
|
+
node,
|
|
2712
|
+
cursorStart,
|
|
2713
|
+
cursorEnd: cursorStart + segmentCount,
|
|
2714
|
+
boundaryOffsets: cached.boundaryOffsets
|
|
2715
|
+
};
|
|
2716
|
+
}
|
|
2717
|
+
const segments = graphemeSegments(data);
|
|
2630
2718
|
const boundaryOffsets = [0];
|
|
2631
2719
|
for (const segment of segments) {
|
|
2632
2720
|
boundaryOffsets.push(segment.index + segment.segment.length);
|
|
2633
2721
|
}
|
|
2634
2722
|
const cursorEnd = cursorStart + segments.length;
|
|
2723
|
+
graphemeCache.set(node, { data, boundaryOffsets });
|
|
2635
2724
|
return { node, cursorStart, cursorEnd, boundaryOffsets };
|
|
2636
2725
|
}
|
|
2637
2726
|
function boundaryIndexForOffset(boundaryOffsets, offset) {
|
|
2638
2727
|
if (offset <= 0) {
|
|
2639
2728
|
return 0;
|
|
2640
2729
|
}
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2730
|
+
const lastIndex = boundaryOffsets.length - 1;
|
|
2731
|
+
if (lastIndex <= 0) {
|
|
2732
|
+
return 0;
|
|
2733
|
+
}
|
|
2734
|
+
const lastBoundary = boundaryOffsets[lastIndex];
|
|
2735
|
+
if (offset >= lastBoundary) {
|
|
2736
|
+
return lastIndex;
|
|
2737
|
+
}
|
|
2738
|
+
let low = 1;
|
|
2739
|
+
let high = lastIndex;
|
|
2740
|
+
while (low < high) {
|
|
2741
|
+
const mid = low + high >>> 1;
|
|
2742
|
+
const boundary2 = boundaryOffsets[mid];
|
|
2743
|
+
if (boundary2 < offset) {
|
|
2744
|
+
low = mid + 1;
|
|
2745
|
+
} else {
|
|
2746
|
+
high = mid;
|
|
2645
2747
|
}
|
|
2646
|
-
|
|
2647
|
-
|
|
2748
|
+
}
|
|
2749
|
+
const boundary = boundaryOffsets[low];
|
|
2750
|
+
return boundary === offset ? low : low - 1;
|
|
2751
|
+
}
|
|
2752
|
+
function firstRunStartingAfterCursor(runs, cursorOffset) {
|
|
2753
|
+
let low = 0;
|
|
2754
|
+
let high = runs.length;
|
|
2755
|
+
while (low < high) {
|
|
2756
|
+
const mid = low + high >>> 1;
|
|
2757
|
+
if (runs[mid].cursorStart <= cursorOffset) {
|
|
2758
|
+
low = mid + 1;
|
|
2759
|
+
} else {
|
|
2760
|
+
high = mid;
|
|
2648
2761
|
}
|
|
2649
2762
|
}
|
|
2650
|
-
return
|
|
2763
|
+
return low;
|
|
2651
2764
|
}
|
|
2652
2765
|
function createDomMap(runs) {
|
|
2653
2766
|
const runForNode = /* @__PURE__ */ new Map();
|
|
@@ -2662,33 +2775,34 @@ function createDomMap(runs) {
|
|
|
2662
2775
|
if (runs.length === 0) {
|
|
2663
2776
|
return null;
|
|
2664
2777
|
}
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
const
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
if (cursorOffset === run.cursorEnd && affinity === "forward" && next && next.cursorStart === cursorOffset) {
|
|
2684
|
-
return { node: next.node, offset: next.boundaryOffsets[0] };
|
|
2685
|
-
}
|
|
2686
|
-
const index = Math.max(0, cursorOffset - run.cursorStart);
|
|
2687
|
-
const boundedIndex = Math.min(index, run.boundaryOffsets.length - 1);
|
|
2688
|
-
return { node: run.node, offset: run.boundaryOffsets[boundedIndex] };
|
|
2778
|
+
const nextIndex = firstRunStartingAfterCursor(runs, cursorOffset);
|
|
2779
|
+
const runIndex = nextIndex - 1;
|
|
2780
|
+
if (runIndex < 0) {
|
|
2781
|
+
const first = runs[0];
|
|
2782
|
+
return { node: first.node, offset: first.boundaryOffsets[0] };
|
|
2783
|
+
}
|
|
2784
|
+
const run = runs[runIndex];
|
|
2785
|
+
const previous = runIndex > 0 ? runs[runIndex - 1] : null;
|
|
2786
|
+
const next = nextIndex < runs.length ? runs[nextIndex] : null;
|
|
2787
|
+
if (cursorOffset === run.cursorStart && previous && affinity === "backward") {
|
|
2788
|
+
return {
|
|
2789
|
+
node: previous.node,
|
|
2790
|
+
offset: previous.boundaryOffsets[previous.boundaryOffsets.length - 1]
|
|
2791
|
+
};
|
|
2792
|
+
}
|
|
2793
|
+
if (cursorOffset <= run.cursorEnd) {
|
|
2794
|
+
if (cursorOffset === run.cursorEnd && affinity === "forward" && next && next.cursorStart === cursorOffset) {
|
|
2795
|
+
return { node: next.node, offset: next.boundaryOffsets[0] };
|
|
2689
2796
|
}
|
|
2797
|
+
const index = Math.max(0, cursorOffset - run.cursorStart);
|
|
2798
|
+
const boundedIndex = Math.min(index, run.boundaryOffsets.length - 1);
|
|
2799
|
+
return { node: run.node, offset: run.boundaryOffsets[boundedIndex] };
|
|
2690
2800
|
}
|
|
2691
|
-
|
|
2801
|
+
if (next) {
|
|
2802
|
+
const runEndOffset = run.boundaryOffsets[run.boundaryOffsets.length - 1];
|
|
2803
|
+
return affinity === "backward" ? { node: run.node, offset: runEndOffset } : { node: next.node, offset: next.boundaryOffsets[0] };
|
|
2804
|
+
}
|
|
2805
|
+
const last = run;
|
|
2692
2806
|
return {
|
|
2693
2807
|
node: last.node,
|
|
2694
2808
|
offset: last.boundaryOffsets[last.boundaryOffsets.length - 1]
|
|
@@ -3076,7 +3190,9 @@ function applyDomSelection(selection, map) {
|
|
|
3076
3190
|
if (!anchorPoint || !focusPoint) {
|
|
3077
3191
|
return;
|
|
3078
3192
|
}
|
|
3079
|
-
domSelection.
|
|
3193
|
+
if (domSelection.rangeCount > 0 && domSelection.anchorNode === anchorPoint.node && domSelection.anchorOffset === anchorPoint.offset && domSelection.focusNode === focusPoint.node && domSelection.focusOffset === focusPoint.offset) {
|
|
3194
|
+
return;
|
|
3195
|
+
}
|
|
3080
3196
|
if (isCollapsed) {
|
|
3081
3197
|
domSelection.collapse(anchorPoint.node, anchorPoint.offset);
|
|
3082
3198
|
return;
|
|
@@ -3096,6 +3212,7 @@ function applyDomSelection(selection, map) {
|
|
|
3096
3212
|
domSelection.extend(focusPoint.node, focusPoint.offset);
|
|
3097
3213
|
return;
|
|
3098
3214
|
}
|
|
3215
|
+
domSelection.removeAllRanges();
|
|
3099
3216
|
const range = document.createRange();
|
|
3100
3217
|
const rangeStart = isForward ? anchorPoint : focusPoint;
|
|
3101
3218
|
const rangeEnd = isForward ? focusPoint : anchorPoint;
|
|
@@ -3239,7 +3356,7 @@ function findTextNodeAtOrBefore$1(nodes, start) {
|
|
|
3239
3356
|
return null;
|
|
3240
3357
|
}
|
|
3241
3358
|
const BOLD_KIND$1 = "bold";
|
|
3242
|
-
const boldExtension = {
|
|
3359
|
+
const boldExtension = defineExtension({
|
|
3243
3360
|
name: "bold",
|
|
3244
3361
|
toggleInline: { kind: BOLD_KIND$1, markers: ["**"] },
|
|
3245
3362
|
keybindings: [
|
|
@@ -3322,7 +3439,7 @@ const boldExtension = {
|
|
|
3322
3439
|
}
|
|
3323
3440
|
return element;
|
|
3324
3441
|
}
|
|
3325
|
-
};
|
|
3442
|
+
});
|
|
3326
3443
|
function countSingleAsterisks(source, start, end) {
|
|
3327
3444
|
let count = 0;
|
|
3328
3445
|
for (let i = start; i < end; i += 1) {
|
|
@@ -3341,7 +3458,7 @@ function countSingleAsterisks(source, start, end) {
|
|
|
3341
3458
|
const BOLD_KIND = "bold";
|
|
3342
3459
|
const ITALIC_KIND$1 = "italic";
|
|
3343
3460
|
const MARKERS = ["***", "___"];
|
|
3344
|
-
const combinedEmphasisExtension = {
|
|
3461
|
+
const combinedEmphasisExtension = defineExtension({
|
|
3345
3462
|
name: "combined-emphasis",
|
|
3346
3463
|
parseInline(source, start, end, context) {
|
|
3347
3464
|
const marker = MARKERS.find((m) => source.slice(start, start + 3) === m);
|
|
@@ -3375,7 +3492,7 @@ const combinedEmphasisExtension = {
|
|
|
3375
3492
|
nextPos: close + 3
|
|
3376
3493
|
};
|
|
3377
3494
|
}
|
|
3378
|
-
};
|
|
3495
|
+
});
|
|
3379
3496
|
function ensureHttpsProtocol(url) {
|
|
3380
3497
|
const trimmedUrl = url.trim();
|
|
3381
3498
|
if (!trimmedUrl) {
|
|
@@ -3423,7 +3540,7 @@ function getPopoverPosition(params) {
|
|
|
3423
3540
|
};
|
|
3424
3541
|
}
|
|
3425
3542
|
function CakeLinkPopover(params) {
|
|
3426
|
-
const { container, contentRoot, toOverlayRect } = params;
|
|
3543
|
+
const { container, contentRoot, toOverlayRect, getSelection, executeCommand } = params;
|
|
3427
3544
|
const anchorRef = require$$0.useRef(null);
|
|
3428
3545
|
const popoverRef = require$$0.useRef(null);
|
|
3429
3546
|
const inputRef = require$$0.useRef(null);
|
|
@@ -3587,6 +3704,12 @@ function CakeLinkPopover(params) {
|
|
|
3587
3704
|
window.open(displayUrl, "_blank", "noopener,noreferrer");
|
|
3588
3705
|
};
|
|
3589
3706
|
const handleUnlink = () => {
|
|
3707
|
+
const selection = getSelection();
|
|
3708
|
+
if (!selection) {
|
|
3709
|
+
close();
|
|
3710
|
+
return;
|
|
3711
|
+
}
|
|
3712
|
+
executeCommand({ type: "unlink", start: selection.start, end: selection.end });
|
|
3590
3713
|
close();
|
|
3591
3714
|
};
|
|
3592
3715
|
const handleInputKeyDown = (event) => {
|
|
@@ -3890,7 +4013,7 @@ function cursorOffsetToVisibleOffset(lines, cursorOffset) {
|
|
|
3890
4013
|
return codeUnitIndex + (lastLine.cursorToCodeUnit[lastOffset] ?? lastLine.text.length);
|
|
3891
4014
|
}
|
|
3892
4015
|
const LINK_KIND = "link";
|
|
3893
|
-
const linkExtension = {
|
|
4016
|
+
const linkExtension = defineExtension({
|
|
3894
4017
|
name: "link",
|
|
3895
4018
|
inlineWrapperAffinity: [{ kind: LINK_KIND, inclusive: false }],
|
|
3896
4019
|
keybindings: [
|
|
@@ -3918,6 +4041,39 @@ const linkExtension = {
|
|
|
3918
4041
|
}
|
|
3919
4042
|
],
|
|
3920
4043
|
onEdit(command, state2) {
|
|
4044
|
+
if (command.type === "unlink") {
|
|
4045
|
+
const cursorPos = command.start;
|
|
4046
|
+
const sourcePos = state2.map.cursorToSource(cursorPos, "forward");
|
|
4047
|
+
const source = state2.source;
|
|
4048
|
+
let linkStart = sourcePos;
|
|
4049
|
+
while (linkStart > 0 && source[linkStart] !== "[") {
|
|
4050
|
+
linkStart--;
|
|
4051
|
+
}
|
|
4052
|
+
if (source[linkStart] !== "[") {
|
|
4053
|
+
return null;
|
|
4054
|
+
}
|
|
4055
|
+
const labelClose = source.indexOf("](", linkStart + 1);
|
|
4056
|
+
if (labelClose === -1) {
|
|
4057
|
+
return null;
|
|
4058
|
+
}
|
|
4059
|
+
const urlClose = source.indexOf(")", labelClose + 2);
|
|
4060
|
+
if (urlClose === -1) {
|
|
4061
|
+
return null;
|
|
4062
|
+
}
|
|
4063
|
+
const label2 = source.slice(linkStart + 1, labelClose);
|
|
4064
|
+
const nextSource2 = source.slice(0, linkStart) + label2 + source.slice(urlClose + 1);
|
|
4065
|
+
const newState = state2.runtime.createState(nextSource2);
|
|
4066
|
+
const labelEndSource = linkStart + label2.length;
|
|
4067
|
+
const newCursor = newState.map.sourceToCursor(labelEndSource, "forward");
|
|
4068
|
+
return {
|
|
4069
|
+
source: nextSource2,
|
|
4070
|
+
selection: {
|
|
4071
|
+
start: newCursor.cursorOffset,
|
|
4072
|
+
end: newCursor.cursorOffset,
|
|
4073
|
+
affinity: "forward"
|
|
4074
|
+
}
|
|
4075
|
+
};
|
|
4076
|
+
}
|
|
3921
4077
|
if (command.type !== "wrap-link") {
|
|
3922
4078
|
return null;
|
|
3923
4079
|
}
|
|
@@ -4044,13 +4200,15 @@ const linkExtension = {
|
|
|
4044
4200
|
{
|
|
4045
4201
|
container: context.container,
|
|
4046
4202
|
contentRoot: context.contentRoot,
|
|
4047
|
-
toOverlayRect: context.toOverlayRect
|
|
4203
|
+
toOverlayRect: context.toOverlayRect,
|
|
4204
|
+
getSelection: context.getSelection,
|
|
4205
|
+
executeCommand: context.executeCommand
|
|
4048
4206
|
}
|
|
4049
4207
|
);
|
|
4050
4208
|
}
|
|
4051
|
-
};
|
|
4209
|
+
});
|
|
4052
4210
|
const PIPE_LINK_KIND = "pipe-link";
|
|
4053
|
-
const pipeLinkExtension = {
|
|
4211
|
+
const pipeLinkExtension = defineExtension({
|
|
4054
4212
|
name: "pipe-link",
|
|
4055
4213
|
parseInline(source, start, end) {
|
|
4056
4214
|
if (source[start] !== "|") {
|
|
@@ -4121,10 +4279,10 @@ const pipeLinkExtension = {
|
|
|
4121
4279
|
}
|
|
4122
4280
|
return element;
|
|
4123
4281
|
}
|
|
4124
|
-
};
|
|
4282
|
+
});
|
|
4125
4283
|
const BLOCKQUOTE_KIND = "blockquote";
|
|
4126
4284
|
const PREFIX = "> ";
|
|
4127
|
-
const blockquoteExtension = {
|
|
4285
|
+
const blockquoteExtension = defineExtension({
|
|
4128
4286
|
name: "blockquote",
|
|
4129
4287
|
parseBlock(source, start, context) {
|
|
4130
4288
|
if (source.slice(start, start + PREFIX.length) !== PREFIX) {
|
|
@@ -4193,9 +4351,9 @@ const blockquoteExtension = {
|
|
|
4193
4351
|
}
|
|
4194
4352
|
return element;
|
|
4195
4353
|
}
|
|
4196
|
-
};
|
|
4354
|
+
});
|
|
4197
4355
|
const ITALIC_KIND = "italic";
|
|
4198
|
-
const italicExtension = {
|
|
4356
|
+
const italicExtension = defineExtension({
|
|
4199
4357
|
name: "italic",
|
|
4200
4358
|
toggleInline: { kind: ITALIC_KIND, markers: ["*", "_"] },
|
|
4201
4359
|
keybindings: [
|
|
@@ -4265,7 +4423,7 @@ const italicExtension = {
|
|
|
4265
4423
|
}
|
|
4266
4424
|
return element;
|
|
4267
4425
|
}
|
|
4268
|
-
};
|
|
4426
|
+
});
|
|
4269
4427
|
const HEADING_KIND = "heading";
|
|
4270
4428
|
const HEADING_PATTERN = /^(#{1,3}) /;
|
|
4271
4429
|
function findLineStartInSource(source, sourceOffset) {
|
|
@@ -4366,7 +4524,7 @@ function shouldExitHeadingOnLineBreak(state2) {
|
|
|
4366
4524
|
const contentStart = lineStart + marker.length;
|
|
4367
4525
|
return sourcePos >= contentStart && sourcePos <= lineEnd;
|
|
4368
4526
|
}
|
|
4369
|
-
const headingExtension = {
|
|
4527
|
+
const headingExtension = defineExtension({
|
|
4370
4528
|
name: "heading",
|
|
4371
4529
|
onEdit(command, state2) {
|
|
4372
4530
|
if (command.type === "delete-backward") {
|
|
@@ -4507,7 +4665,7 @@ const headingExtension = {
|
|
|
4507
4665
|
}
|
|
4508
4666
|
return lineElement;
|
|
4509
4667
|
}
|
|
4510
|
-
};
|
|
4668
|
+
});
|
|
4511
4669
|
const IMAGE_KIND = "image";
|
|
4512
4670
|
const IMAGE_PATTERN = /^!\[([^\]]*)\]\(([^)]*)\)$/;
|
|
4513
4671
|
const UPLOADING_PATTERN = /^!\[uploading:([^\]]+)\]\(\)$/;
|
|
@@ -4525,7 +4683,7 @@ function isImageData(data) {
|
|
|
4525
4683
|
}
|
|
4526
4684
|
return false;
|
|
4527
4685
|
}
|
|
4528
|
-
const imageExtension = {
|
|
4686
|
+
const imageExtension = defineExtension({
|
|
4529
4687
|
name: "image",
|
|
4530
4688
|
parseBlock(source, start) {
|
|
4531
4689
|
let lineEnd = source.indexOf("\n", start);
|
|
@@ -4620,7 +4778,7 @@ const imageExtension = {
|
|
|
4620
4778
|
}
|
|
4621
4779
|
return element;
|
|
4622
4780
|
}
|
|
4623
|
-
};
|
|
4781
|
+
});
|
|
4624
4782
|
const LIST_LINE_REGEX$2 = /^(\s*)([-*+]|\d+\.)( )(.*)$/;
|
|
4625
4783
|
const INDENT_SIZE = 2;
|
|
4626
4784
|
function parseMarkerType(marker) {
|
|
@@ -5439,7 +5597,7 @@ function getParagraphText(block) {
|
|
|
5439
5597
|
}
|
|
5440
5598
|
return text;
|
|
5441
5599
|
}
|
|
5442
|
-
const listExtension = {
|
|
5600
|
+
const listExtension = defineExtension({
|
|
5443
5601
|
name: "list",
|
|
5444
5602
|
keybindings: [
|
|
5445
5603
|
{
|
|
@@ -5532,7 +5690,7 @@ const listExtension = {
|
|
|
5532
5690
|
}
|
|
5533
5691
|
return element;
|
|
5534
5692
|
}
|
|
5535
|
-
};
|
|
5693
|
+
});
|
|
5536
5694
|
const THUMB_MIN_HEIGHT = 30;
|
|
5537
5695
|
const SCROLL_HIDE_DELAY = 500;
|
|
5538
5696
|
const TRACK_PADDING = 8;
|
|
@@ -5769,14 +5927,14 @@ function ScrollbarOverlay({ container }) {
|
|
|
5769
5927
|
}
|
|
5770
5928
|
) });
|
|
5771
5929
|
}
|
|
5772
|
-
const scrollbarExtension = {
|
|
5930
|
+
const scrollbarExtension = defineExtension({
|
|
5773
5931
|
name: "scrollbar",
|
|
5774
5932
|
renderOverlay(context) {
|
|
5775
5933
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollbarOverlay, { container: context.container });
|
|
5776
5934
|
}
|
|
5777
|
-
};
|
|
5935
|
+
});
|
|
5778
5936
|
const STRIKE_KIND = "strikethrough";
|
|
5779
|
-
const strikethroughExtension = {
|
|
5937
|
+
const strikethroughExtension = defineExtension({
|
|
5780
5938
|
name: "strikethrough",
|
|
5781
5939
|
toggleInline: { kind: STRIKE_KIND, markers: ["~~"] },
|
|
5782
5940
|
keybindings: [
|
|
@@ -5849,8 +6007,8 @@ const strikethroughExtension = {
|
|
|
5849
6007
|
}
|
|
5850
6008
|
return element;
|
|
5851
6009
|
}
|
|
5852
|
-
};
|
|
5853
|
-
const
|
|
6010
|
+
});
|
|
6011
|
+
const bundledExtensionsWithoutImage = [
|
|
5854
6012
|
blockquoteExtension,
|
|
5855
6013
|
headingExtension,
|
|
5856
6014
|
listExtension,
|
|
@@ -5859,7 +6017,10 @@ const bundledExtensions = [
|
|
|
5859
6017
|
italicExtension,
|
|
5860
6018
|
strikethroughExtension,
|
|
5861
6019
|
pipeLinkExtension,
|
|
5862
|
-
linkExtension
|
|
6020
|
+
linkExtension
|
|
6021
|
+
];
|
|
6022
|
+
const bundledExtensions = [
|
|
6023
|
+
...bundledExtensionsWithoutImage,
|
|
5863
6024
|
imageExtension
|
|
5864
6025
|
];
|
|
5865
6026
|
function toLayoutRect(params) {
|
|
@@ -5919,6 +6080,46 @@ function cursorOffsetToCodeUnit(cursorToCodeUnit, offset) {
|
|
|
5919
6080
|
const clamped = Math.max(0, Math.min(offset, cursorToCodeUnit.length - 1));
|
|
5920
6081
|
return cursorToCodeUnit[clamped] ?? 0;
|
|
5921
6082
|
}
|
|
6083
|
+
function createDomPositionResolver(lineElement) {
|
|
6084
|
+
const textNodes = [];
|
|
6085
|
+
const cumulativeEnds = [];
|
|
6086
|
+
const walker = createTextWalker(lineElement);
|
|
6087
|
+
let current = walker.nextNode();
|
|
6088
|
+
let total = 0;
|
|
6089
|
+
while (current) {
|
|
6090
|
+
if (current instanceof Text) {
|
|
6091
|
+
const length = current.data.length;
|
|
6092
|
+
textNodes.push(current);
|
|
6093
|
+
total += length;
|
|
6094
|
+
cumulativeEnds.push(total);
|
|
6095
|
+
}
|
|
6096
|
+
current = walker.nextNode();
|
|
6097
|
+
}
|
|
6098
|
+
if (textNodes.length === 0) {
|
|
6099
|
+
return () => {
|
|
6100
|
+
if (!lineElement.textContent) {
|
|
6101
|
+
return { node: lineElement, offset: 0 };
|
|
6102
|
+
}
|
|
6103
|
+
return { node: lineElement, offset: lineElement.childNodes.length };
|
|
6104
|
+
};
|
|
6105
|
+
}
|
|
6106
|
+
return (offsetInLine) => {
|
|
6107
|
+
const clamped = Math.max(0, Math.min(offsetInLine, total));
|
|
6108
|
+
let low = 0;
|
|
6109
|
+
let high = cumulativeEnds.length - 1;
|
|
6110
|
+
while (low < high) {
|
|
6111
|
+
const mid = low + high >>> 1;
|
|
6112
|
+
if ((cumulativeEnds[mid] ?? 0) < clamped) {
|
|
6113
|
+
low = mid + 1;
|
|
6114
|
+
} else {
|
|
6115
|
+
high = mid;
|
|
6116
|
+
}
|
|
6117
|
+
}
|
|
6118
|
+
const node = textNodes[low] ?? lineElement;
|
|
6119
|
+
const prevEnd = low > 0 ? cumulativeEnds[low - 1] ?? 0 : 0;
|
|
6120
|
+
return { node, offset: clamped - prevEnd };
|
|
6121
|
+
};
|
|
6122
|
+
}
|
|
5922
6123
|
function measureCharacterRect(params) {
|
|
5923
6124
|
if (params.lineLength <= 0) {
|
|
5924
6125
|
return null;
|
|
@@ -5931,101 +6132,155 @@ function measureCharacterRect(params) {
|
|
|
5931
6132
|
params.cursorToCodeUnit,
|
|
5932
6133
|
Math.min(params.offset + 1, params.lineLength)
|
|
5933
6134
|
);
|
|
5934
|
-
const startPosition = resolveDomPosition(
|
|
5935
|
-
const endPosition = resolveDomPosition(
|
|
5936
|
-
|
|
5937
|
-
range.
|
|
5938
|
-
range.
|
|
5939
|
-
const rects = range.getClientRects();
|
|
6135
|
+
const startPosition = params.resolveDomPosition(startCodeUnit);
|
|
6136
|
+
const endPosition = params.resolveDomPosition(endCodeUnit);
|
|
6137
|
+
params.range.setStart(startPosition.node, startPosition.offset);
|
|
6138
|
+
params.range.setEnd(endPosition.node, endPosition.offset);
|
|
6139
|
+
const rects = params.range.getClientRects();
|
|
5940
6140
|
if (rects.length > 0) {
|
|
5941
6141
|
return rects[0] ?? null;
|
|
5942
6142
|
}
|
|
5943
|
-
const rect = range.getBoundingClientRect();
|
|
6143
|
+
const rect = params.range.getBoundingClientRect();
|
|
5944
6144
|
if (rect.width === 0 && rect.height === 0) {
|
|
5945
6145
|
return null;
|
|
5946
6146
|
}
|
|
5947
6147
|
return rect;
|
|
5948
6148
|
}
|
|
5949
6149
|
function measureLineRows(params) {
|
|
6150
|
+
var _a, _b;
|
|
6151
|
+
const fallbackLineBox = toLayoutRect({
|
|
6152
|
+
rect: params.lineRect,
|
|
6153
|
+
containerRect: params.containerRect,
|
|
6154
|
+
scroll: params.scroll
|
|
6155
|
+
});
|
|
5950
6156
|
if (params.lineLength === 0) {
|
|
5951
|
-
const lineBox = toLayoutRect({
|
|
5952
|
-
rect: params.lineRect,
|
|
5953
|
-
containerRect: params.containerRect,
|
|
5954
|
-
scroll: params.scroll
|
|
5955
|
-
});
|
|
5956
6157
|
return [
|
|
5957
6158
|
{
|
|
5958
6159
|
startOffset: 0,
|
|
5959
6160
|
endOffset: 0,
|
|
5960
|
-
rect: { ...
|
|
6161
|
+
rect: { ...fallbackLineBox, width: 0 }
|
|
5961
6162
|
}
|
|
5962
6163
|
];
|
|
5963
6164
|
}
|
|
5964
|
-
const
|
|
5965
|
-
const
|
|
5966
|
-
const
|
|
5967
|
-
|
|
5968
|
-
|
|
5969
|
-
);
|
|
5970
|
-
|
|
5971
|
-
|
|
5972
|
-
const fullLineRects = groupDomRectsByRow(
|
|
5973
|
-
|
|
5974
|
-
|
|
5975
|
-
const fallbackLineBox = toLayoutRect({
|
|
5976
|
-
rect: params.lineRect,
|
|
5977
|
-
containerRect: params.containerRect,
|
|
5978
|
-
scroll: params.scroll
|
|
5979
|
-
});
|
|
5980
|
-
const charRect = measureCharacterRect({
|
|
5981
|
-
lineElement: params.lineElement,
|
|
5982
|
-
offset: 0,
|
|
5983
|
-
lineLength: params.lineLength,
|
|
5984
|
-
cursorToCodeUnit: params.cursorToCodeUnit
|
|
5985
|
-
});
|
|
5986
|
-
const charWidth = (charRect == null ? void 0 : charRect.width) ?? 0;
|
|
5987
|
-
if (fullLineRects.length === 0 || charWidth <= 0) {
|
|
5988
|
-
const rows2 = [
|
|
6165
|
+
const WRAP_THRESHOLD_PX = 3;
|
|
6166
|
+
const resolvePosition = createDomPositionResolver(params.lineElement);
|
|
6167
|
+
const scratchRange = document.createRange();
|
|
6168
|
+
const topCache = /* @__PURE__ */ new Map();
|
|
6169
|
+
const fullLineStart = resolvePosition(0);
|
|
6170
|
+
const fullLineEnd = resolvePosition(params.codeUnitLength);
|
|
6171
|
+
scratchRange.setStart(fullLineStart.node, fullLineStart.offset);
|
|
6172
|
+
scratchRange.setEnd(fullLineEnd.node, fullLineEnd.offset);
|
|
6173
|
+
const fullLineRects = groupDomRectsByRow(Array.from(scratchRange.getClientRects()));
|
|
6174
|
+
if (fullLineRects.length === 0) {
|
|
6175
|
+
return [
|
|
5989
6176
|
{
|
|
5990
6177
|
startOffset: 0,
|
|
5991
6178
|
endOffset: params.lineLength,
|
|
5992
6179
|
rect: fallbackLineBox
|
|
5993
6180
|
}
|
|
5994
6181
|
];
|
|
5995
|
-
|
|
6182
|
+
}
|
|
6183
|
+
function offsetToTop(offset) {
|
|
6184
|
+
if (topCache.has(offset)) {
|
|
6185
|
+
return topCache.get(offset) ?? null;
|
|
6186
|
+
}
|
|
6187
|
+
const rect = measureCharacterRect({
|
|
6188
|
+
lineElement: params.lineElement,
|
|
6189
|
+
offset,
|
|
6190
|
+
lineLength: params.lineLength,
|
|
6191
|
+
cursorToCodeUnit: params.cursorToCodeUnit,
|
|
6192
|
+
resolveDomPosition: resolvePosition,
|
|
6193
|
+
range: scratchRange
|
|
6194
|
+
});
|
|
6195
|
+
const top = rect ? rect.top : null;
|
|
6196
|
+
topCache.set(offset, top);
|
|
6197
|
+
return top;
|
|
6198
|
+
}
|
|
6199
|
+
function findFirstMeasurableOffset(from) {
|
|
6200
|
+
for (let offset = Math.max(0, from); offset < params.lineLength; offset++) {
|
|
6201
|
+
if (offsetToTop(offset) !== null) {
|
|
6202
|
+
return offset;
|
|
6203
|
+
}
|
|
6204
|
+
}
|
|
6205
|
+
return null;
|
|
6206
|
+
}
|
|
6207
|
+
function findNextRowStartOffset(fromExclusive, rowTop) {
|
|
6208
|
+
const lastIndex = params.lineLength - 1;
|
|
6209
|
+
if (fromExclusive > lastIndex) {
|
|
6210
|
+
return null;
|
|
6211
|
+
}
|
|
6212
|
+
const isNewRowAt = (offset) => {
|
|
6213
|
+
const top = offsetToTop(offset);
|
|
6214
|
+
return top !== null && Math.abs(top - rowTop) > WRAP_THRESHOLD_PX;
|
|
6215
|
+
};
|
|
6216
|
+
let step = 1;
|
|
6217
|
+
let lastSame = fromExclusive - 1;
|
|
6218
|
+
let probe = fromExclusive;
|
|
6219
|
+
while (probe <= lastIndex) {
|
|
6220
|
+
if (isNewRowAt(probe)) {
|
|
6221
|
+
break;
|
|
6222
|
+
}
|
|
6223
|
+
lastSame = probe;
|
|
6224
|
+
probe += step;
|
|
6225
|
+
step *= 2;
|
|
6226
|
+
}
|
|
6227
|
+
if (probe > lastIndex) {
|
|
6228
|
+
probe = lastIndex;
|
|
6229
|
+
if (!isNewRowAt(probe)) {
|
|
6230
|
+
return null;
|
|
6231
|
+
}
|
|
6232
|
+
}
|
|
6233
|
+
let low = Math.max(fromExclusive, lastSame + 1);
|
|
6234
|
+
let high = probe;
|
|
6235
|
+
while (low < high) {
|
|
6236
|
+
const mid = low + high >>> 1;
|
|
6237
|
+
if (isNewRowAt(mid)) {
|
|
6238
|
+
high = mid;
|
|
6239
|
+
} else {
|
|
6240
|
+
low = mid + 1;
|
|
6241
|
+
}
|
|
6242
|
+
}
|
|
6243
|
+
return low < params.lineLength ? low : null;
|
|
6244
|
+
}
|
|
6245
|
+
const rows = [];
|
|
6246
|
+
const firstMeasurable = findFirstMeasurableOffset(0);
|
|
6247
|
+
if (firstMeasurable === null) {
|
|
6248
|
+
return [
|
|
5996
6249
|
{
|
|
5997
|
-
|
|
5998
|
-
|
|
5999
|
-
|
|
6000
|
-
top: fallbackLineBox.top,
|
|
6001
|
-
height: fallbackLineBox.height
|
|
6002
|
-
}
|
|
6250
|
+
startOffset: 0,
|
|
6251
|
+
endOffset: params.lineLength,
|
|
6252
|
+
rect: fallbackLineBox
|
|
6003
6253
|
}
|
|
6004
|
-
]
|
|
6254
|
+
];
|
|
6005
6255
|
}
|
|
6006
|
-
let
|
|
6007
|
-
|
|
6008
|
-
|
|
6009
|
-
|
|
6010
|
-
|
|
6011
|
-
const
|
|
6012
|
-
const
|
|
6013
|
-
|
|
6014
|
-
|
|
6256
|
+
let currentRowStart = 0;
|
|
6257
|
+
let currentRowTop = ((_a = fullLineRects[0]) == null ? void 0 : _a.top) ?? params.lineRect.top;
|
|
6258
|
+
let searchFrom = firstMeasurable + 1;
|
|
6259
|
+
let rowIndex = 0;
|
|
6260
|
+
while (currentRowStart < params.lineLength) {
|
|
6261
|
+
const nextRowStart = findNextRowStartOffset(searchFrom, currentRowTop);
|
|
6262
|
+
const currentRowEnd = nextRowStart ?? params.lineLength;
|
|
6263
|
+
const domRect = fullLineRects[rowIndex] ?? params.lineRect;
|
|
6264
|
+
rows.push({
|
|
6265
|
+
startOffset: currentRowStart,
|
|
6266
|
+
endOffset: currentRowEnd,
|
|
6015
6267
|
rect: toLayoutRect({
|
|
6016
|
-
rect,
|
|
6268
|
+
rect: domRect,
|
|
6017
6269
|
containerRect: params.containerRect,
|
|
6018
6270
|
scroll: params.scroll
|
|
6019
6271
|
})
|
|
6020
|
-
};
|
|
6021
|
-
|
|
6022
|
-
|
|
6023
|
-
|
|
6024
|
-
|
|
6025
|
-
|
|
6026
|
-
|
|
6027
|
-
|
|
6028
|
-
|
|
6272
|
+
});
|
|
6273
|
+
if (nextRowStart === null) {
|
|
6274
|
+
break;
|
|
6275
|
+
}
|
|
6276
|
+
currentRowStart = nextRowStart;
|
|
6277
|
+
rowIndex += 1;
|
|
6278
|
+
const nextMeasurable = findFirstMeasurableOffset(currentRowStart);
|
|
6279
|
+
if (nextMeasurable === null) {
|
|
6280
|
+
break;
|
|
6281
|
+
}
|
|
6282
|
+
currentRowTop = ((_b = fullLineRects[rowIndex]) == null ? void 0 : _b.top) ?? currentRowTop;
|
|
6283
|
+
searchFrom = nextMeasurable + 1;
|
|
6029
6284
|
}
|
|
6030
6285
|
if (rows.length === 1) {
|
|
6031
6286
|
rows[0] = {
|
|
@@ -6097,6 +6352,44 @@ function measureLayoutModelFromDom(params) {
|
|
|
6097
6352
|
}
|
|
6098
6353
|
return buildLayoutModel(params.lines, measurer);
|
|
6099
6354
|
}
|
|
6355
|
+
function measureLayoutModelRangeFromDom(params) {
|
|
6356
|
+
const measurer = createDomLayoutMeasurer({
|
|
6357
|
+
root: params.root,
|
|
6358
|
+
container: params.container,
|
|
6359
|
+
lines: params.lines
|
|
6360
|
+
});
|
|
6361
|
+
if (!measurer) {
|
|
6362
|
+
return null;
|
|
6363
|
+
}
|
|
6364
|
+
const clampedStart = Math.max(0, Math.min(params.startLineIndex, params.lines.length - 1));
|
|
6365
|
+
const clampedEnd = Math.max(clampedStart, Math.min(params.endLineIndex, params.lines.length - 1));
|
|
6366
|
+
const lineOffsets = getLineOffsets(params.lines);
|
|
6367
|
+
let lineStartOffset = lineOffsets[clampedStart] ?? 0;
|
|
6368
|
+
const layouts = [];
|
|
6369
|
+
for (let lineIndex = clampedStart; lineIndex <= clampedEnd; lineIndex += 1) {
|
|
6370
|
+
const lineInfo = params.lines[lineIndex];
|
|
6371
|
+
if (!lineInfo) {
|
|
6372
|
+
continue;
|
|
6373
|
+
}
|
|
6374
|
+
const measurement = measurer.measureLine({
|
|
6375
|
+
lineIndex: lineInfo.lineIndex,
|
|
6376
|
+
lineText: lineInfo.text,
|
|
6377
|
+
lineLength: lineInfo.cursorLength,
|
|
6378
|
+
lineHasNewline: lineInfo.hasNewline,
|
|
6379
|
+
top: 0
|
|
6380
|
+
});
|
|
6381
|
+
layouts.push({
|
|
6382
|
+
lineIndex: lineInfo.lineIndex,
|
|
6383
|
+
lineStartOffset,
|
|
6384
|
+
lineLength: lineInfo.cursorLength,
|
|
6385
|
+
lineHasNewline: lineInfo.hasNewline,
|
|
6386
|
+
lineBox: measurement.lineBox,
|
|
6387
|
+
rows: measurement.rows
|
|
6388
|
+
});
|
|
6389
|
+
lineStartOffset += lineInfo.cursorLength + (lineInfo.hasNewline ? 1 : 0);
|
|
6390
|
+
}
|
|
6391
|
+
return { container: measurer.container, lines: layouts };
|
|
6392
|
+
}
|
|
6100
6393
|
function getLineElement(root, lineIndex) {
|
|
6101
6394
|
return root.querySelector(`[data-line-index="${lineIndex}"]`);
|
|
6102
6395
|
}
|
|
@@ -6312,7 +6605,17 @@ function getSelectionGeometry(params) {
|
|
|
6312
6605
|
end: selection.start,
|
|
6313
6606
|
affinity: selection.affinity
|
|
6314
6607
|
};
|
|
6315
|
-
const layout = shouldMeasureLayout(normalized) ?
|
|
6608
|
+
const layout = shouldMeasureLayout(normalized) ? (() => {
|
|
6609
|
+
const startLine2 = resolveOffsetToLine(docLines, normalized.start);
|
|
6610
|
+
const endLine = resolveOffsetToLine(docLines, normalized.end);
|
|
6611
|
+
return measureLayoutModelRangeFromDom({
|
|
6612
|
+
lines: docLines,
|
|
6613
|
+
root,
|
|
6614
|
+
container,
|
|
6615
|
+
startLineIndex: startLine2.lineIndex,
|
|
6616
|
+
endLineIndex: endLine.lineIndex
|
|
6617
|
+
});
|
|
6618
|
+
})() : null;
|
|
6316
6619
|
const containerRect = container.getBoundingClientRect();
|
|
6317
6620
|
const scroll = { top: container.scrollTop, left: container.scrollLeft };
|
|
6318
6621
|
const startLine = resolveOffsetToLine(docLines, normalized.start);
|
|
@@ -7320,10 +7623,13 @@ class CakeEngine {
|
|
|
7320
7623
|
this.caretBlinkTimeoutId = null;
|
|
7321
7624
|
this.overlayUpdateId = null;
|
|
7322
7625
|
this.scrollCaretIntoViewId = null;
|
|
7626
|
+
this.selectionRectElements = [];
|
|
7627
|
+
this.lastSelectionRects = null;
|
|
7323
7628
|
this.extensionsRoot = null;
|
|
7324
7629
|
this.placeholderRoot = null;
|
|
7325
7630
|
this.lastFocusRect = null;
|
|
7326
7631
|
this.verticalNavGoalX = null;
|
|
7632
|
+
this.lastRenderPerf = null;
|
|
7327
7633
|
this.history = {
|
|
7328
7634
|
undoStack: [],
|
|
7329
7635
|
redoStack: [],
|
|
@@ -7377,6 +7683,9 @@ class CakeEngine {
|
|
|
7377
7683
|
set state(value) {
|
|
7378
7684
|
this._state = value;
|
|
7379
7685
|
}
|
|
7686
|
+
getLastRenderPerf() {
|
|
7687
|
+
return this.lastRenderPerf;
|
|
7688
|
+
}
|
|
7380
7689
|
isEventTargetInContentRoot(target) {
|
|
7381
7690
|
if (target === this.container) {
|
|
7382
7691
|
return true;
|
|
@@ -7413,6 +7722,9 @@ class CakeEngine {
|
|
|
7413
7722
|
getSelection() {
|
|
7414
7723
|
return this.state.selection;
|
|
7415
7724
|
}
|
|
7725
|
+
getCursorLength() {
|
|
7726
|
+
return this.state.map.cursorLength;
|
|
7727
|
+
}
|
|
7416
7728
|
getFocusRect() {
|
|
7417
7729
|
return this.lastFocusRect;
|
|
7418
7730
|
}
|
|
@@ -7467,6 +7779,7 @@ class CakeEngine {
|
|
|
7467
7779
|
if (!this.isComposing) {
|
|
7468
7780
|
this.applySelection(this.state.selection);
|
|
7469
7781
|
}
|
|
7782
|
+
this.scheduleScrollCaretIntoView();
|
|
7470
7783
|
}
|
|
7471
7784
|
setValue({ value, selection }) {
|
|
7472
7785
|
const valueChanged = value !== this.state.source;
|
|
@@ -7542,7 +7855,7 @@ class CakeEngine {
|
|
|
7542
7855
|
}
|
|
7543
7856
|
executeCommand(command) {
|
|
7544
7857
|
var _a;
|
|
7545
|
-
const shouldOpenLinkPopover =
|
|
7858
|
+
const shouldOpenLinkPopover = "openPopover" in command && command.openPopover === true;
|
|
7546
7859
|
const nextState = this.runtime.applyEdit(command, this.state);
|
|
7547
7860
|
if (nextState === this.state) {
|
|
7548
7861
|
return false;
|
|
@@ -7717,6 +8030,14 @@ class CakeEngine {
|
|
|
7717
8030
|
this.patchedCaretRangeFromPoint = null;
|
|
7718
8031
|
}
|
|
7719
8032
|
render() {
|
|
8033
|
+
const perfEnabled = this.container.dataset.cakePerf === "1";
|
|
8034
|
+
let perfStart = 0;
|
|
8035
|
+
let renderStart = 0;
|
|
8036
|
+
let renderAndMapMs = 0;
|
|
8037
|
+
let applySelectionMs = 0;
|
|
8038
|
+
if (perfEnabled) {
|
|
8039
|
+
perfStart = performance.now();
|
|
8040
|
+
}
|
|
7720
8041
|
if (!this.contentRoot) {
|
|
7721
8042
|
const containerPosition = window.getComputedStyle(
|
|
7722
8043
|
this.container
|
|
@@ -7732,6 +8053,9 @@ class CakeEngine {
|
|
|
7732
8053
|
this.container.replaceChildren(this.contentRoot, overlay, extensionsRoot);
|
|
7733
8054
|
this.attachDragListeners();
|
|
7734
8055
|
}
|
|
8056
|
+
if (perfEnabled) {
|
|
8057
|
+
renderStart = performance.now();
|
|
8058
|
+
}
|
|
7735
8059
|
const { content, map } = renderDocContent(
|
|
7736
8060
|
this.state.doc,
|
|
7737
8061
|
this.extensions,
|
|
@@ -7743,9 +8067,26 @@ class CakeEngine {
|
|
|
7743
8067
|
this.contentRoot.replaceChildren(...content);
|
|
7744
8068
|
}
|
|
7745
8069
|
this.domMap = map;
|
|
7746
|
-
|
|
7747
|
-
|
|
8070
|
+
if (perfEnabled) {
|
|
8071
|
+
renderAndMapMs = performance.now() - renderStart;
|
|
8072
|
+
}
|
|
8073
|
+
if (!this.isComposing && this.hasFocus()) {
|
|
8074
|
+
const selectionStart = perfEnabled ? performance.now() : 0;
|
|
7748
8075
|
this.applySelection(this.state.selection);
|
|
8076
|
+
if (perfEnabled) {
|
|
8077
|
+
applySelectionMs = performance.now() - selectionStart;
|
|
8078
|
+
}
|
|
8079
|
+
}
|
|
8080
|
+
if (perfEnabled) {
|
|
8081
|
+
const totalMs = performance.now() - perfStart;
|
|
8082
|
+
this.lastRenderPerf = {
|
|
8083
|
+
totalMs,
|
|
8084
|
+
renderAndMapMs,
|
|
8085
|
+
applySelectionMs,
|
|
8086
|
+
didUpdateDom: needsUpdate,
|
|
8087
|
+
blockCount: this.state.doc.blocks.length,
|
|
8088
|
+
runCount: map.runs.length
|
|
8089
|
+
};
|
|
7749
8090
|
}
|
|
7750
8091
|
this.updatePlaceholder();
|
|
7751
8092
|
this.scheduleOverlayUpdate();
|
|
@@ -7995,22 +8336,31 @@ class CakeEngine {
|
|
|
7995
8336
|
this.suppressSelectionChange = false;
|
|
7996
8337
|
return;
|
|
7997
8338
|
}
|
|
7998
|
-
const
|
|
7999
|
-
|
|
8000
|
-
if (
|
|
8339
|
+
const pendingHit = this.pendingClickHit;
|
|
8340
|
+
const selection = this.state.selection;
|
|
8341
|
+
if (pendingHit && selection.start !== selection.end) {
|
|
8001
8342
|
const newSelection = {
|
|
8002
|
-
start:
|
|
8003
|
-
end:
|
|
8004
|
-
affinity:
|
|
8343
|
+
start: pendingHit.cursorOffset,
|
|
8344
|
+
end: pendingHit.cursorOffset,
|
|
8345
|
+
affinity: pendingHit.affinity
|
|
8005
8346
|
};
|
|
8347
|
+
this.pendingClickHit = null;
|
|
8348
|
+
this.suppressSelectionChange = true;
|
|
8006
8349
|
this.state = this.runtime.updateSelection(this.state, newSelection, {
|
|
8007
8350
|
kind: "dom"
|
|
8008
8351
|
});
|
|
8009
8352
|
this.applySelection(this.state.selection);
|
|
8010
8353
|
(_b = this.onSelectionChange) == null ? void 0 : _b.call(this, this.state.selection);
|
|
8011
8354
|
this.scheduleOverlayUpdate();
|
|
8355
|
+
setTimeout(() => {
|
|
8356
|
+
this.suppressSelectionChange = false;
|
|
8357
|
+
}, 0);
|
|
8358
|
+
return;
|
|
8012
8359
|
}
|
|
8013
|
-
this.
|
|
8360
|
+
this.pendingClickHit = null;
|
|
8361
|
+
setTimeout(() => {
|
|
8362
|
+
this.suppressSelectionChange = false;
|
|
8363
|
+
}, 0);
|
|
8014
8364
|
return;
|
|
8015
8365
|
}
|
|
8016
8366
|
this.pendingClickHit = null;
|
|
@@ -8388,7 +8738,7 @@ class CakeEngine {
|
|
|
8388
8738
|
if (!command) {
|
|
8389
8739
|
continue;
|
|
8390
8740
|
}
|
|
8391
|
-
if (command
|
|
8741
|
+
if (isApplyEditCommand(command)) {
|
|
8392
8742
|
this.applyEdit(command);
|
|
8393
8743
|
} else {
|
|
8394
8744
|
this.executeCommand(command);
|
|
@@ -8908,6 +9258,39 @@ class CakeEngine {
|
|
|
8908
9258
|
return { start: target, end: target, affinity: direction };
|
|
8909
9259
|
}
|
|
8910
9260
|
const currentPos = selection.start;
|
|
9261
|
+
const currentAffinity = selection.affinity ?? "forward";
|
|
9262
|
+
const measurement = this.getLayoutForNavigation();
|
|
9263
|
+
if (measurement) {
|
|
9264
|
+
const { lines, layout } = measurement;
|
|
9265
|
+
const { rowStart, rowEnd } = getVisualRowBoundaries({
|
|
9266
|
+
lines,
|
|
9267
|
+
layout,
|
|
9268
|
+
offset: currentPos,
|
|
9269
|
+
affinity: currentAffinity
|
|
9270
|
+
});
|
|
9271
|
+
if (direction === "backward" && currentPos === rowStart && currentAffinity === "forward" && currentPos > 0) {
|
|
9272
|
+
const prevBoundaries = getVisualRowBoundaries({
|
|
9273
|
+
lines,
|
|
9274
|
+
layout,
|
|
9275
|
+
offset: currentPos,
|
|
9276
|
+
affinity: "backward"
|
|
9277
|
+
});
|
|
9278
|
+
if (prevBoundaries.rowEnd !== rowEnd || prevBoundaries.rowStart !== rowStart) {
|
|
9279
|
+
return { start: currentPos, end: currentPos, affinity: "backward" };
|
|
9280
|
+
}
|
|
9281
|
+
}
|
|
9282
|
+
if (direction === "forward" && currentPos === rowEnd && currentAffinity === "backward" && currentPos < this.state.map.cursorLength) {
|
|
9283
|
+
const nextBoundaries = getVisualRowBoundaries({
|
|
9284
|
+
lines,
|
|
9285
|
+
layout,
|
|
9286
|
+
offset: currentPos,
|
|
9287
|
+
affinity: "forward"
|
|
9288
|
+
});
|
|
9289
|
+
if (nextBoundaries.rowEnd !== rowEnd || nextBoundaries.rowStart !== rowStart) {
|
|
9290
|
+
return { start: currentPos, end: currentPos, affinity: "forward" };
|
|
9291
|
+
}
|
|
9292
|
+
}
|
|
9293
|
+
}
|
|
8911
9294
|
const nextPos = this.moveOffsetByChar(currentPos, direction);
|
|
8912
9295
|
if (nextPos === null) {
|
|
8913
9296
|
return null;
|
|
@@ -9597,6 +9980,7 @@ class CakeEngine {
|
|
|
9597
9980
|
}
|
|
9598
9981
|
this.overlayUpdateId = window.requestAnimationFrame(() => {
|
|
9599
9982
|
this.overlayUpdateId = null;
|
|
9983
|
+
this.updateExtensionsOverlayPosition();
|
|
9600
9984
|
this.updateSelectionOverlay();
|
|
9601
9985
|
});
|
|
9602
9986
|
}
|
|
@@ -9626,12 +10010,34 @@ class CakeEngine {
|
|
|
9626
10010
|
overlay.style.zIndex = "2";
|
|
9627
10011
|
const caret = document.createElement("div");
|
|
9628
10012
|
caret.className = "cake-caret";
|
|
10013
|
+
caret.style.position = "absolute";
|
|
9629
10014
|
caret.style.display = "none";
|
|
9630
10015
|
overlay.append(caret);
|
|
9631
10016
|
this.overlayRoot = overlay;
|
|
9632
10017
|
this.caretElement = caret;
|
|
10018
|
+
this.selectionRectElements = [];
|
|
10019
|
+
this.lastSelectionRects = null;
|
|
9633
10020
|
return overlay;
|
|
9634
10021
|
}
|
|
10022
|
+
selectionRectsEqual(prev, next) {
|
|
10023
|
+
if (!prev) {
|
|
10024
|
+
return false;
|
|
10025
|
+
}
|
|
10026
|
+
if (prev.length !== next.length) {
|
|
10027
|
+
return false;
|
|
10028
|
+
}
|
|
10029
|
+
for (let index = 0; index < prev.length; index += 1) {
|
|
10030
|
+
const a = prev[index];
|
|
10031
|
+
const b = next[index];
|
|
10032
|
+
if (!a || !b) {
|
|
10033
|
+
return false;
|
|
10034
|
+
}
|
|
10035
|
+
if (a.top !== b.top || a.left !== b.left || a.width !== b.width || a.height !== b.height) {
|
|
10036
|
+
return false;
|
|
10037
|
+
}
|
|
10038
|
+
}
|
|
10039
|
+
return true;
|
|
10040
|
+
}
|
|
9635
10041
|
ensureExtensionsRoot() {
|
|
9636
10042
|
if (this.extensionsRoot) {
|
|
9637
10043
|
return this.extensionsRoot;
|
|
@@ -9692,21 +10098,34 @@ class CakeEngine {
|
|
|
9692
10098
|
if (!this.overlayRoot || !this.caretElement) {
|
|
9693
10099
|
return;
|
|
9694
10100
|
}
|
|
9695
|
-
|
|
9696
|
-
|
|
9697
|
-
|
|
9698
|
-
|
|
9699
|
-
|
|
9700
|
-
|
|
9701
|
-
|
|
9702
|
-
|
|
10101
|
+
if (this.selectionRectsEqual(this.lastSelectionRects, rects)) {
|
|
10102
|
+
return;
|
|
10103
|
+
}
|
|
10104
|
+
this.lastSelectionRects = rects;
|
|
10105
|
+
while (this.selectionRectElements.length > rects.length) {
|
|
10106
|
+
const element = this.selectionRectElements.pop();
|
|
10107
|
+
element == null ? void 0 : element.remove();
|
|
10108
|
+
}
|
|
10109
|
+
if (this.selectionRectElements.length < rects.length) {
|
|
10110
|
+
const fragment = document.createDocumentFragment();
|
|
10111
|
+
while (this.selectionRectElements.length < rects.length) {
|
|
10112
|
+
const element = document.createElement("div");
|
|
10113
|
+
element.className = "cake-selection-rect";
|
|
10114
|
+
fragment.append(element);
|
|
10115
|
+
this.selectionRectElements.push(element);
|
|
10116
|
+
}
|
|
10117
|
+
this.overlayRoot.insertBefore(fragment, this.caretElement);
|
|
10118
|
+
}
|
|
10119
|
+
rects.forEach((rect, index) => {
|
|
10120
|
+
const element = this.selectionRectElements[index];
|
|
10121
|
+
if (!element) {
|
|
10122
|
+
return;
|
|
10123
|
+
}
|
|
9703
10124
|
element.style.top = `${rect.top}px`;
|
|
9704
10125
|
element.style.left = `${rect.left}px`;
|
|
9705
10126
|
element.style.width = `${rect.width}px`;
|
|
9706
10127
|
element.style.height = `${rect.height}px`;
|
|
9707
|
-
fragment.append(element);
|
|
9708
10128
|
});
|
|
9709
|
-
this.overlayRoot.insertBefore(fragment, this.caretElement);
|
|
9710
10129
|
}
|
|
9711
10130
|
updateCaret(position) {
|
|
9712
10131
|
if (!this.caretElement) {
|
|
@@ -9873,7 +10292,7 @@ class CakeEngine {
|
|
|
9873
10292
|
return { cursorOffset: cursor.cursorOffset, affinity: "backward" };
|
|
9874
10293
|
}
|
|
9875
10294
|
handlePointerDown(event) {
|
|
9876
|
-
var _a;
|
|
10295
|
+
var _a, _b, _c;
|
|
9877
10296
|
if (!this.isEventTargetInContentRoot(event.target)) {
|
|
9878
10297
|
return;
|
|
9879
10298
|
}
|
|
@@ -9938,13 +10357,51 @@ class CakeEngine {
|
|
|
9938
10357
|
}
|
|
9939
10358
|
}
|
|
9940
10359
|
}
|
|
9941
|
-
if (
|
|
9942
|
-
this.suppressSelectionChange = true;
|
|
10360
|
+
if (!event.shiftKey) {
|
|
9943
10361
|
const hit2 = this.hitTestFromClientPoint(event.clientX, event.clientY);
|
|
9944
|
-
if (hit2) {
|
|
10362
|
+
if (!hit2) {
|
|
10363
|
+
return;
|
|
10364
|
+
}
|
|
10365
|
+
if (selection.start !== selection.end) {
|
|
10366
|
+
const selStart2 = Math.min(selection.start, selection.end);
|
|
10367
|
+
const selEnd2 = Math.max(selection.start, selection.end);
|
|
10368
|
+
const clickedInsideSelection2 = hit2.cursorOffset >= selStart2 && hit2.cursorOffset <= selEnd2;
|
|
10369
|
+
if (clickedInsideSelection2) {
|
|
10370
|
+
this.suppressSelectionChange = false;
|
|
10371
|
+
this.blockTrustedTextDrag = true;
|
|
10372
|
+
this.pendingClickHit = hit2;
|
|
10373
|
+
} else {
|
|
10374
|
+
this.suppressSelectionChange = true;
|
|
10375
|
+
this.pendingClickHit = hit2;
|
|
10376
|
+
const newSelection = {
|
|
10377
|
+
start: hit2.cursorOffset,
|
|
10378
|
+
end: hit2.cursorOffset,
|
|
10379
|
+
affinity: hit2.affinity
|
|
10380
|
+
};
|
|
10381
|
+
this.state = this.runtime.updateSelection(this.state, newSelection, {
|
|
10382
|
+
kind: "dom"
|
|
10383
|
+
});
|
|
10384
|
+
this.applySelection(this.state.selection);
|
|
10385
|
+
(_b = this.onSelectionChange) == null ? void 0 : _b.call(this, this.state.selection);
|
|
10386
|
+
this.scheduleOverlayUpdate();
|
|
10387
|
+
return;
|
|
10388
|
+
}
|
|
10389
|
+
} else {
|
|
10390
|
+
this.suppressSelectionChange = true;
|
|
9945
10391
|
this.pendingClickHit = hit2;
|
|
10392
|
+
const newSelection = {
|
|
10393
|
+
start: hit2.cursorOffset,
|
|
10394
|
+
end: hit2.cursorOffset,
|
|
10395
|
+
affinity: hit2.affinity
|
|
10396
|
+
};
|
|
10397
|
+
this.state = this.runtime.updateSelection(this.state, newSelection, {
|
|
10398
|
+
kind: "dom"
|
|
10399
|
+
});
|
|
10400
|
+
this.applySelection(this.state.selection);
|
|
10401
|
+
(_c = this.onSelectionChange) == null ? void 0 : _c.call(this, this.state.selection);
|
|
10402
|
+
this.scheduleOverlayUpdate();
|
|
10403
|
+
return;
|
|
9946
10404
|
}
|
|
9947
|
-
return;
|
|
9948
10405
|
}
|
|
9949
10406
|
this.suppressSelectionChange = false;
|
|
9950
10407
|
const selStart = Math.min(selection.start, selection.end);
|
|
@@ -10056,10 +10513,6 @@ class CakeEngine {
|
|
|
10056
10513
|
}
|
|
10057
10514
|
handlePointerUp(event) {
|
|
10058
10515
|
this.blockTrustedTextDrag = false;
|
|
10059
|
-
if (this.pendingClickHit) {
|
|
10060
|
-
this.pendingClickHit = null;
|
|
10061
|
-
this.suppressSelectionChange = false;
|
|
10062
|
-
}
|
|
10063
10516
|
if (this.selectionDragState) {
|
|
10064
10517
|
if (event.pointerId !== this.selectionDragState.pointerId) {
|
|
10065
10518
|
return;
|
|
@@ -10559,7 +11012,7 @@ function findOffsetInTextNode(textNode, clientX, clientY) {
|
|
|
10559
11012
|
let closestDistance = Infinity;
|
|
10560
11013
|
let closestYDistance = Infinity;
|
|
10561
11014
|
let closestCaretX = 0;
|
|
10562
|
-
let
|
|
11015
|
+
let selectedViaRightEdge = false;
|
|
10563
11016
|
const rowInfo = /* @__PURE__ */ new Map();
|
|
10564
11017
|
const range = document.createRange();
|
|
10565
11018
|
let lastCharRect = null;
|
|
@@ -10628,15 +11081,28 @@ function findOffsetInTextNode(textNode, clientX, clientY) {
|
|
|
10628
11081
|
closestDistance = xDistance;
|
|
10629
11082
|
closestOffset = i;
|
|
10630
11083
|
closestCaretX = caretX;
|
|
10631
|
-
|
|
11084
|
+
bestRect.top;
|
|
10632
11085
|
closestYDistance = yDistance;
|
|
11086
|
+
selectedViaRightEdge = false;
|
|
11087
|
+
}
|
|
11088
|
+
if (i < text.length) {
|
|
11089
|
+
const rightEdgeX = bestRect.right;
|
|
11090
|
+
const rightEdgeDistance = Math.abs(clientX - rightEdgeX);
|
|
11091
|
+
if (rightEdgeDistance < closestDistance) {
|
|
11092
|
+
closestDistance = rightEdgeDistance;
|
|
11093
|
+
closestOffset = i + 1;
|
|
11094
|
+
closestCaretX = rightEdgeX;
|
|
11095
|
+
bestRect.top;
|
|
11096
|
+
closestYDistance = yDistance;
|
|
11097
|
+
selectedViaRightEdge = true;
|
|
11098
|
+
}
|
|
10633
11099
|
}
|
|
10634
11100
|
} else if (yDistance < closestYDistance || yDistance === closestYDistance && xDistance < closestDistance) {
|
|
10635
11101
|
closestYDistance = yDistance;
|
|
10636
11102
|
closestDistance = xDistance;
|
|
10637
11103
|
closestOffset = i;
|
|
10638
11104
|
closestCaretX = caretX;
|
|
10639
|
-
|
|
11105
|
+
bestRect.top;
|
|
10640
11106
|
}
|
|
10641
11107
|
}
|
|
10642
11108
|
let closestRow = null;
|
|
@@ -10661,11 +11127,11 @@ function findOffsetInTextNode(textNode, clientX, clientY) {
|
|
|
10661
11127
|
if (clientX < closestRow.left) {
|
|
10662
11128
|
closestOffset = closestRow.startOffset;
|
|
10663
11129
|
closestCaretX = closestRow.left;
|
|
10664
|
-
|
|
11130
|
+
closestRow.top;
|
|
10665
11131
|
} else if (clientX > closestRow.right) {
|
|
10666
|
-
closestOffset = closestRow.endOffset;
|
|
11132
|
+
closestOffset = Math.min(closestRow.endOffset + 1, text.length);
|
|
10667
11133
|
closestCaretX = closestRow.right;
|
|
10668
|
-
|
|
11134
|
+
closestRow.top;
|
|
10669
11135
|
} else if (clientY < closestRow.top || clientY > closestRow.bottom) {
|
|
10670
11136
|
let bestXDistance = Infinity;
|
|
10671
11137
|
const range2 = document.createRange();
|
|
@@ -10685,12 +11151,12 @@ function findOffsetInTextNode(textNode, clientX, clientY) {
|
|
|
10685
11151
|
bestXDistance = xDist;
|
|
10686
11152
|
closestOffset = i;
|
|
10687
11153
|
closestCaretX = rect.left;
|
|
10688
|
-
|
|
11154
|
+
closestRow.top;
|
|
10689
11155
|
}
|
|
10690
11156
|
}
|
|
10691
11157
|
}
|
|
10692
11158
|
}
|
|
10693
|
-
const pastRowEnd = closestRow !== null && clientX > closestRow.right
|
|
11159
|
+
const pastRowEnd = selectedViaRightEdge || closestRow !== null && clientX > closestRow.right;
|
|
10694
11160
|
if (Math.abs(clientX - closestCaretX) <= 2 && closestOffset < text.length && text[closestOffset] === "\n") {
|
|
10695
11161
|
closestOffset = Math.max(0, closestOffset - 1);
|
|
10696
11162
|
}
|
|
@@ -11143,8 +11609,9 @@ const CakeEditor = require$$0.forwardRef(
|
|
|
11143
11609
|
const lastEmittedSelectionRef = require$$0.useRef(null);
|
|
11144
11610
|
const [overlayRoot, setOverlayRoot] = require$$0.useState(null);
|
|
11145
11611
|
const [contentRoot, setContentRoot] = require$$0.useState(null);
|
|
11612
|
+
const baseExtensions = props.disableImageExtension ? bundledExtensionsWithoutImage : bundledExtensions;
|
|
11146
11613
|
const allExtensionsRef = require$$0.useRef([
|
|
11147
|
-
...
|
|
11614
|
+
...baseExtensions,
|
|
11148
11615
|
...props.extensions ?? []
|
|
11149
11616
|
]);
|
|
11150
11617
|
require$$0.useEffect(() => {
|
|
@@ -11302,6 +11769,10 @@ const CakeEditor = require$$0.forwardRef(
|
|
|
11302
11769
|
}
|
|
11303
11770
|
return { start: selection.start, end: selection.end };
|
|
11304
11771
|
},
|
|
11772
|
+
getCursorLength: () => {
|
|
11773
|
+
var _a;
|
|
11774
|
+
return ((_a = engineRef.current) == null ? void 0 : _a.getCursorLength()) ?? 0;
|
|
11775
|
+
},
|
|
11305
11776
|
insertText: (text) => {
|
|
11306
11777
|
var _a;
|
|
11307
11778
|
(_a = engineRef.current) == null ? void 0 : _a.insertText(text);
|
|
@@ -11355,6 +11826,10 @@ const CakeEditor = require$$0.forwardRef(
|
|
|
11355
11826
|
}
|
|
11356
11827
|
const focus = selection.start === selection.end ? selection.start : Math.max(selection.start, selection.end);
|
|
11357
11828
|
return { start: focus, end: focus };
|
|
11829
|
+
},
|
|
11830
|
+
executeCommand: (command) => {
|
|
11831
|
+
var _a;
|
|
11832
|
+
return ((_a = engineRef.current) == null ? void 0 : _a.executeCommand(command)) ?? false;
|
|
11358
11833
|
}
|
|
11359
11834
|
} : null;
|
|
11360
11835
|
const hasOverlayExtensions = allExtensionsRef.current.some(
|
|
@@ -11386,6 +11861,7 @@ exports.CakeEngine = CakeEngine;
|
|
|
11386
11861
|
exports.blockquoteExtension = blockquoteExtension;
|
|
11387
11862
|
exports.boldExtension = boldExtension;
|
|
11388
11863
|
exports.bundledExtensions = bundledExtensions;
|
|
11864
|
+
exports.bundledExtensionsWithoutImage = bundledExtensionsWithoutImage;
|
|
11389
11865
|
exports.combinedEmphasisExtension = combinedEmphasisExtension;
|
|
11390
11866
|
exports.headingExtension = headingExtension;
|
|
11391
11867
|
exports.imageExtension = imageExtension;
|