@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.
Files changed (30) hide show
  1. package/dist/lib/browser/index.mjs +648 -623
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
  5. package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts.map +1 -1
  6. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
  7. package/dist/types/src/extensions/automerge/automerge.stories.d.ts.map +1 -1
  8. package/dist/types/src/extensions/factories.d.ts +1 -1
  9. package/dist/types/src/extensions/factories.d.ts.map +1 -1
  10. package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
  11. package/dist/types/src/extensions/markdown/formatting.d.ts +1 -1
  12. package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
  13. package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
  14. package/dist/types/src/extensions/markdown/table.d.ts.map +1 -1
  15. package/dist/types/src/hooks/index.d.ts +0 -1
  16. package/dist/types/src/hooks/index.d.ts.map +1 -1
  17. package/package.json +26 -25
  18. package/src/components/TextEditor/TextEditor.stories.tsx +18 -17
  19. package/src/components/TextEditor/TextEditor.tsx +3 -1
  20. package/src/components/Toolbar/Toolbar.stories.tsx +10 -9
  21. package/src/extensions/automerge/automerge.stories.tsx +7 -6
  22. package/src/extensions/factories.ts +2 -2
  23. package/src/extensions/markdown/decorate.ts +90 -62
  24. package/src/extensions/markdown/formatting.ts +42 -35
  25. package/src/extensions/markdown/highlight.ts +3 -1
  26. package/src/extensions/markdown/table.ts +7 -6
  27. package/src/hooks/index.ts +0 -1
  28. package/dist/types/src/hooks/useDocAccessor.d.ts +0 -9
  29. package/dist/types/src/hooks/useDocAccessor.d.ts.map +0 -1
  30. 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) => ({ state: state2, dispatch }) => {
2306
- const { selection: { ranges }, doc } = state2;
2307
- const changes = [];
2308
- let prevBlock = -1;
2309
- for (const range of ranges) {
2310
- let sawBlock = false;
2311
- syntaxTree(state2).iterate({
2312
- from: range.from,
2313
- to: range.to,
2314
- enter: (node) => {
2315
- if (!Object.hasOwn(Textblocks, node.name) || prevBlock === node.from) {
2316
- return;
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
- changes.push({
2340
- from: nextLine.from - 1,
2341
- to: nextLine.to
2342
- });
2343
- } else {
2344
- if (level === 0) {
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
- to: Math.min(node.to, node.from + curLevel + 1)
2331
+ insert: "#".repeat(level) + " "
2348
2332
  });
2349
- } else if (level < curLevel) {
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: node.from,
2352
- to: node.from + (curLevel - level)
2342
+ from: nextLine.from - 1,
2343
+ to: nextLine.to
2353
2344
  });
2354
2345
  } else {
2355
- changes.push({
2356
- from: node.from,
2357
- insert: "#".repeat(level - curLevel)
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
- if (!changes.length) {
2373
- return false;
2374
- }
2375
- const changeSet = state2.changes(changes);
2376
- dispatch(state2.update({
2377
- changes: changeSet,
2378
- selection: state2.selection.map(changeSet, 1),
2379
- userEvent: "format.setHeading",
2380
- scrollIntoView: true
2381
- }));
2382
- return true;
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) => ({ state: state2, dispatch }) => {
2385
- const marker = inlineMarkerText(type);
2386
- const changes = state2.changeByRange((range) => {
2387
- if (!enable && range.empty) {
2388
- const after = state2.doc.sliceString(range.head, range.head + 6);
2389
- const found = after.indexOf(marker);
2390
- if (found >= 0 && /^[*~`]*$/.test(after.slice(0, found))) {
2391
- const before = state2.doc.sliceString(range.head - 6, range.head);
2392
- if (before.slice(before.length - found - marker.length, before.length - found) === marker && [
2393
- ...before.slice(before.length - found)
2394
- ].reverse().join("") === after.slice(0, found)) {
2395
- return {
2396
- changes: [
2397
- {
2398
- from: range.head - marker.length - found,
2399
- to: range.head - found
2400
- },
2401
- {
2402
- from: range.head + found,
2403
- to: range.head + found + marker.length
2404
- }
2405
- ],
2406
- range: EditorSelection.cursor(range.from - marker.length)
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
- const changes2 = [];
2412
- const changesAtEnd = [];
2413
- let blockStart = -1;
2414
- let blockEnd = -1;
2415
- let startCovered = false;
2416
- let endCovered = false;
2417
- let { from, to } = range;
2418
- syntaxTree(state2).iterate({
2419
- from,
2420
- to,
2421
- enter: (node) => {
2422
- const { name } = node;
2423
- if (Object.hasOwn(Textblocks, name) && Textblocks[name] !== "codeblock") {
2424
- blockStart = blockContentStart(node);
2425
- blockEnd = blockContentEnd(node, state2.doc);
2426
- startCovered = endCovered = false;
2427
- } else if (name === "Link" || name === "Image" && enable) {
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
- from = node.to;
2439
- }
2440
- if (node.from < to && node.to > to) {
2441
- to = node.from;
2442
- }
2443
- } else if (Object.hasOwn(InlineMarker, name)) {
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 (openEnd <= to && closeStart >= to) {
2456
- endCovered = !enable && closeStart === skipMarkers(to, node.node, 1, closeStart) ? {
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
- if (markType === type || type === 3 && enable) {
2463
- if (node.from >= from && openEnd <= to) {
2464
- changes2.push({
2465
- from: node.from,
2466
- to: openEnd
2467
- });
2468
- if (markType !== type && closeStart >= to) {
2469
- changesAtEnd.push({
2470
- from: skipSpaces(Math.min(to, blockEnd), state2.doc, 1, blockEnd),
2471
- insert: inlineMarkerText(markType)
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 (closeStart >= from && node.to <= to) {
2476
- changes2.push({
2477
- from: closeStart,
2478
- to: node.to
2479
- });
2480
- if (markType !== type && openEnd <= from) {
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: skipSpaces(Math.max(from, blockStart), state2.doc, -1, blockStart),
2483
- insert: inlineMarkerText(markType)
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
- leave: (node) => {
2491
- if (Object.hasOwn(Textblocks, node.name) && Textblocks[node.name] !== "codeblock") {
2492
- const rangeStart = Math.max(from, blockStart);
2493
- const rangeEnd = Math.min(to, blockEnd);
2494
- if (enable) {
2495
- if (!startCovered) {
2496
- changes2.push({
2497
- from: rangeStart,
2498
- insert: marker
2499
- });
2500
- }
2501
- if (!endCovered) {
2502
- changes2.push({
2503
- from: rangeEnd,
2504
- insert: marker
2505
- });
2506
- }
2507
- } else {
2508
- if (typeof startCovered === "object") {
2509
- changes2.push(startCovered);
2510
- } else if (startCovered) {
2511
- changes2.push({
2512
- from: skipSpaces(rangeStart, state2.doc, -1, blockStart),
2513
- insert: marker
2514
- });
2515
- }
2516
- if (typeof endCovered === "object") {
2517
- changes2.push(endCovered);
2518
- } else if (endCovered) {
2519
- changes2.push({
2520
- from: skipSpaces(rangeEnd, state2.doc, 1, blockEnd),
2521
- insert: marker
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
- from: range.head,
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
- const changeSet = state2.changes(changes2.concat(changesAtEnd));
2538
- return {
2539
- changes: changeSet,
2540
- range: range.empty && !changeSet.empty ? EditorSelection.cursor(range.head + marker.length) : EditorSelection.range(changeSet.mapPos(range.from, 1), changeSet.mapPos(range.to, -1))
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) => (arg) => {
2552
- const form = getFormatting(arg.state);
2553
- return setStyle(style, style === 0 ? !form.strong : style === 1 ? !form.emphasis : style === 2 ? !form.strikethrough : !form.code)(arg);
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 } = {}) => ({ state: state2, dispatch }) => {
2658
- const changes = state2.changeByRange((range) => {
2659
- let { from, to } = range;
2660
- const cutStyles = [];
2661
- let okay = null;
2662
- syntaxTree(state2).iterate({
2663
- from,
2664
- to,
2665
- enter: (node) => {
2666
- if (Object.hasOwn(Textblocks, node.name)) {
2667
- okay = Textblocks[node.name] !== "codeblock" && from >= blockContentStart(node) && to <= blockContentEnd(node, state2.doc);
2668
- } else if (Object.hasOwn(InlineMarker, node.name)) {
2669
- const sNode = node.node;
2670
- if (node.from < from && node.to <= to) {
2671
- if (sNode.firstChild.to === from) {
2672
- from = node.from;
2673
- } else {
2674
- cutStyles.push(sNode);
2675
- }
2676
- } else if (node.from >= from && node.to > to) {
2677
- if (sNode.lastChild.from === to) {
2678
- to = node.to;
2679
- } else {
2680
- cutStyles.push(sNode);
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
- if (okay === null) {
2687
- const line = state2.doc.lineAt(from);
2688
- okay = to <= line.to && !/\S/.test(line.text.slice(from - line.from));
2689
- }
2690
- if (!okay) {
2691
- return {
2692
- range
2693
- };
2694
- }
2695
- const changes2 = [];
2696
- const changesAfter = [];
2697
- removeLinkInner(from, to, changesAfter, state2);
2698
- let cursorOffset = 1;
2699
- for (const style of cutStyles) {
2700
- const type = InlineMarker[style.name];
2701
- const mark2 = inlineMarkerText(type);
2702
- if (style.from < from) {
2703
- changes2.push({
2704
- from: skipSpaces(from, state2.doc, -1),
2705
- insert: mark2
2706
- });
2707
- changesAfter.push({
2708
- from: skipSpaces(from, state2.doc, 1, to),
2709
- insert: mark2
2710
- });
2711
- } else {
2712
- changes2.push({
2713
- from: skipSpaces(to, state2.doc, -1, from),
2714
- insert: mark2
2715
- });
2716
- const after = skipSpaces(to, state2.doc, 1);
2717
- if (after === to) {
2718
- cursorOffset += mark2.length;
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
- changes2.push({
2727
- from,
2728
- insert: image2 ? "![" : "["
2729
- }, {
2730
- from: to,
2731
- insert: `](${url ?? ""})`
2734
+ changes2.push({
2735
+ from,
2736
+ insert: image2 ? "![" : "["
2737
+ }, {
2738
+ from: to,
2739
+ insert: `](${url ?? ""})`
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
- const changeSet = state2.changes(changes2.concat(changesAfter));
2734
- return {
2735
- changes: changeSet,
2736
- range: EditorSelection.cursor(changeSet.mapPos(to, 1) - cursorOffset - (url ? url.length + 2 : 0))
2737
- };
2738
- });
2739
- if (changes.changes.empty) {
2740
- return false;
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) => ({ state: state2, dispatch }) => {
2749
- let lastBlock = -1;
2750
- let counter = 1;
2751
- let first = true;
2752
- let parentColumn = null;
2753
- const blocks = [];
2754
- for (const { from, to } of state2.selection.ranges) {
2755
- syntaxTree(state2).iterate({
2756
- from,
2757
- to,
2758
- enter: (node) => {
2759
- if (Object.hasOwn(Textblocks, node.name) && node.name !== "TableCell" || node.name === "Table") {
2760
- if (first) {
2761
- let before = node.node.prevSibling;
2762
- while (before && /Mark$/.test(before.name)) {
2763
- before = before.prevSibling;
2764
- }
2765
- if (before?.name === (type === 0 ? "OrderedList" : "BulletList")) {
2766
- const item = before.lastChild;
2767
- const itemLine = state2.doc.lineAt(item.from);
2768
- const itemText = itemLine.text.slice(item.from - itemLine.from);
2769
- parentColumn = item.from - itemLine.from + /^\s*/.exec(itemText)[0].length;
2770
- if (type === 0) {
2771
- const mark2 = /^\s*(\d+)[.)]/.exec(itemText);
2772
- if (mark2) {
2773
- parentColumn += mark2[1].length;
2774
- counter = +mark2[1] + 1;
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
- first = false;
2793
+ lastBlock = node.from;
2794
+ blocks.push({
2795
+ node: node.node,
2796
+ counter,
2797
+ parentColumn
2798
+ });
2799
+ counter++;
2800
+ return false;
2779
2801
  }
2780
- if (node.from === lastBlock) {
2781
- return;
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
- let line = state2.doc.lineAt(nodeFrom);
2831
- const column = nodeFrom - line.from;
2832
- if (parentColumn2 !== null && parentColumn2 > column) {
2833
- padding = Math.max(padding, parentColumn2 - column);
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
- let mark2;
2836
- if (type === 0) {
2837
- let max = counter2;
2838
- for (let j = i + 1; j < blocks.length; j++) {
2839
- if (blocks[j].counter !== max + 1) {
2840
- break;
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
- max++;
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: line.from + Math.min(open, column),
2859
- insert: " ".repeat(mark2.length)
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
- if (type === 0) {
2864
- const last = blocks[blocks.length - 1];
2865
- let next = last.node.nextSibling;
2866
- while (next && /Mark$/.test(next.name)) {
2867
- next = next.nextSibling;
2868
- }
2869
- if (next?.name === "OrderedList") {
2870
- renumberListItems(next.firstChild, last.counter + 1, changes, state2.doc);
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
- const changeSet = state2.changes(changes);
2874
- dispatch(state2.update({
2875
- changes: changeSet,
2876
- selection: state2.selection.map(changeSet, 1),
2877
- userEvent: "format.list.add",
2878
- scrollIntoView: true
2879
- }));
2880
- return true;
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) => ({ state: state2, dispatch }) => {
2883
- let lastBlock = -1;
2884
- const changes = [];
2885
- const stack = [];
2886
- const targetNodeType = type === 0 ? "OrderedList" : type === 1 ? "BulletList" : "TaskList";
2887
- for (const { from, to } of state2.selection.ranges) {
2888
- syntaxTree(state2).iterate({
2889
- from,
2890
- to,
2891
- enter: (node) => {
2892
- const { name } = node;
2893
- if (name === "BulletList" || name === "OrderedList" || name === "Blockquote") {
2894
- stack.push(name);
2895
- } else if (name === "Task" && stack[stack.length - 1] === "BulletList") {
2896
- stack[stack.length - 1] = "TaskList";
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
- const column = node.from - line.from;
2911
- changes.push({
2912
- from: node.from,
2913
- to: node.from + mark2[0].length
2914
- });
2915
- while (line.to < node.to) {
2916
- line = state2.doc.lineAt(line.to + 1);
2917
- const open = /^[\s>]*/.exec(line.text)[0].length;
2918
- if (open > column) {
2919
- changes.push({
2920
- from: line.from + column,
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
- if (!changes.length) {
2934
- return false;
2935
- }
2936
- dispatch(state2.update({
2937
- changes,
2938
- userEvent: "format.list.remove",
2939
- scrollIntoView: true
2940
- }));
2941
- return true;
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) => (target) => {
2944
- const formatting = getFormatting(target.state);
2945
- const active = formatting.listStyle === (type === 1 ? "bullet" : type === 0 ? "ordered" : "task");
2946
- return (active ? removeList(type) : addList(type))(target);
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) => ({ state: state2, dispatch }) => {
2967
- const lines = [];
2968
- let lastBlock = -1;
2969
- for (const { from, to } of state2.selection.ranges) {
2970
- const sawBlock = false;
2971
- syntaxTree(state2).iterate({
2972
- from,
2973
- to,
2974
- enter: (node) => {
2975
- if (Object.hasOwn(Textblocks, node.name) || node.name === "Table") {
2976
- if (node.from === lastBlock) {
2977
- return false;
2978
- }
2979
- lastBlock = node.from;
2980
- let line2 = state2.doc.lineAt(node.from);
2981
- if (line2.number > 1) {
2982
- const prevLine = state2.doc.line(line2.number - 1);
2983
- if (/^[>\s]*$/.test(prevLine.text)) {
2984
- if (!enable || lines.length && lines[lines.length - 1].number === prevLine.number - 1) {
2985
- lines.push(prevLine);
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
- for (; ; ) {
2990
- lines.push(line2);
2991
- if (line2.to >= node.to) {
2992
- break;
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 = state2.doc.line(line2.number + 1);
2995
- }
2996
- if (!enable && line2.number < state2.doc.lines) {
2997
- const nextLine = state2.doc.line(line2.number + 1);
2998
- if (/^[>\s]*$/.test(nextLine.text)) {
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
- const changes = [];
3012
- for (const line of lines) {
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 + quote[1].length,
3023
- to: line.from + quote[0].length
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
- if (!changes.length) {
3029
- return false;
3030
- }
3031
- const changeSet = state2.changes(changes);
3032
- dispatch(state2.update({
3033
- changes: changeSet,
3034
- selection: state2.selection.map(changeSet, 1),
3035
- userEvent: enable ? "format.blockquote.add" : "format.blockquote.remove",
3036
- scrollIntoView: true
3037
- }));
3038
- return true;
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
- if (node.name === "FencedCode") {
3765
- const editing = editingRange(state2, node, focus);
3766
- for (const block of view.viewportLineBlocks) {
3767
- if (block.to < node.from) {
3768
- continue;
3769
- }
3770
- if (block.from > node.to) {
3771
- break;
3772
- }
3773
- const first = block.from <= node.from;
3774
- const last = block.to >= node.to && /^(\s>)*```$/.test(state2.doc.sliceString(block.from, block.to));
3775
- deco.add(block.from, block.from, first ? fencedCodeLineFirst : last ? fencedCodeLineLast : fencedCodeLine);
3776
- if (!editing && (first || last)) {
3777
- atomicDeco.add(block.from, block.to, hide);
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
- return false;
3781
- } else if (node.name === "Link") {
3782
- const marks = node.node.getChildren("LinkMark");
3783
- const urlNode = node.node.getChild("URL");
3784
- const editing = editingRange(state2, node, focus);
3785
- if (urlNode && marks.length >= 2) {
3786
- const url = state2.sliceDoc(urlNode.from, urlNode.to);
3787
- if (!editing) {
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
- if (!editing) {
3800
- atomicDeco.add(marks[1].from, node.to, options.renderLinkButton ? Decoration5.replace({
3801
- widget: new LinkButton(url, options.renderLinkButton)
3802
- }) : hide);
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
- } else if (node.name === "HeaderMark") {
3806
- const parent = node.node.parent;
3807
- if (/^ATX/.test(parent.name) && !editingRange(state2, state2.doc.lineAt(node.from), focus)) {
3808
- const next = state2.doc.sliceString(node.to, node.to + 1);
3809
- atomicDeco.add(node.from, node.to + (next === " " ? 1 : 0), hide);
3835
+ case "HorizontalRule": {
3836
+ if (!editingRange(state2, node, focus)) {
3837
+ deco.add(node.from, node.to, horizontalRule);
3838
+ }
3839
+ break;
3810
3840
  }
3811
- } else if (node.name === "HorizontalRule") {
3812
- if (!editingRange(state2, node, focus)) {
3813
- deco.add(node.from, node.to, horizontalRule);
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
- } else if (node.name === "TaskMarker") {
3816
- if (!editingRange(state2, node, focus)) {
3817
- const checked = state2.doc.sliceString(node.from + 1, node.to - 1) === "x";
3818
- atomicDeco.add(node.from - 2, node.from - 1, Decoration5.mark({
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
- atomicDeco.add(node.from, node.to, checked ? checkedTask : uncheckedTask);
3856
+ break;
3822
3857
  }
3823
- } else if (MarksByParent.has(node.name)) {
3824
- if (!editingRange(state2, node.node.parent, focus)) {
3825
- atomicDeco.add(node.from, node.to, hide);
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 hide2 = state2.readOnly || cursor < table2.from || cursor > table2.to;
4098
- if (hide2) {
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 = EditorView16.scrollIntoView(0, {
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: 88,
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: 101,
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: 150,
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 useMemo3, useRef as useRef3, useState as useState4 } from "react";
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 } = useMemo3(cb, deps ?? []);
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