rme 0.3.0-beta.60 → 0.3.0-beta.62

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
@@ -9706,12 +9706,32 @@ function updateRangeMarks(tr, forceUpdateAll) {
9706
9706
  if (!range || forceUpdateAll) {
9707
9707
  updateNodeMarks(tr, tr.doc, 0, output);
9708
9708
  } else {
9709
+ const rangeEnd = range.end;
9709
9710
  for (const [child, pos] of iterNodeRange(range)) {
9711
+ if (pos < range.start || pos > rangeEnd) {
9712
+ continue;
9713
+ }
9710
9714
  updateNodeMarks(tr, child, pos, output);
9711
9715
  }
9712
9716
  }
9713
- if (output.length) {
9714
- tr.step(new BatchSetMarkStep(output));
9717
+ if (output.length === 0) {
9718
+ return false;
9719
+ }
9720
+ const docSize = tr.doc.content.size;
9721
+ const validChunks = [];
9722
+ for (const [from, to, marks] of output) {
9723
+ if (from < 0 || to > docSize || from >= to) {
9724
+ continue;
9725
+ }
9726
+ validChunks.push([from, to, marks]);
9727
+ }
9728
+ if (validChunks.length === 0) {
9729
+ return false;
9730
+ }
9731
+ try {
9732
+ tr.step(new BatchSetMarkStep(validChunks));
9733
+ } catch {
9734
+ return false;
9715
9735
  }
9716
9736
  if (tr.docChanged) {
9717
9737
  return true;
@@ -9745,7 +9765,13 @@ function deleteSimpleInlineMark({
9745
9765
  const { tr, dispatch, state } = props;
9746
9766
  const { $from, $to, empty } = state.selection;
9747
9767
  const textBlockNode = $from.parent;
9768
+ if (!textBlockNode || !textBlockNode.isTextblock) {
9769
+ return false;
9770
+ }
9748
9771
  const textBlockStart = $from.start();
9772
+ if (textBlockStart < 0) {
9773
+ return false;
9774
+ }
9749
9775
  let fromIndex = $from.index();
9750
9776
  let toIndex = $to.index();
9751
9777
  if ($to.textOffset === 0) {
@@ -9774,8 +9800,12 @@ function deleteSimpleInlineMark({
9774
9800
  }
9775
9801
  if (found) {
9776
9802
  if (dispatch) {
9777
- updateRangeMarks(tr);
9778
- dispatch(tr);
9803
+ try {
9804
+ updateRangeMarks(tr);
9805
+ dispatch(tr);
9806
+ } catch {
9807
+ return false;
9808
+ }
9779
9809
  }
9780
9810
  return true;
9781
9811
  }
@@ -9841,11 +9871,34 @@ function hasMark(node, mark) {
9841
9871
  return node.marks.some((m) => m.type.name === mark);
9842
9872
  }
9843
9873
  function deleteTextBlockChild(tr, textBlockNode, textBlockStart, childIndex) {
9874
+ if (childIndex < 0 || childIndex >= textBlockNode.childCount) {
9875
+ return tr;
9876
+ }
9877
+ const childNode = textBlockNode.child(childIndex);
9878
+ if (!childNode) {
9879
+ return tr;
9880
+ }
9881
+ const docSize = tr.doc.content.size;
9882
+ if (textBlockStart < 0 || textBlockStart > docSize) {
9883
+ return tr;
9884
+ }
9844
9885
  let offset = textBlockStart;
9845
9886
  for (let i = 0; i < childIndex; i++) {
9846
- offset += textBlockNode.child(i).nodeSize;
9887
+ const node = textBlockNode.child(i);
9888
+ if (node) {
9889
+ offset += node.nodeSize;
9890
+ }
9891
+ }
9892
+ const deleteFrom = offset;
9893
+ const deleteTo = offset + childNode.nodeSize;
9894
+ if (deleteFrom < 0 || deleteTo > docSize || deleteFrom >= deleteTo) {
9895
+ return tr;
9896
+ }
9897
+ try {
9898
+ return tr.delete(deleteFrom, deleteTo);
9899
+ } catch {
9900
+ return tr;
9847
9901
  }
9848
- return tr.delete(offset, offset + textBlockNode.child(childIndex).nodeSize);
9849
9902
  }
9850
9903
 
9851
9904
  // src/editor/extensions/Inline/inline-mark-extensions.ts
@@ -10224,9 +10277,26 @@ var LineInlineMarkExtension = class extends PlainExtension8 {
10224
10277
  clearTimeout(timeoutId);
10225
10278
  }
10226
10279
  timeoutId = setTimeout(() => {
10280
+ if (view2.isDestroyed) {
10281
+ timeoutId = null;
10282
+ return;
10283
+ }
10284
+ const currentDoc = view2.state.doc;
10285
+ const currentSelection = view2.state.selection;
10286
+ const { $head, $anchor } = currentSelection;
10227
10287
  applySelectionMarks(view2);
10228
- const { $head } = view2.state.selection;
10229
- view2.dispatch(view2.state.tr.setSelection(new TextSelection9($head)));
10288
+ const maxPos = currentDoc.content.size;
10289
+ const validHeadPos = Math.min(Math.max($head.pos, 0), maxPos);
10290
+ const validAnchorPos = Math.min(Math.max($anchor.pos, 0), maxPos);
10291
+ if (validHeadPos >= 0 && validHeadPos <= maxPos && validAnchorPos >= 0 && validAnchorPos <= maxPos) {
10292
+ try {
10293
+ const $validHead = currentDoc.resolve(validHeadPos);
10294
+ const $validAnchor = currentDoc.resolve(validAnchorPos);
10295
+ const newSelection = $validHead.parent === $validAnchor.parent ? TextSelection9.create(currentDoc, validAnchorPos, validHeadPos) : TextSelection9.create(currentDoc, validHeadPos);
10296
+ view2.dispatch(view2.state.tr.setSelection(newSelection));
10297
+ } catch {
10298
+ }
10299
+ }
10230
10300
  timeoutId = null;
10231
10301
  }, 10);
10232
10302
  };
@@ -11450,10 +11520,6 @@ function isDraggingToItself(view, pos) {
11450
11520
  return from <= pos && pos <= to;
11451
11521
  }
11452
11522
 
11453
- // src/editor/extensions/NodeIndicator/node-indicator-plugin.ts
11454
- import { PluginKey } from "@rme-sdk/pm/state";
11455
- var pluginKey = new PluginKey("nodeIndicator");
11456
-
11457
11523
  // src/editor/extensions/NodeIndicator/node-target.ts
11458
11524
  import {
11459
11525
  isElement,
@@ -11623,12 +11689,11 @@ var NodeIndicatorExtension = class extends PlainExtension9 {
11623
11689
  rect: null
11624
11690
  };
11625
11691
  return {
11626
- key: pluginKey,
11627
11692
  initialState,
11628
11693
  state: {
11629
11694
  init: () => initialState,
11630
11695
  apply: (tr, value) => {
11631
- const meta = tr.getMeta(pluginKey);
11696
+ const meta = tr.getMeta(this.pluginKey);
11632
11697
  if (meta) {
11633
11698
  return { ...value, ...meta };
11634
11699
  }
@@ -11693,40 +11758,23 @@ var NodeIndicatorExtension = class extends PlainExtension9 {
11693
11758
  return false;
11694
11759
  }
11695
11760
  }
11696
- view.dispatch(view.state.tr.setMeta(pluginKey, { node: null, pos: null }));
11761
+ const currentState = this.pluginKey.getState(view.state);
11762
+ if (currentState?.node !== null) {
11763
+ view.dispatch(view.state.tr.setMeta(this.pluginKey, { node: null, pos: null, rect: null }));
11764
+ }
11697
11765
  return false;
11698
11766
  },
11699
11767
  pointermove: (view, event) => {
11700
- const { x, y } = event;
11701
- const block = findBlockByCoords(view, x, y);
11702
- if (!block) {
11703
- view.dispatch(view.state.tr.setMeta(pluginKey, { node: null, pos: null }));
11704
- return;
11705
- }
11706
- const { node, pos } = block;
11707
- const element = view.nodeDOM(pos);
11708
- if (!element || !isHTMLElement3(element)) {
11709
- view.dispatch(view.state.tr.setMeta(pluginKey, { node: null, pos: null }));
11768
+ if (view.__nodeIndicatorThrottled) {
11710
11769
  return;
11711
11770
  }
11712
- const $pos = view.state.doc.resolve(pos);
11713
- if ($pos.depth > 0 && $pos.index($pos.depth) === 0) {
11714
- const parentPos = $pos.before($pos.depth);
11715
- const parentNode = $pos.parent;
11716
- const parentElement = view.nodeDOM(parentPos);
11717
- const rect = findFirstLineRect(parentElement, element);
11718
- view.dispatch(
11719
- view.state.tr.setMeta(pluginKey, {
11720
- node: parentNode,
11721
- pos: parentPos,
11722
- rect: rect || {}
11723
- })
11724
- );
11725
- } else {
11726
- const rect = findFirstLineRect(void 0, element);
11727
- view.dispatch(view.state.tr.setMeta(pluginKey, { node, pos, rect: rect || {} }));
11728
- }
11729
- return false;
11771
+ ;
11772
+ view.__nodeIndicatorThrottled = true;
11773
+ requestAnimationFrame(() => {
11774
+ ;
11775
+ view.__nodeIndicatorThrottled = false;
11776
+ handlePointerMove(view, event, this.pluginKey);
11777
+ });
11730
11778
  }
11731
11779
  }
11732
11780
  }
@@ -11736,6 +11784,55 @@ var NodeIndicatorExtension = class extends PlainExtension9 {
11736
11784
  function selectionBetween(view, $anchor, $head, bias) {
11737
11785
  return view.someProp("createSelectionBetween", (f) => f(view, $anchor, $head)) || TextSelection12.between($anchor, $head, bias);
11738
11786
  }
11787
+ function handlePointerMove(view, event, pluginKey) {
11788
+ const currentState = pluginKey.getState(view.state);
11789
+ const { x, y } = event;
11790
+ const block = findBlockByCoords(view, x, y);
11791
+ if (!block) {
11792
+ if (currentState?.node !== null) {
11793
+ view.dispatch(view.state.tr.setMeta(pluginKey, { node: null, pos: null, rect: null }));
11794
+ }
11795
+ return;
11796
+ }
11797
+ const { node, pos } = block;
11798
+ const element = view.nodeDOM(pos);
11799
+ if (!element || !isHTMLElement3(element)) {
11800
+ if (currentState?.node !== null) {
11801
+ view.dispatch(view.state.tr.setMeta(pluginKey, { node: null, pos: null, rect: null }));
11802
+ }
11803
+ return;
11804
+ }
11805
+ let newNode = node;
11806
+ let newPos = pos;
11807
+ const $pos = view.state.doc.resolve(pos);
11808
+ if ($pos.depth > 0 && $pos.index($pos.depth) === 0) {
11809
+ const parentPos = $pos.before($pos.depth);
11810
+ const parentNode = $pos.parent;
11811
+ newNode = parentNode;
11812
+ newPos = parentPos;
11813
+ }
11814
+ if (currentState?.pos === newPos && currentState?.node && newNode.type === currentState?.node.type) {
11815
+ return;
11816
+ }
11817
+ const newElement = view.nodeDOM(newPos);
11818
+ if (!newElement || !isHTMLElement3(newElement)) {
11819
+ return;
11820
+ }
11821
+ let rect;
11822
+ if ($pos.depth > 0 && $pos.index($pos.depth) === 0) {
11823
+ const parentElement = view.nodeDOM($pos.before($pos.depth));
11824
+ rect = findFirstLineRect(parentElement, newElement);
11825
+ } else {
11826
+ rect = findFirstLineRect(void 0, newElement);
11827
+ }
11828
+ view.dispatch(
11829
+ view.state.tr.setMeta(pluginKey, {
11830
+ node: newNode,
11831
+ pos: newPos,
11832
+ rect: rect || {}
11833
+ })
11834
+ );
11835
+ }
11739
11836
 
11740
11837
  // src/editor/extensions/Paragraph/paragraph-extension.ts
11741
11838
  import { ParagraphExtension } from "@rme-sdk/main/extensions";
@@ -13434,38 +13531,32 @@ import { jsx as jsx18, jsxs as jsxs8 } from "react/jsx-runtime";
13434
13531
  var BlockHandler = memo5(() => {
13435
13532
  const { view: editorView } = useRemirrorContext3({ autoUpdate: true });
13436
13533
  const nodeIndicatorExtension = useExtension(NodeIndicatorExtension);
13437
- const state = nodeIndicatorExtension.getPluginState();
13534
+ const state = nodeIndicatorExtension?.getPluginState();
13438
13535
  const handleClick = () => {
13439
- if (editorView && nodeIndicatorExtension) {
13440
- const state2 = nodeIndicatorExtension.getPluginState();
13441
- if (state2 && state2.pos !== null && state2.node) {
13442
- const tr = editorView.state.tr;
13443
- tr.setSelection(NodeSelection4.create(tr.doc, state2.pos));
13444
- editorView.dispatch(tr);
13445
- }
13536
+ if (editorView && nodeIndicatorExtension && state && state.pos !== null && state.node) {
13537
+ const tr = editorView.state.tr;
13538
+ tr.setSelection(NodeSelection4.create(tr.doc, state.pos));
13539
+ editorView.dispatch(tr);
13446
13540
  }
13447
13541
  };
13448
13542
  const handleDragStart = (event) => {
13449
- if (editorView && nodeIndicatorExtension) {
13450
- const state2 = nodeIndicatorExtension.getPluginState();
13451
- if (state2 && state2.pos !== null && state2.node && state2.node.isBlock) {
13452
- let tr = editorView.state.tr;
13453
- tr = tr.setSelection(NodeSelection4.create(tr.doc, state2.pos));
13454
- editorView.dispatch(tr);
13455
- editorView.dom.classList.add("rme-dragging");
13456
- const dom = editorView.nodeDOM(state2.pos);
13457
- if (dom && isHTMLElement5(dom)) {
13458
- if (event.dataTransfer) {
13459
- event.dataTransfer.effectAllowed = "move";
13460
- }
13461
- createDraggingPreview(editorView, state2, event);
13462
- setViewDragging(editorView, state2);
13543
+ if (editorView && state && state.pos !== null && state.node && state.node.isBlock) {
13544
+ editorView.dom.classList.add("rme-dragging");
13545
+ handleClick();
13546
+ const dom = editorView.nodeDOM(state.pos);
13547
+ if (dom && isHTMLElement5(dom)) {
13548
+ if (event.dataTransfer) {
13549
+ event.dataTransfer.effectAllowed = "move";
13463
13550
  }
13551
+ createDraggingPreview(editorView, state, event);
13552
+ setViewDragging(editorView, state);
13464
13553
  }
13465
13554
  }
13466
13555
  };
13467
13556
  const handleDragEnd = () => {
13468
- editorView.dom.classList.remove("rme-dragging");
13557
+ if (editorView) {
13558
+ editorView.dom.classList.remove("rme-dragging");
13559
+ }
13469
13560
  };
13470
13561
  if (!editorView || !state?.node) {
13471
13562
  return null;