@dxos/react-ui-editor 0.4.10-main.308cc0e → 0.4.10-main.334c9db
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/lib/browser/index.mjs +648 -623
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
- package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
- package/dist/types/src/extensions/automerge/automerge.stories.d.ts.map +1 -1
- package/dist/types/src/extensions/factories.d.ts +1 -1
- package/dist/types/src/extensions/factories.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/formatting.d.ts +1 -1
- package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
- package/dist/types/src/extensions/markdown/table.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +0 -1
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/package.json +26 -25
- package/src/components/TextEditor/TextEditor.stories.tsx +18 -17
- package/src/components/TextEditor/TextEditor.tsx +3 -1
- package/src/components/Toolbar/Toolbar.stories.tsx +10 -9
- package/src/extensions/automerge/automerge.stories.tsx +7 -6
- package/src/extensions/factories.ts +2 -2
- package/src/extensions/markdown/decorate.ts +90 -62
- package/src/extensions/markdown/formatting.ts +42 -35
- package/src/extensions/markdown/highlight.ts +3 -1
- package/src/extensions/markdown/table.ts +7 -6
- package/src/hooks/index.ts +0 -1
- package/dist/types/src/hooks/useDocAccessor.d.ts +0 -9
- package/dist/types/src/hooks/useDocAccessor.d.ts.map +0 -1
- package/src/hooks/useDocAccessor.ts +0 -27
|
@@ -37,6 +37,7 @@ import { EditorView as EditorView16 } from "@codemirror/view";
|
|
|
37
37
|
import { useFocusableGroup } from "@fluentui/react-tabster";
|
|
38
38
|
import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useRef, useState as useState2 } from "react";
|
|
39
39
|
import { log as log7 } from "@dxos/log";
|
|
40
|
+
import { useDefaultValue } from "@dxos/react-ui";
|
|
40
41
|
import { isNotFalsy as isNotFalsy4 } from "@dxos/util";
|
|
41
42
|
|
|
42
43
|
// packages/ui/react-ui-editor/src/extensions/annotations.ts
|
|
@@ -2247,9 +2248,9 @@ var createThemeExtensions = ({ theme, themeMode, slots: _slots } = {}) => {
|
|
|
2247
2248
|
].filter(isNotFalsy2);
|
|
2248
2249
|
};
|
|
2249
2250
|
var createDataExtensions = ({ id, text, space, identity }) => {
|
|
2250
|
-
const extensions = [
|
|
2251
|
+
const extensions = text ? [
|
|
2251
2252
|
automerge(text)
|
|
2252
|
-
];
|
|
2253
|
+
] : [];
|
|
2253
2254
|
if (space && identity) {
|
|
2254
2255
|
const peerId = identity?.identityKey.toHex();
|
|
2255
2256
|
const { cursorLightValue, cursorDarkValue } = hueTokens[identity?.profile?.data?.hue ?? hexToHue(peerId ?? "0")];
|
|
@@ -2302,255 +2303,261 @@ var List;
|
|
|
2302
2303
|
List2[List2["Bullet"] = 1] = "Bullet";
|
|
2303
2304
|
List2[List2["Task"] = 2] = "Task";
|
|
2304
2305
|
})(List || (List = {}));
|
|
2305
|
-
var setHeading = (level) =>
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
sawBlock = true;
|
|
2319
|
-
prevBlock = node.from;
|
|
2320
|
-
const blockType = Textblocks[node.name];
|
|
2321
|
-
const isHeading = /heading(\d)/.exec(blockType);
|
|
2322
|
-
const curLevel = isHeading ? +isHeading[1] : node.name === "Paragraph" ? 0 : -1;
|
|
2323
|
-
if (curLevel < 0 || curLevel === level) {
|
|
2324
|
-
return;
|
|
2325
|
-
}
|
|
2326
|
-
if (curLevel === 0) {
|
|
2327
|
-
changes.push({
|
|
2328
|
-
from: node.from,
|
|
2329
|
-
insert: "#".repeat(level) + " "
|
|
2330
|
-
});
|
|
2331
|
-
} else if (node.name === "SetextHeading1" || node.name === "SetextHeading2") {
|
|
2332
|
-
const nextLine = doc.lineAt(node.to);
|
|
2333
|
-
if (level) {
|
|
2334
|
-
changes.push({
|
|
2335
|
-
from: node.from,
|
|
2336
|
-
insert: "#".repeat(level) + " "
|
|
2337
|
-
});
|
|
2306
|
+
var setHeading = (level) => {
|
|
2307
|
+
return ({ state: state2, dispatch }) => {
|
|
2308
|
+
const { selection: { ranges }, doc } = state2;
|
|
2309
|
+
const changes = [];
|
|
2310
|
+
let prevBlock = -1;
|
|
2311
|
+
for (const range of ranges) {
|
|
2312
|
+
let sawBlock = false;
|
|
2313
|
+
syntaxTree(state2).iterate({
|
|
2314
|
+
from: range.from,
|
|
2315
|
+
to: range.to,
|
|
2316
|
+
enter: (node) => {
|
|
2317
|
+
if (!Object.hasOwn(Textblocks, node.name) || prevBlock === node.from) {
|
|
2318
|
+
return;
|
|
2338
2319
|
}
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
if (
|
|
2320
|
+
sawBlock = true;
|
|
2321
|
+
prevBlock = node.from;
|
|
2322
|
+
const blockType = Textblocks[node.name];
|
|
2323
|
+
const isHeading = /heading(\d)/.exec(blockType);
|
|
2324
|
+
const curLevel = isHeading ? +isHeading[1] : node.name === "Paragraph" ? 0 : -1;
|
|
2325
|
+
if (curLevel < 0 || curLevel === level) {
|
|
2326
|
+
return;
|
|
2327
|
+
}
|
|
2328
|
+
if (curLevel === 0) {
|
|
2345
2329
|
changes.push({
|
|
2346
2330
|
from: node.from,
|
|
2347
|
-
|
|
2331
|
+
insert: "#".repeat(level) + " "
|
|
2348
2332
|
});
|
|
2349
|
-
} else if (
|
|
2333
|
+
} else if (node.name === "SetextHeading1" || node.name === "SetextHeading2") {
|
|
2334
|
+
const nextLine = doc.lineAt(node.to);
|
|
2335
|
+
if (level) {
|
|
2336
|
+
changes.push({
|
|
2337
|
+
from: node.from,
|
|
2338
|
+
insert: "#".repeat(level) + " "
|
|
2339
|
+
});
|
|
2340
|
+
}
|
|
2350
2341
|
changes.push({
|
|
2351
|
-
from:
|
|
2352
|
-
to:
|
|
2342
|
+
from: nextLine.from - 1,
|
|
2343
|
+
to: nextLine.to
|
|
2353
2344
|
});
|
|
2354
2345
|
} else {
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2346
|
+
if (level === 0) {
|
|
2347
|
+
changes.push({
|
|
2348
|
+
from: node.from,
|
|
2349
|
+
to: Math.min(node.to, node.from + curLevel + 1)
|
|
2350
|
+
});
|
|
2351
|
+
} else if (level < curLevel) {
|
|
2352
|
+
changes.push({
|
|
2353
|
+
from: node.from,
|
|
2354
|
+
to: node.from + (curLevel - level)
|
|
2355
|
+
});
|
|
2356
|
+
} else {
|
|
2357
|
+
changes.push({
|
|
2358
|
+
from: node.from,
|
|
2359
|
+
insert: "#".repeat(level - curLevel)
|
|
2360
|
+
});
|
|
2361
|
+
}
|
|
2359
2362
|
}
|
|
2360
2363
|
}
|
|
2361
|
-
}
|
|
2362
|
-
});
|
|
2363
|
-
let line;
|
|
2364
|
-
if (!sawBlock && range.empty && level > 0 && !/\S/.test((line = state2.doc.lineAt(range.from)).text)) {
|
|
2365
|
-
changes.push({
|
|
2366
|
-
from: line.from,
|
|
2367
|
-
to: line.to,
|
|
2368
|
-
insert: "#".repeat(level) + " "
|
|
2369
2364
|
});
|
|
2365
|
+
let line;
|
|
2366
|
+
if (!sawBlock && range.empty && level > 0 && !/\S/.test((line = state2.doc.lineAt(range.from)).text)) {
|
|
2367
|
+
changes.push({
|
|
2368
|
+
from: line.from,
|
|
2369
|
+
to: line.to,
|
|
2370
|
+
insert: "#".repeat(level) + " "
|
|
2371
|
+
});
|
|
2372
|
+
}
|
|
2370
2373
|
}
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2374
|
+
if (!changes.length) {
|
|
2375
|
+
return false;
|
|
2376
|
+
}
|
|
2377
|
+
const changeSet = state2.changes(changes);
|
|
2378
|
+
dispatch(state2.update({
|
|
2379
|
+
changes: changeSet,
|
|
2380
|
+
selection: state2.selection.map(changeSet, 1),
|
|
2381
|
+
userEvent: "format.setHeading",
|
|
2382
|
+
scrollIntoView: true
|
|
2383
|
+
}));
|
|
2384
|
+
return true;
|
|
2385
|
+
};
|
|
2383
2386
|
};
|
|
2384
|
-
var setStyle = (type, enable) =>
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2387
|
+
var setStyle = (type, enable) => {
|
|
2388
|
+
return ({ state: state2, dispatch }) => {
|
|
2389
|
+
const marker = inlineMarkerText(type);
|
|
2390
|
+
const changes = state2.changeByRange((range) => {
|
|
2391
|
+
if (!enable && range.empty) {
|
|
2392
|
+
const after = state2.doc.sliceString(range.head, range.head + 6);
|
|
2393
|
+
const found = after.indexOf(marker);
|
|
2394
|
+
if (found >= 0 && /^[*~`]*$/.test(after.slice(0, found))) {
|
|
2395
|
+
const before = state2.doc.sliceString(range.head - 6, range.head);
|
|
2396
|
+
if (before.slice(before.length - found - marker.length, before.length - found) === marker && [
|
|
2397
|
+
...before.slice(before.length - found)
|
|
2398
|
+
].reverse().join("") === after.slice(0, found)) {
|
|
2399
|
+
return {
|
|
2400
|
+
changes: [
|
|
2401
|
+
{
|
|
2402
|
+
from: range.head - marker.length - found,
|
|
2403
|
+
to: range.head - found
|
|
2404
|
+
},
|
|
2405
|
+
{
|
|
2406
|
+
from: range.head + found,
|
|
2407
|
+
to: range.head + found + marker.length
|
|
2408
|
+
}
|
|
2409
|
+
],
|
|
2410
|
+
range: EditorSelection.cursor(range.from - marker.length)
|
|
2411
|
+
};
|
|
2412
|
+
}
|
|
2408
2413
|
}
|
|
2409
2414
|
}
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
if (from < node.from && to > node.from && to <= node.to) {
|
|
2429
|
-
to = node.to;
|
|
2430
|
-
} else if (to > node.to && from >= node.from && from < node.to) {
|
|
2431
|
-
from = node.from;
|
|
2432
|
-
}
|
|
2433
|
-
} else if (IgnoreInline.has(name) && enable) {
|
|
2434
|
-
if (node.from < from && node.to > from) {
|
|
2435
|
-
if (to === from) {
|
|
2415
|
+
const changes2 = [];
|
|
2416
|
+
const changesAtEnd = [];
|
|
2417
|
+
let blockStart = -1;
|
|
2418
|
+
let blockEnd = -1;
|
|
2419
|
+
let startCovered = false;
|
|
2420
|
+
let endCovered = false;
|
|
2421
|
+
let { from, to } = range;
|
|
2422
|
+
syntaxTree(state2).iterate({
|
|
2423
|
+
from,
|
|
2424
|
+
to,
|
|
2425
|
+
enter: (node) => {
|
|
2426
|
+
const { name } = node;
|
|
2427
|
+
if (Object.hasOwn(Textblocks, name) && Textblocks[name] !== "codeblock") {
|
|
2428
|
+
blockStart = blockContentStart(node);
|
|
2429
|
+
blockEnd = blockContentEnd(node, state2.doc);
|
|
2430
|
+
startCovered = endCovered = false;
|
|
2431
|
+
} else if (name === "Link" || name === "Image" && enable) {
|
|
2432
|
+
if (from < node.from && to > node.from && to <= node.to) {
|
|
2436
2433
|
to = node.to;
|
|
2434
|
+
} else if (to > node.to && from >= node.from && from < node.to) {
|
|
2435
|
+
from = node.from;
|
|
2437
2436
|
}
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
const markType = InlineMarker[name];
|
|
2445
|
-
const size = inlineMarkerText(markType).length;
|
|
2446
|
-
const openEnd = node.from + size;
|
|
2447
|
-
const closeStart = node.to - size;
|
|
2448
|
-
if (markType === type) {
|
|
2449
|
-
if (openEnd <= from && closeStart >= from) {
|
|
2450
|
-
startCovered = !enable && openEnd === skipMarkers(from, node.node, -1, openEnd) ? {
|
|
2451
|
-
from: node.from,
|
|
2452
|
-
to: openEnd
|
|
2453
|
-
} : true;
|
|
2437
|
+
} else if (IgnoreInline.has(name) && enable) {
|
|
2438
|
+
if (node.from < from && node.to > from) {
|
|
2439
|
+
if (to === from) {
|
|
2440
|
+
to = node.to;
|
|
2441
|
+
}
|
|
2442
|
+
from = node.to;
|
|
2454
2443
|
}
|
|
2455
|
-
if (
|
|
2456
|
-
|
|
2457
|
-
from: closeStart,
|
|
2458
|
-
to: node.to
|
|
2459
|
-
} : true;
|
|
2444
|
+
if (node.from < to && node.to > to) {
|
|
2445
|
+
to = node.from;
|
|
2460
2446
|
}
|
|
2461
|
-
}
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2447
|
+
} else if (Object.hasOwn(InlineMarker, name)) {
|
|
2448
|
+
const markType = InlineMarker[name];
|
|
2449
|
+
const size = inlineMarkerText(markType).length;
|
|
2450
|
+
const openEnd = node.from + size;
|
|
2451
|
+
const closeStart = node.to - size;
|
|
2452
|
+
if (markType === type) {
|
|
2453
|
+
if (openEnd <= from && closeStart >= from) {
|
|
2454
|
+
startCovered = !enable && openEnd === skipMarkers(from, node.node, -1, openEnd) ? {
|
|
2455
|
+
from: node.from,
|
|
2456
|
+
to: openEnd
|
|
2457
|
+
} : true;
|
|
2458
|
+
}
|
|
2459
|
+
if (openEnd <= to && closeStart >= to) {
|
|
2460
|
+
endCovered = !enable && closeStart === skipMarkers(to, node.node, 1, closeStart) ? {
|
|
2461
|
+
from: closeStart,
|
|
2462
|
+
to: node.to
|
|
2463
|
+
} : true;
|
|
2473
2464
|
}
|
|
2474
2465
|
}
|
|
2475
|
-
if (
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2466
|
+
if (markType === type || type === 3 && enable) {
|
|
2467
|
+
if (node.from >= from && openEnd <= to) {
|
|
2468
|
+
changes2.push({
|
|
2469
|
+
from: node.from,
|
|
2470
|
+
to: openEnd
|
|
2471
|
+
});
|
|
2472
|
+
if (markType !== type && closeStart >= to) {
|
|
2473
|
+
changesAtEnd.push({
|
|
2474
|
+
from: skipSpaces(Math.min(to, blockEnd), state2.doc, 1, blockEnd),
|
|
2475
|
+
insert: inlineMarkerText(markType)
|
|
2476
|
+
});
|
|
2477
|
+
}
|
|
2478
|
+
}
|
|
2479
|
+
if (closeStart >= from && node.to <= to) {
|
|
2481
2480
|
changes2.push({
|
|
2482
|
-
from:
|
|
2483
|
-
|
|
2481
|
+
from: closeStart,
|
|
2482
|
+
to: node.to
|
|
2484
2483
|
});
|
|
2484
|
+
if (markType !== type && openEnd <= from) {
|
|
2485
|
+
changes2.push({
|
|
2486
|
+
from: skipSpaces(Math.max(from, blockStart), state2.doc, -1, blockStart),
|
|
2487
|
+
insert: inlineMarkerText(markType)
|
|
2488
|
+
});
|
|
2489
|
+
}
|
|
2485
2490
|
}
|
|
2486
2491
|
}
|
|
2487
2492
|
}
|
|
2488
|
-
}
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
}
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
}
|
|
2506
|
-
}
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
}
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
}
|
|
2493
|
+
},
|
|
2494
|
+
leave: (node) => {
|
|
2495
|
+
if (Object.hasOwn(Textblocks, node.name) && Textblocks[node.name] !== "codeblock") {
|
|
2496
|
+
const rangeStart = Math.max(from, blockStart);
|
|
2497
|
+
const rangeEnd = Math.min(to, blockEnd);
|
|
2498
|
+
if (enable) {
|
|
2499
|
+
if (!startCovered) {
|
|
2500
|
+
changes2.push({
|
|
2501
|
+
from: rangeStart,
|
|
2502
|
+
insert: marker
|
|
2503
|
+
});
|
|
2504
|
+
}
|
|
2505
|
+
if (!endCovered) {
|
|
2506
|
+
changes2.push({
|
|
2507
|
+
from: rangeEnd,
|
|
2508
|
+
insert: marker
|
|
2509
|
+
});
|
|
2510
|
+
}
|
|
2511
|
+
} else {
|
|
2512
|
+
if (typeof startCovered === "object") {
|
|
2513
|
+
changes2.push(startCovered);
|
|
2514
|
+
} else if (startCovered) {
|
|
2515
|
+
changes2.push({
|
|
2516
|
+
from: skipSpaces(rangeStart, state2.doc, -1, blockStart),
|
|
2517
|
+
insert: marker
|
|
2518
|
+
});
|
|
2519
|
+
}
|
|
2520
|
+
if (typeof endCovered === "object") {
|
|
2521
|
+
changes2.push(endCovered);
|
|
2522
|
+
} else if (endCovered) {
|
|
2523
|
+
changes2.push({
|
|
2524
|
+
from: skipSpaces(rangeEnd, state2.doc, 1, blockEnd),
|
|
2525
|
+
insert: marker
|
|
2526
|
+
});
|
|
2527
|
+
}
|
|
2523
2528
|
}
|
|
2524
2529
|
}
|
|
2525
2530
|
}
|
|
2531
|
+
});
|
|
2532
|
+
if (blockStart < 0 && range.empty && enable && !/\S/.test(state2.doc.lineAt(range.from).text)) {
|
|
2533
|
+
return {
|
|
2534
|
+
changes: {
|
|
2535
|
+
from: range.head,
|
|
2536
|
+
insert: marker + marker
|
|
2537
|
+
},
|
|
2538
|
+
range: EditorSelection.cursor(range.head + marker.length)
|
|
2539
|
+
};
|
|
2526
2540
|
}
|
|
2527
|
-
|
|
2528
|
-
if (blockStart < 0 && range.empty && enable && !/\S/.test(state2.doc.lineAt(range.from).text)) {
|
|
2541
|
+
const changeSet = state2.changes(changes2.concat(changesAtEnd));
|
|
2529
2542
|
return {
|
|
2530
|
-
changes:
|
|
2531
|
-
|
|
2532
|
-
insert: marker + marker
|
|
2533
|
-
},
|
|
2534
|
-
range: EditorSelection.cursor(range.head + marker.length)
|
|
2543
|
+
changes: changeSet,
|
|
2544
|
+
range: range.empty && !changeSet.empty ? EditorSelection.cursor(range.head + marker.length) : EditorSelection.range(changeSet.mapPos(range.from, 1), changeSet.mapPos(range.to, -1))
|
|
2535
2545
|
};
|
|
2536
|
-
}
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
}
|
|
2543
|
-
dispatch(state2.update(changes, {
|
|
2544
|
-
userEvent: enable ? "format.style.add" : "format.style.remove",
|
|
2545
|
-
scrollIntoView: true
|
|
2546
|
-
}));
|
|
2547
|
-
return true;
|
|
2546
|
+
});
|
|
2547
|
+
dispatch(state2.update(changes, {
|
|
2548
|
+
userEvent: enable ? "format.style.add" : "format.style.remove",
|
|
2549
|
+
scrollIntoView: true
|
|
2550
|
+
}));
|
|
2551
|
+
return true;
|
|
2552
|
+
};
|
|
2548
2553
|
};
|
|
2549
2554
|
var addStyle = (style) => setStyle(style, true);
|
|
2550
2555
|
var removeStyle = (style) => setStyle(style, false);
|
|
2551
|
-
var toggleStyle = (style) =>
|
|
2552
|
-
|
|
2553
|
-
|
|
2556
|
+
var toggleStyle = (style) => {
|
|
2557
|
+
return (arg) => {
|
|
2558
|
+
const form = getFormatting(arg.state);
|
|
2559
|
+
return setStyle(style, style === 0 ? !form.strong : style === 1 ? !form.emphasis : style === 2 ? !form.strikethrough : !form.code)(arg);
|
|
2560
|
+
};
|
|
2554
2561
|
};
|
|
2555
2562
|
var toggleStrong = toggleStyle(0);
|
|
2556
2563
|
var toggleEmphasis = toggleStyle(1);
|
|
@@ -2654,296 +2661,305 @@ var removeLink = ({ state: state2, dispatch }) => {
|
|
|
2654
2661
|
}));
|
|
2655
2662
|
return true;
|
|
2656
2663
|
};
|
|
2657
|
-
var addLink = ({ url, image: image2 } = {}) =>
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
if (
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
if (
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2664
|
+
var addLink = ({ url, image: image2 } = {}) => {
|
|
2665
|
+
return ({ state: state2, dispatch }) => {
|
|
2666
|
+
const changes = state2.changeByRange((range) => {
|
|
2667
|
+
let { from, to } = range;
|
|
2668
|
+
const cutStyles = [];
|
|
2669
|
+
let okay = null;
|
|
2670
|
+
syntaxTree(state2).iterate({
|
|
2671
|
+
from,
|
|
2672
|
+
to,
|
|
2673
|
+
enter: (node) => {
|
|
2674
|
+
if (Object.hasOwn(Textblocks, node.name)) {
|
|
2675
|
+
okay = Textblocks[node.name] !== "codeblock" && from >= blockContentStart(node) && to <= blockContentEnd(node, state2.doc);
|
|
2676
|
+
} else if (Object.hasOwn(InlineMarker, node.name)) {
|
|
2677
|
+
const sNode = node.node;
|
|
2678
|
+
if (node.from < from && node.to <= to) {
|
|
2679
|
+
if (sNode.firstChild.to === from) {
|
|
2680
|
+
from = node.from;
|
|
2681
|
+
} else {
|
|
2682
|
+
cutStyles.push(sNode);
|
|
2683
|
+
}
|
|
2684
|
+
} else if (node.from >= from && node.to > to) {
|
|
2685
|
+
if (sNode.lastChild.from === to) {
|
|
2686
|
+
to = node.to;
|
|
2687
|
+
} else {
|
|
2688
|
+
cutStyles.push(sNode);
|
|
2689
|
+
}
|
|
2681
2690
|
}
|
|
2682
2691
|
}
|
|
2683
2692
|
}
|
|
2693
|
+
});
|
|
2694
|
+
if (okay === null) {
|
|
2695
|
+
const line = state2.doc.lineAt(from);
|
|
2696
|
+
okay = to <= line.to && !/\S/.test(line.text.slice(from - line.from));
|
|
2684
2697
|
}
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
}
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2698
|
+
if (!okay) {
|
|
2699
|
+
return {
|
|
2700
|
+
range
|
|
2701
|
+
};
|
|
2702
|
+
}
|
|
2703
|
+
const changes2 = [];
|
|
2704
|
+
const changesAfter = [];
|
|
2705
|
+
removeLinkInner(from, to, changesAfter, state2);
|
|
2706
|
+
let cursorOffset = 1;
|
|
2707
|
+
for (const style of cutStyles) {
|
|
2708
|
+
const type = InlineMarker[style.name];
|
|
2709
|
+
const mark2 = inlineMarkerText(type);
|
|
2710
|
+
if (style.from < from) {
|
|
2711
|
+
changes2.push({
|
|
2712
|
+
from: skipSpaces(from, state2.doc, -1),
|
|
2713
|
+
insert: mark2
|
|
2714
|
+
});
|
|
2715
|
+
changesAfter.push({
|
|
2716
|
+
from: skipSpaces(from, state2.doc, 1, to),
|
|
2717
|
+
insert: mark2
|
|
2718
|
+
});
|
|
2719
|
+
} else {
|
|
2720
|
+
changes2.push({
|
|
2721
|
+
from: skipSpaces(to, state2.doc, -1, from),
|
|
2722
|
+
insert: mark2
|
|
2723
|
+
});
|
|
2724
|
+
const after = skipSpaces(to, state2.doc, 1);
|
|
2725
|
+
if (after === to) {
|
|
2726
|
+
cursorOffset += mark2.length;
|
|
2727
|
+
}
|
|
2728
|
+
changesAfter.push({
|
|
2729
|
+
from: after,
|
|
2730
|
+
insert: mark2
|
|
2731
|
+
});
|
|
2719
2732
|
}
|
|
2720
|
-
changesAfter.push({
|
|
2721
|
-
from: after,
|
|
2722
|
-
insert: mark2
|
|
2723
|
-
});
|
|
2724
2733
|
}
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2734
|
+
changes2.push({
|
|
2735
|
+
from,
|
|
2736
|
+
insert: image2 ? "`
|
|
2740
|
+
});
|
|
2741
|
+
const changeSet = state2.changes(changes2.concat(changesAfter));
|
|
2742
|
+
return {
|
|
2743
|
+
changes: changeSet,
|
|
2744
|
+
range: EditorSelection.cursor(changeSet.mapPos(to, 1) - cursorOffset - (url ? url.length + 2 : 0))
|
|
2745
|
+
};
|
|
2732
2746
|
});
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
return
|
|
2741
|
-
}
|
|
2742
|
-
dispatch(state2.update(changes, {
|
|
2743
|
-
userEvent: "format.link.add",
|
|
2744
|
-
scrollIntoView: true
|
|
2745
|
-
}));
|
|
2746
|
-
return true;
|
|
2747
|
+
if (changes.changes.empty) {
|
|
2748
|
+
return false;
|
|
2749
|
+
}
|
|
2750
|
+
dispatch(state2.update(changes, {
|
|
2751
|
+
userEvent: "format.link.add",
|
|
2752
|
+
scrollIntoView: true
|
|
2753
|
+
}));
|
|
2754
|
+
return true;
|
|
2755
|
+
};
|
|
2747
2756
|
};
|
|
2748
|
-
var addList = (type) =>
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
if (
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
before
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2757
|
+
var addList = (type) => {
|
|
2758
|
+
return ({ state: state2, dispatch }) => {
|
|
2759
|
+
let lastBlock = -1;
|
|
2760
|
+
let counter = 1;
|
|
2761
|
+
let first = true;
|
|
2762
|
+
let parentColumn = null;
|
|
2763
|
+
const blocks = [];
|
|
2764
|
+
for (const { from, to } of state2.selection.ranges) {
|
|
2765
|
+
syntaxTree(state2).iterate({
|
|
2766
|
+
from,
|
|
2767
|
+
to,
|
|
2768
|
+
enter: (node) => {
|
|
2769
|
+
if (Object.hasOwn(Textblocks, node.name) && node.name !== "TableCell" || node.name === "Table") {
|
|
2770
|
+
if (first) {
|
|
2771
|
+
let before = node.node.prevSibling;
|
|
2772
|
+
while (before && /Mark$/.test(before.name)) {
|
|
2773
|
+
before = before.prevSibling;
|
|
2774
|
+
}
|
|
2775
|
+
if (before?.name === (type === 0 ? "OrderedList" : "BulletList")) {
|
|
2776
|
+
const item = before.lastChild;
|
|
2777
|
+
const itemLine = state2.doc.lineAt(item.from);
|
|
2778
|
+
const itemText = itemLine.text.slice(item.from - itemLine.from);
|
|
2779
|
+
parentColumn = item.from - itemLine.from + /^\s*/.exec(itemText)[0].length;
|
|
2780
|
+
if (type === 0) {
|
|
2781
|
+
const mark2 = /^\s*(\d+)[.)]/.exec(itemText);
|
|
2782
|
+
if (mark2) {
|
|
2783
|
+
parentColumn += mark2[1].length;
|
|
2784
|
+
counter = +mark2[1] + 1;
|
|
2785
|
+
}
|
|
2775
2786
|
}
|
|
2776
2787
|
}
|
|
2788
|
+
first = false;
|
|
2789
|
+
}
|
|
2790
|
+
if (node.from === lastBlock) {
|
|
2791
|
+
return;
|
|
2777
2792
|
}
|
|
2778
|
-
|
|
2793
|
+
lastBlock = node.from;
|
|
2794
|
+
blocks.push({
|
|
2795
|
+
node: node.node,
|
|
2796
|
+
counter,
|
|
2797
|
+
parentColumn
|
|
2798
|
+
});
|
|
2799
|
+
counter++;
|
|
2800
|
+
return false;
|
|
2779
2801
|
}
|
|
2780
|
-
|
|
2781
|
-
|
|
2802
|
+
},
|
|
2803
|
+
leave: (node) => {
|
|
2804
|
+
if (node.name === "BulletList" || node.name === "OrderedList" || node.name === "Blockquote") {
|
|
2805
|
+
counter = 1;
|
|
2806
|
+
parentColumn = null;
|
|
2782
2807
|
}
|
|
2783
|
-
lastBlock = node.from;
|
|
2784
|
-
blocks.push({
|
|
2785
|
-
node: node.node,
|
|
2786
|
-
counter,
|
|
2787
|
-
parentColumn
|
|
2788
|
-
});
|
|
2789
|
-
counter++;
|
|
2790
|
-
return false;
|
|
2791
|
-
}
|
|
2792
|
-
},
|
|
2793
|
-
leave: (node) => {
|
|
2794
|
-
if (node.name === "BulletList" || node.name === "OrderedList" || node.name === "Blockquote") {
|
|
2795
|
-
counter = 1;
|
|
2796
|
-
parentColumn = null;
|
|
2797
2808
|
}
|
|
2798
|
-
}
|
|
2799
|
-
});
|
|
2800
|
-
}
|
|
2801
|
-
if (!blocks.length) {
|
|
2802
|
-
const { from, to } = state2.doc.lineAt(state2.selection.main.anchor);
|
|
2803
|
-
if (from === to) {
|
|
2804
|
-
const insert = type === 1 ? "- " : type === 0 ? "1. " : "- [ ] ";
|
|
2805
|
-
dispatch(state2.update({
|
|
2806
|
-
changes: [
|
|
2807
|
-
{
|
|
2808
|
-
from,
|
|
2809
|
-
insert
|
|
2810
|
-
}
|
|
2811
|
-
],
|
|
2812
|
-
selection: {
|
|
2813
|
-
anchor: from + insert.length
|
|
2814
|
-
},
|
|
2815
|
-
userEvent: "format.list.add",
|
|
2816
|
-
scrollIntoView: true
|
|
2817
|
-
}));
|
|
2818
|
-
return true;
|
|
2819
|
-
}
|
|
2820
|
-
return false;
|
|
2821
|
-
}
|
|
2822
|
-
const changes = [];
|
|
2823
|
-
for (let i = 0; i < blocks.length; i++) {
|
|
2824
|
-
const { node, counter: counter2, parentColumn: parentColumn2 } = blocks[i];
|
|
2825
|
-
const nodeFrom = node.name === "CodeBlock" ? node.from - 4 : node.from;
|
|
2826
|
-
let padding = nodeFrom > 0 && !/\s/.test(state2.doc.sliceString(nodeFrom - 1, nodeFrom)) ? 1 : 0;
|
|
2827
|
-
if (type === 0) {
|
|
2828
|
-
padding += String(counter2).length;
|
|
2809
|
+
});
|
|
2829
2810
|
}
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2811
|
+
if (!blocks.length) {
|
|
2812
|
+
const { from, to } = state2.doc.lineAt(state2.selection.main.anchor);
|
|
2813
|
+
if (from === to) {
|
|
2814
|
+
const insert = type === 1 ? "- " : type === 0 ? "1. " : "- [ ] ";
|
|
2815
|
+
dispatch(state2.update({
|
|
2816
|
+
changes: [
|
|
2817
|
+
{
|
|
2818
|
+
from,
|
|
2819
|
+
insert
|
|
2820
|
+
}
|
|
2821
|
+
],
|
|
2822
|
+
selection: {
|
|
2823
|
+
anchor: from + insert.length
|
|
2824
|
+
},
|
|
2825
|
+
userEvent: "format.list.add",
|
|
2826
|
+
scrollIntoView: true
|
|
2827
|
+
}));
|
|
2828
|
+
return true;
|
|
2829
|
+
}
|
|
2830
|
+
return false;
|
|
2834
2831
|
}
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2832
|
+
const changes = [];
|
|
2833
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
2834
|
+
const { node, counter: counter2, parentColumn: parentColumn2 } = blocks[i];
|
|
2835
|
+
const nodeFrom = node.name === "CodeBlock" ? node.from - 4 : node.from;
|
|
2836
|
+
let padding = nodeFrom > 0 && !/\s/.test(state2.doc.sliceString(nodeFrom - 1, nodeFrom)) ? 1 : 0;
|
|
2837
|
+
if (type === 0) {
|
|
2838
|
+
padding += String(counter2).length;
|
|
2839
|
+
}
|
|
2840
|
+
let line = state2.doc.lineAt(nodeFrom);
|
|
2841
|
+
const column = nodeFrom - line.from;
|
|
2842
|
+
if (parentColumn2 !== null && parentColumn2 > column) {
|
|
2843
|
+
padding = Math.max(padding, parentColumn2 - column);
|
|
2844
|
+
}
|
|
2845
|
+
let mark2;
|
|
2846
|
+
if (type === 0) {
|
|
2847
|
+
let max = counter2;
|
|
2848
|
+
for (let j = i + 1; j < blocks.length; j++) {
|
|
2849
|
+
if (blocks[j].counter !== max + 1) {
|
|
2850
|
+
break;
|
|
2851
|
+
}
|
|
2852
|
+
max++;
|
|
2841
2853
|
}
|
|
2842
|
-
|
|
2854
|
+
const num = String(counter2);
|
|
2855
|
+
padding = Math.max(String(max).length, padding);
|
|
2856
|
+
mark2 = " ".repeat(Math.max(0, padding - num.length)) + num + ". ";
|
|
2857
|
+
} else {
|
|
2858
|
+
mark2 = " ".repeat(padding) + "- " + (type === 2 ? "[ ] " : "");
|
|
2843
2859
|
}
|
|
2844
|
-
const num = String(counter2);
|
|
2845
|
-
padding = Math.max(String(max).length, padding);
|
|
2846
|
-
mark2 = " ".repeat(Math.max(0, padding - num.length)) + num + ". ";
|
|
2847
|
-
} else {
|
|
2848
|
-
mark2 = " ".repeat(padding) + "- " + (type === 2 ? "[ ] " : "");
|
|
2849
|
-
}
|
|
2850
|
-
changes.push({
|
|
2851
|
-
from: nodeFrom,
|
|
2852
|
-
insert: mark2
|
|
2853
|
-
});
|
|
2854
|
-
while (line.to < node.to) {
|
|
2855
|
-
line = state2.doc.lineAt(line.to + 1);
|
|
2856
|
-
const open = /^[\s>]*/.exec(line.text)[0].length;
|
|
2857
2860
|
changes.push({
|
|
2858
|
-
from:
|
|
2859
|
-
insert:
|
|
2861
|
+
from: nodeFrom,
|
|
2862
|
+
insert: mark2
|
|
2860
2863
|
});
|
|
2864
|
+
while (line.to < node.to) {
|
|
2865
|
+
line = state2.doc.lineAt(line.to + 1);
|
|
2866
|
+
const open = /^[\s>]*/.exec(line.text)[0].length;
|
|
2867
|
+
changes.push({
|
|
2868
|
+
from: line.from + Math.min(open, column),
|
|
2869
|
+
insert: " ".repeat(mark2.length)
|
|
2870
|
+
});
|
|
2871
|
+
}
|
|
2861
2872
|
}
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2873
|
+
if (type === 0) {
|
|
2874
|
+
const last = blocks[blocks.length - 1];
|
|
2875
|
+
let next = last.node.nextSibling;
|
|
2876
|
+
while (next && /Mark$/.test(next.name)) {
|
|
2877
|
+
next = next.nextSibling;
|
|
2878
|
+
}
|
|
2879
|
+
if (next?.name === "OrderedList") {
|
|
2880
|
+
renumberListItems(next.firstChild, last.counter + 1, changes, state2.doc);
|
|
2881
|
+
}
|
|
2871
2882
|
}
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2883
|
+
"Oeswe";
|
|
2884
|
+
const changeSet = state2.changes(changes);
|
|
2885
|
+
dispatch(state2.update({
|
|
2886
|
+
changes: changeSet,
|
|
2887
|
+
selection: state2.selection.map(changeSet, 1),
|
|
2888
|
+
userEvent: "format.list.add",
|
|
2889
|
+
scrollIntoView: true
|
|
2890
|
+
}));
|
|
2891
|
+
return true;
|
|
2892
|
+
};
|
|
2881
2893
|
};
|
|
2882
|
-
var removeList = (type) =>
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
stack[stack.length - 1]
|
|
2897
|
-
|
|
2898
|
-
},
|
|
2899
|
-
leave: (node) => {
|
|
2900
|
-
const { name } = node;
|
|
2901
|
-
if (name === "BulletList" || name === "OrderedList" || name === "Blockquote") {
|
|
2902
|
-
stack.pop();
|
|
2903
|
-
} else if (name === "ListItem" && stack[stack.length - 1] === targetNodeType && node.from !== lastBlock) {
|
|
2904
|
-
lastBlock = node.from;
|
|
2905
|
-
let line = state2.doc.lineAt(node.from);
|
|
2906
|
-
const mark2 = /^\s*(\d+[.)] |[-*+] (\[[ x]\] )?)/.exec(line.text.slice(node.from - line.from));
|
|
2907
|
-
if (!mark2) {
|
|
2908
|
-
return false;
|
|
2894
|
+
var removeList = (type) => {
|
|
2895
|
+
return ({ state: state2, dispatch }) => {
|
|
2896
|
+
let lastBlock = -1;
|
|
2897
|
+
const changes = [];
|
|
2898
|
+
const stack = [];
|
|
2899
|
+
const targetNodeType = type === 0 ? "OrderedList" : type === 1 ? "BulletList" : "TaskList";
|
|
2900
|
+
for (const { from, to } of state2.selection.ranges) {
|
|
2901
|
+
syntaxTree(state2).iterate({
|
|
2902
|
+
from,
|
|
2903
|
+
to,
|
|
2904
|
+
enter: (node) => {
|
|
2905
|
+
const { name } = node;
|
|
2906
|
+
if (name === "BulletList" || name === "OrderedList" || name === "Blockquote") {
|
|
2907
|
+
stack.push(name);
|
|
2908
|
+
} else if (name === "Task" && stack[stack.length - 1] === "BulletList") {
|
|
2909
|
+
stack[stack.length - 1] = "TaskList";
|
|
2909
2910
|
}
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
to: line.from + Math.min(column + mark2[0].length, open)
|
|
2922
|
-
});
|
|
2911
|
+
},
|
|
2912
|
+
leave: (node) => {
|
|
2913
|
+
const { name } = node;
|
|
2914
|
+
if (name === "BulletList" || name === "OrderedList" || name === "Blockquote") {
|
|
2915
|
+
stack.pop();
|
|
2916
|
+
} else if (name === "ListItem" && stack[stack.length - 1] === targetNodeType && node.from !== lastBlock) {
|
|
2917
|
+
lastBlock = node.from;
|
|
2918
|
+
let line = state2.doc.lineAt(node.from);
|
|
2919
|
+
const mark2 = /^\s*(\d+[.)] |[-*+] (\[[ x]\] )?)/.exec(line.text.slice(node.from - line.from));
|
|
2920
|
+
if (!mark2) {
|
|
2921
|
+
return false;
|
|
2923
2922
|
}
|
|
2923
|
+
const column = node.from - line.from;
|
|
2924
|
+
changes.push({
|
|
2925
|
+
from: node.from,
|
|
2926
|
+
to: node.from + mark2[0].length
|
|
2927
|
+
});
|
|
2928
|
+
while (line.to < node.to) {
|
|
2929
|
+
line = state2.doc.lineAt(line.to + 1);
|
|
2930
|
+
const open = /^[\s>]*/.exec(line.text)[0].length;
|
|
2931
|
+
if (open > column) {
|
|
2932
|
+
changes.push({
|
|
2933
|
+
from: line.from + column,
|
|
2934
|
+
to: line.from + Math.min(column + mark2[0].length, open)
|
|
2935
|
+
});
|
|
2936
|
+
}
|
|
2937
|
+
}
|
|
2938
|
+
if (node.to >= to) {
|
|
2939
|
+
renumberListItems(node.node.nextSibling, 1, changes, state2.doc);
|
|
2940
|
+
}
|
|
2941
|
+
return false;
|
|
2924
2942
|
}
|
|
2925
|
-
if (node.to >= to) {
|
|
2926
|
-
renumberListItems(node.node.nextSibling, 1, changes, state2.doc);
|
|
2927
|
-
}
|
|
2928
|
-
return false;
|
|
2929
2943
|
}
|
|
2930
|
-
}
|
|
2931
|
-
}
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2944
|
+
});
|
|
2945
|
+
}
|
|
2946
|
+
if (!changes.length) {
|
|
2947
|
+
return false;
|
|
2948
|
+
}
|
|
2949
|
+
dispatch(state2.update({
|
|
2950
|
+
changes,
|
|
2951
|
+
userEvent: "format.list.remove",
|
|
2952
|
+
scrollIntoView: true
|
|
2953
|
+
}));
|
|
2954
|
+
return true;
|
|
2955
|
+
};
|
|
2942
2956
|
};
|
|
2943
|
-
var toggleList = (type) =>
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2957
|
+
var toggleList = (type) => {
|
|
2958
|
+
return (target) => {
|
|
2959
|
+
const formatting = getFormatting(target.state);
|
|
2960
|
+
const active = formatting.listStyle === (type === 1 ? "bullet" : type === 0 ? "ordered" : "task");
|
|
2961
|
+
return (active ? removeList(type) : addList(type))(target);
|
|
2962
|
+
};
|
|
2947
2963
|
};
|
|
2948
2964
|
var renumberListItems = (item, counter, changes, doc) => {
|
|
2949
2965
|
for (; item; item = item.nextSibling) {
|
|
@@ -2963,79 +2979,81 @@ var renumberListItems = (item, counter, changes, doc) => {
|
|
|
2963
2979
|
}
|
|
2964
2980
|
}
|
|
2965
2981
|
};
|
|
2966
|
-
var setBlockquote = (enable) =>
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
const
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
if (node.
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
if (
|
|
2985
|
-
lines.
|
|
2982
|
+
var setBlockquote = (enable) => {
|
|
2983
|
+
return ({ state: state2, dispatch }) => {
|
|
2984
|
+
const lines = [];
|
|
2985
|
+
let lastBlock = -1;
|
|
2986
|
+
for (const { from, to } of state2.selection.ranges) {
|
|
2987
|
+
const sawBlock = false;
|
|
2988
|
+
syntaxTree(state2).iterate({
|
|
2989
|
+
from,
|
|
2990
|
+
to,
|
|
2991
|
+
enter: (node) => {
|
|
2992
|
+
if (Object.hasOwn(Textblocks, node.name) || node.name === "Table") {
|
|
2993
|
+
if (node.from === lastBlock) {
|
|
2994
|
+
return false;
|
|
2995
|
+
}
|
|
2996
|
+
lastBlock = node.from;
|
|
2997
|
+
let line2 = state2.doc.lineAt(node.from);
|
|
2998
|
+
if (line2.number > 1) {
|
|
2999
|
+
const prevLine = state2.doc.line(line2.number - 1);
|
|
3000
|
+
if (/^[>\s]*$/.test(prevLine.text)) {
|
|
3001
|
+
if (!enable || lines.length && lines[lines.length - 1].number === prevLine.number - 1) {
|
|
3002
|
+
lines.push(prevLine);
|
|
3003
|
+
}
|
|
2986
3004
|
}
|
|
2987
3005
|
}
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
3006
|
+
for (; ; ) {
|
|
3007
|
+
lines.push(line2);
|
|
3008
|
+
if (line2.to >= node.to) {
|
|
3009
|
+
break;
|
|
3010
|
+
}
|
|
3011
|
+
line2 = state2.doc.line(line2.number + 1);
|
|
2993
3012
|
}
|
|
2994
|
-
line2
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
lines.push(nextLine);
|
|
3013
|
+
if (!enable && line2.number < state2.doc.lines) {
|
|
3014
|
+
const nextLine = state2.doc.line(line2.number + 1);
|
|
3015
|
+
if (/^[>\s]*$/.test(nextLine.text)) {
|
|
3016
|
+
lines.push(nextLine);
|
|
3017
|
+
}
|
|
3000
3018
|
}
|
|
3019
|
+
return false;
|
|
3001
3020
|
}
|
|
3002
|
-
return false;
|
|
3003
3021
|
}
|
|
3022
|
+
});
|
|
3023
|
+
let line;
|
|
3024
|
+
if (!sawBlock && enable && from === to && !/\S/.test((line = state2.doc.lineAt(from)).text)) {
|
|
3025
|
+
lines.push(line);
|
|
3004
3026
|
}
|
|
3005
|
-
});
|
|
3006
|
-
let line;
|
|
3007
|
-
if (!sawBlock && enable && from === to && !/\S/.test((line = state2.doc.lineAt(from)).text)) {
|
|
3008
|
-
lines.push(line);
|
|
3009
3027
|
}
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
if (enable) {
|
|
3014
|
-
changes.push({
|
|
3015
|
-
from: line.from,
|
|
3016
|
-
insert: /\S/.test(line.text) ? "> " : ">"
|
|
3017
|
-
});
|
|
3018
|
-
} else {
|
|
3019
|
-
const quote = /((?:[\s>\-+*]|\d+[.)])*?)> ?/.exec(line.text);
|
|
3020
|
-
if (quote) {
|
|
3028
|
+
const changes = [];
|
|
3029
|
+
for (const line of lines) {
|
|
3030
|
+
if (enable) {
|
|
3021
3031
|
changes.push({
|
|
3022
|
-
from: line.from
|
|
3023
|
-
|
|
3032
|
+
from: line.from,
|
|
3033
|
+
insert: /\S/.test(line.text) ? "> " : ">"
|
|
3024
3034
|
});
|
|
3035
|
+
} else {
|
|
3036
|
+
const quote = /((?:[\s>\-+*]|\d+[.)])*?)> ?/.exec(line.text);
|
|
3037
|
+
if (quote) {
|
|
3038
|
+
changes.push({
|
|
3039
|
+
from: line.from + quote[1].length,
|
|
3040
|
+
to: line.from + quote[0].length
|
|
3041
|
+
});
|
|
3042
|
+
}
|
|
3025
3043
|
}
|
|
3026
3044
|
}
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3045
|
+
if (!changes.length) {
|
|
3046
|
+
return false;
|
|
3047
|
+
}
|
|
3048
|
+
const changeSet = state2.changes(changes);
|
|
3049
|
+
dispatch(state2.update({
|
|
3050
|
+
changes: changeSet,
|
|
3051
|
+
selection: state2.selection.map(changeSet, 1),
|
|
3052
|
+
userEvent: enable ? "format.blockquote.add" : "format.blockquote.remove",
|
|
3053
|
+
scrollIntoView: true
|
|
3054
|
+
}));
|
|
3055
|
+
return true;
|
|
3056
|
+
};
|
|
3039
3057
|
};
|
|
3040
3058
|
var addBlockquote = setBlockquote(true);
|
|
3041
3059
|
var removeBlockquote = setBlockquote(false);
|
|
@@ -3105,8 +3123,8 @@ var addCodeblock = (target) => {
|
|
|
3105
3123
|
return true;
|
|
3106
3124
|
};
|
|
3107
3125
|
var removeCodeblock = ({ state: state2, dispatch }) => {
|
|
3108
|
-
const changes = [];
|
|
3109
3126
|
let lastBlock = -1;
|
|
3127
|
+
const changes = [];
|
|
3110
3128
|
for (const { from, to } of state2.selection.ranges) {
|
|
3111
3129
|
syntaxTree(state2).iterate({
|
|
3112
3130
|
from,
|
|
@@ -3761,68 +3779,88 @@ var buildDecorations = (view, options, focus) => {
|
|
|
3761
3779
|
from,
|
|
3762
3780
|
to,
|
|
3763
3781
|
enter: (node) => {
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3782
|
+
switch (node.name) {
|
|
3783
|
+
case "FencedCode": {
|
|
3784
|
+
const editing = editingRange(state2, node, focus);
|
|
3785
|
+
for (const block of view.viewportLineBlocks) {
|
|
3786
|
+
if (block.to < node.from) {
|
|
3787
|
+
continue;
|
|
3788
|
+
}
|
|
3789
|
+
if (block.from > node.to) {
|
|
3790
|
+
break;
|
|
3791
|
+
}
|
|
3792
|
+
const first = block.from <= node.from;
|
|
3793
|
+
const last = block.to >= node.to && /^(\s>)*```$/.test(state2.doc.sliceString(block.from, block.to));
|
|
3794
|
+
deco.add(block.from, block.from, first ? fencedCodeLineFirst : last ? fencedCodeLineLast : fencedCodeLine);
|
|
3795
|
+
if (!editing && (first || last)) {
|
|
3796
|
+
atomicDeco.add(block.from, block.to, hide);
|
|
3797
|
+
}
|
|
3778
3798
|
}
|
|
3799
|
+
return false;
|
|
3779
3800
|
}
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
atomicDeco.add(node.from, marks[0].to, hide);
|
|
3789
|
-
}
|
|
3790
|
-
deco.add(marks[0].to, marks[1].from, Decoration5.mark({
|
|
3791
|
-
tagName: "a",
|
|
3792
|
-
attributes: {
|
|
3793
|
-
class: "cm-link",
|
|
3794
|
-
href: url,
|
|
3795
|
-
rel: "noreferrer",
|
|
3796
|
-
target: "_blank"
|
|
3801
|
+
case "Link": {
|
|
3802
|
+
const marks = node.node.getChildren("LinkMark");
|
|
3803
|
+
const urlNode = node.node.getChild("URL");
|
|
3804
|
+
const editing = editingRange(state2, node, focus);
|
|
3805
|
+
if (urlNode && marks.length >= 2) {
|
|
3806
|
+
const url = state2.sliceDoc(urlNode.from, urlNode.to);
|
|
3807
|
+
if (!editing) {
|
|
3808
|
+
atomicDeco.add(node.from, marks[0].to, hide);
|
|
3797
3809
|
}
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3810
|
+
deco.add(marks[0].to, marks[1].from, Decoration5.mark({
|
|
3811
|
+
tagName: "a",
|
|
3812
|
+
attributes: {
|
|
3813
|
+
class: "cm-link",
|
|
3814
|
+
href: url,
|
|
3815
|
+
rel: "noreferrer",
|
|
3816
|
+
target: "_blank"
|
|
3817
|
+
}
|
|
3818
|
+
}));
|
|
3819
|
+
if (!editing) {
|
|
3820
|
+
atomicDeco.add(marks[1].from, node.to, options.renderLinkButton ? Decoration5.replace({
|
|
3821
|
+
widget: new LinkButton(url, options.renderLinkButton)
|
|
3822
|
+
}) : hide);
|
|
3823
|
+
}
|
|
3824
|
+
}
|
|
3825
|
+
break;
|
|
3826
|
+
}
|
|
3827
|
+
case "HeaderMark": {
|
|
3828
|
+
const parent = node.node.parent;
|
|
3829
|
+
if (/^ATX/.test(parent.name) && !editingRange(state2, state2.doc.lineAt(node.from), focus)) {
|
|
3830
|
+
const next = state2.doc.sliceString(node.to, node.to + 1);
|
|
3831
|
+
atomicDeco.add(node.from, node.to + (next === " " ? 1 : 0), hide);
|
|
3803
3832
|
}
|
|
3833
|
+
break;
|
|
3804
3834
|
}
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3835
|
+
case "HorizontalRule": {
|
|
3836
|
+
if (!editingRange(state2, node, focus)) {
|
|
3837
|
+
deco.add(node.from, node.to, horizontalRule);
|
|
3838
|
+
}
|
|
3839
|
+
break;
|
|
3810
3840
|
}
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3841
|
+
case "TaskMarker": {
|
|
3842
|
+
if (!editingRange(state2, node, focus)) {
|
|
3843
|
+
const checked = state2.doc.sliceString(node.from + 1, node.to - 1) === "x";
|
|
3844
|
+
atomicDeco.add(node.from - 2, node.from - 1, Decoration5.mark({
|
|
3845
|
+
class: "cm-task"
|
|
3846
|
+
}));
|
|
3847
|
+
atomicDeco.add(node.from, node.to, checked ? checkedTask : uncheckedTask);
|
|
3848
|
+
}
|
|
3849
|
+
break;
|
|
3814
3850
|
}
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
class: "cm-task"
|
|
3851
|
+
case "ListItem": {
|
|
3852
|
+
const start = state2.doc.lineAt(node.from);
|
|
3853
|
+
deco.add(start.from, start.from, Decoration5.line({
|
|
3854
|
+
class: "cm-list-item"
|
|
3820
3855
|
}));
|
|
3821
|
-
|
|
3856
|
+
break;
|
|
3822
3857
|
}
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3858
|
+
default: {
|
|
3859
|
+
if (MarksByParent.has(node.name)) {
|
|
3860
|
+
if (!editingRange(state2, node.node.parent, focus)) {
|
|
3861
|
+
atomicDeco.add(node.from, node.to, hide);
|
|
3862
|
+
}
|
|
3863
|
+
}
|
|
3826
3864
|
}
|
|
3827
3865
|
}
|
|
3828
3866
|
}
|
|
@@ -3848,8 +3886,6 @@ var decorateMarkdown = (options = {}) => {
|
|
|
3848
3886
|
this.scheduleUpdate(update2.view);
|
|
3849
3887
|
}
|
|
3850
3888
|
}
|
|
3851
|
-
// TODO(burdon): BUG: If the cursor is at the end of a link at the end of a line,
|
|
3852
|
-
// the cursor will float in space or be in the wrong position after the decoration is applied.
|
|
3853
3889
|
scheduleUpdate(view) {
|
|
3854
3890
|
this.clearUpdate();
|
|
3855
3891
|
this.pendingUpdate = setTimeout(() => {
|
|
@@ -4094,15 +4130,17 @@ var update = (state2, options) => {
|
|
|
4094
4130
|
}
|
|
4095
4131
|
});
|
|
4096
4132
|
tables.forEach((table2) => {
|
|
4097
|
-
const
|
|
4098
|
-
if (
|
|
4133
|
+
const replace = state2.readOnly || cursor < table2.from || cursor > table2.to;
|
|
4134
|
+
if (replace) {
|
|
4099
4135
|
builder.add(table2.from, table2.to, Decoration7.replace({
|
|
4136
|
+
block: true,
|
|
4100
4137
|
widget: new TableWidget(table2)
|
|
4101
4138
|
}));
|
|
4139
|
+
} else {
|
|
4140
|
+
builder.add(table2.from, table2.to, Decoration7.mark({
|
|
4141
|
+
class: "cm-table"
|
|
4142
|
+
}));
|
|
4102
4143
|
}
|
|
4103
|
-
builder.add(table2.from, table2.to, Decoration7.mark({
|
|
4104
|
-
class: "cm-table"
|
|
4105
|
-
}));
|
|
4106
4144
|
});
|
|
4107
4145
|
return builder.finish();
|
|
4108
4146
|
};
|
|
@@ -4367,10 +4405,11 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
|
|
|
4367
4405
|
// packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
|
|
4368
4406
|
var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx";
|
|
4369
4407
|
var instanceCount = 0;
|
|
4370
|
-
var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, className, autoFocus, scrollTo
|
|
4371
|
-
yMargin: 0
|
|
4372
|
-
}), moveToEndOfLine, debug, dataTestId }, forwardedRef) => {
|
|
4408
|
+
var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, className, autoFocus, scrollTo: propsScrollTo, moveToEndOfLine, debug, dataTestId }, forwardedRef) => {
|
|
4373
4409
|
const [instanceId] = useState2(() => `text-editor-${++instanceCount}`);
|
|
4410
|
+
const scrollTo = useDefaultValue(propsScrollTo, EditorView16.scrollIntoView(0, {
|
|
4411
|
+
yMargin: 0
|
|
4412
|
+
}));
|
|
4374
4413
|
const tabsterDOMAttribute = useFocusableGroup({
|
|
4375
4414
|
tabBehavior: "limited"
|
|
4376
4415
|
});
|
|
@@ -4393,7 +4432,7 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, c
|
|
|
4393
4432
|
instanceId
|
|
4394
4433
|
}, {
|
|
4395
4434
|
F: __dxlog_file10,
|
|
4396
|
-
L:
|
|
4435
|
+
L: 90,
|
|
4397
4436
|
S: void 0,
|
|
4398
4437
|
C: (f, a) => f(...a)
|
|
4399
4438
|
});
|
|
@@ -4406,7 +4445,7 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, c
|
|
|
4406
4445
|
EditorView16.exceptionSink.of((err) => {
|
|
4407
4446
|
log7.catch(err, void 0, {
|
|
4408
4447
|
F: __dxlog_file10,
|
|
4409
|
-
L:
|
|
4448
|
+
L: 103,
|
|
4410
4449
|
S: void 0,
|
|
4411
4450
|
C: (f, a) => f(...a)
|
|
4412
4451
|
});
|
|
@@ -4453,7 +4492,7 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, c
|
|
|
4453
4492
|
instanceId
|
|
4454
4493
|
}, {
|
|
4455
4494
|
F: __dxlog_file10,
|
|
4456
|
-
L:
|
|
4495
|
+
L: 152,
|
|
4457
4496
|
S: void 0,
|
|
4458
4497
|
C: (f, a) => f(...a)
|
|
4459
4498
|
});
|
|
@@ -4800,28 +4839,15 @@ var useActionHandler = (view) => {
|
|
|
4800
4839
|
return (action) => view && processAction(view, action);
|
|
4801
4840
|
};
|
|
4802
4841
|
|
|
4803
|
-
// packages/ui/react-ui-editor/src/hooks/useDocAccessor.ts
|
|
4804
|
-
import { useMemo as useMemo2 } from "react";
|
|
4805
|
-
import { createDocAccessor, getTextContent } from "@dxos/echo-schema";
|
|
4806
|
-
var useDocAccessor = (text) => {
|
|
4807
|
-
return useMemo2(() => ({
|
|
4808
|
-
id: text.id,
|
|
4809
|
-
doc: getTextContent(text),
|
|
4810
|
-
accessor: createDocAccessor(text)
|
|
4811
|
-
}), [
|
|
4812
|
-
text
|
|
4813
|
-
]);
|
|
4814
|
-
};
|
|
4815
|
-
|
|
4816
4842
|
// packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
|
|
4817
4843
|
import { EditorSelection as EditorSelection2, EditorState as EditorState3 } from "@codemirror/state";
|
|
4818
4844
|
import { EditorView as EditorView17 } from "@codemirror/view";
|
|
4819
|
-
import { useEffect as useEffect4, useMemo as
|
|
4845
|
+
import { useEffect as useEffect4, useMemo as useMemo2, useRef as useRef3, useState as useState4 } from "react";
|
|
4820
4846
|
import { log as log8 } from "@dxos/log";
|
|
4821
4847
|
import { isNotFalsy as isNotFalsy5 } from "@dxos/util";
|
|
4822
4848
|
var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
|
|
4823
4849
|
var useTextEditor = (cb = () => ({}), deps = []) => {
|
|
4824
|
-
let { id, doc, selection, extensions, autoFocus, scrollTo, debug } =
|
|
4850
|
+
let { id, doc, selection, extensions, autoFocus, scrollTo, debug } = useMemo2(cb, deps ?? []);
|
|
4825
4851
|
const onUpdate = useRef3();
|
|
4826
4852
|
const [view, setView] = useState4();
|
|
4827
4853
|
const parentRef = useRef3(null);
|
|
@@ -4997,7 +5023,6 @@ export {
|
|
|
4997
5023
|
typewriter,
|
|
4998
5024
|
useActionHandler,
|
|
4999
5025
|
useComments,
|
|
5000
|
-
useDocAccessor,
|
|
5001
5026
|
useFormattingState,
|
|
5002
5027
|
useTextEditor,
|
|
5003
5028
|
useToolbarContext
|