@blankdotpage/cake 0.1.6 → 0.1.7
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/engine/cake-engine.d.ts +8 -1
- package/dist/cake/engine/selection/selection-layout-dom.d.ts +12 -0
- package/dist/cake/index.d.ts +1 -0
- package/dist/cake/react/CakeEditor.d.ts +17 -3
- package/dist/index.cjs +714 -726
- package/dist/index.d.ts +1 -1
- package/dist/index.js +596 -608
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
3
3
|
const require$$0 = require("react");
|
|
4
4
|
const lucideReact = require("lucide-react");
|
|
5
5
|
const TurndownService = require("turndown");
|
|
6
|
-
const state = require("@codemirror/state");
|
|
7
6
|
var jsxRuntime = { exports: {} };
|
|
8
7
|
var reactJsxRuntime_production_min = {};
|
|
9
8
|
/**
|
|
@@ -1305,14 +1304,14 @@ function createRuntime(extensions) {
|
|
|
1305
1304
|
runtime
|
|
1306
1305
|
};
|
|
1307
1306
|
}
|
|
1308
|
-
function applyEdit(command,
|
|
1307
|
+
function applyEdit(command, state) {
|
|
1309
1308
|
while (true) {
|
|
1310
1309
|
let delegated = false;
|
|
1311
1310
|
for (const extension of extensions) {
|
|
1312
1311
|
if (!extension.onEdit) {
|
|
1313
1312
|
continue;
|
|
1314
1313
|
}
|
|
1315
|
-
const result = extension.onEdit(command,
|
|
1314
|
+
const result = extension.onEdit(command, state);
|
|
1316
1315
|
if (!result) {
|
|
1317
1316
|
continue;
|
|
1318
1317
|
}
|
|
@@ -1327,12 +1326,12 @@ function createRuntime(extensions) {
|
|
|
1327
1326
|
break;
|
|
1328
1327
|
}
|
|
1329
1328
|
}
|
|
1330
|
-
const selection = normalizeSelection$1(
|
|
1329
|
+
const selection = normalizeSelection$1(state.selection);
|
|
1331
1330
|
if (isStructuralEdit(command)) {
|
|
1332
|
-
const structural = applyStructuralEdit(command,
|
|
1331
|
+
const structural = applyStructuralEdit(command, state.doc, selection);
|
|
1333
1332
|
if (!structural) {
|
|
1334
1333
|
if (command.type === "delete-backward" || command.type === "delete-forward") {
|
|
1335
|
-
const cursorLength =
|
|
1334
|
+
const cursorLength = state.map.cursorLength;
|
|
1336
1335
|
const cursorStart = Math.max(
|
|
1337
1336
|
0,
|
|
1338
1337
|
Math.min(cursorLength, Math.min(selection.start, selection.end))
|
|
@@ -1343,22 +1342,22 @@ function createRuntime(extensions) {
|
|
|
1343
1342
|
);
|
|
1344
1343
|
if (cursorStart === cursorEnd) {
|
|
1345
1344
|
if (command.type === "delete-backward" && cursorStart === 0) {
|
|
1346
|
-
return
|
|
1345
|
+
return state;
|
|
1347
1346
|
}
|
|
1348
1347
|
if (command.type === "delete-forward" && cursorStart === cursorLength) {
|
|
1349
|
-
return
|
|
1348
|
+
return state;
|
|
1350
1349
|
}
|
|
1351
1350
|
}
|
|
1352
1351
|
const range = cursorStart === cursorEnd ? command.type === "delete-backward" ? { start: cursorStart - 1, end: cursorStart } : { start: cursorStart, end: cursorStart + 1 } : { start: cursorStart, end: cursorEnd };
|
|
1353
1352
|
const fullDocDelete = range.start === 0 && range.end === cursorLength;
|
|
1354
|
-
const from = fullDocDelete ? 0 :
|
|
1355
|
-
const to = fullDocDelete ?
|
|
1356
|
-
const fromClamped = Math.max(0, Math.min(from,
|
|
1353
|
+
const from = fullDocDelete ? 0 : state.map.cursorToSource(range.start, "backward");
|
|
1354
|
+
const to = fullDocDelete ? state.source.length : state.map.cursorToSource(range.end, "forward");
|
|
1355
|
+
const fromClamped = Math.max(0, Math.min(from, state.source.length));
|
|
1357
1356
|
const toClamped = Math.max(
|
|
1358
1357
|
fromClamped,
|
|
1359
|
-
Math.min(to,
|
|
1358
|
+
Math.min(to, state.source.length)
|
|
1360
1359
|
);
|
|
1361
|
-
const nextSource =
|
|
1360
|
+
const nextSource = state.source.slice(0, fromClamped) + state.source.slice(toClamped);
|
|
1362
1361
|
const next2 = createState(nextSource);
|
|
1363
1362
|
const caretCursor2 = next2.map.sourceToCursor(fromClamped, "forward");
|
|
1364
1363
|
return {
|
|
@@ -1371,7 +1370,7 @@ function createRuntime(extensions) {
|
|
|
1371
1370
|
};
|
|
1372
1371
|
}
|
|
1373
1372
|
if (command.type === "insert" || command.type === "insert-line-break") {
|
|
1374
|
-
const cursorLength =
|
|
1373
|
+
const cursorLength = state.map.cursorLength;
|
|
1375
1374
|
const cursorStart = Math.max(
|
|
1376
1375
|
0,
|
|
1377
1376
|
Math.min(cursorLength, Math.min(selection.start, selection.end))
|
|
@@ -1382,15 +1381,15 @@ function createRuntime(extensions) {
|
|
|
1382
1381
|
);
|
|
1383
1382
|
const range = { start: cursorStart, end: cursorEnd };
|
|
1384
1383
|
const fullDocReplace = range.start === 0 && range.end === cursorLength;
|
|
1385
|
-
const from = fullDocReplace ? 0 :
|
|
1386
|
-
const to = fullDocReplace ?
|
|
1387
|
-
const fromClamped = Math.max(0, Math.min(from,
|
|
1384
|
+
const from = fullDocReplace ? 0 : state.map.cursorToSource(range.start, "backward");
|
|
1385
|
+
const to = fullDocReplace ? state.source.length : state.map.cursorToSource(range.end, "forward");
|
|
1386
|
+
const fromClamped = Math.max(0, Math.min(from, state.source.length));
|
|
1388
1387
|
const toClamped = Math.max(
|
|
1389
1388
|
fromClamped,
|
|
1390
|
-
Math.min(to,
|
|
1389
|
+
Math.min(to, state.source.length)
|
|
1391
1390
|
);
|
|
1392
1391
|
const insertText = command.type === "insert" ? command.text : "\n";
|
|
1393
|
-
const nextSource =
|
|
1392
|
+
const nextSource = state.source.slice(0, fromClamped) + insertText + state.source.slice(toClamped);
|
|
1394
1393
|
const next2 = createState(nextSource);
|
|
1395
1394
|
const caretSource2 = fromClamped + insertText.length;
|
|
1396
1395
|
const caretCursor2 = next2.map.sourceToCursor(caretSource2, "forward");
|
|
@@ -1403,7 +1402,7 @@ function createRuntime(extensions) {
|
|
|
1403
1402
|
}
|
|
1404
1403
|
};
|
|
1405
1404
|
}
|
|
1406
|
-
return
|
|
1405
|
+
return state;
|
|
1407
1406
|
}
|
|
1408
1407
|
const interim = createStateFromDoc(structural.doc);
|
|
1409
1408
|
const interimAffinity = structural.nextAffinity ?? "forward";
|
|
@@ -1423,15 +1422,15 @@ function createRuntime(extensions) {
|
|
|
1423
1422
|
};
|
|
1424
1423
|
}
|
|
1425
1424
|
if (command.type === "indent" || command.type === "outdent") {
|
|
1426
|
-
return
|
|
1425
|
+
return state;
|
|
1427
1426
|
}
|
|
1428
1427
|
if (command.type === "toggle-bullet-list" || command.type === "toggle-numbered-list") {
|
|
1429
|
-
return
|
|
1428
|
+
return state;
|
|
1430
1429
|
}
|
|
1431
1430
|
if (command.type === "toggle-inline") {
|
|
1432
|
-
return applyInlineToggle(
|
|
1431
|
+
return applyInlineToggle(state, command.marker);
|
|
1433
1432
|
}
|
|
1434
|
-
return
|
|
1433
|
+
return state;
|
|
1435
1434
|
}
|
|
1436
1435
|
function applyStructuralEdit(command, doc, selection) {
|
|
1437
1436
|
var _a;
|
|
@@ -2210,16 +2209,16 @@ function createRuntime(extensions) {
|
|
|
2210
2209
|
}
|
|
2211
2210
|
return true;
|
|
2212
2211
|
}
|
|
2213
|
-
function applyInlineToggle(
|
|
2214
|
-
const selection = normalizeSelection$1(
|
|
2215
|
-
const source =
|
|
2216
|
-
const map =
|
|
2212
|
+
function applyInlineToggle(state, marker) {
|
|
2213
|
+
const selection = normalizeSelection$1(state.selection);
|
|
2214
|
+
const source = state.source;
|
|
2215
|
+
const map = state.map;
|
|
2217
2216
|
if (selection.start === selection.end) {
|
|
2218
2217
|
const caret = selection.start;
|
|
2219
2218
|
const markerLen2 = marker.length;
|
|
2220
2219
|
const markerKind2 = toggleMarkerToKind.get(marker) ?? null;
|
|
2221
2220
|
if (markerKind2) {
|
|
2222
|
-
const around = marksAroundCursor(
|
|
2221
|
+
const around = marksAroundCursor(state.doc, caret);
|
|
2223
2222
|
if (isMarksPrefix(around.right, around.left) && around.left.length > around.right.length) {
|
|
2224
2223
|
const exiting = around.left.slice(around.right.length);
|
|
2225
2224
|
if (exiting.some((mark) => mark.kind === markerKind2)) {
|
|
@@ -2249,7 +2248,7 @@ function createRuntime(extensions) {
|
|
|
2249
2248
|
}
|
|
2250
2249
|
}
|
|
2251
2250
|
return {
|
|
2252
|
-
...
|
|
2251
|
+
...state,
|
|
2253
2252
|
selection: {
|
|
2254
2253
|
start: caret,
|
|
2255
2254
|
end: caret,
|
|
@@ -2295,12 +2294,12 @@ function createRuntime(extensions) {
|
|
|
2295
2294
|
const selectedText = source.slice(from, to);
|
|
2296
2295
|
const markerLen = marker.length;
|
|
2297
2296
|
const markerKind = toggleMarkerToKind.get(marker) ?? null;
|
|
2298
|
-
const linesForSelection = flattenDocToLines(
|
|
2297
|
+
const linesForSelection = flattenDocToLines(state.doc);
|
|
2299
2298
|
const commonMarks = markerKind ? commonMarksAcrossSelection(
|
|
2300
2299
|
linesForSelection,
|
|
2301
2300
|
cursorStart,
|
|
2302
2301
|
cursorEnd,
|
|
2303
|
-
|
|
2302
|
+
state.doc
|
|
2304
2303
|
) : [];
|
|
2305
2304
|
const hasCommonMark = markerKind !== null && commonMarks.some((mark) => mark.kind === markerKind);
|
|
2306
2305
|
const canUnwrap = markerKind ? hasCommonMark : true;
|
|
@@ -2375,7 +2374,7 @@ function createRuntime(extensions) {
|
|
|
2375
2374
|
}
|
|
2376
2375
|
}
|
|
2377
2376
|
if (edits.length === 0) {
|
|
2378
|
-
return
|
|
2377
|
+
return state;
|
|
2379
2378
|
}
|
|
2380
2379
|
edits.sort((a, b) => b.from - a.from);
|
|
2381
2380
|
let newSource2 = source;
|
|
@@ -2417,15 +2416,15 @@ function createRuntime(extensions) {
|
|
|
2417
2416
|
}
|
|
2418
2417
|
};
|
|
2419
2418
|
}
|
|
2420
|
-
function updateSelection(
|
|
2419
|
+
function updateSelection(state, selection, options) {
|
|
2421
2420
|
const normalized = normalizeSelection$1(selection);
|
|
2422
|
-
const cursorLength =
|
|
2421
|
+
const cursorLength = state.map.cursorLength;
|
|
2423
2422
|
const start = Math.max(0, Math.min(cursorLength, normalized.start));
|
|
2424
2423
|
const end = Math.max(0, Math.min(cursorLength, normalized.end));
|
|
2425
2424
|
const kind = (options == null ? void 0 : options.kind) ?? "programmatic";
|
|
2426
2425
|
let affinity = normalized.affinity ?? "forward";
|
|
2427
2426
|
if (start === end) {
|
|
2428
|
-
const around = marksAroundCursor(
|
|
2427
|
+
const around = marksAroundCursor(state.doc, start);
|
|
2429
2428
|
if (kind === "keyboard") {
|
|
2430
2429
|
affinity = preferredTypingAffinityAtGap(
|
|
2431
2430
|
around.left,
|
|
@@ -2444,13 +2443,13 @@ function createRuntime(extensions) {
|
|
|
2444
2443
|
}
|
|
2445
2444
|
}
|
|
2446
2445
|
return {
|
|
2447
|
-
...
|
|
2446
|
+
...state,
|
|
2448
2447
|
selection: { start, end, affinity }
|
|
2449
2448
|
};
|
|
2450
2449
|
}
|
|
2451
|
-
function serializeSelection(
|
|
2450
|
+
function serializeSelection(state, selection) {
|
|
2452
2451
|
const normalized = normalizeSelection$1(selection);
|
|
2453
|
-
const lines = flattenDocToLines(
|
|
2452
|
+
const lines = flattenDocToLines(state.doc);
|
|
2454
2453
|
const docCursorLength = cursorLengthForLines(lines);
|
|
2455
2454
|
const cursorStart = Math.max(
|
|
2456
2455
|
0,
|
|
@@ -2471,7 +2470,7 @@ function createRuntime(extensions) {
|
|
|
2471
2470
|
if (!line) {
|
|
2472
2471
|
continue;
|
|
2473
2472
|
}
|
|
2474
|
-
const block = getBlockAtPath(
|
|
2473
|
+
const block = getBlockAtPath(state.doc.blocks, line.path);
|
|
2475
2474
|
if (!block || block.type !== "paragraph") {
|
|
2476
2475
|
continue;
|
|
2477
2476
|
}
|
|
@@ -2483,7 +2482,7 @@ function createRuntime(extensions) {
|
|
|
2483
2482
|
const paragraph = { type: "paragraph", content };
|
|
2484
2483
|
if (line.path.length > 1) {
|
|
2485
2484
|
const wrapperPath = line.path.slice(0, -1);
|
|
2486
|
-
const wrapper = getBlockAtPath(
|
|
2485
|
+
const wrapper = getBlockAtPath(state.doc.blocks, wrapperPath);
|
|
2487
2486
|
if (wrapper && wrapper.type === "block-wrapper") {
|
|
2488
2487
|
blocks.push({
|
|
2489
2488
|
type: "block-wrapper",
|
|
@@ -2526,9 +2525,9 @@ function createRuntime(extensions) {
|
|
|
2526
2525
|
}
|
|
2527
2526
|
return html;
|
|
2528
2527
|
}
|
|
2529
|
-
function serializeSelectionToHtml(
|
|
2528
|
+
function serializeSelectionToHtml(state, selection) {
|
|
2530
2529
|
const normalized = normalizeSelection$1(selection);
|
|
2531
|
-
const lines = flattenDocToLines(
|
|
2530
|
+
const lines = flattenDocToLines(state.doc);
|
|
2532
2531
|
const docCursorLength = cursorLengthForLines(lines);
|
|
2533
2532
|
const cursorStart = Math.max(
|
|
2534
2533
|
0,
|
|
@@ -2564,7 +2563,7 @@ function createRuntime(extensions) {
|
|
|
2564
2563
|
if (!line) {
|
|
2565
2564
|
continue;
|
|
2566
2565
|
}
|
|
2567
|
-
const block = getBlockAtPath(
|
|
2566
|
+
const block = getBlockAtPath(state.doc.blocks, line.path);
|
|
2568
2567
|
if (!block || block.type !== "paragraph") {
|
|
2569
2568
|
continue;
|
|
2570
2569
|
}
|
|
@@ -2576,7 +2575,7 @@ function createRuntime(extensions) {
|
|
|
2576
2575
|
let wrapperData;
|
|
2577
2576
|
if (line.path.length > 1) {
|
|
2578
2577
|
const wrapperPath = line.path.slice(0, -1);
|
|
2579
|
-
const wrapper = getBlockAtPath(
|
|
2578
|
+
const wrapper = getBlockAtPath(state.doc.blocks, wrapperPath);
|
|
2580
2579
|
if (wrapper && wrapper.type === "block-wrapper") {
|
|
2581
2580
|
wrapperKind = wrapper.kind;
|
|
2582
2581
|
wrapperData = wrapper.data;
|
|
@@ -3375,10 +3374,16 @@ const boldExtension = defineExtension({
|
|
|
3375
3374
|
name: "bold",
|
|
3376
3375
|
toggleInline: { kind: BOLD_KIND$1, markers: ["**"] },
|
|
3377
3376
|
keybindings: [
|
|
3378
|
-
{ key: "b", meta: true, command: { type: "toggle-
|
|
3379
|
-
{ key: "b", ctrl: true, command: { type: "toggle-
|
|
3377
|
+
{ key: "b", meta: true, command: { type: "toggle-bold" } },
|
|
3378
|
+
{ key: "b", ctrl: true, command: { type: "toggle-bold" } }
|
|
3380
3379
|
],
|
|
3381
3380
|
inlineWrapperAffinity: [{ kind: BOLD_KIND$1, inclusive: true }],
|
|
3381
|
+
onEdit(command) {
|
|
3382
|
+
if (command.type === "toggle-bold") {
|
|
3383
|
+
return { type: "toggle-inline", marker: "**" };
|
|
3384
|
+
}
|
|
3385
|
+
return null;
|
|
3386
|
+
},
|
|
3382
3387
|
parseInline(source, start, end, context) {
|
|
3383
3388
|
if (source.slice(start, start + 3) === "***") {
|
|
3384
3389
|
const close2 = source.indexOf("***", start + 3);
|
|
@@ -3559,14 +3564,14 @@ function CakeLinkPopover(params) {
|
|
|
3559
3564
|
const anchorRef = require$$0.useRef(null);
|
|
3560
3565
|
const popoverRef = require$$0.useRef(null);
|
|
3561
3566
|
const inputRef = require$$0.useRef(null);
|
|
3562
|
-
const [
|
|
3563
|
-
const isEditing =
|
|
3567
|
+
const [state, setState] = require$$0.useState({ status: "closed" });
|
|
3568
|
+
const isEditing = state.status === "open" ? state.isEditing : false;
|
|
3564
3569
|
const close = require$$0.useCallback(() => {
|
|
3565
3570
|
anchorRef.current = null;
|
|
3566
3571
|
setState({ status: "closed" });
|
|
3567
3572
|
}, []);
|
|
3568
3573
|
const reposition = require$$0.useCallback(() => {
|
|
3569
|
-
if (
|
|
3574
|
+
if (state.status !== "open") {
|
|
3570
3575
|
return;
|
|
3571
3576
|
}
|
|
3572
3577
|
const anchor = anchorRef.current;
|
|
@@ -3583,7 +3588,7 @@ function CakeLinkPopover(params) {
|
|
|
3583
3588
|
position: getPopoverPosition({ anchor, toOverlayRect })
|
|
3584
3589
|
};
|
|
3585
3590
|
});
|
|
3586
|
-
}, [close,
|
|
3591
|
+
}, [close, state.status, toOverlayRect]);
|
|
3587
3592
|
const openForLink = require$$0.useCallback(
|
|
3588
3593
|
(link, options) => {
|
|
3589
3594
|
anchorRef.current = link;
|
|
@@ -3599,18 +3604,18 @@ function CakeLinkPopover(params) {
|
|
|
3599
3604
|
[toOverlayRect]
|
|
3600
3605
|
);
|
|
3601
3606
|
require$$0.useEffect(() => {
|
|
3602
|
-
if (
|
|
3607
|
+
if (state.status !== "open") {
|
|
3603
3608
|
return;
|
|
3604
3609
|
}
|
|
3605
3610
|
reposition();
|
|
3606
|
-
}, [reposition,
|
|
3611
|
+
}, [reposition, state.status, isEditing]);
|
|
3607
3612
|
require$$0.useEffect(() => {
|
|
3608
3613
|
var _a;
|
|
3609
|
-
if (
|
|
3614
|
+
if (state.status !== "open" || !isEditing) {
|
|
3610
3615
|
return;
|
|
3611
3616
|
}
|
|
3612
3617
|
(_a = inputRef.current) == null ? void 0 : _a.focus();
|
|
3613
|
-
}, [
|
|
3618
|
+
}, [state.status, isEditing]);
|
|
3614
3619
|
require$$0.useEffect(() => {
|
|
3615
3620
|
function handleContentClick(event) {
|
|
3616
3621
|
const link = getLinkFromEventTarget(event.target);
|
|
@@ -3653,7 +3658,7 @@ function CakeLinkPopover(params) {
|
|
|
3653
3658
|
};
|
|
3654
3659
|
}, [contentRoot, openForLink]);
|
|
3655
3660
|
require$$0.useEffect(() => {
|
|
3656
|
-
if (
|
|
3661
|
+
if (state.status !== "open") {
|
|
3657
3662
|
return;
|
|
3658
3663
|
}
|
|
3659
3664
|
container.addEventListener("scroll", close, { passive: true });
|
|
@@ -3662,7 +3667,7 @@ function CakeLinkPopover(params) {
|
|
|
3662
3667
|
container.removeEventListener("scroll", close);
|
|
3663
3668
|
window.removeEventListener("resize", reposition);
|
|
3664
3669
|
};
|
|
3665
|
-
}, [close, container, reposition,
|
|
3670
|
+
}, [close, container, reposition, state.status]);
|
|
3666
3671
|
const handleMouseDown = require$$0.useCallback(
|
|
3667
3672
|
(event) => {
|
|
3668
3673
|
event.stopPropagation();
|
|
@@ -3673,10 +3678,10 @@ function CakeLinkPopover(params) {
|
|
|
3673
3678
|
},
|
|
3674
3679
|
[]
|
|
3675
3680
|
);
|
|
3676
|
-
if (
|
|
3681
|
+
if (state.status !== "open") {
|
|
3677
3682
|
return null;
|
|
3678
3683
|
}
|
|
3679
|
-
const displayUrl = ensureHttpsProtocol(
|
|
3684
|
+
const displayUrl = ensureHttpsProtocol(state.url);
|
|
3680
3685
|
const handleEdit = () => {
|
|
3681
3686
|
setState((current) => {
|
|
3682
3687
|
if (current.status !== "open") {
|
|
@@ -3695,10 +3700,10 @@ function CakeLinkPopover(params) {
|
|
|
3695
3700
|
};
|
|
3696
3701
|
const handleSave = () => {
|
|
3697
3702
|
var _a;
|
|
3698
|
-
if (
|
|
3703
|
+
if (state.status !== "open") {
|
|
3699
3704
|
return;
|
|
3700
3705
|
}
|
|
3701
|
-
const draftValue = ((_a = inputRef.current) == null ? void 0 : _a.value) ??
|
|
3706
|
+
const draftValue = ((_a = inputRef.current) == null ? void 0 : _a.value) ?? state.draftUrl;
|
|
3702
3707
|
const trimmed = draftValue.trim();
|
|
3703
3708
|
if (!trimmed) {
|
|
3704
3709
|
close();
|
|
@@ -3712,7 +3717,7 @@ function CakeLinkPopover(params) {
|
|
|
3712
3717
|
url: nextUrl,
|
|
3713
3718
|
isEditing: false,
|
|
3714
3719
|
draftUrl: nextUrl,
|
|
3715
|
-
position:
|
|
3720
|
+
position: state.position
|
|
3716
3721
|
});
|
|
3717
3722
|
};
|
|
3718
3723
|
const handleOpen = () => {
|
|
@@ -3744,13 +3749,13 @@ function CakeLinkPopover(params) {
|
|
|
3744
3749
|
ref: popoverRef,
|
|
3745
3750
|
style: {
|
|
3746
3751
|
position: "absolute",
|
|
3747
|
-
top:
|
|
3748
|
-
left:
|
|
3752
|
+
top: state.position.top,
|
|
3753
|
+
left: state.position.left,
|
|
3749
3754
|
pointerEvents: "auto"
|
|
3750
3755
|
},
|
|
3751
3756
|
onMouseDown: handleMouseDown,
|
|
3752
3757
|
onClick: (event) => event.stopPropagation(),
|
|
3753
|
-
children:
|
|
3758
|
+
children: state.isEditing ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
3754
3759
|
"form",
|
|
3755
3760
|
{
|
|
3756
3761
|
className: "cake-link-editor",
|
|
@@ -3764,7 +3769,7 @@ function CakeLinkPopover(params) {
|
|
|
3764
3769
|
{
|
|
3765
3770
|
className: "cake-link-input",
|
|
3766
3771
|
type: "text",
|
|
3767
|
-
value:
|
|
3772
|
+
value: state.draftUrl,
|
|
3768
3773
|
ref: inputRef,
|
|
3769
3774
|
onChange: (event) => {
|
|
3770
3775
|
setState((current) => {
|
|
@@ -4036,8 +4041,8 @@ const linkExtension = defineExtension({
|
|
|
4036
4041
|
key: "u",
|
|
4037
4042
|
meta: true,
|
|
4038
4043
|
shift: true,
|
|
4039
|
-
command: (
|
|
4040
|
-
if (
|
|
4044
|
+
command: (state) => {
|
|
4045
|
+
if (state.selection.start === state.selection.end) {
|
|
4041
4046
|
return null;
|
|
4042
4047
|
}
|
|
4043
4048
|
return { type: "wrap-link", openPopover: true };
|
|
@@ -4047,19 +4052,19 @@ const linkExtension = defineExtension({
|
|
|
4047
4052
|
key: "u",
|
|
4048
4053
|
ctrl: true,
|
|
4049
4054
|
shift: true,
|
|
4050
|
-
command: (
|
|
4051
|
-
if (
|
|
4055
|
+
command: (state) => {
|
|
4056
|
+
if (state.selection.start === state.selection.end) {
|
|
4052
4057
|
return null;
|
|
4053
4058
|
}
|
|
4054
4059
|
return { type: "wrap-link", openPopover: true };
|
|
4055
4060
|
}
|
|
4056
4061
|
}
|
|
4057
4062
|
],
|
|
4058
|
-
onEdit(command,
|
|
4063
|
+
onEdit(command, state) {
|
|
4059
4064
|
if (command.type === "unlink") {
|
|
4060
4065
|
const cursorPos = command.start;
|
|
4061
|
-
const sourcePos =
|
|
4062
|
-
const source =
|
|
4066
|
+
const sourcePos = state.map.cursorToSource(cursorPos, "forward");
|
|
4067
|
+
const source = state.source;
|
|
4063
4068
|
let linkStart = sourcePos;
|
|
4064
4069
|
while (linkStart > 0 && source[linkStart] !== "[") {
|
|
4065
4070
|
linkStart--;
|
|
@@ -4077,7 +4082,7 @@ const linkExtension = defineExtension({
|
|
|
4077
4082
|
}
|
|
4078
4083
|
const label2 = source.slice(linkStart + 1, labelClose);
|
|
4079
4084
|
const nextSource2 = source.slice(0, linkStart) + label2 + source.slice(urlClose + 1);
|
|
4080
|
-
const newState =
|
|
4085
|
+
const newState = state.runtime.createState(nextSource2);
|
|
4081
4086
|
const labelEndSource = linkStart + label2.length;
|
|
4082
4087
|
const newCursor = newState.map.sourceToCursor(labelEndSource, "forward");
|
|
4083
4088
|
return {
|
|
@@ -4092,21 +4097,21 @@ const linkExtension = defineExtension({
|
|
|
4092
4097
|
if (command.type !== "wrap-link") {
|
|
4093
4098
|
return null;
|
|
4094
4099
|
}
|
|
4095
|
-
const selection =
|
|
4100
|
+
const selection = state.selection;
|
|
4096
4101
|
const cursorStart = Math.min(selection.start, selection.end);
|
|
4097
4102
|
const cursorEnd = Math.max(selection.start, selection.end);
|
|
4098
4103
|
if (cursorStart === cursorEnd) {
|
|
4099
4104
|
return null;
|
|
4100
4105
|
}
|
|
4101
|
-
const from =
|
|
4102
|
-
const to =
|
|
4106
|
+
const from = state.map.cursorToSource(cursorStart, "forward");
|
|
4107
|
+
const to = state.map.cursorToSource(cursorEnd, "backward");
|
|
4103
4108
|
if (from === to) {
|
|
4104
4109
|
return null;
|
|
4105
4110
|
}
|
|
4106
|
-
const label =
|
|
4111
|
+
const label = state.source.slice(from, to);
|
|
4107
4112
|
const url = command.url ?? "";
|
|
4108
4113
|
const linkMarkdown = `[${label}](${url})`;
|
|
4109
|
-
const nextSource =
|
|
4114
|
+
const nextSource = state.source.slice(0, from) + linkMarkdown + state.source.slice(to);
|
|
4110
4115
|
return {
|
|
4111
4116
|
source: nextSource,
|
|
4112
4117
|
selection: {
|
|
@@ -4116,16 +4121,16 @@ const linkExtension = defineExtension({
|
|
|
4116
4121
|
}
|
|
4117
4122
|
};
|
|
4118
4123
|
},
|
|
4119
|
-
onPasteText(text,
|
|
4124
|
+
onPasteText(text, state) {
|
|
4120
4125
|
if (!isUrl(text)) {
|
|
4121
4126
|
return null;
|
|
4122
4127
|
}
|
|
4123
4128
|
const url = ensureHttpsProtocol(text.trim());
|
|
4124
|
-
const selection =
|
|
4129
|
+
const selection = state.selection;
|
|
4125
4130
|
const start = Math.min(selection.start, selection.end);
|
|
4126
4131
|
const end = Math.max(selection.start, selection.end);
|
|
4127
4132
|
if (start !== end) {
|
|
4128
|
-
const lines = getDocLines(
|
|
4133
|
+
const lines = getDocLines(state.doc);
|
|
4129
4134
|
const visibleText = getVisibleText(lines);
|
|
4130
4135
|
const visibleStart = cursorOffsetToVisibleOffset(lines, start);
|
|
4131
4136
|
const visibleEnd = cursorOffsetToVisibleOffset(lines, end);
|
|
@@ -4297,8 +4302,61 @@ const pipeLinkExtension = defineExtension({
|
|
|
4297
4302
|
});
|
|
4298
4303
|
const BLOCKQUOTE_KIND = "blockquote";
|
|
4299
4304
|
const PREFIX = "> ";
|
|
4305
|
+
const BLOCKQUOTE_PATTERN = /^> /;
|
|
4306
|
+
function findLineStartInSource$1(source, sourceOffset) {
|
|
4307
|
+
let lineStart = sourceOffset;
|
|
4308
|
+
while (lineStart > 0 && source[lineStart - 1] !== "\n") {
|
|
4309
|
+
lineStart--;
|
|
4310
|
+
}
|
|
4311
|
+
return lineStart;
|
|
4312
|
+
}
|
|
4313
|
+
function handleToggleBlockquote(state) {
|
|
4314
|
+
const { source, selection, map, runtime } = state;
|
|
4315
|
+
const cursorPos = Math.min(selection.start, selection.end);
|
|
4316
|
+
const sourcePos = map.cursorToSource(
|
|
4317
|
+
cursorPos,
|
|
4318
|
+
selection.affinity ?? "forward"
|
|
4319
|
+
);
|
|
4320
|
+
const lineStart = findLineStartInSource$1(source, sourcePos);
|
|
4321
|
+
let lineEnd = source.indexOf("\n", lineStart);
|
|
4322
|
+
if (lineEnd === -1) {
|
|
4323
|
+
lineEnd = source.length;
|
|
4324
|
+
}
|
|
4325
|
+
const lineContent = source.slice(lineStart, lineEnd);
|
|
4326
|
+
const blockquoteMatch = lineContent.match(BLOCKQUOTE_PATTERN);
|
|
4327
|
+
let newSource;
|
|
4328
|
+
let newCursorOffset;
|
|
4329
|
+
if (blockquoteMatch) {
|
|
4330
|
+
newSource = source.slice(0, lineStart) + lineContent.slice(PREFIX.length) + source.slice(lineEnd);
|
|
4331
|
+
const cursorLineOffset = sourcePos - lineStart;
|
|
4332
|
+
if (cursorLineOffset >= PREFIX.length) {
|
|
4333
|
+
newCursorOffset = sourcePos - PREFIX.length;
|
|
4334
|
+
} else {
|
|
4335
|
+
newCursorOffset = lineStart;
|
|
4336
|
+
}
|
|
4337
|
+
} else {
|
|
4338
|
+
newSource = source.slice(0, lineStart) + PREFIX + lineContent + source.slice(lineEnd);
|
|
4339
|
+
newCursorOffset = sourcePos + PREFIX.length;
|
|
4340
|
+
}
|
|
4341
|
+
const next = runtime.createState(newSource);
|
|
4342
|
+
const caretCursor = next.map.sourceToCursor(newCursorOffset, "forward");
|
|
4343
|
+
return {
|
|
4344
|
+
source: newSource,
|
|
4345
|
+
selection: {
|
|
4346
|
+
start: caretCursor.cursorOffset,
|
|
4347
|
+
end: caretCursor.cursorOffset,
|
|
4348
|
+
affinity: "forward"
|
|
4349
|
+
}
|
|
4350
|
+
};
|
|
4351
|
+
}
|
|
4300
4352
|
const blockquoteExtension = defineExtension({
|
|
4301
4353
|
name: "blockquote",
|
|
4354
|
+
onEdit(command, state) {
|
|
4355
|
+
if (command.type === "toggle-blockquote") {
|
|
4356
|
+
return handleToggleBlockquote(state);
|
|
4357
|
+
}
|
|
4358
|
+
return null;
|
|
4359
|
+
},
|
|
4302
4360
|
parseBlock(source, start, context) {
|
|
4303
4361
|
if (source.slice(start, start + PREFIX.length) !== PREFIX) {
|
|
4304
4362
|
return null;
|
|
@@ -4361,6 +4419,7 @@ const blockquoteExtension = defineExtension({
|
|
|
4361
4419
|
return null;
|
|
4362
4420
|
}
|
|
4363
4421
|
const element = document.createElement("blockquote");
|
|
4422
|
+
element.setAttribute("data-block-wrapper", BLOCKQUOTE_KIND);
|
|
4364
4423
|
for (const node of context.renderBlocks(block.blocks)) {
|
|
4365
4424
|
element.append(node);
|
|
4366
4425
|
}
|
|
@@ -4372,10 +4431,16 @@ const italicExtension = defineExtension({
|
|
|
4372
4431
|
name: "italic",
|
|
4373
4432
|
toggleInline: { kind: ITALIC_KIND, markers: ["*", "_"] },
|
|
4374
4433
|
keybindings: [
|
|
4375
|
-
{ key: "i", meta: true, command: { type: "toggle-
|
|
4376
|
-
{ key: "i", ctrl: true, command: { type: "toggle-
|
|
4434
|
+
{ key: "i", meta: true, command: { type: "toggle-italic" } },
|
|
4435
|
+
{ key: "i", ctrl: true, command: { type: "toggle-italic" } }
|
|
4377
4436
|
],
|
|
4378
4437
|
inlineWrapperAffinity: [{ kind: ITALIC_KIND, inclusive: true }],
|
|
4438
|
+
onEdit(command) {
|
|
4439
|
+
if (command.type === "toggle-italic") {
|
|
4440
|
+
return { type: "toggle-inline", marker: "*" };
|
|
4441
|
+
}
|
|
4442
|
+
return null;
|
|
4443
|
+
},
|
|
4379
4444
|
parseInline(source, start, end, context) {
|
|
4380
4445
|
const char = source[start];
|
|
4381
4446
|
if (char !== "_" && char !== "*") {
|
|
@@ -4448,8 +4513,8 @@ function findLineStartInSource(source, sourceOffset) {
|
|
|
4448
4513
|
}
|
|
4449
4514
|
return lineStart;
|
|
4450
4515
|
}
|
|
4451
|
-
function handleDeleteBackward$1(
|
|
4452
|
-
const { source, selection, map } =
|
|
4516
|
+
function handleDeleteBackward$1(state) {
|
|
4517
|
+
const { source, selection, map } = state;
|
|
4453
4518
|
if (selection.start !== selection.end) {
|
|
4454
4519
|
return null;
|
|
4455
4520
|
}
|
|
@@ -4476,8 +4541,8 @@ function handleDeleteBackward$1(state2) {
|
|
|
4476
4541
|
}
|
|
4477
4542
|
};
|
|
4478
4543
|
}
|
|
4479
|
-
function handleMultilineInsertInHeading(
|
|
4480
|
-
const { source, selection, map, runtime } =
|
|
4544
|
+
function handleMultilineInsertInHeading(state, text) {
|
|
4545
|
+
const { source, selection, map, runtime } = state;
|
|
4481
4546
|
const normalizedText = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
4482
4547
|
if (!normalizedText.includes("\n")) {
|
|
4483
4548
|
return null;
|
|
@@ -4518,8 +4583,8 @@ function handleMultilineInsertInHeading(state2, text) {
|
|
|
4518
4583
|
}
|
|
4519
4584
|
};
|
|
4520
4585
|
}
|
|
4521
|
-
function shouldExitHeadingOnLineBreak(
|
|
4522
|
-
const { source, selection, map } =
|
|
4586
|
+
function shouldExitHeadingOnLineBreak(state) {
|
|
4587
|
+
const { source, selection, map } = state;
|
|
4523
4588
|
if (selection.start !== selection.end) {
|
|
4524
4589
|
return false;
|
|
4525
4590
|
}
|
|
@@ -4539,20 +4604,78 @@ function shouldExitHeadingOnLineBreak(state2) {
|
|
|
4539
4604
|
const contentStart = lineStart + marker.length;
|
|
4540
4605
|
return sourcePos >= contentStart && sourcePos <= lineEnd;
|
|
4541
4606
|
}
|
|
4607
|
+
function handleToggleHeading(state, targetLevel) {
|
|
4608
|
+
const { source, selection, map, runtime } = state;
|
|
4609
|
+
const cursorPos = Math.min(selection.start, selection.end);
|
|
4610
|
+
const sourcePos = map.cursorToSource(
|
|
4611
|
+
cursorPos,
|
|
4612
|
+
selection.affinity ?? "forward"
|
|
4613
|
+
);
|
|
4614
|
+
const lineStart = findLineStartInSource(source, sourcePos);
|
|
4615
|
+
let lineEnd = source.indexOf("\n", lineStart);
|
|
4616
|
+
if (lineEnd === -1) {
|
|
4617
|
+
lineEnd = source.length;
|
|
4618
|
+
}
|
|
4619
|
+
const lineContent = source.slice(lineStart, lineEnd);
|
|
4620
|
+
const headingMatch = lineContent.match(HEADING_PATTERN);
|
|
4621
|
+
let newSource;
|
|
4622
|
+
let newCursorOffset;
|
|
4623
|
+
if (headingMatch) {
|
|
4624
|
+
const currentLevel = headingMatch[1].length;
|
|
4625
|
+
const existingMarker = headingMatch[0];
|
|
4626
|
+
if (currentLevel === targetLevel) {
|
|
4627
|
+
newSource = source.slice(0, lineStart) + lineContent.slice(existingMarker.length) + source.slice(lineEnd);
|
|
4628
|
+
const cursorLineOffset = sourcePos - lineStart;
|
|
4629
|
+
if (cursorLineOffset >= existingMarker.length) {
|
|
4630
|
+
newCursorOffset = sourcePos - existingMarker.length;
|
|
4631
|
+
} else {
|
|
4632
|
+
newCursorOffset = lineStart;
|
|
4633
|
+
}
|
|
4634
|
+
} else {
|
|
4635
|
+
const newMarker = "#".repeat(targetLevel) + " ";
|
|
4636
|
+
newSource = source.slice(0, lineStart) + newMarker + lineContent.slice(existingMarker.length) + source.slice(lineEnd);
|
|
4637
|
+
const markerDiff = newMarker.length - existingMarker.length;
|
|
4638
|
+
const cursorLineOffset = sourcePos - lineStart;
|
|
4639
|
+
if (cursorLineOffset >= existingMarker.length) {
|
|
4640
|
+
newCursorOffset = sourcePos + markerDiff;
|
|
4641
|
+
} else {
|
|
4642
|
+
newCursorOffset = lineStart + newMarker.length;
|
|
4643
|
+
}
|
|
4644
|
+
}
|
|
4645
|
+
} else {
|
|
4646
|
+
const newMarker = "#".repeat(targetLevel) + " ";
|
|
4647
|
+
newSource = source.slice(0, lineStart) + newMarker + lineContent + source.slice(lineEnd);
|
|
4648
|
+
newCursorOffset = sourcePos + newMarker.length;
|
|
4649
|
+
}
|
|
4650
|
+
const next = runtime.createState(newSource);
|
|
4651
|
+
const caretCursor = next.map.sourceToCursor(newCursorOffset, "forward");
|
|
4652
|
+
return {
|
|
4653
|
+
source: newSource,
|
|
4654
|
+
selection: {
|
|
4655
|
+
start: caretCursor.cursorOffset,
|
|
4656
|
+
end: caretCursor.cursorOffset,
|
|
4657
|
+
affinity: "forward"
|
|
4658
|
+
}
|
|
4659
|
+
};
|
|
4660
|
+
}
|
|
4542
4661
|
const headingExtension = defineExtension({
|
|
4543
4662
|
name: "heading",
|
|
4544
|
-
onEdit(command,
|
|
4663
|
+
onEdit(command, state) {
|
|
4664
|
+
if (command.type === "toggle-heading") {
|
|
4665
|
+
const level = command.level ?? 1;
|
|
4666
|
+
return handleToggleHeading(state, level);
|
|
4667
|
+
}
|
|
4545
4668
|
if (command.type === "delete-backward") {
|
|
4546
|
-
return handleDeleteBackward$1(
|
|
4669
|
+
return handleDeleteBackward$1(state);
|
|
4547
4670
|
}
|
|
4548
4671
|
if (command.type === "insert-line-break") {
|
|
4549
|
-
if (shouldExitHeadingOnLineBreak(
|
|
4672
|
+
if (shouldExitHeadingOnLineBreak(state)) {
|
|
4550
4673
|
return { type: "exit-block-wrapper" };
|
|
4551
4674
|
}
|
|
4552
4675
|
return null;
|
|
4553
4676
|
}
|
|
4554
4677
|
if (command.type === "insert") {
|
|
4555
|
-
const multiline = handleMultilineInsertInHeading(
|
|
4678
|
+
const multiline = handleMultilineInsertInHeading(state, command.text);
|
|
4556
4679
|
if (multiline) {
|
|
4557
4680
|
return multiline;
|
|
4558
4681
|
}
|
|
@@ -4560,7 +4683,7 @@ const headingExtension = defineExtension({
|
|
|
4560
4683
|
if (command.type !== "insert" || command.text !== " ") {
|
|
4561
4684
|
return null;
|
|
4562
4685
|
}
|
|
4563
|
-
const { source, selection, map } =
|
|
4686
|
+
const { source, selection, map } = state;
|
|
4564
4687
|
if (selection.start !== selection.end) {
|
|
4565
4688
|
return null;
|
|
4566
4689
|
}
|
|
@@ -4795,13 +4918,13 @@ const imageExtension = defineExtension({
|
|
|
4795
4918
|
return element;
|
|
4796
4919
|
}
|
|
4797
4920
|
});
|
|
4798
|
-
const LIST_LINE_REGEX$
|
|
4921
|
+
const LIST_LINE_REGEX$1 = /^(\s*)([-*+]|\d+\.)( )(.*)$/;
|
|
4799
4922
|
const INDENT_SIZE = 2;
|
|
4800
4923
|
function parseMarkerType(marker) {
|
|
4801
4924
|
return /^\d+\.$/.test(marker) ? "numbered" : "bullet";
|
|
4802
4925
|
}
|
|
4803
4926
|
function parseLine(line) {
|
|
4804
|
-
const match = line.match(LIST_LINE_REGEX$
|
|
4927
|
+
const match = line.match(LIST_LINE_REGEX$1);
|
|
4805
4928
|
if (!match) {
|
|
4806
4929
|
return { type: "plain", content: line };
|
|
4807
4930
|
}
|
|
@@ -4881,14 +5004,14 @@ function getLineInfo(source, offset) {
|
|
|
4881
5004
|
};
|
|
4882
5005
|
}
|
|
4883
5006
|
function getListPrefixLength(line) {
|
|
4884
|
-
const match = line.match(LIST_LINE_REGEX$
|
|
5007
|
+
const match = line.match(LIST_LINE_REGEX$1);
|
|
4885
5008
|
if (!match) {
|
|
4886
5009
|
return null;
|
|
4887
5010
|
}
|
|
4888
5011
|
return match[1].length + match[2].length + match[3].length;
|
|
4889
5012
|
}
|
|
4890
5013
|
function isListLine(line) {
|
|
4891
|
-
return LIST_LINE_REGEX$
|
|
5014
|
+
return LIST_LINE_REGEX$1.test(line);
|
|
4892
5015
|
}
|
|
4893
5016
|
function parseListItem(line) {
|
|
4894
5017
|
const parsed = parseLine(line);
|
|
@@ -4908,9 +5031,9 @@ function countNumberedItemsBefore(source, beforeLineIndex) {
|
|
|
4908
5031
|
}
|
|
4909
5032
|
return count;
|
|
4910
5033
|
}
|
|
4911
|
-
const LIST_LINE_REGEX
|
|
5034
|
+
const LIST_LINE_REGEX = /^(\s*)([-*+]|\d+\.)( )(.*)$/;
|
|
4912
5035
|
function matchListLine(line) {
|
|
4913
|
-
const match = line.match(LIST_LINE_REGEX
|
|
5036
|
+
const match = line.match(LIST_LINE_REGEX);
|
|
4914
5037
|
if (!match) {
|
|
4915
5038
|
return null;
|
|
4916
5039
|
}
|
|
@@ -4989,8 +5112,8 @@ function getSelectionLineRange(source, selection) {
|
|
|
4989
5112
|
);
|
|
4990
5113
|
return { startLine: startInfo.lineIndex, endLine: endInfo.lineIndex };
|
|
4991
5114
|
}
|
|
4992
|
-
function handleInsertLineBreak(
|
|
4993
|
-
const { source, selection, map, runtime } =
|
|
5115
|
+
function handleInsertLineBreak(state) {
|
|
5116
|
+
const { source, selection, map, runtime } = state;
|
|
4994
5117
|
let workingSource = source;
|
|
4995
5118
|
let cursorPos = selection.start;
|
|
4996
5119
|
let cursorSourcePos = map.cursorToSource(cursorPos, "forward");
|
|
@@ -5110,8 +5233,8 @@ function handleInsertLineBreak(state2) {
|
|
|
5110
5233
|
}
|
|
5111
5234
|
};
|
|
5112
5235
|
}
|
|
5113
|
-
function handleDeleteBackward(
|
|
5114
|
-
const { source, selection, map, runtime } =
|
|
5236
|
+
function handleDeleteBackward(state) {
|
|
5237
|
+
const { source, selection, map, runtime } = state;
|
|
5115
5238
|
const resultAtSource = (nextSource, sourceOffset, bias = "forward") => {
|
|
5116
5239
|
const next = runtime.createState(nextSource);
|
|
5117
5240
|
const cursor = next.map.sourceToCursor(sourceOffset, bias);
|
|
@@ -5165,9 +5288,14 @@ function handleDeleteBackward(state2) {
|
|
|
5165
5288
|
if (cursorPos === 0) {
|
|
5166
5289
|
return null;
|
|
5167
5290
|
}
|
|
5168
|
-
const
|
|
5169
|
-
const
|
|
5170
|
-
const
|
|
5291
|
+
const cursorSourcePosBackward = map.cursorToSource(cursorPos, "backward");
|
|
5292
|
+
const cursorSourcePosForward = map.cursorToSource(cursorPos, "forward");
|
|
5293
|
+
const lineInfoBackward = getLineInfo(source, cursorSourcePosBackward);
|
|
5294
|
+
const lineInfoForward = getLineInfo(source, cursorSourcePosForward);
|
|
5295
|
+
const forwardPrefixLength = getListPrefixLength(lineInfoForward.line);
|
|
5296
|
+
const backwardPrefixLength = getListPrefixLength(lineInfoBackward.line);
|
|
5297
|
+
const lineInfo = forwardPrefixLength !== null && lineInfoForward.offsetInLine === forwardPrefixLength ? lineInfoForward : lineInfoBackward;
|
|
5298
|
+
const prefixLength = lineInfo === lineInfoForward ? forwardPrefixLength : backwardPrefixLength;
|
|
5171
5299
|
if (prefixLength === null) {
|
|
5172
5300
|
if (lineInfo.offsetInLine === 0 && lineInfo.lineIndex > 0) {
|
|
5173
5301
|
const lines = source.split("\n");
|
|
@@ -5261,8 +5389,8 @@ function handleDeleteBackward(state2) {
|
|
|
5261
5389
|
}
|
|
5262
5390
|
return null;
|
|
5263
5391
|
}
|
|
5264
|
-
function handleDeleteForward(
|
|
5265
|
-
const { source, selection, map, runtime } =
|
|
5392
|
+
function handleDeleteForward(state) {
|
|
5393
|
+
const { source, selection, map, runtime } = state;
|
|
5266
5394
|
if (selection.start !== selection.end) {
|
|
5267
5395
|
return null;
|
|
5268
5396
|
}
|
|
@@ -5304,8 +5432,8 @@ function handleDeleteForward(state2) {
|
|
|
5304
5432
|
}
|
|
5305
5433
|
return null;
|
|
5306
5434
|
}
|
|
5307
|
-
function handleIndent(
|
|
5308
|
-
const { source, selection } =
|
|
5435
|
+
function handleIndent(state) {
|
|
5436
|
+
const { source, selection } = state;
|
|
5309
5437
|
const { startLine, endLine } = getSelectionLineRange(source, selection);
|
|
5310
5438
|
const lines = getSourceLines(source);
|
|
5311
5439
|
let hasListLine = false;
|
|
@@ -5339,8 +5467,8 @@ function handleIndent(state2) {
|
|
|
5339
5467
|
selection: { start: newStart, end: newEnd, affinity: "forward" }
|
|
5340
5468
|
};
|
|
5341
5469
|
}
|
|
5342
|
-
function handleOutdent(
|
|
5343
|
-
const { source, selection } =
|
|
5470
|
+
function handleOutdent(state) {
|
|
5471
|
+
const { source, selection } = state;
|
|
5344
5472
|
const { startLine, endLine } = getSelectionLineRange(source, selection);
|
|
5345
5473
|
const lines = getSourceLines(source);
|
|
5346
5474
|
let hasListLine = false;
|
|
@@ -5413,8 +5541,8 @@ function handleOutdent(state2) {
|
|
|
5413
5541
|
selection: { start: newStart, end: newEnd, affinity: "forward" }
|
|
5414
5542
|
};
|
|
5415
5543
|
}
|
|
5416
|
-
function handleToggleList(
|
|
5417
|
-
const { source, selection } =
|
|
5544
|
+
function handleToggleList(state, isBullet) {
|
|
5545
|
+
const { source, selection } = state;
|
|
5418
5546
|
const { startLine, endLine } = getSelectionLineRange(source, selection);
|
|
5419
5547
|
const lines = getSourceLines(source);
|
|
5420
5548
|
const bulletPattern = /^(\s*)([-*+])( )/;
|
|
@@ -5502,8 +5630,8 @@ function handleToggleList(state2, isBullet) {
|
|
|
5502
5630
|
}
|
|
5503
5631
|
};
|
|
5504
5632
|
}
|
|
5505
|
-
function handleInsertListMarkerWithSelection(
|
|
5506
|
-
const { source, selection } =
|
|
5633
|
+
function handleInsertListMarkerWithSelection(state, marker) {
|
|
5634
|
+
const { source, selection } = state;
|
|
5507
5635
|
if (selection.start === selection.end) {
|
|
5508
5636
|
return null;
|
|
5509
5637
|
}
|
|
@@ -5557,14 +5685,14 @@ function handleInsertListMarkerWithSelection(state2, marker) {
|
|
|
5557
5685
|
selection: { start: cursorPos, end: cursorPos, affinity: "forward" }
|
|
5558
5686
|
};
|
|
5559
5687
|
}
|
|
5560
|
-
function handleMarkerSwitch(
|
|
5561
|
-
const { source, selection } =
|
|
5688
|
+
function handleMarkerSwitch(state, insertedChar) {
|
|
5689
|
+
const { source, selection } = state;
|
|
5562
5690
|
if (selection.start !== selection.end) {
|
|
5563
5691
|
const { startLine, endLine } = getSelectionLineRange(source, selection);
|
|
5564
5692
|
if (startLine !== endLine && (insertedChar === "-" || insertedChar === "*" || insertedChar === "+")) {
|
|
5565
5693
|
return { type: "toggle-bullet-list" };
|
|
5566
5694
|
}
|
|
5567
|
-
return handleInsertListMarkerWithSelection(
|
|
5695
|
+
return handleInsertListMarkerWithSelection(state, insertedChar);
|
|
5568
5696
|
}
|
|
5569
5697
|
if (insertedChar !== "-" && insertedChar !== "*" && insertedChar !== "+") {
|
|
5570
5698
|
return null;
|
|
@@ -5641,30 +5769,30 @@ const listExtension = defineExtension({
|
|
|
5641
5769
|
command: { type: "toggle-numbered-list" }
|
|
5642
5770
|
}
|
|
5643
5771
|
],
|
|
5644
|
-
onEdit(command,
|
|
5772
|
+
onEdit(command, state) {
|
|
5645
5773
|
if (command.type === "insert-line-break") {
|
|
5646
|
-
return handleInsertLineBreak(
|
|
5774
|
+
return handleInsertLineBreak(state);
|
|
5647
5775
|
}
|
|
5648
5776
|
if (command.type === "delete-backward") {
|
|
5649
|
-
return handleDeleteBackward(
|
|
5777
|
+
return handleDeleteBackward(state);
|
|
5650
5778
|
}
|
|
5651
5779
|
if (command.type === "delete-forward") {
|
|
5652
|
-
return handleDeleteForward(
|
|
5780
|
+
return handleDeleteForward(state);
|
|
5653
5781
|
}
|
|
5654
5782
|
if (command.type === "indent") {
|
|
5655
|
-
return handleIndent(
|
|
5783
|
+
return handleIndent(state);
|
|
5656
5784
|
}
|
|
5657
5785
|
if (command.type === "outdent") {
|
|
5658
|
-
return handleOutdent(
|
|
5786
|
+
return handleOutdent(state);
|
|
5659
5787
|
}
|
|
5660
5788
|
if (command.type === "toggle-bullet-list") {
|
|
5661
|
-
return handleToggleList(
|
|
5789
|
+
return handleToggleList(state, true);
|
|
5662
5790
|
}
|
|
5663
5791
|
if (command.type === "toggle-numbered-list") {
|
|
5664
|
-
return handleToggleList(
|
|
5792
|
+
return handleToggleList(state, false);
|
|
5665
5793
|
}
|
|
5666
5794
|
if (command.type === "insert" && command.text.length === 1) {
|
|
5667
|
-
return handleMarkerSwitch(
|
|
5795
|
+
return handleMarkerSwitch(state, command.text);
|
|
5668
5796
|
}
|
|
5669
5797
|
return null;
|
|
5670
5798
|
},
|
|
@@ -5710,7 +5838,7 @@ const THUMB_MIN_HEIGHT = 30;
|
|
|
5710
5838
|
const SCROLL_HIDE_DELAY = 500;
|
|
5711
5839
|
const TRACK_PADDING = 8;
|
|
5712
5840
|
function ScrollbarOverlay({ container }) {
|
|
5713
|
-
const [
|
|
5841
|
+
const [state, setState] = require$$0.useState({
|
|
5714
5842
|
scrollTop: 0,
|
|
5715
5843
|
scrollHeight: 0,
|
|
5716
5844
|
clientHeight: 0
|
|
@@ -5723,7 +5851,7 @@ function ScrollbarOverlay({ container }) {
|
|
|
5723
5851
|
null
|
|
5724
5852
|
);
|
|
5725
5853
|
const scrollTimeoutRef = require$$0.useRef(null);
|
|
5726
|
-
const { scrollTop, scrollHeight, clientHeight } =
|
|
5854
|
+
const { scrollTop, scrollHeight, clientHeight } = state;
|
|
5727
5855
|
const hasOverflow = scrollHeight > clientHeight;
|
|
5728
5856
|
const trackHeight = clientHeight - TRACK_PADDING * 2;
|
|
5729
5857
|
const rawThumbHeight = hasOverflow ? clientHeight / scrollHeight * trackHeight : 0;
|
|
@@ -5957,16 +6085,22 @@ const strikethroughExtension = defineExtension({
|
|
|
5957
6085
|
key: "x",
|
|
5958
6086
|
meta: true,
|
|
5959
6087
|
shift: true,
|
|
5960
|
-
command: { type: "toggle-
|
|
6088
|
+
command: { type: "toggle-strikethrough" }
|
|
5961
6089
|
},
|
|
5962
6090
|
{
|
|
5963
6091
|
key: "x",
|
|
5964
6092
|
ctrl: true,
|
|
5965
6093
|
shift: true,
|
|
5966
|
-
command: { type: "toggle-
|
|
6094
|
+
command: { type: "toggle-strikethrough" }
|
|
5967
6095
|
}
|
|
5968
6096
|
],
|
|
5969
6097
|
inlineWrapperAffinity: [{ kind: STRIKE_KIND, inclusive: true }],
|
|
6098
|
+
onEdit(command) {
|
|
6099
|
+
if (command.type === "toggle-strikethrough") {
|
|
6100
|
+
return { type: "toggle-inline", marker: "~~" };
|
|
6101
|
+
}
|
|
6102
|
+
return null;
|
|
6103
|
+
},
|
|
5970
6104
|
parseInline(source, start, end, context) {
|
|
5971
6105
|
if (source.slice(start, start + 2) !== "~~") {
|
|
5972
6106
|
return null;
|
|
@@ -6065,27 +6199,23 @@ function mergeDomRects(rects) {
|
|
|
6065
6199
|
});
|
|
6066
6200
|
return new DOMRect(left, top, right - left, bottom - top);
|
|
6067
6201
|
}
|
|
6068
|
-
function rectsOverlapVertically(a, b) {
|
|
6069
|
-
const aBottom = a.top + a.height;
|
|
6070
|
-
const bBottom = b.top + b.height;
|
|
6071
|
-
return a.top < bBottom && b.top < aBottom;
|
|
6072
|
-
}
|
|
6073
6202
|
function groupDomRectsByRow(rects) {
|
|
6074
6203
|
if (rects.length === 0) {
|
|
6075
6204
|
return [];
|
|
6076
6205
|
}
|
|
6206
|
+
const ROW_TOP_EPS_PX = 1;
|
|
6077
6207
|
const sorted = [...rects].sort(
|
|
6078
6208
|
(a, b) => a.top === b.top ? a.left - b.left : a.top - b.top
|
|
6079
6209
|
);
|
|
6080
6210
|
const grouped = [];
|
|
6081
|
-
|
|
6211
|
+
for (const rect of sorted) {
|
|
6082
6212
|
const last = grouped[grouped.length - 1];
|
|
6083
|
-
if (last &&
|
|
6213
|
+
if (last && Math.abs(rect.top - last.top) <= ROW_TOP_EPS_PX) {
|
|
6084
6214
|
grouped[grouped.length - 1] = mergeDomRects([last, rect]) ?? last;
|
|
6085
|
-
|
|
6215
|
+
continue;
|
|
6086
6216
|
}
|
|
6087
6217
|
grouped.push(rect);
|
|
6088
|
-
}
|
|
6218
|
+
}
|
|
6089
6219
|
return grouped;
|
|
6090
6220
|
}
|
|
6091
6221
|
function cursorOffsetToCodeUnit(cursorToCodeUnit, offset) {
|
|
@@ -6149,11 +6279,26 @@ function measureCharacterRect(params) {
|
|
|
6149
6279
|
);
|
|
6150
6280
|
const startPosition = params.resolveDomPosition(startCodeUnit);
|
|
6151
6281
|
const endPosition = params.resolveDomPosition(endCodeUnit);
|
|
6152
|
-
|
|
6153
|
-
|
|
6282
|
+
if (startPosition.node !== endPosition.node && startPosition.node instanceof Text && endPosition.node instanceof Text && startPosition.offset === startPosition.node.length && endPosition.offset > 0) {
|
|
6283
|
+
params.range.setStart(endPosition.node, 0);
|
|
6284
|
+
params.range.setEnd(endPosition.node, endPosition.offset);
|
|
6285
|
+
} else {
|
|
6286
|
+
params.range.setStart(startPosition.node, startPosition.offset);
|
|
6287
|
+
params.range.setEnd(endPosition.node, endPosition.offset);
|
|
6288
|
+
}
|
|
6154
6289
|
const rects = params.range.getClientRects();
|
|
6155
6290
|
if (rects.length > 0) {
|
|
6156
|
-
|
|
6291
|
+
const list = Array.from(rects);
|
|
6292
|
+
let best = list[0] ?? null;
|
|
6293
|
+
let bestArea = best ? best.width * best.height : 0;
|
|
6294
|
+
for (const rect2 of list) {
|
|
6295
|
+
const area = rect2.width * rect2.height;
|
|
6296
|
+
if (area > bestArea) {
|
|
6297
|
+
best = rect2;
|
|
6298
|
+
bestArea = area;
|
|
6299
|
+
}
|
|
6300
|
+
}
|
|
6301
|
+
return bestArea > 0 ? best : list[0] ?? null;
|
|
6157
6302
|
}
|
|
6158
6303
|
const rect = params.range.getBoundingClientRect();
|
|
6159
6304
|
if (rect.width === 0 && rect.height === 0) {
|
|
@@ -6185,7 +6330,9 @@ function measureLineRows(params) {
|
|
|
6185
6330
|
const fullLineEnd = resolvePosition(params.codeUnitLength);
|
|
6186
6331
|
scratchRange.setStart(fullLineStart.node, fullLineStart.offset);
|
|
6187
6332
|
scratchRange.setEnd(fullLineEnd.node, fullLineEnd.offset);
|
|
6188
|
-
const fullLineRects = groupDomRectsByRow(
|
|
6333
|
+
const fullLineRects = groupDomRectsByRow(
|
|
6334
|
+
Array.from(scratchRange.getClientRects())
|
|
6335
|
+
);
|
|
6189
6336
|
if (fullLineRects.length === 0) {
|
|
6190
6337
|
return [
|
|
6191
6338
|
{
|
|
@@ -6195,7 +6342,15 @@ function measureLineRows(params) {
|
|
|
6195
6342
|
}
|
|
6196
6343
|
];
|
|
6197
6344
|
}
|
|
6345
|
+
const rowRects = fullLineRects.map((rect, index) => {
|
|
6346
|
+
var _a2;
|
|
6347
|
+
const nextTop = ((_a2 = fullLineRects[index + 1]) == null ? void 0 : _a2.top) ?? params.lineRect.bottom;
|
|
6348
|
+
const bottom = Math.max(rect.top, nextTop);
|
|
6349
|
+
const height = Math.max(0, bottom - rect.top);
|
|
6350
|
+
return new DOMRect(rect.left, rect.top, rect.width, height);
|
|
6351
|
+
});
|
|
6198
6352
|
function offsetToTop(offset) {
|
|
6353
|
+
var _a2;
|
|
6199
6354
|
if (topCache.has(offset)) {
|
|
6200
6355
|
return topCache.get(offset) ?? null;
|
|
6201
6356
|
}
|
|
@@ -6207,7 +6362,22 @@ function measureLineRows(params) {
|
|
|
6207
6362
|
resolveDomPosition: resolvePosition,
|
|
6208
6363
|
range: scratchRange
|
|
6209
6364
|
});
|
|
6210
|
-
|
|
6365
|
+
let top = rect ? rect.top : null;
|
|
6366
|
+
if (top === null) {
|
|
6367
|
+
const codeUnitOffset = cursorOffsetToCodeUnit(params.cursorToCodeUnit, offset);
|
|
6368
|
+
const position = resolvePosition(codeUnitOffset);
|
|
6369
|
+
scratchRange.setStart(position.node, position.offset);
|
|
6370
|
+
scratchRange.setEnd(position.node, position.offset);
|
|
6371
|
+
const rects = scratchRange.getClientRects();
|
|
6372
|
+
if (rects.length > 0) {
|
|
6373
|
+
top = ((_a2 = rects[0]) == null ? void 0 : _a2.top) ?? null;
|
|
6374
|
+
} else {
|
|
6375
|
+
const caretRect = scratchRange.getBoundingClientRect();
|
|
6376
|
+
if (!(caretRect.width === 0 && caretRect.height === 0)) {
|
|
6377
|
+
top = caretRect.top;
|
|
6378
|
+
}
|
|
6379
|
+
}
|
|
6380
|
+
}
|
|
6211
6381
|
topCache.set(offset, top);
|
|
6212
6382
|
return top;
|
|
6213
6383
|
}
|
|
@@ -6275,7 +6445,7 @@ function measureLineRows(params) {
|
|
|
6275
6445
|
while (currentRowStart < params.lineLength) {
|
|
6276
6446
|
const nextRowStart = findNextRowStartOffset(searchFrom, currentRowTop);
|
|
6277
6447
|
const currentRowEnd = nextRowStart ?? params.lineLength;
|
|
6278
|
-
const domRect =
|
|
6448
|
+
const domRect = rowRects[rowIndex] ?? params.lineRect;
|
|
6279
6449
|
rows.push({
|
|
6280
6450
|
startOffset: currentRowStart,
|
|
6281
6451
|
endOffset: currentRowEnd,
|
|
@@ -6462,6 +6632,249 @@ function createOffsetToXMeasurer(params) {
|
|
|
6462
6632
|
function cursorOffsetToDomOffset(cursorToCodeUnit, offset) {
|
|
6463
6633
|
return cursorOffsetToCodeUnit(cursorToCodeUnit, offset);
|
|
6464
6634
|
}
|
|
6635
|
+
function hitTestFromLayout(params) {
|
|
6636
|
+
const { clientX, clientY, root, container, lines } = params;
|
|
6637
|
+
const layout = measureLayoutModelFromDom({ lines, root, container });
|
|
6638
|
+
if (!layout || layout.lines.length === 0) {
|
|
6639
|
+
return null;
|
|
6640
|
+
}
|
|
6641
|
+
const containerRect = container.getBoundingClientRect();
|
|
6642
|
+
const scroll = { top: container.scrollTop, left: container.scrollLeft };
|
|
6643
|
+
const relativeX = clientX - containerRect.left + scroll.left;
|
|
6644
|
+
const relativeY = clientY - containerRect.top + scroll.top;
|
|
6645
|
+
const allRows = [];
|
|
6646
|
+
for (const lineLayout of layout.lines) {
|
|
6647
|
+
for (const row2 of lineLayout.rows) {
|
|
6648
|
+
const centerY = row2.rect.top + row2.rect.height / 2;
|
|
6649
|
+
allRows.push({
|
|
6650
|
+
lineIndex: lineLayout.lineIndex,
|
|
6651
|
+
lineStartOffset: lineLayout.lineStartOffset,
|
|
6652
|
+
row: row2,
|
|
6653
|
+
centerY
|
|
6654
|
+
});
|
|
6655
|
+
}
|
|
6656
|
+
}
|
|
6657
|
+
if (allRows.length === 0) {
|
|
6658
|
+
return null;
|
|
6659
|
+
}
|
|
6660
|
+
let targetRowInfo = allRows[0];
|
|
6661
|
+
let smallestCenterDistance = Math.abs(relativeY - targetRowInfo.centerY);
|
|
6662
|
+
for (let i = 1; i < allRows.length; i++) {
|
|
6663
|
+
const rowInfo = allRows[i];
|
|
6664
|
+
const distance = Math.abs(relativeY - rowInfo.centerY);
|
|
6665
|
+
if (distance < smallestCenterDistance) {
|
|
6666
|
+
smallestCenterDistance = distance;
|
|
6667
|
+
targetRowInfo = rowInfo;
|
|
6668
|
+
}
|
|
6669
|
+
}
|
|
6670
|
+
const { lineIndex, lineStartOffset, row } = targetRowInfo;
|
|
6671
|
+
const lineInfo = lines[lineIndex];
|
|
6672
|
+
if (!lineInfo) {
|
|
6673
|
+
return null;
|
|
6674
|
+
}
|
|
6675
|
+
const lineElement = getLineElement(root, lineIndex);
|
|
6676
|
+
if (!lineElement) {
|
|
6677
|
+
return null;
|
|
6678
|
+
}
|
|
6679
|
+
const resolvePosition = createDomPositionResolver(lineElement);
|
|
6680
|
+
const scratchRange = document.createRange();
|
|
6681
|
+
const rowTop = row.rect.top;
|
|
6682
|
+
const approximateX = (cursorOffsetInLine) => {
|
|
6683
|
+
const clamped = Math.max(
|
|
6684
|
+
row.startOffset,
|
|
6685
|
+
Math.min(cursorOffsetInLine, row.endOffset)
|
|
6686
|
+
);
|
|
6687
|
+
const rowLength = row.endOffset - row.startOffset;
|
|
6688
|
+
if (rowLength <= 0) {
|
|
6689
|
+
return row.rect.left;
|
|
6690
|
+
}
|
|
6691
|
+
const fraction = (clamped - row.startOffset) / rowLength;
|
|
6692
|
+
return row.rect.left + row.rect.width * fraction;
|
|
6693
|
+
};
|
|
6694
|
+
const measureCaretXOnRow = (cursorOffsetInLine) => {
|
|
6695
|
+
const maxRowTopDelta = Math.max(2, row.rect.height / 2);
|
|
6696
|
+
const measureCharEdgeX = (from, to, edge) => {
|
|
6697
|
+
const fromCodeUnit = cursorOffsetToCodeUnit(lineInfo.cursorToCodeUnit, from);
|
|
6698
|
+
const toCodeUnit = cursorOffsetToCodeUnit(lineInfo.cursorToCodeUnit, to);
|
|
6699
|
+
const fromPos = resolvePosition(fromCodeUnit);
|
|
6700
|
+
const toPos = resolvePosition(toCodeUnit);
|
|
6701
|
+
if (fromPos.node !== toPos.node && fromPos.node instanceof Text && toPos.node instanceof Text && fromPos.offset === fromPos.node.length && toPos.offset > 0) {
|
|
6702
|
+
scratchRange.setStart(toPos.node, 0);
|
|
6703
|
+
scratchRange.setEnd(toPos.node, toPos.offset);
|
|
6704
|
+
} else {
|
|
6705
|
+
scratchRange.setStart(fromPos.node, fromPos.offset);
|
|
6706
|
+
scratchRange.setEnd(toPos.node, toPos.offset);
|
|
6707
|
+
}
|
|
6708
|
+
const rects2 = scratchRange.getClientRects();
|
|
6709
|
+
const list = rects2.length > 0 ? Array.from(rects2) : (() => {
|
|
6710
|
+
const rect = scratchRange.getBoundingClientRect();
|
|
6711
|
+
return rect.width === 0 && rect.height === 0 ? [] : [rect];
|
|
6712
|
+
})();
|
|
6713
|
+
if (list.length === 0) {
|
|
6714
|
+
return null;
|
|
6715
|
+
}
|
|
6716
|
+
const DIST_EPS = 0.01;
|
|
6717
|
+
let bestTopDistance = Number.POSITIVE_INFINITY;
|
|
6718
|
+
const candidates2 = [];
|
|
6719
|
+
for (const rect of list) {
|
|
6720
|
+
const top = rect.top - containerRect.top + scroll.top;
|
|
6721
|
+
const distance = Math.abs(top - rowTop);
|
|
6722
|
+
if (distance + DIST_EPS < bestTopDistance) {
|
|
6723
|
+
bestTopDistance = distance;
|
|
6724
|
+
candidates2.length = 0;
|
|
6725
|
+
candidates2.push(rect);
|
|
6726
|
+
} else if (Math.abs(distance - bestTopDistance) <= DIST_EPS) {
|
|
6727
|
+
candidates2.push(rect);
|
|
6728
|
+
}
|
|
6729
|
+
}
|
|
6730
|
+
if (candidates2.length === 0 || bestTopDistance > maxRowTopDelta) {
|
|
6731
|
+
return null;
|
|
6732
|
+
}
|
|
6733
|
+
if (edge === "left") {
|
|
6734
|
+
let left = candidates2[0].left;
|
|
6735
|
+
for (const rect of candidates2) {
|
|
6736
|
+
left = Math.min(left, rect.left);
|
|
6737
|
+
}
|
|
6738
|
+
return left - containerRect.left + scroll.left;
|
|
6739
|
+
}
|
|
6740
|
+
let right = candidates2[0].right;
|
|
6741
|
+
for (const rect of candidates2) {
|
|
6742
|
+
right = Math.max(right, rect.right);
|
|
6743
|
+
}
|
|
6744
|
+
return right - containerRect.left + scroll.left;
|
|
6745
|
+
};
|
|
6746
|
+
const prevChar = cursorOffsetInLine > 0 ? lineInfo.text[cursorOffsetInLine - 1] ?? "" : "";
|
|
6747
|
+
const preferNextForPrevWhitespace = cursorOffsetInLine > row.startOffset && cursorOffsetInLine < row.endOffset && /\s/.test(prevChar);
|
|
6748
|
+
if (preferNextForPrevWhitespace) {
|
|
6749
|
+
const xNext = measureCharEdgeX(
|
|
6750
|
+
cursorOffsetInLine,
|
|
6751
|
+
cursorOffsetInLine + 1,
|
|
6752
|
+
"left"
|
|
6753
|
+
);
|
|
6754
|
+
if (xNext !== null) {
|
|
6755
|
+
return xNext;
|
|
6756
|
+
}
|
|
6757
|
+
}
|
|
6758
|
+
if (cursorOffsetInLine > row.startOffset) {
|
|
6759
|
+
const xPrev = measureCharEdgeX(
|
|
6760
|
+
cursorOffsetInLine - 1,
|
|
6761
|
+
cursorOffsetInLine,
|
|
6762
|
+
"right"
|
|
6763
|
+
);
|
|
6764
|
+
if (xPrev !== null) {
|
|
6765
|
+
return xPrev;
|
|
6766
|
+
}
|
|
6767
|
+
}
|
|
6768
|
+
if (cursorOffsetInLine < row.endOffset) {
|
|
6769
|
+
const xNext = measureCharEdgeX(
|
|
6770
|
+
cursorOffsetInLine,
|
|
6771
|
+
cursorOffsetInLine + 1,
|
|
6772
|
+
"left"
|
|
6773
|
+
);
|
|
6774
|
+
if (xNext !== null) {
|
|
6775
|
+
return xNext;
|
|
6776
|
+
}
|
|
6777
|
+
}
|
|
6778
|
+
const codeUnitOffset = cursorOffsetToCodeUnit(
|
|
6779
|
+
lineInfo.cursorToCodeUnit,
|
|
6780
|
+
cursorOffsetInLine
|
|
6781
|
+
);
|
|
6782
|
+
const position = resolvePosition(codeUnitOffset);
|
|
6783
|
+
scratchRange.setStart(position.node, position.offset);
|
|
6784
|
+
scratchRange.setEnd(position.node, position.offset);
|
|
6785
|
+
const rects = scratchRange.getClientRects();
|
|
6786
|
+
const candidates = rects.length > 0 ? Array.from(rects) : [scratchRange.getBoundingClientRect()];
|
|
6787
|
+
if (candidates.length === 0) {
|
|
6788
|
+
return null;
|
|
6789
|
+
}
|
|
6790
|
+
let best = candidates[0];
|
|
6791
|
+
let bestDistance = Number.POSITIVE_INFINITY;
|
|
6792
|
+
for (const rect of candidates) {
|
|
6793
|
+
const top = rect.top - containerRect.top + scroll.top;
|
|
6794
|
+
const distance = Math.abs(top - rowTop);
|
|
6795
|
+
if (distance < bestDistance) {
|
|
6796
|
+
bestDistance = distance;
|
|
6797
|
+
best = rect;
|
|
6798
|
+
}
|
|
6799
|
+
}
|
|
6800
|
+
if (bestDistance > maxRowTopDelta) {
|
|
6801
|
+
return null;
|
|
6802
|
+
}
|
|
6803
|
+
if (best.height <= 0) {
|
|
6804
|
+
return null;
|
|
6805
|
+
}
|
|
6806
|
+
return best.left - containerRect.left + scroll.left;
|
|
6807
|
+
};
|
|
6808
|
+
const caretX = (cursorOffsetInLine) => {
|
|
6809
|
+
return measureCaretXOnRow(cursorOffsetInLine) ?? approximateX(cursorOffsetInLine);
|
|
6810
|
+
};
|
|
6811
|
+
let low = row.startOffset;
|
|
6812
|
+
let high = row.endOffset;
|
|
6813
|
+
while (low < high) {
|
|
6814
|
+
const mid = low + high >>> 1;
|
|
6815
|
+
const xMid = caretX(mid);
|
|
6816
|
+
if (xMid < relativeX) {
|
|
6817
|
+
low = mid + 1;
|
|
6818
|
+
} else {
|
|
6819
|
+
high = mid;
|
|
6820
|
+
}
|
|
6821
|
+
}
|
|
6822
|
+
const candidateA = Math.max(row.startOffset, Math.min(low, row.endOffset));
|
|
6823
|
+
const candidateB = Math.max(
|
|
6824
|
+
row.startOffset,
|
|
6825
|
+
Math.min(candidateA - 1, row.endOffset)
|
|
6826
|
+
);
|
|
6827
|
+
const xA = caretX(candidateA);
|
|
6828
|
+
const xB = caretX(candidateB);
|
|
6829
|
+
const distA = Math.abs(relativeX - xA);
|
|
6830
|
+
const distB = Math.abs(relativeX - xB);
|
|
6831
|
+
const DIST_EPS_PX = 0.5;
|
|
6832
|
+
let closestOffset = (() => {
|
|
6833
|
+
if (distB + DIST_EPS_PX < distA) {
|
|
6834
|
+
return candidateB;
|
|
6835
|
+
}
|
|
6836
|
+
if (distA + DIST_EPS_PX < distB) {
|
|
6837
|
+
return candidateA;
|
|
6838
|
+
}
|
|
6839
|
+
const mid = (xA + xB) / 2;
|
|
6840
|
+
return relativeX >= mid ? candidateA : candidateB;
|
|
6841
|
+
})();
|
|
6842
|
+
const endX = caretX(row.endOffset);
|
|
6843
|
+
{
|
|
6844
|
+
const baseMeasuredX = measureCaretXOnRow(closestOffset);
|
|
6845
|
+
if (baseMeasuredX !== null) {
|
|
6846
|
+
const baseCodeUnit = cursorOffsetToCodeUnit(
|
|
6847
|
+
lineInfo.cursorToCodeUnit,
|
|
6848
|
+
closestOffset
|
|
6849
|
+
);
|
|
6850
|
+
const COLLAPSE_EPS_PX = 0.25;
|
|
6851
|
+
while (closestOffset > row.startOffset) {
|
|
6852
|
+
const prev = closestOffset - 1;
|
|
6853
|
+
const prevCodeUnit = cursorOffsetToCodeUnit(lineInfo.cursorToCodeUnit, prev);
|
|
6854
|
+
if (prevCodeUnit !== baseCodeUnit) {
|
|
6855
|
+
break;
|
|
6856
|
+
}
|
|
6857
|
+
const prevMeasuredX = measureCaretXOnRow(prev);
|
|
6858
|
+
if (prevMeasuredX === null) {
|
|
6859
|
+
break;
|
|
6860
|
+
}
|
|
6861
|
+
if (Math.abs(prevMeasuredX - baseMeasuredX) > COLLAPSE_EPS_PX) {
|
|
6862
|
+
break;
|
|
6863
|
+
}
|
|
6864
|
+
closestOffset = prev;
|
|
6865
|
+
}
|
|
6866
|
+
}
|
|
6867
|
+
}
|
|
6868
|
+
const boundaryX = caretX(closestOffset);
|
|
6869
|
+
const choseRightEdge = closestOffset > row.startOffset && relativeX < boundaryX - 0.01;
|
|
6870
|
+
const isEndOfLine = row.endOffset === lineInfo.cursorLength;
|
|
6871
|
+
const atLineEnd = closestOffset === row.endOffset && isEndOfLine;
|
|
6872
|
+
const pastRowEnd = !atLineEnd && choseRightEdge || !atLineEnd && closestOffset === row.endOffset && row.endOffset < lineInfo.cursorLength && relativeX > endX + 0.5;
|
|
6873
|
+
return {
|
|
6874
|
+
cursorOffset: lineStartOffset + closestOffset,
|
|
6875
|
+
pastRowEnd
|
|
6876
|
+
};
|
|
6877
|
+
}
|
|
6465
6878
|
function rectRight$1(rect) {
|
|
6466
6879
|
return rect.left + rect.width;
|
|
6467
6880
|
}
|
|
@@ -6771,7 +7184,14 @@ function getCaretRect(params) {
|
|
|
6771
7184
|
backRange.setEnd(backEnd.node, backEnd.offset);
|
|
6772
7185
|
const backRects = backRange.getClientRects();
|
|
6773
7186
|
if (backRects.length > 0) {
|
|
6774
|
-
|
|
7187
|
+
let bestRect = backRects[backRects.length - 1];
|
|
7188
|
+
for (let i = 0; i < backRects.length; i += 1) {
|
|
7189
|
+
const rect = backRects[i];
|
|
7190
|
+
if (rect.width > 0 && (bestRect.width === 0 || rect.top < bestRect.top)) {
|
|
7191
|
+
bestRect = rect;
|
|
7192
|
+
}
|
|
7193
|
+
}
|
|
7194
|
+
backwardRect = bestRect;
|
|
6775
7195
|
}
|
|
6776
7196
|
}
|
|
6777
7197
|
if (canProbeForward) {
|
|
@@ -6788,7 +7208,14 @@ function getCaretRect(params) {
|
|
|
6788
7208
|
fwdRange.setEnd(fwdEnd.node, fwdEnd.offset);
|
|
6789
7209
|
const fwdRects = fwdRange.getClientRects();
|
|
6790
7210
|
if (fwdRects.length > 0) {
|
|
6791
|
-
|
|
7211
|
+
let bestRect = fwdRects[0];
|
|
7212
|
+
for (let i = 1; i < fwdRects.length; i += 1) {
|
|
7213
|
+
const rect = fwdRects[i];
|
|
7214
|
+
if (rect.width > 0 && (bestRect.width === 0 || rect.top > bestRect.top)) {
|
|
7215
|
+
bestRect = rect;
|
|
7216
|
+
}
|
|
7217
|
+
}
|
|
7218
|
+
forwardRect = bestRect;
|
|
6792
7219
|
}
|
|
6793
7220
|
}
|
|
6794
7221
|
const atWrapBoundary = backwardRect && forwardRect && Math.abs(backwardRect.top - forwardRect.top) > 5;
|
|
@@ -6796,8 +7223,43 @@ function getCaretRect(params) {
|
|
|
6796
7223
|
let useRightEdge = false;
|
|
6797
7224
|
if (atWrapBoundary) {
|
|
6798
7225
|
if (affinity === "backward" && backwardRect) {
|
|
6799
|
-
|
|
6800
|
-
|
|
7226
|
+
if (forwardRect) {
|
|
7227
|
+
const startPos = resolveDomPosition(
|
|
7228
|
+
lineElement,
|
|
7229
|
+
cursorOffsetToDomOffset(lineInfo.cursorToCodeUnit, 0)
|
|
7230
|
+
);
|
|
7231
|
+
const endPos = resolveDomPosition(
|
|
7232
|
+
lineElement,
|
|
7233
|
+
cursorOffsetToDomOffset(lineInfo.cursorToCodeUnit, lineInfo.cursorLength)
|
|
7234
|
+
);
|
|
7235
|
+
const lineRange = document.createRange();
|
|
7236
|
+
lineRange.setStart(startPos.node, startPos.offset);
|
|
7237
|
+
lineRange.setEnd(endPos.node, endPos.offset);
|
|
7238
|
+
const rowRects = groupDomRectsByRow(Array.from(lineRange.getClientRects()));
|
|
7239
|
+
const ROW_EPS_PX = 1;
|
|
7240
|
+
let previousRow = null;
|
|
7241
|
+
for (const rowRect of rowRects) {
|
|
7242
|
+
if (rowRect.top < forwardRect.top - ROW_EPS_PX) {
|
|
7243
|
+
previousRow = rowRect;
|
|
7244
|
+
} else {
|
|
7245
|
+
break;
|
|
7246
|
+
}
|
|
7247
|
+
}
|
|
7248
|
+
if (previousRow) {
|
|
7249
|
+
caretRect = new DOMRect(
|
|
7250
|
+
previousRow.right,
|
|
7251
|
+
previousRow.top,
|
|
7252
|
+
0,
|
|
7253
|
+
previousRow.height
|
|
7254
|
+
);
|
|
7255
|
+
} else {
|
|
7256
|
+
probeRect = backwardRect;
|
|
7257
|
+
useRightEdge = true;
|
|
7258
|
+
}
|
|
7259
|
+
} else {
|
|
7260
|
+
probeRect = backwardRect;
|
|
7261
|
+
useRightEdge = true;
|
|
7262
|
+
}
|
|
6801
7263
|
} else if (forwardRect) {
|
|
6802
7264
|
probeRect = forwardRect;
|
|
6803
7265
|
useRightEdge = false;
|
|
@@ -6818,6 +7280,37 @@ function getCaretRect(params) {
|
|
|
6818
7280
|
const left = useRightEdge ? probeRect.right : probeRect.left;
|
|
6819
7281
|
caretRect = new DOMRect(left, probeRect.top, 0, probeRect.height);
|
|
6820
7282
|
}
|
|
7283
|
+
if (affinity === "backward" && forwardRect) {
|
|
7284
|
+
const startPos = resolveDomPosition(
|
|
7285
|
+
lineElement,
|
|
7286
|
+
cursorOffsetToDomOffset(lineInfo.cursorToCodeUnit, 0)
|
|
7287
|
+
);
|
|
7288
|
+
const endPos = resolveDomPosition(
|
|
7289
|
+
lineElement,
|
|
7290
|
+
cursorOffsetToDomOffset(lineInfo.cursorToCodeUnit, lineInfo.cursorLength)
|
|
7291
|
+
);
|
|
7292
|
+
const lineRange = document.createRange();
|
|
7293
|
+
lineRange.setStart(startPos.node, startPos.offset);
|
|
7294
|
+
lineRange.setEnd(endPos.node, endPos.offset);
|
|
7295
|
+
const rowRects = groupDomRectsByRow(Array.from(lineRange.getClientRects()));
|
|
7296
|
+
const ROW_EPS_PX = 1;
|
|
7297
|
+
let previousRow = null;
|
|
7298
|
+
for (const rowRect of rowRects) {
|
|
7299
|
+
if (rowRect.top < forwardRect.top - ROW_EPS_PX) {
|
|
7300
|
+
previousRow = rowRect;
|
|
7301
|
+
} else {
|
|
7302
|
+
break;
|
|
7303
|
+
}
|
|
7304
|
+
}
|
|
7305
|
+
if (previousRow && caretRect.top >= forwardRect.top - ROW_EPS_PX) {
|
|
7306
|
+
caretRect = new DOMRect(
|
|
7307
|
+
previousRow.right,
|
|
7308
|
+
previousRow.top,
|
|
7309
|
+
0,
|
|
7310
|
+
previousRow.height
|
|
7311
|
+
);
|
|
7312
|
+
}
|
|
7313
|
+
}
|
|
6821
7314
|
}
|
|
6822
7315
|
if (caretRect.height === 0 && lineRect.height === 0) {
|
|
6823
7316
|
return null;
|
|
@@ -7656,6 +8149,8 @@ class CakeEngine {
|
|
|
7656
8149
|
this.handleCompositionStartBound = this.handleCompositionStart.bind(this);
|
|
7657
8150
|
this.handleCompositionEndBound = this.handleCompositionEnd.bind(this);
|
|
7658
8151
|
this.handleSelectionChangeBound = this.handleSelectionChange.bind(this);
|
|
8152
|
+
this.handleFocusInBound = this.handleFocusIn.bind(this);
|
|
8153
|
+
this.handleFocusOutBound = this.handleFocusOut.bind(this);
|
|
7659
8154
|
this.handleScrollBound = this.handleScroll.bind(this);
|
|
7660
8155
|
this.handleResizeBound = this.handleResize.bind(this);
|
|
7661
8156
|
this.handleClickBound = this.handleClick.bind(this);
|
|
@@ -7753,6 +8248,9 @@ class CakeEngine {
|
|
|
7753
8248
|
getContentRoot() {
|
|
7754
8249
|
return this.contentRoot;
|
|
7755
8250
|
}
|
|
8251
|
+
getLines() {
|
|
8252
|
+
return getDocLines(this.state.doc);
|
|
8253
|
+
}
|
|
7756
8254
|
getOverlayRoot() {
|
|
7757
8255
|
return this.ensureExtensionsRoot();
|
|
7758
8256
|
}
|
|
@@ -7872,7 +8370,7 @@ class CakeEngine {
|
|
|
7872
8370
|
canRedo() {
|
|
7873
8371
|
return this.history.redoStack.length > 0;
|
|
7874
8372
|
}
|
|
7875
|
-
executeCommand(command) {
|
|
8373
|
+
executeCommand(command, options) {
|
|
7876
8374
|
var _a;
|
|
7877
8375
|
const shouldOpenLinkPopover = "openPopover" in command && command.openPopover === true;
|
|
7878
8376
|
const nextState = this.runtime.applyEdit(command, this.state);
|
|
@@ -7885,10 +8383,13 @@ class CakeEngine {
|
|
|
7885
8383
|
(_a = this.onChange) == null ? void 0 : _a.call(this, this.state.source, this.state.selection);
|
|
7886
8384
|
this.scheduleScrollCaretIntoView();
|
|
7887
8385
|
if (shouldOpenLinkPopover) {
|
|
7888
|
-
|
|
8386
|
+
window.requestAnimationFrame(() => {
|
|
7889
8387
|
this.openLinkPopoverForSelection(true);
|
|
7890
8388
|
});
|
|
7891
8389
|
}
|
|
8390
|
+
if (options == null ? void 0 : options.restoreFocus) {
|
|
8391
|
+
this.focus();
|
|
8392
|
+
}
|
|
7892
8393
|
return true;
|
|
7893
8394
|
}
|
|
7894
8395
|
attachListeners() {
|
|
@@ -7902,6 +8403,8 @@ class CakeEngine {
|
|
|
7902
8403
|
"compositionend",
|
|
7903
8404
|
this.handleCompositionEndBound
|
|
7904
8405
|
);
|
|
8406
|
+
this.container.addEventListener("focusin", this.handleFocusInBound);
|
|
8407
|
+
this.container.addEventListener("focusout", this.handleFocusOutBound);
|
|
7905
8408
|
document.addEventListener(
|
|
7906
8409
|
"selectionchange",
|
|
7907
8410
|
this.handleSelectionChangeBound
|
|
@@ -7958,6 +8461,8 @@ class CakeEngine {
|
|
|
7958
8461
|
"compositionend",
|
|
7959
8462
|
this.handleCompositionEndBound
|
|
7960
8463
|
);
|
|
8464
|
+
this.container.removeEventListener("focusin", this.handleFocusInBound);
|
|
8465
|
+
this.container.removeEventListener("focusout", this.handleFocusOutBound);
|
|
7961
8466
|
document.removeEventListener(
|
|
7962
8467
|
"selectionchange",
|
|
7963
8468
|
this.handleSelectionChangeBound
|
|
@@ -7982,6 +8487,16 @@ class CakeEngine {
|
|
|
7982
8487
|
this.container.removeEventListener("pointerup", this.handlePointerUpBound);
|
|
7983
8488
|
this.detachDragListeners();
|
|
7984
8489
|
}
|
|
8490
|
+
handleFocusIn() {
|
|
8491
|
+
queueMicrotask(() => {
|
|
8492
|
+
this.scheduleOverlayUpdate();
|
|
8493
|
+
});
|
|
8494
|
+
}
|
|
8495
|
+
handleFocusOut() {
|
|
8496
|
+
queueMicrotask(() => {
|
|
8497
|
+
this.scheduleOverlayUpdate();
|
|
8498
|
+
});
|
|
8499
|
+
}
|
|
7985
8500
|
render() {
|
|
7986
8501
|
const perfEnabled = this.container.dataset.cakePerf === "1";
|
|
7987
8502
|
let perfStart = 0;
|
|
@@ -8037,7 +8552,7 @@ class CakeEngine {
|
|
|
8037
8552
|
this.contentRoot
|
|
8038
8553
|
);
|
|
8039
8554
|
const existingChildren = Array.from(this.contentRoot.childNodes);
|
|
8040
|
-
const isManagedChild = (node) => node instanceof Element && node.hasAttribute("data-line-index");
|
|
8555
|
+
const isManagedChild = (node) => node instanceof Element && (node.hasAttribute("data-line-index") || node.hasAttribute("data-block-wrapper"));
|
|
8041
8556
|
const existingManagedChildren = existingChildren.filter(isManagedChild);
|
|
8042
8557
|
const preservedChildren = existingChildren.filter((node) => !isManagedChild(node));
|
|
8043
8558
|
const needsUpdate = content.length !== existingManagedChildren.length || content.some((node, i) => node !== existingManagedChildren[i]);
|
|
@@ -8283,7 +8798,7 @@ class CakeEngine {
|
|
|
8283
8798
|
};
|
|
8284
8799
|
}
|
|
8285
8800
|
handleClick(event) {
|
|
8286
|
-
var _a, _b, _c, _d;
|
|
8801
|
+
var _a, _b, _c, _d, _e;
|
|
8287
8802
|
if (this.isComposing) {
|
|
8288
8803
|
return;
|
|
8289
8804
|
}
|
|
@@ -8338,6 +8853,29 @@ class CakeEngine {
|
|
|
8338
8853
|
}, 0);
|
|
8339
8854
|
return;
|
|
8340
8855
|
}
|
|
8856
|
+
if (!pendingHit) {
|
|
8857
|
+
const hit2 = this.hitTestFromClientPoint(event.clientX, event.clientY);
|
|
8858
|
+
if (!hit2) {
|
|
8859
|
+
return;
|
|
8860
|
+
}
|
|
8861
|
+
const newSelection = {
|
|
8862
|
+
start: hit2.cursorOffset,
|
|
8863
|
+
end: hit2.cursorOffset,
|
|
8864
|
+
affinity: hit2.affinity
|
|
8865
|
+
};
|
|
8866
|
+
this.pendingClickHit = null;
|
|
8867
|
+
this.suppressSelectionChange = true;
|
|
8868
|
+
this.state = this.runtime.updateSelection(this.state, newSelection, {
|
|
8869
|
+
kind: "dom"
|
|
8870
|
+
});
|
|
8871
|
+
this.applySelection(this.state.selection);
|
|
8872
|
+
(_c = this.onSelectionChange) == null ? void 0 : _c.call(this, this.state.selection);
|
|
8873
|
+
this.scheduleOverlayUpdate();
|
|
8874
|
+
setTimeout(() => {
|
|
8875
|
+
this.suppressSelectionChange = false;
|
|
8876
|
+
}, 0);
|
|
8877
|
+
return;
|
|
8878
|
+
}
|
|
8341
8879
|
this.pendingClickHit = null;
|
|
8342
8880
|
setTimeout(() => {
|
|
8343
8881
|
this.suppressSelectionChange = false;
|
|
@@ -8373,7 +8911,7 @@ class CakeEngine {
|
|
|
8373
8911
|
kind: "dom"
|
|
8374
8912
|
});
|
|
8375
8913
|
this.applySelection(this.state.selection);
|
|
8376
|
-
(
|
|
8914
|
+
(_d = this.onSelectionChange) == null ? void 0 : _d.call(this, this.state.selection);
|
|
8377
8915
|
this.suppressSelectionChange = false;
|
|
8378
8916
|
return;
|
|
8379
8917
|
}
|
|
@@ -8397,7 +8935,7 @@ class CakeEngine {
|
|
|
8397
8935
|
kind: "dom"
|
|
8398
8936
|
});
|
|
8399
8937
|
this.applySelection(this.state.selection);
|
|
8400
|
-
(
|
|
8938
|
+
(_e = this.onSelectionChange) == null ? void 0 : _e.call(this, this.state.selection);
|
|
8401
8939
|
this.suppressSelectionChange = false;
|
|
8402
8940
|
}
|
|
8403
8941
|
}
|
|
@@ -8622,13 +9160,15 @@ class CakeEngine {
|
|
|
8622
9160
|
}
|
|
8623
9161
|
}
|
|
8624
9162
|
resolveExtensionKeybinding(event) {
|
|
9163
|
+
const eventKey = event.key.length === 1 ? event.key.toLowerCase() : event.key;
|
|
8625
9164
|
for (const extension of this.extensions) {
|
|
8626
9165
|
const bindings = extension.keybindings;
|
|
8627
9166
|
if (!bindings) {
|
|
8628
9167
|
continue;
|
|
8629
9168
|
}
|
|
8630
9169
|
for (const binding of bindings) {
|
|
8631
|
-
|
|
9170
|
+
const bindingKey = binding.key.length === 1 ? binding.key.toLowerCase() : binding.key;
|
|
9171
|
+
if (bindingKey !== eventKey) {
|
|
8632
9172
|
continue;
|
|
8633
9173
|
}
|
|
8634
9174
|
if (binding.meta !== void 0 && binding.meta !== event.metaKey) {
|
|
@@ -10103,78 +10643,22 @@ class CakeEngine {
|
|
|
10103
10643
|
}
|
|
10104
10644
|
}
|
|
10105
10645
|
hitTestFromClientPoint(clientX, clientY) {
|
|
10106
|
-
|
|
10107
|
-
let node = null;
|
|
10108
|
-
let offset = 0;
|
|
10109
|
-
let pastRowEnd = false;
|
|
10110
|
-
const position = caretPositionFromPoint(clientX, clientY);
|
|
10111
|
-
if (position) {
|
|
10112
|
-
node = position.offsetNode;
|
|
10113
|
-
offset = position.offset;
|
|
10114
|
-
} else {
|
|
10115
|
-
const range = caretRangeFromPoint(clientX, clientY);
|
|
10116
|
-
if (range) {
|
|
10117
|
-
node = range.startContainer;
|
|
10118
|
-
offset = range.startOffset;
|
|
10119
|
-
}
|
|
10120
|
-
}
|
|
10121
|
-
if (!node || !this.container.contains(node)) {
|
|
10122
|
-
const closestLine = this.findClosestLineByY(clientY);
|
|
10123
|
-
const textNode = closestLine ? findFirstTextNode(closestLine) : null;
|
|
10124
|
-
if (textNode) {
|
|
10125
|
-
node = textNode;
|
|
10126
|
-
const hit = findOffsetInTextNode(textNode, clientX, clientY);
|
|
10127
|
-
offset = hit.offset;
|
|
10128
|
-
pastRowEnd = hit.pastRowEnd;
|
|
10129
|
-
}
|
|
10130
|
-
}
|
|
10131
|
-
if (!node || !this.container.contains(node)) {
|
|
10646
|
+
if (!this.contentRoot) {
|
|
10132
10647
|
return null;
|
|
10133
10648
|
}
|
|
10134
|
-
const
|
|
10135
|
-
|
|
10136
|
-
|
|
10137
|
-
|
|
10138
|
-
|
|
10139
|
-
|
|
10140
|
-
|
|
10141
|
-
|
|
10142
|
-
|
|
10143
|
-
node = textNode;
|
|
10144
|
-
const hit = findOffsetInTextNode(textNode, clientX, clientY);
|
|
10145
|
-
offset = hit.offset;
|
|
10146
|
-
pastRowEnd = hit.pastRowEnd;
|
|
10147
|
-
}
|
|
10148
|
-
}
|
|
10149
|
-
}
|
|
10150
|
-
}
|
|
10151
|
-
if (node instanceof Element) {
|
|
10152
|
-
const resolved = resolveTextPoint(node, offset);
|
|
10153
|
-
if (resolved) {
|
|
10154
|
-
node = resolved.node;
|
|
10155
|
-
offset = resolved.offset;
|
|
10156
|
-
}
|
|
10157
|
-
}
|
|
10158
|
-
if (node instanceof Text) {
|
|
10159
|
-
const hit = findOffsetInTextNode(node, clientX, clientY);
|
|
10160
|
-
offset = hit.offset;
|
|
10161
|
-
pastRowEnd = hit.pastRowEnd;
|
|
10162
|
-
}
|
|
10163
|
-
if (!pastRowEnd) {
|
|
10164
|
-
const lineElement2 = node instanceof Element ? node.closest(".cake-line") : (_b = node.parentElement) == null ? void 0 : _b.closest(".cake-line");
|
|
10165
|
-
if (lineElement2) {
|
|
10166
|
-
const lineRect = lineElement2.getBoundingClientRect();
|
|
10167
|
-
pastRowEnd = clientX > lineRect.right;
|
|
10168
|
-
}
|
|
10169
|
-
}
|
|
10170
|
-
const cursor = this.cursorFromDom(node, offset);
|
|
10171
|
-
if (!cursor) {
|
|
10649
|
+
const lines = getDocLines(this.state.doc);
|
|
10650
|
+
const hit = hitTestFromLayout({
|
|
10651
|
+
clientX,
|
|
10652
|
+
clientY,
|
|
10653
|
+
root: this.contentRoot,
|
|
10654
|
+
container: this.container,
|
|
10655
|
+
lines
|
|
10656
|
+
});
|
|
10657
|
+
if (!hit) {
|
|
10172
10658
|
return null;
|
|
10173
10659
|
}
|
|
10174
|
-
|
|
10175
|
-
|
|
10176
|
-
}
|
|
10177
|
-
return { cursorOffset: cursor.cursorOffset, affinity: "backward" };
|
|
10660
|
+
const affinity = hit.pastRowEnd ? "backward" : "forward";
|
|
10661
|
+
return { cursorOffset: hit.cursorOffset, affinity };
|
|
10178
10662
|
}
|
|
10179
10663
|
handlePointerDown(event) {
|
|
10180
10664
|
var _a, _b, _c;
|
|
@@ -10886,178 +11370,6 @@ function findTextNodeAtOrAfter(nodes, start) {
|
|
|
10886
11370
|
}
|
|
10887
11371
|
return null;
|
|
10888
11372
|
}
|
|
10889
|
-
function findOffsetInTextNode(textNode, clientX, clientY) {
|
|
10890
|
-
const text = textNode.textContent ?? "";
|
|
10891
|
-
if (text.length === 0) {
|
|
10892
|
-
return { offset: 0, pastRowEnd: false };
|
|
10893
|
-
}
|
|
10894
|
-
let closestOffset = 0;
|
|
10895
|
-
let closestDistance = Infinity;
|
|
10896
|
-
let closestYDistance = Infinity;
|
|
10897
|
-
let closestCaretX = 0;
|
|
10898
|
-
let selectedViaRightEdge = false;
|
|
10899
|
-
const rowInfo = /* @__PURE__ */ new Map();
|
|
10900
|
-
const range = document.createRange();
|
|
10901
|
-
let lastCharRect = null;
|
|
10902
|
-
for (let i = 0; i <= text.length; i += 1) {
|
|
10903
|
-
if (i < text.length) {
|
|
10904
|
-
range.setStart(textNode, i);
|
|
10905
|
-
range.setEnd(textNode, i + 1);
|
|
10906
|
-
} else {
|
|
10907
|
-
range.setStart(textNode, i);
|
|
10908
|
-
range.setEnd(textNode, i);
|
|
10909
|
-
}
|
|
10910
|
-
let rects = range.getClientRects();
|
|
10911
|
-
if (rects.length === 0 && i === text.length && lastCharRect) {
|
|
10912
|
-
const syntheticRect = new DOMRect(
|
|
10913
|
-
lastCharRect.right,
|
|
10914
|
-
lastCharRect.top,
|
|
10915
|
-
0,
|
|
10916
|
-
lastCharRect.height
|
|
10917
|
-
);
|
|
10918
|
-
rects = [syntheticRect];
|
|
10919
|
-
}
|
|
10920
|
-
if (rects.length === 0) {
|
|
10921
|
-
continue;
|
|
10922
|
-
}
|
|
10923
|
-
if (i < text.length) {
|
|
10924
|
-
lastCharRect = rects[0];
|
|
10925
|
-
}
|
|
10926
|
-
let bestRect = rects[0];
|
|
10927
|
-
for (let r = 1; r < rects.length; r += 1) {
|
|
10928
|
-
const rect = rects[r];
|
|
10929
|
-
const bestCenterY = bestRect.top + bestRect.height / 2;
|
|
10930
|
-
const rectCenterY = rect.top + rect.height / 2;
|
|
10931
|
-
if (Math.abs(clientY - rectCenterY) < Math.abs(clientY - bestCenterY)) {
|
|
10932
|
-
bestRect = rect;
|
|
10933
|
-
}
|
|
10934
|
-
}
|
|
10935
|
-
const rowKey = Math.round(bestRect.top);
|
|
10936
|
-
if (!rowInfo.has(rowKey)) {
|
|
10937
|
-
rowInfo.set(rowKey, {
|
|
10938
|
-
startOffset: i,
|
|
10939
|
-
endOffset: i,
|
|
10940
|
-
left: bestRect.left,
|
|
10941
|
-
right: bestRect.right,
|
|
10942
|
-
top: bestRect.top,
|
|
10943
|
-
bottom: bestRect.bottom
|
|
10944
|
-
});
|
|
10945
|
-
} else {
|
|
10946
|
-
const row = rowInfo.get(rowKey);
|
|
10947
|
-
if (row) {
|
|
10948
|
-
row.startOffset = Math.min(row.startOffset, i);
|
|
10949
|
-
row.endOffset = Math.max(row.endOffset, i);
|
|
10950
|
-
row.left = Math.min(row.left, bestRect.left);
|
|
10951
|
-
row.right = Math.max(row.right, bestRect.right);
|
|
10952
|
-
row.top = Math.min(row.top, bestRect.top);
|
|
10953
|
-
row.bottom = Math.max(row.bottom, bestRect.bottom);
|
|
10954
|
-
}
|
|
10955
|
-
}
|
|
10956
|
-
const centerY = bestRect.top + bestRect.height / 2;
|
|
10957
|
-
const yDistance = Math.abs(clientY - centerY);
|
|
10958
|
-
const isWithinRowBounds = clientY >= bestRect.top && clientY <= bestRect.bottom;
|
|
10959
|
-
const isSameRow = isWithinRowBounds;
|
|
10960
|
-
const caretX = bestRect.left;
|
|
10961
|
-
const xDistance = Math.abs(clientX - caretX);
|
|
10962
|
-
if (isSameRow) {
|
|
10963
|
-
if (xDistance <= closestDistance) {
|
|
10964
|
-
closestDistance = xDistance;
|
|
10965
|
-
closestOffset = i;
|
|
10966
|
-
closestCaretX = caretX;
|
|
10967
|
-
bestRect.top;
|
|
10968
|
-
closestYDistance = yDistance;
|
|
10969
|
-
selectedViaRightEdge = false;
|
|
10970
|
-
}
|
|
10971
|
-
if (i < text.length) {
|
|
10972
|
-
const rightEdgeX = bestRect.right;
|
|
10973
|
-
const rightEdgeDistance = Math.abs(clientX - rightEdgeX);
|
|
10974
|
-
if (rightEdgeDistance < closestDistance) {
|
|
10975
|
-
closestDistance = rightEdgeDistance;
|
|
10976
|
-
closestOffset = i + 1;
|
|
10977
|
-
closestCaretX = rightEdgeX;
|
|
10978
|
-
bestRect.top;
|
|
10979
|
-
closestYDistance = yDistance;
|
|
10980
|
-
selectedViaRightEdge = true;
|
|
10981
|
-
}
|
|
10982
|
-
}
|
|
10983
|
-
} else if (yDistance < closestYDistance || yDistance === closestYDistance && xDistance < closestDistance) {
|
|
10984
|
-
closestYDistance = yDistance;
|
|
10985
|
-
closestDistance = xDistance;
|
|
10986
|
-
closestOffset = i;
|
|
10987
|
-
closestCaretX = caretX;
|
|
10988
|
-
bestRect.top;
|
|
10989
|
-
}
|
|
10990
|
-
}
|
|
10991
|
-
let closestRow = null;
|
|
10992
|
-
for (const row of rowInfo.values()) {
|
|
10993
|
-
if (clientY >= row.top && clientY <= row.bottom) {
|
|
10994
|
-
closestRow = row;
|
|
10995
|
-
break;
|
|
10996
|
-
}
|
|
10997
|
-
}
|
|
10998
|
-
if (!closestRow) {
|
|
10999
|
-
let smallestDistance = Infinity;
|
|
11000
|
-
for (const row of rowInfo.values()) {
|
|
11001
|
-
const centerY = row.top + (row.bottom - row.top) / 2;
|
|
11002
|
-
const distance = Math.abs(clientY - centerY);
|
|
11003
|
-
if (distance < smallestDistance) {
|
|
11004
|
-
smallestDistance = distance;
|
|
11005
|
-
closestRow = row;
|
|
11006
|
-
}
|
|
11007
|
-
}
|
|
11008
|
-
}
|
|
11009
|
-
if (closestRow) {
|
|
11010
|
-
if (clientX < closestRow.left) {
|
|
11011
|
-
closestOffset = closestRow.startOffset;
|
|
11012
|
-
closestCaretX = closestRow.left;
|
|
11013
|
-
closestRow.top;
|
|
11014
|
-
} else if (clientX > closestRow.right) {
|
|
11015
|
-
closestOffset = Math.min(closestRow.endOffset + 1, text.length);
|
|
11016
|
-
closestCaretX = closestRow.right;
|
|
11017
|
-
closestRow.top;
|
|
11018
|
-
} else if (clientY < closestRow.top || clientY > closestRow.bottom) {
|
|
11019
|
-
let bestXDistance = Infinity;
|
|
11020
|
-
const range2 = document.createRange();
|
|
11021
|
-
for (let i = closestRow.startOffset; i <= closestRow.endOffset; i += 1) {
|
|
11022
|
-
if (i < text.length) {
|
|
11023
|
-
range2.setStart(textNode, i);
|
|
11024
|
-
range2.setEnd(textNode, i + 1);
|
|
11025
|
-
} else {
|
|
11026
|
-
range2.setStart(textNode, i);
|
|
11027
|
-
range2.setEnd(textNode, i);
|
|
11028
|
-
}
|
|
11029
|
-
const rects = range2.getClientRects();
|
|
11030
|
-
if (rects.length === 0) continue;
|
|
11031
|
-
const rect = rects[0];
|
|
11032
|
-
const xDist = Math.abs(clientX - rect.left);
|
|
11033
|
-
if (xDist <= bestXDistance) {
|
|
11034
|
-
bestXDistance = xDist;
|
|
11035
|
-
closestOffset = i;
|
|
11036
|
-
closestCaretX = rect.left;
|
|
11037
|
-
closestRow.top;
|
|
11038
|
-
}
|
|
11039
|
-
}
|
|
11040
|
-
}
|
|
11041
|
-
}
|
|
11042
|
-
const pastRowEnd = selectedViaRightEdge || closestRow !== null && clientX > closestRow.right;
|
|
11043
|
-
if (Math.abs(clientX - closestCaretX) <= 2 && closestOffset < text.length && text[closestOffset] === "\n") {
|
|
11044
|
-
closestOffset = Math.max(0, closestOffset - 1);
|
|
11045
|
-
}
|
|
11046
|
-
return { offset: closestOffset, pastRowEnd };
|
|
11047
|
-
}
|
|
11048
|
-
function caretPositionFromPoint(x, y) {
|
|
11049
|
-
const doc = document;
|
|
11050
|
-
if (typeof doc.caretPositionFromPoint === "function") {
|
|
11051
|
-
return doc.caretPositionFromPoint(x, y);
|
|
11052
|
-
}
|
|
11053
|
-
return null;
|
|
11054
|
-
}
|
|
11055
|
-
function caretRangeFromPoint(x, y) {
|
|
11056
|
-
if (typeof document.caretRangeFromPoint === "function") {
|
|
11057
|
-
return document.caretRangeFromPoint(x, y);
|
|
11058
|
-
}
|
|
11059
|
-
return null;
|
|
11060
|
-
}
|
|
11061
11373
|
function getVisualRowBoundaries(params) {
|
|
11062
11374
|
const { lines, layout, offset, affinity } = params;
|
|
11063
11375
|
if (!layout || layout.lines.length === 0) {
|
|
@@ -11152,302 +11464,6 @@ function findTextNodeAtOrBefore(nodes, start) {
|
|
|
11152
11464
|
}
|
|
11153
11465
|
return null;
|
|
11154
11466
|
}
|
|
11155
|
-
const toggleBold = ({ state: state$1, dispatch }) => {
|
|
11156
|
-
const changes = state$1.changeByRange((range) => {
|
|
11157
|
-
const isBoldBefore = state$1.sliceDoc(range.from - 2, range.from) === "**";
|
|
11158
|
-
const isBoldAfter = state$1.sliceDoc(range.to, range.to + 2) === "**";
|
|
11159
|
-
const changes2 = [];
|
|
11160
|
-
changes2.push(
|
|
11161
|
-
isBoldBefore ? {
|
|
11162
|
-
from: range.from - 2,
|
|
11163
|
-
to: range.from,
|
|
11164
|
-
insert: ""
|
|
11165
|
-
} : {
|
|
11166
|
-
from: range.from,
|
|
11167
|
-
insert: "**"
|
|
11168
|
-
}
|
|
11169
|
-
);
|
|
11170
|
-
changes2.push(
|
|
11171
|
-
isBoldAfter ? {
|
|
11172
|
-
from: range.to,
|
|
11173
|
-
to: range.to + 2,
|
|
11174
|
-
insert: ""
|
|
11175
|
-
} : {
|
|
11176
|
-
from: range.to,
|
|
11177
|
-
insert: "**"
|
|
11178
|
-
}
|
|
11179
|
-
);
|
|
11180
|
-
const extendBefore = isBoldBefore ? -2 : 2;
|
|
11181
|
-
const extendAfter = isBoldAfter ? -2 : 2;
|
|
11182
|
-
return {
|
|
11183
|
-
changes: changes2,
|
|
11184
|
-
range: state.EditorSelection.range(
|
|
11185
|
-
range.from + extendBefore,
|
|
11186
|
-
range.to + extendAfter
|
|
11187
|
-
)
|
|
11188
|
-
};
|
|
11189
|
-
});
|
|
11190
|
-
dispatch(
|
|
11191
|
-
state$1.update(changes, {
|
|
11192
|
-
scrollIntoView: true,
|
|
11193
|
-
annotations: state.Transaction.userEvent.of("input")
|
|
11194
|
-
})
|
|
11195
|
-
);
|
|
11196
|
-
return true;
|
|
11197
|
-
};
|
|
11198
|
-
const toggleItalic = ({ state: state$1, dispatch }) => {
|
|
11199
|
-
const changes = state$1.changeByRange((range) => {
|
|
11200
|
-
const isItalicBefore = state$1.sliceDoc(range.from - 1, range.from) === "*";
|
|
11201
|
-
const isItalicAfter = state$1.sliceDoc(range.to, range.to + 1) === "*";
|
|
11202
|
-
const changes2 = [];
|
|
11203
|
-
changes2.push(
|
|
11204
|
-
isItalicBefore ? {
|
|
11205
|
-
from: range.from - 1,
|
|
11206
|
-
to: range.from,
|
|
11207
|
-
insert: ""
|
|
11208
|
-
} : {
|
|
11209
|
-
from: range.from,
|
|
11210
|
-
insert: "*"
|
|
11211
|
-
}
|
|
11212
|
-
);
|
|
11213
|
-
changes2.push(
|
|
11214
|
-
isItalicAfter ? {
|
|
11215
|
-
from: range.to,
|
|
11216
|
-
to: range.to + 1,
|
|
11217
|
-
insert: ""
|
|
11218
|
-
} : {
|
|
11219
|
-
from: range.to,
|
|
11220
|
-
insert: "*"
|
|
11221
|
-
}
|
|
11222
|
-
);
|
|
11223
|
-
const extendBefore = isItalicBefore ? -1 : 1;
|
|
11224
|
-
const extendAfter = isItalicAfter ? -1 : 1;
|
|
11225
|
-
return {
|
|
11226
|
-
changes: changes2,
|
|
11227
|
-
range: state.EditorSelection.range(
|
|
11228
|
-
range.from + extendBefore,
|
|
11229
|
-
range.to + extendAfter
|
|
11230
|
-
)
|
|
11231
|
-
};
|
|
11232
|
-
});
|
|
11233
|
-
dispatch(
|
|
11234
|
-
state$1.update(changes, {
|
|
11235
|
-
scrollIntoView: true,
|
|
11236
|
-
annotations: state.Transaction.userEvent.of("input")
|
|
11237
|
-
})
|
|
11238
|
-
);
|
|
11239
|
-
return true;
|
|
11240
|
-
};
|
|
11241
|
-
const toggleStrikethrough = ({ state: state$1, dispatch }) => {
|
|
11242
|
-
const changes = state$1.changeByRange((range) => {
|
|
11243
|
-
const isStrikethroughBefore = state$1.sliceDoc(range.from - 2, range.from) === "~~";
|
|
11244
|
-
const isStrikethroughAfter = state$1.sliceDoc(range.to, range.to + 2) === "~~";
|
|
11245
|
-
const changes2 = [];
|
|
11246
|
-
changes2.push(
|
|
11247
|
-
isStrikethroughBefore ? {
|
|
11248
|
-
from: range.from - 2,
|
|
11249
|
-
to: range.from,
|
|
11250
|
-
insert: ""
|
|
11251
|
-
} : {
|
|
11252
|
-
from: range.from,
|
|
11253
|
-
insert: "~~"
|
|
11254
|
-
}
|
|
11255
|
-
);
|
|
11256
|
-
changes2.push(
|
|
11257
|
-
isStrikethroughAfter ? {
|
|
11258
|
-
from: range.to,
|
|
11259
|
-
to: range.to + 2,
|
|
11260
|
-
insert: ""
|
|
11261
|
-
} : {
|
|
11262
|
-
from: range.to,
|
|
11263
|
-
insert: "~~"
|
|
11264
|
-
}
|
|
11265
|
-
);
|
|
11266
|
-
const extendBefore = isStrikethroughBefore ? -2 : 2;
|
|
11267
|
-
const extendAfter = isStrikethroughAfter ? -2 : 2;
|
|
11268
|
-
return {
|
|
11269
|
-
changes: changes2,
|
|
11270
|
-
range: state.EditorSelection.range(
|
|
11271
|
-
range.from + extendBefore,
|
|
11272
|
-
range.to + extendAfter
|
|
11273
|
-
)
|
|
11274
|
-
};
|
|
11275
|
-
});
|
|
11276
|
-
dispatch(
|
|
11277
|
-
state$1.update(changes, {
|
|
11278
|
-
scrollIntoView: true,
|
|
11279
|
-
annotations: state.Transaction.userEvent.of("input")
|
|
11280
|
-
})
|
|
11281
|
-
);
|
|
11282
|
-
return true;
|
|
11283
|
-
};
|
|
11284
|
-
const toggleLink = ({ state: state$1, dispatch }) => {
|
|
11285
|
-
const changes = state$1.changeByRange((range) => {
|
|
11286
|
-
const changes2 = [];
|
|
11287
|
-
const selectedText = state$1.sliceDoc(range.from, range.to);
|
|
11288
|
-
const linkRegex = /^\[([^\]]*)\]\(([^)]*)\)$/;
|
|
11289
|
-
const linkMatch = selectedText.match(linkRegex);
|
|
11290
|
-
if (linkMatch) {
|
|
11291
|
-
const linkText = linkMatch[1];
|
|
11292
|
-
changes2.push({
|
|
11293
|
-
from: range.from,
|
|
11294
|
-
to: range.to,
|
|
11295
|
-
insert: linkText
|
|
11296
|
-
});
|
|
11297
|
-
return {
|
|
11298
|
-
changes: changes2,
|
|
11299
|
-
range: state.EditorSelection.range(range.from, range.from + linkText.length)
|
|
11300
|
-
};
|
|
11301
|
-
} else {
|
|
11302
|
-
changes2.push({
|
|
11303
|
-
from: range.from,
|
|
11304
|
-
insert: "["
|
|
11305
|
-
});
|
|
11306
|
-
changes2.push({
|
|
11307
|
-
from: range.to,
|
|
11308
|
-
insert: "]()"
|
|
11309
|
-
});
|
|
11310
|
-
const newCursorPos = range.to + 3;
|
|
11311
|
-
return {
|
|
11312
|
-
changes: changes2,
|
|
11313
|
-
range: state.EditorSelection.cursor(newCursorPos)
|
|
11314
|
-
// Place cursor inside ()
|
|
11315
|
-
};
|
|
11316
|
-
}
|
|
11317
|
-
});
|
|
11318
|
-
dispatch(
|
|
11319
|
-
state$1.update(changes, {
|
|
11320
|
-
scrollIntoView: true,
|
|
11321
|
-
annotations: state.Transaction.userEvent.of("input")
|
|
11322
|
-
})
|
|
11323
|
-
);
|
|
11324
|
-
return true;
|
|
11325
|
-
};
|
|
11326
|
-
const LIST_LINE_REGEX = /^(\s*)([-*+]|(\d+)\.)(\s+)(.*)/;
|
|
11327
|
-
const toggleBulletList = ({ state: state$1, dispatch }) => {
|
|
11328
|
-
const changes = state$1.changeByRange((range) => {
|
|
11329
|
-
const changes2 = [];
|
|
11330
|
-
if (range.from === range.to) {
|
|
11331
|
-
changes2.push({
|
|
11332
|
-
from: range.from,
|
|
11333
|
-
insert: "-"
|
|
11334
|
-
});
|
|
11335
|
-
return {
|
|
11336
|
-
changes: changes2,
|
|
11337
|
-
range: state.EditorSelection.cursor(range.from + 1)
|
|
11338
|
-
};
|
|
11339
|
-
}
|
|
11340
|
-
const startLine = state$1.doc.lineAt(range.from);
|
|
11341
|
-
const endLine = state$1.doc.lineAt(range.to);
|
|
11342
|
-
let rangeDelta = 0;
|
|
11343
|
-
for (let i = startLine.number; i <= endLine.number; i++) {
|
|
11344
|
-
const line = state$1.doc.line(i);
|
|
11345
|
-
const lineText = line.text;
|
|
11346
|
-
const match = lineText.match(LIST_LINE_REGEX);
|
|
11347
|
-
if (match) {
|
|
11348
|
-
const [, indent, , numberPart, space] = match;
|
|
11349
|
-
if (numberPart) {
|
|
11350
|
-
const prefixLength = indent.length + numberPart.length + 1 + space.length;
|
|
11351
|
-
const newPrefix = `${indent}- `;
|
|
11352
|
-
changes2.push({
|
|
11353
|
-
from: line.from,
|
|
11354
|
-
to: line.from + prefixLength,
|
|
11355
|
-
insert: newPrefix
|
|
11356
|
-
});
|
|
11357
|
-
rangeDelta += newPrefix.length - prefixLength;
|
|
11358
|
-
}
|
|
11359
|
-
} else {
|
|
11360
|
-
const indentMatch = lineText.match(/^(\s*)/);
|
|
11361
|
-
const indent = indentMatch ? indentMatch[1] : "";
|
|
11362
|
-
changes2.push({
|
|
11363
|
-
from: line.from + indent.length,
|
|
11364
|
-
insert: "- "
|
|
11365
|
-
});
|
|
11366
|
-
rangeDelta += 2;
|
|
11367
|
-
}
|
|
11368
|
-
}
|
|
11369
|
-
return {
|
|
11370
|
-
changes: changes2,
|
|
11371
|
-
range: state.EditorSelection.range(range.from, range.to + rangeDelta)
|
|
11372
|
-
};
|
|
11373
|
-
});
|
|
11374
|
-
dispatch(
|
|
11375
|
-
state$1.update(changes, {
|
|
11376
|
-
scrollIntoView: true,
|
|
11377
|
-
annotations: state.Transaction.userEvent.of("input")
|
|
11378
|
-
})
|
|
11379
|
-
);
|
|
11380
|
-
return true;
|
|
11381
|
-
};
|
|
11382
|
-
const toggleNumberedList = ({ state: state$1, dispatch }) => {
|
|
11383
|
-
const changes = state$1.changeByRange((range) => {
|
|
11384
|
-
const changes2 = [];
|
|
11385
|
-
if (range.from === range.to) {
|
|
11386
|
-
changes2.push({
|
|
11387
|
-
from: range.from,
|
|
11388
|
-
insert: "1. "
|
|
11389
|
-
});
|
|
11390
|
-
return {
|
|
11391
|
-
changes: changes2,
|
|
11392
|
-
range: state.EditorSelection.cursor(range.from + 3)
|
|
11393
|
-
};
|
|
11394
|
-
}
|
|
11395
|
-
const startLine = state$1.doc.lineAt(range.from);
|
|
11396
|
-
const endLine = state$1.doc.lineAt(range.to);
|
|
11397
|
-
let listNumber = 1;
|
|
11398
|
-
let rangeDelta = 0;
|
|
11399
|
-
for (let i = startLine.number; i <= endLine.number; i++) {
|
|
11400
|
-
const line = state$1.doc.line(i);
|
|
11401
|
-
const lineText = line.text;
|
|
11402
|
-
const match = lineText.match(LIST_LINE_REGEX);
|
|
11403
|
-
if (match) {
|
|
11404
|
-
const [, indent, bullet, numberPart, space] = match;
|
|
11405
|
-
if (!numberPart) {
|
|
11406
|
-
const prefixLength = indent.length + bullet.length + space.length;
|
|
11407
|
-
const newPrefix = `${indent}${listNumber}. `;
|
|
11408
|
-
changes2.push({
|
|
11409
|
-
from: line.from,
|
|
11410
|
-
to: line.from + prefixLength,
|
|
11411
|
-
insert: newPrefix
|
|
11412
|
-
});
|
|
11413
|
-
rangeDelta += newPrefix.length - prefixLength;
|
|
11414
|
-
listNumber++;
|
|
11415
|
-
} else {
|
|
11416
|
-
const prefixLength = indent.length + numberPart.length + 1 + space.length;
|
|
11417
|
-
const newPrefix = `${indent}${listNumber}. `;
|
|
11418
|
-
changes2.push({
|
|
11419
|
-
from: line.from,
|
|
11420
|
-
to: line.from + prefixLength,
|
|
11421
|
-
insert: newPrefix
|
|
11422
|
-
});
|
|
11423
|
-
rangeDelta += newPrefix.length - prefixLength;
|
|
11424
|
-
listNumber++;
|
|
11425
|
-
}
|
|
11426
|
-
} else {
|
|
11427
|
-
const indentMatch = lineText.match(/^(\s*)/);
|
|
11428
|
-
const indent = indentMatch ? indentMatch[1] : "";
|
|
11429
|
-
const newPrefix = `${listNumber}. `;
|
|
11430
|
-
changes2.push({
|
|
11431
|
-
from: line.from + indent.length,
|
|
11432
|
-
insert: newPrefix
|
|
11433
|
-
});
|
|
11434
|
-
rangeDelta += newPrefix.length;
|
|
11435
|
-
listNumber++;
|
|
11436
|
-
}
|
|
11437
|
-
}
|
|
11438
|
-
return {
|
|
11439
|
-
changes: changes2,
|
|
11440
|
-
range: state.EditorSelection.range(range.from, range.to + rangeDelta)
|
|
11441
|
-
};
|
|
11442
|
-
});
|
|
11443
|
-
dispatch(
|
|
11444
|
-
state$1.update(changes, {
|
|
11445
|
-
scrollIntoView: true,
|
|
11446
|
-
annotations: state.Transaction.userEvent.of("input")
|
|
11447
|
-
})
|
|
11448
|
-
);
|
|
11449
|
-
return true;
|
|
11450
|
-
};
|
|
11451
11467
|
function toEngineSelection(selection) {
|
|
11452
11468
|
if (!selection) {
|
|
11453
11469
|
return { start: 0, end: 0, affinity: "forward" };
|
|
@@ -11458,30 +11474,6 @@ function toEngineSelection(selection) {
|
|
|
11458
11474
|
affinity: selection.affinity
|
|
11459
11475
|
};
|
|
11460
11476
|
}
|
|
11461
|
-
const BOLD_MARKER = "**";
|
|
11462
|
-
const ITALIC_MARKER = "*";
|
|
11463
|
-
const STRIKETHROUGH_MARKER = "~~";
|
|
11464
|
-
function mapCommandToEditCommand(command) {
|
|
11465
|
-
if (command === toggleBold) {
|
|
11466
|
-
return { type: "toggle-inline", marker: BOLD_MARKER };
|
|
11467
|
-
}
|
|
11468
|
-
if (command === toggleItalic) {
|
|
11469
|
-
return { type: "toggle-inline", marker: ITALIC_MARKER };
|
|
11470
|
-
}
|
|
11471
|
-
if (command === toggleStrikethrough) {
|
|
11472
|
-
return { type: "toggle-inline", marker: STRIKETHROUGH_MARKER };
|
|
11473
|
-
}
|
|
11474
|
-
if (command === toggleLink) {
|
|
11475
|
-
return { type: "wrap-link", openPopover: true };
|
|
11476
|
-
}
|
|
11477
|
-
if (command === toggleBulletList) {
|
|
11478
|
-
return { type: "toggle-bullet-list" };
|
|
11479
|
-
}
|
|
11480
|
-
if (command === toggleNumberedList) {
|
|
11481
|
-
return { type: "toggle-numbered-list" };
|
|
11482
|
-
}
|
|
11483
|
-
return null;
|
|
11484
|
-
}
|
|
11485
11477
|
const CakeEditor = require$$0.forwardRef(
|
|
11486
11478
|
function CakeEditor2(props, outerRef) {
|
|
11487
11479
|
const containerRef = require$$0.useRef(null);
|
|
@@ -11600,15 +11592,11 @@ const CakeEditor = require$$0.forwardRef(
|
|
|
11600
11592
|
var _a;
|
|
11601
11593
|
(_a = engineRef.current) == null ? void 0 : _a.selectAll();
|
|
11602
11594
|
},
|
|
11603
|
-
executeCommand: (command) => {
|
|
11595
|
+
executeCommand: (command, options) => {
|
|
11604
11596
|
if (!engineRef.current) {
|
|
11605
11597
|
return false;
|
|
11606
11598
|
}
|
|
11607
|
-
|
|
11608
|
-
if (!editCommand) {
|
|
11609
|
-
return false;
|
|
11610
|
-
}
|
|
11611
|
-
return engineRef.current.executeCommand(editCommand);
|
|
11599
|
+
return engineRef.current.executeCommand(command, options);
|
|
11612
11600
|
},
|
|
11613
11601
|
applyUpdate: (update) => {
|
|
11614
11602
|
if (!engineRef.current) {
|