@dxos/react-ui-editor 0.4.10-main.fa5a270 → 0.4.10-main.fd8ea31

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 (45) hide show
  1. package/dist/lib/browser/index.mjs +707 -694
  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 +1 -1
  6. package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts.map +1 -1
  7. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
  8. package/dist/types/src/extensions/automerge/automerge.d.ts +1 -1
  9. package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -1
  10. package/dist/types/src/extensions/automerge/automerge.stories.d.ts +1 -1
  11. package/dist/types/src/extensions/automerge/automerge.stories.d.ts.map +1 -1
  12. package/dist/types/src/extensions/automerge/cursor.d.ts +2 -2
  13. package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -1
  14. package/dist/types/src/extensions/automerge/sync.d.ts +1 -1
  15. package/dist/types/src/extensions/automerge/sync.d.ts.map +1 -1
  16. package/dist/types/src/extensions/automerge/update-automerge.d.ts +1 -1
  17. package/dist/types/src/extensions/automerge/update-automerge.d.ts.map +1 -1
  18. package/dist/types/src/extensions/factories.d.ts +2 -3
  19. package/dist/types/src/extensions/factories.d.ts.map +1 -1
  20. package/dist/types/src/extensions/markdown/decorate.d.ts.map +1 -1
  21. package/dist/types/src/extensions/markdown/formatting.d.ts +1 -1
  22. package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
  23. package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
  24. package/dist/types/src/extensions/markdown/table.d.ts.map +1 -1
  25. package/dist/types/src/hooks/index.d.ts +0 -1
  26. package/dist/types/src/hooks/index.d.ts.map +1 -1
  27. package/package.json +30 -29
  28. package/src/components/TextEditor/TextEditor.stories.tsx +21 -18
  29. package/src/components/TextEditor/TextEditor.tsx +6 -3
  30. package/src/components/Toolbar/Toolbar.stories.tsx +10 -9
  31. package/src/extensions/automerge/automerge.stories.tsx +7 -6
  32. package/src/extensions/automerge/automerge.ts +1 -1
  33. package/src/extensions/automerge/cursor.ts +4 -37
  34. package/src/extensions/automerge/sync.ts +1 -1
  35. package/src/extensions/automerge/update-automerge.ts +1 -1
  36. package/src/extensions/factories.ts +3 -4
  37. package/src/extensions/markdown/decorate.ts +90 -62
  38. package/src/extensions/markdown/formatting.ts +42 -35
  39. package/src/extensions/markdown/highlight.ts +3 -1
  40. package/src/extensions/markdown/table.ts +7 -6
  41. package/src/hooks/index.ts +0 -1
  42. package/src/hooks/useTextEditor.ts +1 -1
  43. package/dist/types/src/hooks/useDocAccessor.d.ts +0 -9
  44. package/dist/types/src/hooks/useDocAccessor.d.ts.map +0 -1
  45. 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
@@ -180,30 +181,21 @@ var autocomplete = ({ onSearch }) => {
180
181
  // packages/ui/react-ui-editor/src/extensions/automerge/automerge.ts
181
182
  import { StateField as StateField2 } from "@codemirror/state";
182
183
  import { EditorView as EditorView2, ViewPlugin } from "@codemirror/view";
183
- import { next as A4 } from "@dxos/automerge/automerge";
184
+ import { next as A3 } from "@dxos/automerge/automerge";
184
185
 
185
186
  // packages/ui/react-ui-editor/src/extensions/automerge/cursor.ts
186
- import get from "lodash.get";
187
- import { next as A } from "@dxos/automerge/automerge";
188
187
  import { log } from "@dxos/log";
188
+ import { toCursor, fromCursor } from "@dxos/react-client/echo";
189
189
  var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/automerge/cursor.ts";
190
- var cursorConverter = ({ handle, path }) => ({
190
+ var cursorConverter = (accessor) => ({
191
191
  // TODO(burdon): Handle assoc to associate with a previous character.
192
192
  toCursor: (pos) => {
193
- const doc = handle.docSync();
194
- if (!doc) {
195
- return "";
196
- }
197
- const value = get(doc, path);
198
- if (typeof value === "string" && value.length <= pos) {
199
- return "end";
200
- }
201
193
  try {
202
- return A.getCursor(doc, path.slice(), pos);
194
+ return toCursor(accessor, pos);
203
195
  } catch (err) {
204
196
  log.catch(err, void 0, {
205
197
  F: __dxlog_file,
206
- L: 30,
198
+ L: 16,
207
199
  S: void 0,
208
200
  C: (f, a) => f(...a)
209
201
  });
@@ -211,27 +203,12 @@ var cursorConverter = ({ handle, path }) => ({
211
203
  }
212
204
  },
213
205
  fromCursor: (cursor) => {
214
- if (cursor === "") {
215
- return 0;
216
- }
217
- const doc = handle.docSync();
218
- if (!doc) {
219
- return 0;
220
- }
221
- if (cursor === "end") {
222
- const value = get(doc, path);
223
- if (typeof value === "string") {
224
- return value.length;
225
- } else {
226
- return 0;
227
- }
228
- }
229
206
  try {
230
- return A.getCursorPosition(doc, path.slice(), cursor);
207
+ return fromCursor(accessor, cursor);
231
208
  } catch (err) {
232
209
  log.catch(err, void 0, {
233
210
  F: __dxlog_file,
234
- L: 58,
211
+ L: 25,
235
212
  S: void 0,
236
213
  C: (f, a) => f(...a)
237
214
  });
@@ -254,10 +231,10 @@ var isReconcile = (tr) => {
254
231
  };
255
232
 
256
233
  // packages/ui/react-ui-editor/src/extensions/automerge/sync.ts
257
- import { next as A3 } from "@dxos/automerge/automerge";
234
+ import { next as A2 } from "@dxos/automerge/automerge";
258
235
 
259
236
  // packages/ui/react-ui-editor/src/extensions/automerge/update-automerge.ts
260
- import { next as A2 } from "@dxos/automerge/automerge";
237
+ import { next as A } from "@dxos/automerge/automerge";
261
238
  var updateAutomerge = (field, handle, transactions, state2) => {
262
239
  const { lastHeads, path } = state2.field(field);
263
240
  let hasChanges = false;
@@ -281,7 +258,7 @@ var updateAutomerge = (field, handle, transactions, state2) => {
281
258
  });
282
259
  }
283
260
  invertedTransactions.reverse().forEach(({ from, del, insert }) => {
284
- A2.splice(doc, path.slice(), from, del, insert.toString());
261
+ A.splice(doc, path.slice(), from, del, insert.toString());
285
262
  });
286
263
  });
287
264
  return newHeads ?? void 0;
@@ -426,8 +403,8 @@ var Syncer = class {
426
403
  }
427
404
  onAutomergeChange(view) {
428
405
  const oldHeads = getLastHeads(view.state, this._state);
429
- const newHeads = A3.getHeads(this._handle.docSync());
430
- const diff = A3.equals(oldHeads, newHeads) ? [] : A3.diff(this._handle.docSync(), oldHeads, newHeads);
406
+ const newHeads = A2.getHeads(this._handle.docSync());
407
+ const diff = A2.equals(oldHeads, newHeads) ? [] : A2.diff(this._handle.docSync(), oldHeads, newHeads);
431
408
  const selection = view.state.selection;
432
409
  const path = getPath(view.state, this._state);
433
410
  updateCodeMirror(view, selection, path, diff);
@@ -443,7 +420,7 @@ var automerge = (accessor) => {
443
420
  const syncState = StateField2.define({
444
421
  create: () => ({
445
422
  path: accessor.path.slice(),
446
- lastHeads: A4.getHeads(accessor.handle.docSync()),
423
+ lastHeads: A3.getHeads(accessor.handle.docSync()),
447
424
  unreconciledTransactions: []
448
425
  }),
449
426
  update: (value, tr) => {
@@ -1395,10 +1372,10 @@ var inlineUrl = mx(code, "px-1");
1395
1372
  var blockquote = mx("pl-1 mr-1 border-is-4 border-primary-500/70 dark:border-primary-500/30", light);
1396
1373
 
1397
1374
  // packages/ui/react-ui-editor/src/styles/tokens.ts
1398
- import get2 from "lodash.get";
1375
+ import get from "lodash.get";
1399
1376
  import { tailwindConfig } from "@dxos/react-ui-theme";
1400
1377
  var tokens = tailwindConfig({}).theme;
1401
- var getToken = (path, defaultValue = void 0) => get2(tokens, path, defaultValue);
1378
+ var getToken = (path, defaultValue = void 0) => get(tokens, path, defaultValue);
1402
1379
 
1403
1380
  // packages/ui/react-ui-editor/src/styles/layout.ts
1404
1381
  var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
@@ -1922,7 +1899,7 @@ import { hueTokens } from "@dxos/react-ui-theme";
1922
1899
  import { hexToHue, isNotFalsy as isNotFalsy2 } from "@dxos/util";
1923
1900
 
1924
1901
  // packages/ui/react-ui-editor/src/themes/default.ts
1925
- import get3 from "lodash.get";
1902
+ import get2 from "lodash.get";
1926
1903
  var defaultTheme = {
1927
1904
  //
1928
1905
  // Main layout:
@@ -1956,7 +1933,7 @@ var defaultTheme = {
1956
1933
  // TODO(burdon): Reconcile with docs: https://codemirror.net/docs/guide
1957
1934
  // Inside of that is the scroller element. If the editor has its own scrollbar, this one should be styled with overflow: auto. But it doesn't have to—the editor also supports growing to accomodate its content, or growing up to a certain max-height and then scrolling.
1958
1935
  overflowY: "auto",
1959
- fontFamily: get3(tokens, "fontFamily.body", []).join(","),
1936
+ fontFamily: get2(tokens, "fontFamily.body", []).join(","),
1960
1937
  lineHeight: 1.5
1961
1938
  },
1962
1939
  ".cm-content": {
@@ -1966,11 +1943,11 @@ var defaultTheme = {
1966
1943
  fontSize: "16px"
1967
1944
  },
1968
1945
  "&light .cm-content": {
1969
- color: get3(tokens, "extend.semanticColors.base.fg.light", "black"),
1946
+ color: get2(tokens, "extend.semanticColors.base.fg.light", "black"),
1970
1947
  caretColor: "black"
1971
1948
  },
1972
1949
  "&dark .cm-content": {
1973
- color: get3(tokens, "extend.semanticColors.base.fg.dark", "white"),
1950
+ color: get2(tokens, "extend.semanticColors.base.fg.dark", "white"),
1974
1951
  caretColor: "white"
1975
1952
  },
1976
1953
  //
@@ -1983,10 +1960,10 @@ var defaultTheme = {
1983
1960
  borderLeft: "2px solid white"
1984
1961
  },
1985
1962
  "&light .cm-placeholder": {
1986
- color: get3(tokens, "extend.semanticColors.description.light", "rgba(0,0,0,.2)")
1963
+ color: get2(tokens, "extend.semanticColors.description.light", "rgba(0,0,0,.2)")
1987
1964
  },
1988
1965
  "&dark .cm-placeholder": {
1989
- color: get3(tokens, "extend.semanticColors.description.dark", "rgba(255,255,255,.2)")
1966
+ color: get2(tokens, "extend.semanticColors.description.dark", "rgba(255,255,255,.2)")
1990
1967
  },
1991
1968
  //
1992
1969
  // line
@@ -2007,36 +1984,36 @@ var defaultTheme = {
2007
1984
  // Selection
2008
1985
  //
2009
1986
  "&light .cm-selectionBackground": {
2010
- background: get3(tokens, "extend.colors.primary.100")
1987
+ background: get2(tokens, "extend.colors.primary.100")
2011
1988
  },
2012
1989
  "&light.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
2013
- background: get3(tokens, "extend.colors.primary.200")
1990
+ background: get2(tokens, "extend.colors.primary.200")
2014
1991
  },
2015
1992
  "&dark .cm-selectionBackground": {
2016
- background: get3(tokens, "extend.colors.primary.700")
1993
+ background: get2(tokens, "extend.colors.primary.700")
2017
1994
  },
2018
1995
  "&dark.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
2019
- background: get3(tokens, "extend.colors.primary.600")
1996
+ background: get2(tokens, "extend.colors.primary.600")
2020
1997
  },
2021
1998
  //
2022
1999
  // Search
2023
2000
  //
2024
2001
  "&light .cm-searchMatch": {
2025
- backgroundColor: get3(tokens, "extend.colors.yellow.100")
2002
+ backgroundColor: get2(tokens, "extend.colors.yellow.100")
2026
2003
  },
2027
2004
  "&dark .cm-searchMatch": {
2028
- backgroundColor: get3(tokens, "extend.colors.yellow.700")
2005
+ backgroundColor: get2(tokens, "extend.colors.yellow.700")
2029
2006
  },
2030
2007
  //
2031
2008
  // link
2032
2009
  //
2033
2010
  ".cm-link": {
2034
- color: get3(tokens, "extend.colors.primary.500"),
2011
+ color: get2(tokens, "extend.colors.primary.500"),
2035
2012
  textDecorationLine: "underline",
2036
2013
  textDecorationThickness: "1px",
2037
2014
  textUnderlineOffset: "2px",
2038
2015
  borderRadius: ".125rem",
2039
- fontFamily: get3(tokens, "fontFamily.body", []).join(",")
2016
+ fontFamily: get2(tokens, "fontFamily.body", []).join(",")
2040
2017
  },
2041
2018
  //
2042
2019
  // tooltip
@@ -2059,7 +2036,7 @@ var defaultTheme = {
2059
2036
  display: "none"
2060
2037
  },
2061
2038
  ".cm-completionLabel": {
2062
- fontFamily: get3(tokens, "fontFamily.body", []).join(",")
2039
+ fontFamily: get2(tokens, "fontFamily.body", []).join(",")
2063
2040
  },
2064
2041
  ".cm-completionMatchedText": {
2065
2042
  textDecoration: "none"
@@ -2068,15 +2045,15 @@ var defaultTheme = {
2068
2045
  // table
2069
2046
  //
2070
2047
  ".cm-table *": {
2071
- fontFamily: `${get3(tokens, "fontFamily.mono", []).join(",")} !important`,
2048
+ fontFamily: `${get2(tokens, "fontFamily.mono", []).join(",")} !important`,
2072
2049
  textDecoration: "none !important"
2073
2050
  },
2074
2051
  ".cm-table-head": {
2075
2052
  padding: "2px 16px 2px 0px",
2076
- borderBottom: `1px solid ${get3(tokens, "extend.colors.neutral.500")}`,
2053
+ borderBottom: `1px solid ${get2(tokens, "extend.colors.neutral.500")}`,
2077
2054
  fontWeight: 100,
2078
2055
  textAlign: "left",
2079
- color: get3(tokens, "extend.colors.neutral.500")
2056
+ color: get2(tokens, "extend.colors.neutral.500")
2080
2057
  },
2081
2058
  ".cm-table-cell": {
2082
2059
  padding: "2px 16px 2px 0px"
@@ -2124,20 +2101,20 @@ var defaultTheme = {
2124
2101
  */
2125
2102
  ".cm-panels": {},
2126
2103
  ".cm-panel": {
2127
- fontFamily: get3(tokens, "fontFamily.body", []).join(",")
2104
+ fontFamily: get2(tokens, "fontFamily.body", []).join(",")
2128
2105
  },
2129
2106
  ".cm-panel input[type=checkbox]": {
2130
2107
  marginRight: "0.4rem !important"
2131
2108
  },
2132
2109
  "&light .cm-panel": {
2133
- background: get3(tokens, "extend.colors.neutral.50")
2110
+ background: get2(tokens, "extend.colors.neutral.50")
2134
2111
  },
2135
2112
  "&dark .cm-panel": {
2136
- background: get3(tokens, "extend.colors.neutral.850")
2113
+ background: get2(tokens, "extend.colors.neutral.850")
2137
2114
  },
2138
2115
  ".cm-button": {
2139
2116
  margin: "4px",
2140
- fontFamily: get3(tokens, "fontFamily.body", []).join(","),
2117
+ fontFamily: get2(tokens, "fontFamily.body", []).join(","),
2141
2118
  backgroundImage: "none",
2142
2119
  border: "none",
2143
2120
  "&:active": {
@@ -2145,21 +2122,21 @@ var defaultTheme = {
2145
2122
  }
2146
2123
  },
2147
2124
  "&light .cm-button": {
2148
- background: get3(tokens, "extend.colors.neutral.100"),
2125
+ background: get2(tokens, "extend.colors.neutral.100"),
2149
2126
  "&:hover": {
2150
- background: get3(tokens, "extend.colors.neutral.200")
2127
+ background: get2(tokens, "extend.colors.neutral.200")
2151
2128
  },
2152
2129
  "&:active": {
2153
- background: get3(tokens, "extend.colors.neutral.300")
2130
+ background: get2(tokens, "extend.colors.neutral.300")
2154
2131
  }
2155
2132
  },
2156
2133
  "&dark .cm-button": {
2157
- background: get3(tokens, "extend.colors.neutral.800"),
2134
+ background: get2(tokens, "extend.colors.neutral.800"),
2158
2135
  "&:hover": {
2159
- background: get3(tokens, "extend.colors.neutral.700")
2136
+ background: get2(tokens, "extend.colors.neutral.700")
2160
2137
  },
2161
2138
  "&:active": {
2162
- background: get3(tokens, "extend.colors.neutral.600")
2139
+ background: get2(tokens, "extend.colors.neutral.600")
2163
2140
  }
2164
2141
  }
2165
2142
  };
@@ -2190,7 +2167,7 @@ var createBasicExtensions = (_props) => {
2190
2167
  EditorView9.exceptionSink.of((err) => {
2191
2168
  log5.catch(err, void 0, {
2192
2169
  F: __dxlog_file7,
2193
- L: 91,
2170
+ L: 90,
2194
2171
  S: void 0,
2195
2172
  C: (f, a) => f(...a)
2196
2173
  });
@@ -2247,9 +2224,9 @@ var createThemeExtensions = ({ theme, themeMode, slots: _slots } = {}) => {
2247
2224
  ].filter(isNotFalsy2);
2248
2225
  };
2249
2226
  var createDataExtensions = ({ id, text, space, identity }) => {
2250
- const extensions = [
2227
+ const extensions = text ? [
2251
2228
  automerge(text)
2252
- ];
2229
+ ] : [];
2253
2230
  if (space && identity) {
2254
2231
  const peerId = identity?.identityKey.toHex();
2255
2232
  const { cursorLightValue, cursorDarkValue } = hueTokens[identity?.profile?.data?.hue ?? hexToHue(peerId ?? "0")];
@@ -2302,255 +2279,261 @@ var List;
2302
2279
  List2[List2["Bullet"] = 1] = "Bullet";
2303
2280
  List2[List2["Task"] = 2] = "Task";
2304
2281
  })(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
- });
2282
+ var setHeading = (level) => {
2283
+ return ({ state: state2, dispatch }) => {
2284
+ const { selection: { ranges }, doc } = state2;
2285
+ const changes = [];
2286
+ let prevBlock = -1;
2287
+ for (const range of ranges) {
2288
+ let sawBlock = false;
2289
+ syntaxTree(state2).iterate({
2290
+ from: range.from,
2291
+ to: range.to,
2292
+ enter: (node) => {
2293
+ if (!Object.hasOwn(Textblocks, node.name) || prevBlock === node.from) {
2294
+ return;
2338
2295
  }
2339
- changes.push({
2340
- from: nextLine.from - 1,
2341
- to: nextLine.to
2342
- });
2343
- } else {
2344
- if (level === 0) {
2296
+ sawBlock = true;
2297
+ prevBlock = node.from;
2298
+ const blockType = Textblocks[node.name];
2299
+ const isHeading = /heading(\d)/.exec(blockType);
2300
+ const curLevel = isHeading ? +isHeading[1] : node.name === "Paragraph" ? 0 : -1;
2301
+ if (curLevel < 0 || curLevel === level) {
2302
+ return;
2303
+ }
2304
+ if (curLevel === 0) {
2345
2305
  changes.push({
2346
2306
  from: node.from,
2347
- to: Math.min(node.to, node.from + curLevel + 1)
2307
+ insert: "#".repeat(level) + " "
2348
2308
  });
2349
- } else if (level < curLevel) {
2309
+ } else if (node.name === "SetextHeading1" || node.name === "SetextHeading2") {
2310
+ const nextLine = doc.lineAt(node.to);
2311
+ if (level) {
2312
+ changes.push({
2313
+ from: node.from,
2314
+ insert: "#".repeat(level) + " "
2315
+ });
2316
+ }
2350
2317
  changes.push({
2351
- from: node.from,
2352
- to: node.from + (curLevel - level)
2318
+ from: nextLine.from - 1,
2319
+ to: nextLine.to
2353
2320
  });
2354
2321
  } else {
2355
- changes.push({
2356
- from: node.from,
2357
- insert: "#".repeat(level - curLevel)
2358
- });
2322
+ if (level === 0) {
2323
+ changes.push({
2324
+ from: node.from,
2325
+ to: Math.min(node.to, node.from + curLevel + 1)
2326
+ });
2327
+ } else if (level < curLevel) {
2328
+ changes.push({
2329
+ from: node.from,
2330
+ to: node.from + (curLevel - level)
2331
+ });
2332
+ } else {
2333
+ changes.push({
2334
+ from: node.from,
2335
+ insert: "#".repeat(level - curLevel)
2336
+ });
2337
+ }
2359
2338
  }
2360
2339
  }
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
2340
  });
2341
+ let line;
2342
+ if (!sawBlock && range.empty && level > 0 && !/\S/.test((line = state2.doc.lineAt(range.from)).text)) {
2343
+ changes.push({
2344
+ from: line.from,
2345
+ to: line.to,
2346
+ insert: "#".repeat(level) + " "
2347
+ });
2348
+ }
2370
2349
  }
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;
2350
+ if (!changes.length) {
2351
+ return false;
2352
+ }
2353
+ const changeSet = state2.changes(changes);
2354
+ dispatch(state2.update({
2355
+ changes: changeSet,
2356
+ selection: state2.selection.map(changeSet, 1),
2357
+ userEvent: "format.setHeading",
2358
+ scrollIntoView: true
2359
+ }));
2360
+ return true;
2361
+ };
2383
2362
  };
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
- };
2363
+ var setStyle = (type, enable) => {
2364
+ return ({ state: state2, dispatch }) => {
2365
+ const marker = inlineMarkerText(type);
2366
+ const changes = state2.changeByRange((range) => {
2367
+ if (!enable && range.empty) {
2368
+ const after = state2.doc.sliceString(range.head, range.head + 6);
2369
+ const found = after.indexOf(marker);
2370
+ if (found >= 0 && /^[*~`]*$/.test(after.slice(0, found))) {
2371
+ const before = state2.doc.sliceString(range.head - 6, range.head);
2372
+ if (before.slice(before.length - found - marker.length, before.length - found) === marker && [
2373
+ ...before.slice(before.length - found)
2374
+ ].reverse().join("") === after.slice(0, found)) {
2375
+ return {
2376
+ changes: [
2377
+ {
2378
+ from: range.head - marker.length - found,
2379
+ to: range.head - found
2380
+ },
2381
+ {
2382
+ from: range.head + found,
2383
+ to: range.head + found + marker.length
2384
+ }
2385
+ ],
2386
+ range: EditorSelection.cursor(range.from - marker.length)
2387
+ };
2388
+ }
2408
2389
  }
2409
2390
  }
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) {
2391
+ const changes2 = [];
2392
+ const changesAtEnd = [];
2393
+ let blockStart = -1;
2394
+ let blockEnd = -1;
2395
+ let startCovered = false;
2396
+ let endCovered = false;
2397
+ let { from, to } = range;
2398
+ syntaxTree(state2).iterate({
2399
+ from,
2400
+ to,
2401
+ enter: (node) => {
2402
+ const { name } = node;
2403
+ if (Object.hasOwn(Textblocks, name) && Textblocks[name] !== "codeblock") {
2404
+ blockStart = blockContentStart(node);
2405
+ blockEnd = blockContentEnd(node, state2.doc);
2406
+ startCovered = endCovered = false;
2407
+ } else if (name === "Link" || name === "Image" && enable) {
2408
+ if (from < node.from && to > node.from && to <= node.to) {
2436
2409
  to = node.to;
2410
+ } else if (to > node.to && from >= node.from && from < node.to) {
2411
+ from = node.from;
2437
2412
  }
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;
2413
+ } else if (IgnoreInline.has(name) && enable) {
2414
+ if (node.from < from && node.to > from) {
2415
+ if (to === from) {
2416
+ to = node.to;
2417
+ }
2418
+ from = node.to;
2454
2419
  }
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;
2420
+ if (node.from < to && node.to > to) {
2421
+ to = node.from;
2460
2422
  }
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
- });
2423
+ } else if (Object.hasOwn(InlineMarker, name)) {
2424
+ const markType = InlineMarker[name];
2425
+ const size = inlineMarkerText(markType).length;
2426
+ const openEnd = node.from + size;
2427
+ const closeStart = node.to - size;
2428
+ if (markType === type) {
2429
+ if (openEnd <= from && closeStart >= from) {
2430
+ startCovered = !enable && openEnd === skipMarkers(from, node.node, -1, openEnd) ? {
2431
+ from: node.from,
2432
+ to: openEnd
2433
+ } : true;
2434
+ }
2435
+ if (openEnd <= to && closeStart >= to) {
2436
+ endCovered = !enable && closeStart === skipMarkers(to, node.node, 1, closeStart) ? {
2437
+ from: closeStart,
2438
+ to: node.to
2439
+ } : true;
2473
2440
  }
2474
2441
  }
2475
- if (closeStart >= from && node.to <= to) {
2476
- changes2.push({
2477
- from: closeStart,
2478
- to: node.to
2479
- });
2480
- if (markType !== type && openEnd <= from) {
2442
+ if (markType === type || type === 3 && enable) {
2443
+ if (node.from >= from && openEnd <= to) {
2481
2444
  changes2.push({
2482
- from: skipSpaces(Math.max(from, blockStart), state2.doc, -1, blockStart),
2483
- insert: inlineMarkerText(markType)
2445
+ from: node.from,
2446
+ to: openEnd
2484
2447
  });
2448
+ if (markType !== type && closeStart >= to) {
2449
+ changesAtEnd.push({
2450
+ from: skipSpaces(Math.min(to, blockEnd), state2.doc, 1, blockEnd),
2451
+ insert: inlineMarkerText(markType)
2452
+ });
2453
+ }
2454
+ }
2455
+ if (closeStart >= from && node.to <= to) {
2456
+ changes2.push({
2457
+ from: closeStart,
2458
+ to: node.to
2459
+ });
2460
+ if (markType !== type && openEnd <= from) {
2461
+ changes2.push({
2462
+ from: skipSpaces(Math.max(from, blockStart), state2.doc, -1, blockStart),
2463
+ insert: inlineMarkerText(markType)
2464
+ });
2465
+ }
2485
2466
  }
2486
2467
  }
2487
2468
  }
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
- });
2469
+ },
2470
+ leave: (node) => {
2471
+ if (Object.hasOwn(Textblocks, node.name) && Textblocks[node.name] !== "codeblock") {
2472
+ const rangeStart = Math.max(from, blockStart);
2473
+ const rangeEnd = Math.min(to, blockEnd);
2474
+ if (enable) {
2475
+ if (!startCovered) {
2476
+ changes2.push({
2477
+ from: rangeStart,
2478
+ insert: marker
2479
+ });
2480
+ }
2481
+ if (!endCovered) {
2482
+ changes2.push({
2483
+ from: rangeEnd,
2484
+ insert: marker
2485
+ });
2486
+ }
2487
+ } else {
2488
+ if (typeof startCovered === "object") {
2489
+ changes2.push(startCovered);
2490
+ } else if (startCovered) {
2491
+ changes2.push({
2492
+ from: skipSpaces(rangeStart, state2.doc, -1, blockStart),
2493
+ insert: marker
2494
+ });
2495
+ }
2496
+ if (typeof endCovered === "object") {
2497
+ changes2.push(endCovered);
2498
+ } else if (endCovered) {
2499
+ changes2.push({
2500
+ from: skipSpaces(rangeEnd, state2.doc, 1, blockEnd),
2501
+ insert: marker
2502
+ });
2503
+ }
2523
2504
  }
2524
2505
  }
2525
2506
  }
2507
+ });
2508
+ if (blockStart < 0 && range.empty && enable && !/\S/.test(state2.doc.lineAt(range.from).text)) {
2509
+ return {
2510
+ changes: {
2511
+ from: range.head,
2512
+ insert: marker + marker
2513
+ },
2514
+ range: EditorSelection.cursor(range.head + marker.length)
2515
+ };
2526
2516
  }
2527
- });
2528
- if (blockStart < 0 && range.empty && enable && !/\S/.test(state2.doc.lineAt(range.from).text)) {
2517
+ const changeSet = state2.changes(changes2.concat(changesAtEnd));
2529
2518
  return {
2530
- changes: {
2531
- from: range.head,
2532
- insert: marker + marker
2533
- },
2534
- range: EditorSelection.cursor(range.head + marker.length)
2519
+ changes: changeSet,
2520
+ range: range.empty && !changeSet.empty ? EditorSelection.cursor(range.head + marker.length) : EditorSelection.range(changeSet.mapPos(range.from, 1), changeSet.mapPos(range.to, -1))
2535
2521
  };
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;
2522
+ });
2523
+ dispatch(state2.update(changes, {
2524
+ userEvent: enable ? "format.style.add" : "format.style.remove",
2525
+ scrollIntoView: true
2526
+ }));
2527
+ return true;
2528
+ };
2548
2529
  };
2549
2530
  var addStyle = (style) => setStyle(style, true);
2550
2531
  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);
2532
+ var toggleStyle = (style) => {
2533
+ return (arg) => {
2534
+ const form = getFormatting(arg.state);
2535
+ return setStyle(style, style === 0 ? !form.strong : style === 1 ? !form.emphasis : style === 2 ? !form.strikethrough : !form.code)(arg);
2536
+ };
2554
2537
  };
2555
2538
  var toggleStrong = toggleStyle(0);
2556
2539
  var toggleEmphasis = toggleStyle(1);
@@ -2654,296 +2637,305 @@ var removeLink = ({ state: state2, dispatch }) => {
2654
2637
  }));
2655
2638
  return true;
2656
2639
  };
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);
2640
+ var addLink = ({ url, image: image2 } = {}) => {
2641
+ return ({ state: state2, dispatch }) => {
2642
+ const changes = state2.changeByRange((range) => {
2643
+ let { from, to } = range;
2644
+ const cutStyles = [];
2645
+ let okay = null;
2646
+ syntaxTree(state2).iterate({
2647
+ from,
2648
+ to,
2649
+ enter: (node) => {
2650
+ if (Object.hasOwn(Textblocks, node.name)) {
2651
+ okay = Textblocks[node.name] !== "codeblock" && from >= blockContentStart(node) && to <= blockContentEnd(node, state2.doc);
2652
+ } else if (Object.hasOwn(InlineMarker, node.name)) {
2653
+ const sNode = node.node;
2654
+ if (node.from < from && node.to <= to) {
2655
+ if (sNode.firstChild.to === from) {
2656
+ from = node.from;
2657
+ } else {
2658
+ cutStyles.push(sNode);
2659
+ }
2660
+ } else if (node.from >= from && node.to > to) {
2661
+ if (sNode.lastChild.from === to) {
2662
+ to = node.to;
2663
+ } else {
2664
+ cutStyles.push(sNode);
2665
+ }
2681
2666
  }
2682
2667
  }
2683
2668
  }
2669
+ });
2670
+ if (okay === null) {
2671
+ const line = state2.doc.lineAt(from);
2672
+ okay = to <= line.to && !/\S/.test(line.text.slice(from - line.from));
2684
2673
  }
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;
2674
+ if (!okay) {
2675
+ return {
2676
+ range
2677
+ };
2678
+ }
2679
+ const changes2 = [];
2680
+ const changesAfter = [];
2681
+ removeLinkInner(from, to, changesAfter, state2);
2682
+ let cursorOffset = 1;
2683
+ for (const style of cutStyles) {
2684
+ const type = InlineMarker[style.name];
2685
+ const mark2 = inlineMarkerText(type);
2686
+ if (style.from < from) {
2687
+ changes2.push({
2688
+ from: skipSpaces(from, state2.doc, -1),
2689
+ insert: mark2
2690
+ });
2691
+ changesAfter.push({
2692
+ from: skipSpaces(from, state2.doc, 1, to),
2693
+ insert: mark2
2694
+ });
2695
+ } else {
2696
+ changes2.push({
2697
+ from: skipSpaces(to, state2.doc, -1, from),
2698
+ insert: mark2
2699
+ });
2700
+ const after = skipSpaces(to, state2.doc, 1);
2701
+ if (after === to) {
2702
+ cursorOffset += mark2.length;
2703
+ }
2704
+ changesAfter.push({
2705
+ from: after,
2706
+ insert: mark2
2707
+ });
2719
2708
  }
2720
- changesAfter.push({
2721
- from: after,
2722
- insert: mark2
2723
- });
2724
2709
  }
2725
- }
2726
- changes2.push({
2727
- from,
2728
- insert: image2 ? "![" : "["
2729
- }, {
2730
- from: to,
2731
- insert: `](${url ?? ""})`
2710
+ changes2.push({
2711
+ from,
2712
+ insert: image2 ? "![" : "["
2713
+ }, {
2714
+ from: to,
2715
+ insert: `](${url ?? ""})`
2716
+ });
2717
+ const changeSet = state2.changes(changes2.concat(changesAfter));
2718
+ return {
2719
+ changes: changeSet,
2720
+ range: EditorSelection.cursor(changeSet.mapPos(to, 1) - cursorOffset - (url ? url.length + 2 : 0))
2721
+ };
2732
2722
  });
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;
2723
+ if (changes.changes.empty) {
2724
+ return false;
2725
+ }
2726
+ dispatch(state2.update(changes, {
2727
+ userEvent: "format.link.add",
2728
+ scrollIntoView: true
2729
+ }));
2730
+ return true;
2731
+ };
2747
2732
  };
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;
2733
+ var addList = (type) => {
2734
+ return ({ state: state2, dispatch }) => {
2735
+ let lastBlock = -1;
2736
+ let counter = 1;
2737
+ let first = true;
2738
+ let parentColumn = null;
2739
+ const blocks = [];
2740
+ for (const { from, to } of state2.selection.ranges) {
2741
+ syntaxTree(state2).iterate({
2742
+ from,
2743
+ to,
2744
+ enter: (node) => {
2745
+ if (Object.hasOwn(Textblocks, node.name) && node.name !== "TableCell" || node.name === "Table") {
2746
+ if (first) {
2747
+ let before = node.node.prevSibling;
2748
+ while (before && /Mark$/.test(before.name)) {
2749
+ before = before.prevSibling;
2750
+ }
2751
+ if (before?.name === (type === 0 ? "OrderedList" : "BulletList")) {
2752
+ const item = before.lastChild;
2753
+ const itemLine = state2.doc.lineAt(item.from);
2754
+ const itemText = itemLine.text.slice(item.from - itemLine.from);
2755
+ parentColumn = item.from - itemLine.from + /^\s*/.exec(itemText)[0].length;
2756
+ if (type === 0) {
2757
+ const mark2 = /^\s*(\d+)[.)]/.exec(itemText);
2758
+ if (mark2) {
2759
+ parentColumn += mark2[1].length;
2760
+ counter = +mark2[1] + 1;
2761
+ }
2775
2762
  }
2776
2763
  }
2764
+ first = false;
2765
+ }
2766
+ if (node.from === lastBlock) {
2767
+ return;
2777
2768
  }
2778
- first = false;
2769
+ lastBlock = node.from;
2770
+ blocks.push({
2771
+ node: node.node,
2772
+ counter,
2773
+ parentColumn
2774
+ });
2775
+ counter++;
2776
+ return false;
2779
2777
  }
2780
- if (node.from === lastBlock) {
2781
- return;
2778
+ },
2779
+ leave: (node) => {
2780
+ if (node.name === "BulletList" || node.name === "OrderedList" || node.name === "Blockquote") {
2781
+ counter = 1;
2782
+ parentColumn = null;
2782
2783
  }
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
2784
  }
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;
2785
+ });
2829
2786
  }
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);
2787
+ if (!blocks.length) {
2788
+ const { from, to } = state2.doc.lineAt(state2.selection.main.anchor);
2789
+ if (from === to) {
2790
+ const insert = type === 1 ? "- " : type === 0 ? "1. " : "- [ ] ";
2791
+ dispatch(state2.update({
2792
+ changes: [
2793
+ {
2794
+ from,
2795
+ insert
2796
+ }
2797
+ ],
2798
+ selection: {
2799
+ anchor: from + insert.length
2800
+ },
2801
+ userEvent: "format.list.add",
2802
+ scrollIntoView: true
2803
+ }));
2804
+ return true;
2805
+ }
2806
+ return false;
2834
2807
  }
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;
2808
+ const changes = [];
2809
+ for (let i = 0; i < blocks.length; i++) {
2810
+ const { node, counter: counter2, parentColumn: parentColumn2 } = blocks[i];
2811
+ const nodeFrom = node.name === "CodeBlock" ? node.from - 4 : node.from;
2812
+ let padding = nodeFrom > 0 && !/\s/.test(state2.doc.sliceString(nodeFrom - 1, nodeFrom)) ? 1 : 0;
2813
+ if (type === 0) {
2814
+ padding += String(counter2).length;
2815
+ }
2816
+ let line = state2.doc.lineAt(nodeFrom);
2817
+ const column = nodeFrom - line.from;
2818
+ if (parentColumn2 !== null && parentColumn2 > column) {
2819
+ padding = Math.max(padding, parentColumn2 - column);
2820
+ }
2821
+ let mark2;
2822
+ if (type === 0) {
2823
+ let max = counter2;
2824
+ for (let j = i + 1; j < blocks.length; j++) {
2825
+ if (blocks[j].counter !== max + 1) {
2826
+ break;
2827
+ }
2828
+ max++;
2841
2829
  }
2842
- max++;
2830
+ const num = String(counter2);
2831
+ padding = Math.max(String(max).length, padding);
2832
+ mark2 = " ".repeat(Math.max(0, padding - num.length)) + num + ". ";
2833
+ } else {
2834
+ mark2 = " ".repeat(padding) + "- " + (type === 2 ? "[ ] " : "");
2843
2835
  }
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
2836
  changes.push({
2858
- from: line.from + Math.min(open, column),
2859
- insert: " ".repeat(mark2.length)
2837
+ from: nodeFrom,
2838
+ insert: mark2
2860
2839
  });
2840
+ while (line.to < node.to) {
2841
+ line = state2.doc.lineAt(line.to + 1);
2842
+ const open = /^[\s>]*/.exec(line.text)[0].length;
2843
+ changes.push({
2844
+ from: line.from + Math.min(open, column),
2845
+ insert: " ".repeat(mark2.length)
2846
+ });
2847
+ }
2861
2848
  }
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);
2849
+ if (type === 0) {
2850
+ const last = blocks[blocks.length - 1];
2851
+ let next = last.node.nextSibling;
2852
+ while (next && /Mark$/.test(next.name)) {
2853
+ next = next.nextSibling;
2854
+ }
2855
+ if (next?.name === "OrderedList") {
2856
+ renumberListItems(next.firstChild, last.counter + 1, changes, state2.doc);
2857
+ }
2871
2858
  }
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;
2859
+ "Oeswe";
2860
+ const changeSet = state2.changes(changes);
2861
+ dispatch(state2.update({
2862
+ changes: changeSet,
2863
+ selection: state2.selection.map(changeSet, 1),
2864
+ userEvent: "format.list.add",
2865
+ scrollIntoView: true
2866
+ }));
2867
+ return true;
2868
+ };
2881
2869
  };
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;
2870
+ var removeList = (type) => {
2871
+ return ({ state: state2, dispatch }) => {
2872
+ let lastBlock = -1;
2873
+ const changes = [];
2874
+ const stack = [];
2875
+ const targetNodeType = type === 0 ? "OrderedList" : type === 1 ? "BulletList" : "TaskList";
2876
+ for (const { from, to } of state2.selection.ranges) {
2877
+ syntaxTree(state2).iterate({
2878
+ from,
2879
+ to,
2880
+ enter: (node) => {
2881
+ const { name } = node;
2882
+ if (name === "BulletList" || name === "OrderedList" || name === "Blockquote") {
2883
+ stack.push(name);
2884
+ } else if (name === "Task" && stack[stack.length - 1] === "BulletList") {
2885
+ stack[stack.length - 1] = "TaskList";
2909
2886
  }
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
- });
2887
+ },
2888
+ leave: (node) => {
2889
+ const { name } = node;
2890
+ if (name === "BulletList" || name === "OrderedList" || name === "Blockquote") {
2891
+ stack.pop();
2892
+ } else if (name === "ListItem" && stack[stack.length - 1] === targetNodeType && node.from !== lastBlock) {
2893
+ lastBlock = node.from;
2894
+ let line = state2.doc.lineAt(node.from);
2895
+ const mark2 = /^\s*(\d+[.)] |[-*+] (\[[ x]\] )?)/.exec(line.text.slice(node.from - line.from));
2896
+ if (!mark2) {
2897
+ return false;
2923
2898
  }
2899
+ const column = node.from - line.from;
2900
+ changes.push({
2901
+ from: node.from,
2902
+ to: node.from + mark2[0].length
2903
+ });
2904
+ while (line.to < node.to) {
2905
+ line = state2.doc.lineAt(line.to + 1);
2906
+ const open = /^[\s>]*/.exec(line.text)[0].length;
2907
+ if (open > column) {
2908
+ changes.push({
2909
+ from: line.from + column,
2910
+ to: line.from + Math.min(column + mark2[0].length, open)
2911
+ });
2912
+ }
2913
+ }
2914
+ if (node.to >= to) {
2915
+ renumberListItems(node.node.nextSibling, 1, changes, state2.doc);
2916
+ }
2917
+ return false;
2924
2918
  }
2925
- if (node.to >= to) {
2926
- renumberListItems(node.node.nextSibling, 1, changes, state2.doc);
2927
- }
2928
- return false;
2929
2919
  }
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;
2920
+ });
2921
+ }
2922
+ if (!changes.length) {
2923
+ return false;
2924
+ }
2925
+ dispatch(state2.update({
2926
+ changes,
2927
+ userEvent: "format.list.remove",
2928
+ scrollIntoView: true
2929
+ }));
2930
+ return true;
2931
+ };
2942
2932
  };
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);
2933
+ var toggleList = (type) => {
2934
+ return (target) => {
2935
+ const formatting = getFormatting(target.state);
2936
+ const active = formatting.listStyle === (type === 1 ? "bullet" : type === 0 ? "ordered" : "task");
2937
+ return (active ? removeList(type) : addList(type))(target);
2938
+ };
2947
2939
  };
2948
2940
  var renumberListItems = (item, counter, changes, doc) => {
2949
2941
  for (; item; item = item.nextSibling) {
@@ -2963,79 +2955,81 @@ var renumberListItems = (item, counter, changes, doc) => {
2963
2955
  }
2964
2956
  }
2965
2957
  };
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);
2958
+ var setBlockquote = (enable) => {
2959
+ return ({ state: state2, dispatch }) => {
2960
+ const lines = [];
2961
+ let lastBlock = -1;
2962
+ for (const { from, to } of state2.selection.ranges) {
2963
+ const sawBlock = false;
2964
+ syntaxTree(state2).iterate({
2965
+ from,
2966
+ to,
2967
+ enter: (node) => {
2968
+ if (Object.hasOwn(Textblocks, node.name) || node.name === "Table") {
2969
+ if (node.from === lastBlock) {
2970
+ return false;
2971
+ }
2972
+ lastBlock = node.from;
2973
+ let line2 = state2.doc.lineAt(node.from);
2974
+ if (line2.number > 1) {
2975
+ const prevLine = state2.doc.line(line2.number - 1);
2976
+ if (/^[>\s]*$/.test(prevLine.text)) {
2977
+ if (!enable || lines.length && lines[lines.length - 1].number === prevLine.number - 1) {
2978
+ lines.push(prevLine);
2979
+ }
2986
2980
  }
2987
2981
  }
2988
- }
2989
- for (; ; ) {
2990
- lines.push(line2);
2991
- if (line2.to >= node.to) {
2992
- break;
2982
+ for (; ; ) {
2983
+ lines.push(line2);
2984
+ if (line2.to >= node.to) {
2985
+ break;
2986
+ }
2987
+ line2 = state2.doc.line(line2.number + 1);
2993
2988
  }
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);
2989
+ if (!enable && line2.number < state2.doc.lines) {
2990
+ const nextLine = state2.doc.line(line2.number + 1);
2991
+ if (/^[>\s]*$/.test(nextLine.text)) {
2992
+ lines.push(nextLine);
2993
+ }
3000
2994
  }
2995
+ return false;
3001
2996
  }
3002
- return false;
3003
2997
  }
2998
+ });
2999
+ let line;
3000
+ if (!sawBlock && enable && from === to && !/\S/.test((line = state2.doc.lineAt(from)).text)) {
3001
+ lines.push(line);
3004
3002
  }
3005
- });
3006
- let line;
3007
- if (!sawBlock && enable && from === to && !/\S/.test((line = state2.doc.lineAt(from)).text)) {
3008
- lines.push(line);
3009
3003
  }
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) {
3004
+ const changes = [];
3005
+ for (const line of lines) {
3006
+ if (enable) {
3021
3007
  changes.push({
3022
- from: line.from + quote[1].length,
3023
- to: line.from + quote[0].length
3008
+ from: line.from,
3009
+ insert: /\S/.test(line.text) ? "> " : ">"
3024
3010
  });
3011
+ } else {
3012
+ const quote = /((?:[\s>\-+*]|\d+[.)])*?)> ?/.exec(line.text);
3013
+ if (quote) {
3014
+ changes.push({
3015
+ from: line.from + quote[1].length,
3016
+ to: line.from + quote[0].length
3017
+ });
3018
+ }
3025
3019
  }
3026
3020
  }
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;
3021
+ if (!changes.length) {
3022
+ return false;
3023
+ }
3024
+ const changeSet = state2.changes(changes);
3025
+ dispatch(state2.update({
3026
+ changes: changeSet,
3027
+ selection: state2.selection.map(changeSet, 1),
3028
+ userEvent: enable ? "format.blockquote.add" : "format.blockquote.remove",
3029
+ scrollIntoView: true
3030
+ }));
3031
+ return true;
3032
+ };
3039
3033
  };
3040
3034
  var addBlockquote = setBlockquote(true);
3041
3035
  var removeBlockquote = setBlockquote(false);
@@ -3105,8 +3099,8 @@ var addCodeblock = (target) => {
3105
3099
  return true;
3106
3100
  };
3107
3101
  var removeCodeblock = ({ state: state2, dispatch }) => {
3108
- const changes = [];
3109
3102
  let lastBlock = -1;
3103
+ const changes = [];
3110
3104
  for (const { from, to } of state2.selection.ranges) {
3111
3105
  syntaxTree(state2).iterate({
3112
3106
  from,
@@ -3761,68 +3755,88 @@ var buildDecorations = (view, options, focus) => {
3761
3755
  from,
3762
3756
  to,
3763
3757
  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);
3758
+ switch (node.name) {
3759
+ case "FencedCode": {
3760
+ const editing = editingRange(state2, node, focus);
3761
+ for (const block of view.viewportLineBlocks) {
3762
+ if (block.to < node.from) {
3763
+ continue;
3764
+ }
3765
+ if (block.from > node.to) {
3766
+ break;
3767
+ }
3768
+ const first = block.from <= node.from;
3769
+ const last = block.to >= node.to && /^(\s>)*```$/.test(state2.doc.sliceString(block.from, block.to));
3770
+ deco.add(block.from, block.from, first ? fencedCodeLineFirst : last ? fencedCodeLineLast : fencedCodeLine);
3771
+ if (!editing && (first || last)) {
3772
+ atomicDeco.add(block.from, block.to, hide);
3773
+ }
3778
3774
  }
3775
+ return false;
3779
3776
  }
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"
3777
+ case "Link": {
3778
+ const marks = node.node.getChildren("LinkMark");
3779
+ const urlNode = node.node.getChild("URL");
3780
+ const editing = editingRange(state2, node, focus);
3781
+ if (urlNode && marks.length >= 2) {
3782
+ const url = state2.sliceDoc(urlNode.from, urlNode.to);
3783
+ if (!editing) {
3784
+ atomicDeco.add(node.from, marks[0].to, hide);
3785
+ }
3786
+ deco.add(marks[0].to, marks[1].from, Decoration5.mark({
3787
+ tagName: "a",
3788
+ attributes: {
3789
+ class: "cm-link",
3790
+ href: url,
3791
+ rel: "noreferrer",
3792
+ target: "_blank"
3793
+ }
3794
+ }));
3795
+ if (!editing) {
3796
+ atomicDeco.add(marks[1].from, node.to, options.renderLinkButton ? Decoration5.replace({
3797
+ widget: new LinkButton(url, options.renderLinkButton)
3798
+ }) : hide);
3797
3799
  }
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
3800
  }
3801
+ break;
3804
3802
  }
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);
3803
+ case "HeaderMark": {
3804
+ const parent = node.node.parent;
3805
+ if (/^ATX/.test(parent.name) && !editingRange(state2, state2.doc.lineAt(node.from), focus)) {
3806
+ const next = state2.doc.sliceString(node.to, node.to + 1);
3807
+ atomicDeco.add(node.from, node.to + (next === " " ? 1 : 0), hide);
3808
+ }
3809
+ break;
3810
3810
  }
3811
- } else if (node.name === "HorizontalRule") {
3812
- if (!editingRange(state2, node, focus)) {
3813
- deco.add(node.from, node.to, horizontalRule);
3811
+ case "HorizontalRule": {
3812
+ if (!editingRange(state2, node, focus)) {
3813
+ deco.add(node.from, node.to, horizontalRule);
3814
+ }
3815
+ break;
3814
3816
  }
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"
3817
+ case "TaskMarker": {
3818
+ if (!editingRange(state2, node, focus)) {
3819
+ const checked = state2.doc.sliceString(node.from + 1, node.to - 1) === "x";
3820
+ atomicDeco.add(node.from - 2, node.from - 1, Decoration5.mark({
3821
+ class: "cm-task"
3822
+ }));
3823
+ atomicDeco.add(node.from, node.to, checked ? checkedTask : uncheckedTask);
3824
+ }
3825
+ break;
3826
+ }
3827
+ case "ListItem": {
3828
+ const start = state2.doc.lineAt(node.from);
3829
+ deco.add(start.from, start.from, Decoration5.line({
3830
+ class: "cm-list-item"
3820
3831
  }));
3821
- atomicDeco.add(node.from, node.to, checked ? checkedTask : uncheckedTask);
3832
+ break;
3822
3833
  }
3823
- } else if (MarksByParent.has(node.name)) {
3824
- if (!editingRange(state2, node.node.parent, focus)) {
3825
- atomicDeco.add(node.from, node.to, hide);
3834
+ default: {
3835
+ if (MarksByParent.has(node.name)) {
3836
+ if (!editingRange(state2, node.node.parent, focus)) {
3837
+ atomicDeco.add(node.from, node.to, hide);
3838
+ }
3839
+ }
3826
3840
  }
3827
3841
  }
3828
3842
  }
@@ -3848,8 +3862,6 @@ var decorateMarkdown = (options = {}) => {
3848
3862
  this.scheduleUpdate(update2.view);
3849
3863
  }
3850
3864
  }
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
3865
  scheduleUpdate(view) {
3854
3866
  this.clearUpdate();
3855
3867
  this.pendingUpdate = setTimeout(() => {
@@ -4094,15 +4106,17 @@ var update = (state2, options) => {
4094
4106
  }
4095
4107
  });
4096
4108
  tables.forEach((table2) => {
4097
- const hide2 = state2.readOnly || cursor < table2.from || cursor > table2.to;
4098
- if (hide2) {
4109
+ const replace = state2.readOnly || cursor < table2.from || cursor > table2.to;
4110
+ if (replace) {
4099
4111
  builder.add(table2.from, table2.to, Decoration7.replace({
4112
+ block: true,
4100
4113
  widget: new TableWidget(table2)
4101
4114
  }));
4115
+ } else {
4116
+ builder.add(table2.from, table2.to, Decoration7.mark({
4117
+ class: "cm-table"
4118
+ }));
4102
4119
  }
4103
- builder.add(table2.from, table2.to, Decoration7.mark({
4104
- class: "cm-table"
4105
- }));
4106
4120
  });
4107
4121
  return builder.finish();
4108
4122
  };
@@ -4367,10 +4381,23 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
4367
4381
  // packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
4368
4382
  var __dxlog_file10 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx";
4369
4383
  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) => {
4384
+ var TextEditor = /* @__PURE__ */ forwardRef(({
4385
+ id,
4386
+ // TODO(wittjosiah): Rename initialText?
4387
+ doc,
4388
+ selection,
4389
+ extensions,
4390
+ className,
4391
+ autoFocus,
4392
+ scrollTo: propsScrollTo,
4393
+ moveToEndOfLine,
4394
+ debug,
4395
+ dataTestId
4396
+ }, forwardedRef) => {
4373
4397
  const [instanceId] = useState2(() => `text-editor-${++instanceCount}`);
4398
+ const scrollTo = useDefaultValue(propsScrollTo, EditorView16.scrollIntoView(0, {
4399
+ yMargin: 0
4400
+ }));
4374
4401
  const tabsterDOMAttribute = useFocusableGroup({
4375
4402
  tabBehavior: "limited"
4376
4403
  });
@@ -4393,20 +4420,19 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, c
4393
4420
  instanceId
4394
4421
  }, {
4395
4422
  F: __dxlog_file10,
4396
- L: 88,
4423
+ L: 91,
4397
4424
  S: void 0,
4398
4425
  C: (f, a) => f(...a)
4399
4426
  });
4400
4427
  const state2 = EditorState2.create({
4401
4428
  doc,
4402
- selection,
4403
4429
  extensions: [
4404
4430
  id && documentId2.of(id),
4405
4431
  // TODO(burdon): NOTE: Doesn't catch errors in keymap functions.
4406
4432
  EditorView16.exceptionSink.of((err) => {
4407
4433
  log7.catch(err, void 0, {
4408
4434
  F: __dxlog_file10,
4409
- L: 101,
4435
+ L: 104,
4410
4436
  S: void 0,
4411
4437
  C: (f, a) => f(...a)
4412
4438
  });
@@ -4453,15 +4479,17 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ id, doc, selection, extensions, c
4453
4479
  instanceId
4454
4480
  }, {
4455
4481
  F: __dxlog_file10,
4456
- L: 150,
4482
+ L: 153,
4457
4483
  S: void 0,
4458
4484
  C: (f, a) => f(...a)
4459
4485
  });
4460
4486
  view2?.destroy();
4461
4487
  };
4462
4488
  }, [
4463
- doc,
4489
+ id,
4464
4490
  selection,
4491
+ scrollTo,
4492
+ editorMode,
4465
4493
  extensions
4466
4494
  ]);
4467
4495
  const handleKeyUp = useCallback((event) => {
@@ -4800,28 +4828,15 @@ var useActionHandler = (view) => {
4800
4828
  return (action) => view && processAction(view, action);
4801
4829
  };
4802
4830
 
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
4831
  // packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
4817
4832
  import { EditorSelection as EditorSelection2, EditorState as EditorState3 } from "@codemirror/state";
4818
4833
  import { EditorView as EditorView17 } from "@codemirror/view";
4819
- import { useEffect as useEffect4, useMemo as useMemo3, useRef as useRef3, useState as useState4 } from "react";
4834
+ import { useEffect as useEffect4, useMemo as useMemo2, useRef as useRef3, useState as useState4 } from "react";
4820
4835
  import { log as log8 } from "@dxos/log";
4821
4836
  import { isNotFalsy as isNotFalsy5 } from "@dxos/util";
4822
4837
  var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
4823
4838
  var useTextEditor = (cb = () => ({}), deps = []) => {
4824
- let { id, doc, selection, extensions, autoFocus, scrollTo, debug } = useMemo3(cb, deps ?? []);
4839
+ let { id, doc, selection, extensions, autoFocus, scrollTo, debug } = useMemo2(cb, deps ?? []);
4825
4840
  const onUpdate = useRef3();
4826
4841
  const [view, setView] = useState4();
4827
4842
  const parentRef = useRef3(null);
@@ -4838,7 +4853,6 @@ var useTextEditor = (cb = () => ({}), deps = []) => {
4838
4853
  });
4839
4854
  const state2 = EditorState3.create({
4840
4855
  doc,
4841
- selection,
4842
4856
  extensions: [
4843
4857
  id && documentId2.of(id),
4844
4858
  // TODO(burdon): Doesn't catch errors in keymap functions.
@@ -4997,7 +5011,6 @@ export {
4997
5011
  typewriter,
4998
5012
  useActionHandler,
4999
5013
  useComments,
5000
- useDocAccessor,
5001
5014
  useFormattingState,
5002
5015
  useTextEditor,
5003
5016
  useToolbarContext