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