@portabletext/editor 7.12.1 → 7.12.3

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/lib/index.js CHANGED
@@ -107,7 +107,7 @@ const getDefaultView = (value) => value && value.ownerDocument && value.ownerDoc
107
107
  for (; current;) {
108
108
  if (current.matches && current.matches(selector)) return current;
109
109
  if (current.parentElement) current = current.parentElement;
110
- else if (current.parentNode && "host" in current.parentNode) current = current.parentNode.host;
110
+ else if (isShadowRoot(current.parentNode)) current = current.parentNode.host;
111
111
  else return null;
112
112
  }
113
113
  return null;
@@ -117,11 +117,11 @@ const getDefaultView = (value) => value && value.ownerDocument && value.ownerDoc
117
117
  let current = child;
118
118
  for (; current;) {
119
119
  if (current === parent) return !0;
120
- if (current.parentNode) current = "host" in current.parentNode ? current.parentNode.host : current.parentNode;
120
+ if (current.parentNode) current = isShadowRoot(current.parentNode) ? current.parentNode.host : current.parentNode;
121
121
  else return !1;
122
122
  }
123
123
  return !1;
124
- }, KEYED_SEGMENT_PATTERN = /\[_key=="(.+?)"\]/;
124
+ }, isShadowRoot = (value) => isDOMNode(value) && value.nodeType === Node.DOCUMENT_FRAGMENT_NODE && "host" in value, KEYED_SEGMENT_PATTERN = /\[_key=="(.+?)"\]/;
125
125
  /**
126
126
  * Deserialize a serialized keyed path using Sanity's bracket notation.
127
127
  *
@@ -750,6 +750,40 @@ function move(editor, options = {}) {
750
750
  }
751
751
  editor.setSelection(props);
752
752
  }
753
+ function subscribeToOperations(editor, listener, options) {
754
+ let phase = options?.phase ?? "after";
755
+ return editor.operationListeners[phase] = [...editor.operationListeners[phase], listener], () => {
756
+ let listeners = editor.operationListeners[phase], index = listeners.indexOf(listener);
757
+ index !== -1 && (editor.operationListeners[phase] = [...listeners.slice(0, index), ...listeners.slice(index + 1)]);
758
+ };
759
+ }
760
+ /**
761
+ * Captures the operation together with the engine state that `after`
762
+ * listeners can no longer read once the operation has been applied. All
763
+ * engine flags are stable for the duration of a single apply call, so
764
+ * capturing them at entry is equivalent to reading them at any point during
765
+ * the apply.
766
+ */
767
+ function createOperationEvent(editor, operation) {
768
+ let isNormalizingNode = !!editor.isNormalizingNode, isProcessingRemoteChanges = !!editor.isProcessingRemoteChanges, isUndoing = !!editor.isUndoing, isRedoing = !!editor.isRedoing;
769
+ return {
770
+ operation,
771
+ beforeValue: editor.snapshot.context.value,
772
+ beforeSelection: editor.snapshot.context.selection,
773
+ operationsInProgress: editor.operations.length > 0,
774
+ isNormalizingNode,
775
+ isPatching: !!editor.isPatching,
776
+ isProcessingRemoteChanges,
777
+ isUndoing,
778
+ isRedoing,
779
+ withHistory: !!editor.withHistory,
780
+ undoStepId: editor.undoStepId,
781
+ origin: isProcessingRemoteChanges ? "remote" : isUndoing ? "undo" : isRedoing ? "redo" : isNormalizingNode ? "normalization" : "local"
782
+ };
783
+ }
784
+ function emitOperationEvent(listeners, event) {
785
+ for (let index = 0; index < listeners.length; index++) listeners[index]?.(event);
786
+ }
753
787
  const bold$1 = createKeyboardShortcut({
754
788
  default: [{
755
789
  key: "B",
@@ -2786,9 +2820,12 @@ const RestoreDOM = IS_ANDROID ? RestoreDOMComponent : ({ children }) => /* @__PU
2786
2820
  editor.forceRender = forceRender, editor.readOnly = readOnly;
2787
2821
  let state = useMemo(() => ({
2788
2822
  isUpdatingSelection: !1,
2789
- latestElement: null
2823
+ latestElement: null,
2824
+ localContentChangePending: !1
2790
2825
  }), []);
2791
- useEffect(() => {
2826
+ useEffect(() => subscribeToOperations(editor, (event) => {
2827
+ event.operation.type !== "set.selection" && (event.origin === "local" || event.origin === "undo" || event.origin === "redo") && (state.localContentChangePending = !0);
2828
+ }), [editor, state]), useEffect(() => {
2792
2829
  ref.current && autoFocus && ref.current.focus();
2793
2830
  }, [autoFocus]);
2794
2831
  /**
@@ -2843,6 +2880,8 @@ const RestoreDOM = IS_ANDROID ? RestoreDOMComponent : ({ children }) => /* @__PU
2843
2880
  onDOMSelectionChange,
2844
2881
  scheduleOnDOMSelectionChange
2845
2882
  }), useIsomorphicLayoutEffect(() => {
2883
+ let hadPendingLocalContentChange = state.localContentChangePending;
2884
+ state.localContentChangePending = !1;
2846
2885
  let window = null;
2847
2886
  ref.current && (window = getDefaultView(ref.current)) && (editor.domWindow = window, editor.domElement = ref.current);
2848
2887
  let { selection } = editor.snapshot.context, root = DOMEditor.findDocumentOrShadowRoot(editor), domSelection = getSelection(root);
@@ -2861,7 +2900,13 @@ const RestoreDOM = IS_ANDROID ? RestoreDOMComponent : ({ children }) => /* @__PU
2861
2900
  exactMatch: !0,
2862
2901
  suppressThrow: !0
2863
2902
  });
2864
- if (editorSelection && rangeEquals(editorSelection, selection)) return;
2903
+ if (editorSelection && rangeEquals(editorSelection, selection)) {
2904
+ if (hadPendingLocalContentChange) try {
2905
+ let domRange = DOMEditor.toDOMRange(editor, selection);
2906
+ scrollSelectionIntoView(editor, domRange);
2907
+ } catch {}
2908
+ return;
2909
+ }
2865
2910
  }
2866
2911
  if (selection && !DOMEditor.hasRange(editor, selection)) {
2867
2912
  let fallbackRange = DOMEditor.toEditorSelection(editor, domSelection, {
@@ -4261,40 +4306,6 @@ function performHotkey({ editorActor, editor, portableTextEditor, hotkeys, event
4261
4306
  }
4262
4307
  });
4263
4308
  }
4264
- function subscribeToOperations(editor, listener, options) {
4265
- let phase = options?.phase ?? "after";
4266
- return editor.operationListeners[phase] = [...editor.operationListeners[phase], listener], () => {
4267
- let listeners = editor.operationListeners[phase], index = listeners.indexOf(listener);
4268
- index !== -1 && (editor.operationListeners[phase] = [...listeners.slice(0, index), ...listeners.slice(index + 1)]);
4269
- };
4270
- }
4271
- /**
4272
- * Captures the operation together with the engine state that `after`
4273
- * listeners can no longer read once the operation has been applied. All
4274
- * engine flags are stable for the duration of a single apply call, so
4275
- * capturing them at entry is equivalent to reading them at any point during
4276
- * the apply.
4277
- */
4278
- function createOperationEvent(editor, operation) {
4279
- let isNormalizingNode = !!editor.isNormalizingNode, isProcessingRemoteChanges = !!editor.isProcessingRemoteChanges, isUndoing = !!editor.isUndoing, isRedoing = !!editor.isRedoing;
4280
- return {
4281
- operation,
4282
- beforeValue: editor.snapshot.context.value,
4283
- beforeSelection: editor.snapshot.context.selection,
4284
- operationsInProgress: editor.operations.length > 0,
4285
- isNormalizingNode,
4286
- isPatching: !!editor.isPatching,
4287
- isProcessingRemoteChanges,
4288
- isUndoing,
4289
- isRedoing,
4290
- withHistory: !!editor.withHistory,
4291
- undoStepId: editor.undoStepId,
4292
- origin: isProcessingRemoteChanges ? "remote" : isUndoing ? "undo" : isRedoing ? "redo" : isNormalizingNode ? "normalization" : "local"
4293
- };
4294
- }
4295
- function emitOperationEvent(listeners, event) {
4296
- for (let index = 0; index < listeners.length; index++) listeners[index]?.(event);
4297
- }
4298
4309
  function isForwardRange(range, root) {
4299
4310
  return !isBackwardRange(range, root);
4300
4311
  }