@dxos/react-ui-editor 0.4.7-main.be31fed → 0.4.7-main.dca306f

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.
@@ -1897,7 +1897,7 @@ var createMarkdownExtensions = ({ themeMode, placeholder: _placeholder, lineWrap
1897
1897
 
1898
1898
  // packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
1899
1899
  import { syntaxTree } from "@codemirror/language";
1900
- import { RangeSetBuilder } from "@codemirror/state";
1900
+ import { RangeSetBuilder, StateEffect as StateEffect3 } from "@codemirror/state";
1901
1901
  import { EditorView as EditorView10, Decoration as Decoration4, WidgetType as WidgetType2, ViewPlugin as ViewPlugin3 } from "@codemirror/view";
1902
1902
  import { mx as mx2 } from "@dxos/react-ui-theme";
1903
1903
  var HorizontalRuleWidget = class extends WidgetType2 {
@@ -1978,9 +1978,9 @@ var checkedTask = Decoration4.replace({
1978
1978
  var uncheckedTask = Decoration4.replace({
1979
1979
  widget: new CheckboxWidget(false)
1980
1980
  });
1981
- var editingRange = (state, range) => {
1981
+ var editingRange = (state, range, focus) => {
1982
1982
  const { readOnly, selection: { main: { head } } } = state;
1983
- return !readOnly && head >= range.from && head <= range.to;
1983
+ return focus && !readOnly && head >= range.from && head <= range.to;
1984
1984
  };
1985
1985
  var MarksByParent = /* @__PURE__ */ new Set([
1986
1986
  "CodeMark",
@@ -1989,8 +1989,9 @@ var MarksByParent = /* @__PURE__ */ new Set([
1989
1989
  "SubscriptMark",
1990
1990
  "SuperscriptMark"
1991
1991
  ]);
1992
- var buildDecorations = (view, options) => {
1993
- const builder = new RangeSetBuilder();
1992
+ var buildDecorations = (view, options, focus) => {
1993
+ const deco = new RangeSetBuilder();
1994
+ const atomicDeco = new RangeSetBuilder();
1994
1995
  const { state } = view;
1995
1996
  for (const { from, to } of view.visibleRanges) {
1996
1997
  syntaxTree(state).iterate({
@@ -1998,7 +1999,7 @@ var buildDecorations = (view, options) => {
1998
1999
  to,
1999
2000
  enter: (node) => {
2000
2001
  if (node.name === "FencedCode") {
2001
- const editing = editingRange(state, node);
2002
+ const editing = editingRange(state, node, focus);
2002
2003
  for (const block of view.viewportLineBlocks) {
2003
2004
  if (block.to < node.from) {
2004
2005
  continue;
@@ -2008,22 +2009,22 @@ var buildDecorations = (view, options) => {
2008
2009
  }
2009
2010
  const first = block.from <= node.from;
2010
2011
  const last = block.to >= node.to;
2011
- builder.add(block.from, block.from, first ? fencedCodeLineFirst : last ? fencedCodeLineLast : fencedCodeLine);
2012
+ deco.add(block.from, block.from, first ? fencedCodeLineFirst : last ? fencedCodeLineLast : fencedCodeLine);
2012
2013
  if (!editing && (first || last)) {
2013
- builder.add(block.from, block.to, hide);
2014
+ atomicDeco.add(block.from, block.to, hide);
2014
2015
  }
2015
2016
  }
2016
2017
  return false;
2017
2018
  } else if (node.name === "Link") {
2018
2019
  const marks = node.node.getChildren("LinkMark");
2019
2020
  const urlNode = node.node.getChild("URL");
2020
- const editing = editingRange(state, node);
2021
+ const editing = editingRange(state, node, focus);
2021
2022
  if (urlNode && marks.length >= 2) {
2022
2023
  const url = state.sliceDoc(urlNode.from, urlNode.to);
2023
2024
  if (!editing) {
2024
- builder.add(node.from, marks[0].to, hide);
2025
+ atomicDeco.add(node.from, marks[0].to, hide);
2025
2026
  }
2026
- builder.add(marks[0].to, marks[1].from, Decoration4.mark({
2027
+ deco.add(marks[0].to, marks[1].from, Decoration4.mark({
2027
2028
  tagName: "a",
2028
2029
  attributes: {
2029
2030
  class: "cm-link",
@@ -2033,52 +2034,81 @@ var buildDecorations = (view, options) => {
2033
2034
  }
2034
2035
  }));
2035
2036
  if (!editing) {
2036
- builder.add(marks[1].from, node.to, options.renderLinkButton ? Decoration4.replace({
2037
+ atomicDeco.add(marks[1].from, node.to, options.renderLinkButton ? Decoration4.replace({
2037
2038
  widget: new LinkButton(url, options.renderLinkButton)
2038
2039
  }) : hide);
2039
2040
  }
2040
2041
  }
2041
2042
  } else if (node.name === "HeaderMark") {
2042
2043
  const parent = node.node.parent;
2043
- if (/^ATX/.test(parent.name) && !editingRange(state, state.doc.lineAt(node.from))) {
2044
+ if (/^ATX/.test(parent.name) && !editingRange(state, state.doc.lineAt(node.from), focus)) {
2044
2045
  const next = state.doc.sliceString(node.to, node.to + 1);
2045
- builder.add(node.from, node.to + (next === " " ? 1 : 0), hide);
2046
+ atomicDeco.add(node.from, node.to + (next === " " ? 1 : 0), hide);
2046
2047
  }
2047
2048
  } else if (node.name === "HorizontalRule") {
2048
- if (!editingRange(state, node)) {
2049
- builder.add(node.from, node.to, horizontalRule);
2049
+ if (!editingRange(state, node, focus)) {
2050
+ deco.add(node.from, node.to, horizontalRule);
2050
2051
  }
2051
2052
  } else if (node.name === "TaskMarker") {
2052
- if (!editingRange(state, node)) {
2053
+ if (!editingRange(state, node, focus)) {
2053
2054
  const checked = state.doc.sliceString(node.from + 1, node.to - 1) === "x";
2054
- builder.add(node.from - 2, node.from - 1, Decoration4.mark({
2055
+ atomicDeco.add(node.from - 2, node.from - 1, Decoration4.mark({
2055
2056
  class: "cm-task"
2056
2057
  }));
2057
- builder.add(node.from, node.to, checked ? checkedTask : uncheckedTask);
2058
+ atomicDeco.add(node.from, node.to, checked ? checkedTask : uncheckedTask);
2058
2059
  }
2059
2060
  } else if (MarksByParent.has(node.name)) {
2060
- if (!editingRange(state, node.node.parent)) {
2061
- builder.add(node.from, node.to, hide);
2061
+ if (!editingRange(state, node.node.parent, focus)) {
2062
+ atomicDeco.add(node.from, node.to, hide);
2062
2063
  }
2063
2064
  }
2064
2065
  }
2065
2066
  });
2066
2067
  }
2067
- return builder.finish();
2068
+ return {
2069
+ deco: deco.finish(),
2070
+ atomicDeco: atomicDeco.finish()
2071
+ };
2068
2072
  };
2073
+ var forceUpdate = StateEffect3.define();
2069
2074
  var decorateMarkdown = (options = {}) => {
2070
2075
  return [
2071
2076
  ViewPlugin3.fromClass(class {
2072
2077
  constructor(view) {
2073
- this.decorations = buildDecorations(view, options);
2078
+ this.pendingUpdate = -1;
2079
+ ({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations(view, options, view.hasFocus));
2074
2080
  }
2075
2081
  update(update2) {
2076
- if (update2.docChanged || update2.selectionSet || update2.viewportChanged) {
2077
- this.decorations = buildDecorations(update2.view, options);
2082
+ if (update2.docChanged || update2.viewportChanged || update2.focusChanged || update2.transactions.some((tr) => tr.effects.some((e) => e.is(forceUpdate)))) {
2083
+ ({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations(update2.view, options, update2.view.hasFocus));
2084
+ this.clearUpdate();
2085
+ } else if (update2.selectionSet) {
2086
+ this.scheduleUpdate(update2.view);
2078
2087
  }
2079
2088
  }
2089
+ clearUpdate() {
2090
+ if (this.pendingUpdate > -1) {
2091
+ window.clearTimeout(this.pendingUpdate);
2092
+ this.pendingUpdate = -1;
2093
+ }
2094
+ }
2095
+ scheduleUpdate(view) {
2096
+ this.clearUpdate();
2097
+ this.pendingUpdate = window.setTimeout(() => {
2098
+ view.dispatch({
2099
+ effects: forceUpdate.of(null)
2100
+ });
2101
+ }, options.selectionChangeDelay ?? 400);
2102
+ }
2103
+ destroy() {
2104
+ this.clearUpdate();
2105
+ }
2080
2106
  }, {
2081
- decorations: (value) => value.decorations
2107
+ provide: (plugin) => [
2108
+ EditorView10.atomicRanges.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration4.none),
2109
+ EditorView10.decorations.of((view) => view.plugin(plugin)?.deco ?? Decoration4.none),
2110
+ EditorView10.decorations.of((view) => view.plugin(plugin)?.atomicDeco ?? Decoration4.none)
2111
+ ]
2082
2112
  }),
2083
2113
  formattingStyles
2084
2114
  ];