@trafica/editor 1.0.53 → 1.0.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -894,6 +894,21 @@ function renderDocument(doc, container) {
894
894
  container.appendChild(blockEl);
895
895
  }
896
896
  }
897
+ function patchDocument(prevDoc, nextDoc, container) {
898
+ const prev = prevDoc.children;
899
+ const next = nextDoc.children;
900
+ if (prev.length !== next.length) {
901
+ renderDocument(nextDoc, container);
902
+ return;
903
+ }
904
+ const domChildren = container.children;
905
+ for (let i = 0; i < next.length; i++) {
906
+ if (next[i] !== prev[i]) {
907
+ const newEl = renderBlock(next[i], [i]);
908
+ container.replaceChild(newEl, domChildren[i]);
909
+ }
910
+ }
911
+ }
897
912
  function renderBlock(node, path) {
898
913
  switch (node.type) {
899
914
  case "paragraph":
@@ -7737,7 +7752,6 @@ function ImageToolbar({ engine, imagePath, editorContainer, onClose }) {
7737
7752
  const top = Math.max(4, rect.top - toolbarH - 6);
7738
7753
  toolbar.style.top = `${top}px`;
7739
7754
  toolbar.style.left = `${rect.left}px`;
7740
- toolbar.style.minWidth = `${rect.width}px`;
7741
7755
  toolbar.style.visibility = "visible";
7742
7756
  });
7743
7757
  const run = (attrs) => {
@@ -8008,6 +8022,9 @@ function EditorCore({
8008
8022
  }) {
8009
8023
  const containerRef = useRef(null);
8010
8024
  const isRenderingRef = useRef(false);
8025
+ const prevDocRef = useRef(null);
8026
+ const htmlDebounceRef = useRef(null);
8027
+ const jsonDebounceRef = useRef(null);
8011
8028
  const skipRestoreSelectionRef = useRef(false);
8012
8029
  const scrollCaretIntoView = useCallback(() => {
8013
8030
  var _a, _b;
@@ -8103,7 +8120,13 @@ function EditorCore({
8103
8120
  const container = containerRef.current;
8104
8121
  if (!container) return;
8105
8122
  isRenderingRef.current = true;
8106
- renderDocument(state.doc, container);
8123
+ const prevDoc = prevDocRef.current;
8124
+ if (prevDoc) {
8125
+ patchDocument(prevDoc, state.doc, container);
8126
+ } else {
8127
+ renderDocument(state.doc, container);
8128
+ }
8129
+ prevDocRef.current = state.doc;
8107
8130
  if (!container.contains(document.activeElement)) {
8108
8131
  container.focus({ preventScroll: true });
8109
8132
  }
@@ -8113,10 +8136,16 @@ function EditorCore({
8113
8136
  }
8114
8137
  isRenderingRef.current = false;
8115
8138
  if (onHTMLChange) {
8116
- onHTMLChange(htmlSerializer.serialize(state.doc));
8139
+ if (htmlDebounceRef.current) clearTimeout(htmlDebounceRef.current);
8140
+ htmlDebounceRef.current = setTimeout(() => {
8141
+ onHTMLChange(htmlSerializer.serialize(engine.getState().doc));
8142
+ }, 300);
8117
8143
  }
8118
8144
  if (onJSONChange) {
8119
- onJSONChange(jsonSerializer.serialize(state.doc));
8145
+ if (jsonDebounceRef.current) clearTimeout(jsonDebounceRef.current);
8146
+ jsonDebounceRef.current = setTimeout(() => {
8147
+ onJSONChange(jsonSerializer.serialize(engine.getState().doc));
8148
+ }, 300);
8120
8149
  }
8121
8150
  }, [state.doc]);
8122
8151
  useLayoutEffect(() => {
@@ -8191,7 +8220,7 @@ function EditorCore({
8191
8220
  const captured = captureSelection(container);
8192
8221
  if (!captured) return;
8193
8222
  const currentSelection = engine.getState().selection;
8194
- if (currentSelection && JSON.stringify(currentSelection.anchor) === JSON.stringify(captured.anchor) && JSON.stringify(currentSelection.focus) === JSON.stringify(captured.focus)) {
8223
+ if (currentSelection && selectionEqual(currentSelection.anchor, captured.anchor) && selectionEqual(currentSelection.focus, captured.focus)) {
8195
8224
  return;
8196
8225
  }
8197
8226
  skipRestoreSelectionRef.current = true;
@@ -8898,6 +8927,14 @@ var BLOCK_TAGS = "p|h[1-6]|ul|ol|li|blockquote|pre|figure|table|thead|tbody|tr|t
8898
8927
  var _OPEN_ONLY_RE = new RegExp(`^<(${BLOCK_TAGS})(?:\\s[^>]*)?>$`, "i");
8899
8928
  var _CLOSE_ONLY_RE = new RegExp(`^<\\/(${BLOCK_TAGS})>$`, "i");
8900
8929
  var _HR_RE = /^<hr(\s[^>]*)?\/?>$/i;
8930
+ function selectionEqual(a, b) {
8931
+ if (a.offset !== b.offset) return false;
8932
+ if (a.path.length !== b.path.length) return false;
8933
+ for (let i = 0; i < a.path.length; i++) {
8934
+ if (a.path[i] !== b.path[i]) return false;
8935
+ }
8936
+ return true;
8937
+ }
8901
8938
  function leafTextNode(el, end) {
8902
8939
  let node = el;
8903
8940
  while (node.hasChildNodes()) {