@meowdown/core 0.74.1 → 0.74.2

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.d.ts CHANGED
@@ -1482,6 +1482,12 @@ interface LinkHoverOptions {
1482
1482
  * software keyboard.
1483
1483
  */
1484
1484
  export declare function defineLinkHoverHandler(onHoverChange: LinkHoverHandler, { canLeave }?: LinkHoverOptions): PlainExtension;
1485
+ /**
1486
+ * Tell the link hover handler that the user dismissed the UI it opened. The
1487
+ * link under the pointer stays silent until the pointer leaves it, so a
1488
+ * pending hover cannot reopen the UI.
1489
+ */
1490
+ export declare function dismissLinkHover(state: EditorState): void;
1485
1491
  //#endregion
1486
1492
  //#region src/extensions/link-paste.d.ts
1487
1493
  /**
package/dist/index.js CHANGED
@@ -84,20 +84,86 @@ function getIsComposing() {
84
84
  }
85
85
 
86
86
  //#endregion
87
- //#region src/utils/transaction.ts
87
+ //#region src/utils/input-modality.ts
88
+ const KEYBOARD_MODALITY_KEYS = /* @__PURE__ */ new Set([
89
+ "ArrowLeft",
90
+ "ArrowRight",
91
+ "ArrowUp",
92
+ "ArrowDown",
93
+ "Home",
94
+ "End",
95
+ "PageUp",
96
+ "PageDown"
97
+ ]);
98
+ let lastIsTouchInput = false;
99
+ let lastIsPointerSelection = false;
100
+ const listeners = /* @__PURE__ */ new Set();
101
+ function setIsTouchInput(isTouchInput) {
102
+ if (isTouchInput === lastIsTouchInput) return;
103
+ lastIsTouchInput = isTouchInput;
104
+ for (const listener of listeners) listener();
105
+ }
106
+ function handlePointerDown(event) {
107
+ const target = event.target;
108
+ lastIsPointerSelection = target instanceof Element && !!target.closest(".ProseMirror");
109
+ const pointerType = event.pointerType;
110
+ if (pointerType === "mouse") setIsTouchInput(false);
111
+ else if (pointerType === "touch" || pointerType === "pen") setIsTouchInput(true);
112
+ }
113
+ function handleKeyDown(event) {
114
+ if (getIsComposing() || event.isComposing) return;
115
+ lastIsPointerSelection = false;
116
+ if (KEYBOARD_MODALITY_KEYS.has(event.key) || event.metaKey || event.ctrlKey) setIsTouchInput(false);
117
+ }
118
+ if (typeof window !== "undefined") {
119
+ window.addEventListener("pointerdown", handlePointerDown, {
120
+ capture: true,
121
+ passive: true
122
+ });
123
+ window.addEventListener("keydown", handleKeyDown, {
124
+ capture: true,
125
+ passive: true
126
+ });
127
+ }
88
128
  /**
89
- * Whether the given transaction is selection transactions directly caused by mouse or touch input.
129
+ * Whether the user last drove the selection with a finger (or pen) on the
130
+ * screen, as opposed to precise input (hardware keyboard navigation).
90
131
  *
91
- * See https://code.haverbeke.berlin/prosemirror/prosemirror-view/src/tag/1.42.2/src/input.ts#L191
132
+ * Starts as `false` and follows the events; a touch device flips it on the
133
+ * first tap, which necessarily precedes any caret. Only navigation keys and
134
+ * modifier combos flip it back: letter keys are ignored because a software
135
+ * keyboard sends them too, and the software keyboard's own caret gestures (a
136
+ * spacebar long-press drag) reach the page as bare `selectionchange` events
137
+ * with no key or touch events at all, so staying on the previous value is the
138
+ * correct reading for them.
139
+ */
140
+ function getIsTouchInput() {
141
+ return lastIsTouchInput;
142
+ }
143
+ /**
144
+ * Whether the next selection change in an editor comes from a pointer: the
145
+ * last `pointerdown` landed inside an editor and no key was pressed since.
92
146
  */
93
- function isPointerSelectionTransaction(tr) {
94
- return !!tr.getMeta("pointer");
147
+ function getIsPointerSelection() {
148
+ return lastIsPointerSelection;
95
149
  }
96
150
  /**
151
+ * Calls `listener` whenever {@link getIsTouchInput} may report a new value.
152
+ */
153
+ function onIsTouchInputChange(listener) {
154
+ listeners.add(listener);
155
+ return () => {
156
+ listeners.delete(listener);
157
+ };
158
+ }
159
+
160
+ //#endregion
161
+ //#region src/utils/transaction.ts
162
+ /**
97
163
  * Whether any of the given transactions are selection transactions directly caused by mouse or touch input.
98
164
  */
99
165
  function hasPointerSelectionTransaction(transactions) {
100
- return transactions.some(isPointerSelectionTransaction);
166
+ return getIsPointerSelection() && transactions.some((tr) => tr.selectionSet && !tr.docChanged);
101
167
  }
102
168
 
103
169
  //#endregion
@@ -512,9 +578,8 @@ function createCaretSnapPlugin(marks) {
512
578
  if (markNames.length === 0) return null;
513
579
  const selection = newState.selection;
514
580
  if (!isTextSelection(selection)) return null;
515
- const isPointer = hasPointerSelectionTransaction(transactions);
516
581
  if (!selection.empty) {
517
- if (!isPointer) return null;
582
+ if (!hasPointerSelectionTransaction(transactions)) return null;
518
583
  const from = getMarkRangeStrictlyAround(newState, selection.from, markNames)?.from ?? selection.from;
519
584
  const to = getMarkRangeStrictlyAround(newState, selection.to, markNames)?.to ?? selection.to;
520
585
  if (from === selection.from && to === selection.to) return null;
@@ -524,6 +589,7 @@ function createCaretSnapPlugin(marks) {
524
589
  }
525
590
  const range = getMarkRangeStrictlyAround(newState, selection.head, markNames);
526
591
  if (!range) return null;
592
+ const isPointer = hasPointerSelectionTransaction(transactions);
527
593
  const head = getUnitEdge(range, oldState.selection.head, selection.head, isPointer);
528
594
  return newState.tr.setSelection(TextSelection.create(newState.doc, head));
529
595
  }
@@ -614,6 +680,9 @@ function handleMouseDown(view, event) {
614
680
  const { doc } = view.state;
615
681
  const lastBlock = doc.lastChild;
616
682
  if (!lastBlock || acceptsCaretAtEnd(lastBlock)) return false;
683
+ let bottom = lastBlock;
684
+ while (bottom && !bottom.isTextblock && !isNodeOfType(bottom, "table")) bottom = bottom.lastChild;
685
+ if (bottom && bottom.content.size === 0 && acceptsCaretAtEnd(bottom)) return false;
617
686
  const lastBlockDOM = view.nodeDOM(doc.content.size - lastBlock.nodeSize);
618
687
  if (!(lastBlockDOM instanceof HTMLElement)) return false;
619
688
  if (event.clientY <= lastBlockDOM.getBoundingClientRect().bottom) return false;
@@ -628,7 +697,8 @@ function handleMouseDown(view, event) {
628
697
  }
629
698
  /**
630
699
  * A press below the last block appends an empty paragraph and puts the caret
631
- * in it, when that block would otherwise keep the caret inside itself.
700
+ * in it, when that block would otherwise keep the caret inside itself and
701
+ * does not end in an empty line.
632
702
  */
633
703
  function defineClickBelow() {
634
704
  return definePlugin(new Plugin({
@@ -3469,8 +3539,8 @@ function createSnapPlugin() {
3469
3539
  if (getMarkMode(newState) !== "hide") return null;
3470
3540
  const selection = newState.selection;
3471
3541
  if (!isTextSelection(selection)) return null;
3472
- const isPointer = hasPointerSelectionTransaction(transactions);
3473
3542
  if (selection.empty) {
3543
+ const isPointer = hasPointerSelectionTransaction(transactions);
3474
3544
  const next = getRestPosition(newState, oldState.selection.head, selection.head, isPointer);
3475
3545
  if (next === selection.head) return null;
3476
3546
  return newState.tr.setSelection(TextSelection.create(newState.doc, next));
@@ -8478,32 +8548,29 @@ const EDITOR_KEY_BINDINGS = {
8478
8548
 
8479
8549
  //#endregion
8480
8550
  //#region src/extensions/mark-hover.ts
8551
+ const IDLE = { kind: "idle" };
8552
+ function getHit(phase) {
8553
+ return phase.kind === "active" || phase.kind === "leaving" ? phase.hit : void 0;
8554
+ }
8481
8555
  /**
8482
- * Delegate hover tracking for a rendered mark to the editor root.
8483
- *
8484
- * Movement within a mark is de-duplicated. The active hit is also revalidated
8485
- * after every editor update, so deleting, replacing, or rewriting a hovered
8486
- * mark emits leave even when the pointer itself never moves. Destroying the
8487
- * editor or removing the extension emits leave as well.
8488
- *
8489
- * With `tap`, a touch tap enters too. The browser is the tap recognizer:
8490
- * only a recognized stationary single-finger tap synthesizes the
8491
- * compatibility mouse events and the trailing `click`; scrolls, drags,
8492
- * long-presses, and multi-finger gestures never produce them.
8556
+ * The tracked element the pointer is on, if any.
8493
8557
  */
8494
- function defineMarkHoverHandler(config) {
8495
- const { openDelay, closeDelay, tap } = config;
8558
+ function getPointerElement(phase) {
8559
+ switch (phase.kind) {
8560
+ case "pending":
8561
+ case "dismissed": return phase.element;
8562
+ case "active": return phase.hit.element;
8563
+ default: return;
8564
+ }
8565
+ }
8566
+ function createHoverTracker(config) {
8567
+ const { openDelay, closeDelay } = config;
8568
+ let phase = IDLE;
8496
8569
  /**
8497
- * What `onHoverChange` last received, while that is a hit.
8570
+ * Runs exactly while the phase is `pending` or `leaving`.
8498
8571
  */
8499
- let emitted;
8500
8572
  let timer;
8501
8573
  /**
8502
- * The element of a scheduled enter, `null` for a scheduled leave,
8503
- * `undefined` when nothing is scheduled.
8504
- */
8505
- let scheduledElement;
8506
- /**
8507
8574
  * The type of the pointer that spawned the current event sequence:
8508
8575
  * compatibility mouse events carry no pointer type of their own.
8509
8576
  */
@@ -8514,127 +8581,201 @@ function defineMarkHoverHandler(config) {
8514
8581
  const findPayloadForElement = (view, element) => {
8515
8582
  return config.findPayloadForElement ? config.findPayloadForElement(view, element) : config.findPayloadAt(view.state, view.posAtDOM(element, 0));
8516
8583
  };
8517
- const cancel = () => {
8584
+ /**
8585
+ * The only transition. It restarts the timer the next phase needs and
8586
+ * reports a change of the hit element.
8587
+ */
8588
+ const go = (next) => {
8518
8589
  clearTimeout(timer);
8519
- scheduledElement = void 0;
8590
+ const previousHit = getHit(phase);
8591
+ phase = next;
8592
+ if (next.kind === "pending") timer = setTimeout(finishOpen, openDelay);
8593
+ if (next.kind === "leaving") timer = setTimeout(finishLeave, closeDelay);
8594
+ const hit = getHit(next);
8595
+ if (hit?.element !== previousHit?.element) config.onHoverChange(hit);
8520
8596
  };
8521
- const emit = (hit) => {
8522
- cancel();
8523
- if (!hit && !emitted) return;
8524
- emitted = hit;
8525
- config.onHoverChange(hit);
8597
+ const finishOpen = () => {
8598
+ if (phase.kind !== "pending") return;
8599
+ const { element, view } = phase;
8600
+ const payload = element.isConnected ? findPayloadForElement(view, element) : void 0;
8601
+ go(payload == null ? IDLE : {
8602
+ kind: "active",
8603
+ hit: {
8604
+ payload,
8605
+ element
8606
+ }
8607
+ });
8608
+ };
8609
+ const finishLeave = () => {
8610
+ if (phase.kind !== "leaving") return;
8611
+ go(config.canLeave?.() === false ? phase : IDLE);
8612
+ };
8613
+ const startPending = (view, element) => {
8614
+ if (findPayloadForElement(view, element) == null) return;
8615
+ go({
8616
+ kind: "pending",
8617
+ element,
8618
+ view
8619
+ });
8526
8620
  };
8527
- const scheduleLeave = () => {
8528
- cancel();
8529
- scheduledElement = null;
8530
- const fire = () => {
8531
- if (config.canLeave?.() === false) {
8532
- timer = setTimeout(fire, closeDelay);
8621
+ const handleOver = (view, event) => {
8622
+ const element = findClosestMark(event.target);
8623
+ if (!element || !view.dom.contains(element)) return;
8624
+ switch (phase.kind) {
8625
+ case "idle": return startPending(view, element);
8626
+ case "pending":
8627
+ case "dismissed":
8628
+ if (element !== phase.element) startPending(view, element);
8629
+ return;
8630
+ case "active":
8631
+ case "leaving": {
8632
+ if (element === phase.hit.element) return go({
8633
+ kind: "active",
8634
+ hit: phase.hit
8635
+ });
8636
+ const payload = findPayloadForElement(view, element);
8637
+ if (payload != null) go({
8638
+ kind: "active",
8639
+ hit: {
8640
+ payload,
8641
+ element
8642
+ }
8643
+ });
8533
8644
  return;
8534
8645
  }
8535
- emit(void 0);
8536
- };
8537
- timer = setTimeout(fire, closeDelay);
8646
+ }
8538
8647
  };
8539
- const enter = (view, element) => {
8648
+ const handleOut = (event) => {
8649
+ const element = getPointerElement(phase);
8650
+ if (!element) return;
8651
+ const related = event.relatedTarget;
8652
+ if (related instanceof Node && element.contains(related)) return;
8653
+ go(phase.kind === "active" ? {
8654
+ kind: "leaving",
8655
+ hit: phase.hit
8656
+ } : IDLE);
8657
+ };
8658
+ const handlePointerDown = (event) => {
8659
+ lastPointerType = event.pointerType;
8660
+ };
8661
+ const handleMouseDown = (event) => {
8662
+ if (lastPointerType !== "touch" || !findClosestMark(event.target)) return false;
8663
+ event.preventDefault();
8664
+ return true;
8665
+ };
8666
+ const handleClick = (view, event) => {
8667
+ if (lastPointerType !== "touch") return false;
8668
+ const element = findClosestMark(event.target);
8669
+ if (!element || !view.dom.contains(element)) {
8670
+ go(IDLE);
8671
+ return false;
8672
+ }
8673
+ event.preventDefault();
8540
8674
  const payload = findPayloadForElement(view, element);
8541
- if (payload == null) return;
8542
- if (emitted) {
8543
- emit({
8675
+ if (payload != null) go({
8676
+ kind: "active",
8677
+ hit: {
8544
8678
  payload,
8545
8679
  element
8546
- });
8680
+ }
8681
+ });
8682
+ return true;
8683
+ };
8684
+ const update = (view) => {
8685
+ if (phase.kind === "dismissed") {
8686
+ if (!view.dom.contains(phase.element)) go(IDLE);
8547
8687
  return;
8548
8688
  }
8549
- cancel();
8550
- scheduledElement = element;
8551
- timer = setTimeout(() => {
8552
- const fresh = element.isConnected ? findPayloadForElement(view, element) : void 0;
8553
- if (fresh == null) {
8554
- cancel();
8555
- return;
8556
- }
8557
- emit({
8558
- payload: fresh,
8689
+ if (phase.kind !== "active" && phase.kind !== "leaving") return;
8690
+ const { element } = phase.hit;
8691
+ if (!element.isConnected || !view.dom.contains(element)) return go(IDLE);
8692
+ const payload = findPayloadForElement(view, element);
8693
+ if (payload == null || !config.isSamePayload(phase.hit.payload, payload)) return go(IDLE);
8694
+ phase = {
8695
+ kind: phase.kind,
8696
+ hit: {
8697
+ payload,
8559
8698
  element
8560
- });
8561
- }, openDelay);
8699
+ }
8700
+ };
8562
8701
  };
8563
- const handleOver = (view, event) => {
8564
- const element = findClosestMark(event.target);
8565
- if (!element || !view.dom.contains(element)) return;
8566
- if (element === emitted?.element) {
8567
- if (scheduledElement === null) cancel();
8568
- return;
8702
+ const dismiss = () => {
8703
+ switch (phase.kind) {
8704
+ case "pending": return go({
8705
+ kind: "dismissed",
8706
+ element: phase.element
8707
+ });
8708
+ case "active": return go({
8709
+ kind: "dismissed",
8710
+ element: phase.hit.element
8711
+ });
8712
+ case "leaving": return go(IDLE);
8569
8713
  }
8570
- if (element === scheduledElement) return;
8571
- enter(view, element);
8572
8714
  };
8573
- const handleOut = (event) => {
8574
- const active = emitted?.element ?? scheduledElement;
8575
- if (!active) return;
8576
- const related = event.relatedTarget;
8577
- if (related instanceof Node && active.contains(related)) return;
8578
- if (emitted) scheduleLeave();
8579
- else cancel();
8715
+ return {
8716
+ handleOver,
8717
+ handleOut,
8718
+ handlePointerDown,
8719
+ handleMouseDown,
8720
+ handleClick,
8721
+ update,
8722
+ dismiss,
8723
+ destroy: () => go(IDLE)
8580
8724
  };
8725
+ }
8726
+ /**
8727
+ * Delegate hover tracking for a rendered mark to the editor root.
8728
+ *
8729
+ * Movement within a mark is de-duplicated. The active hit is also revalidated
8730
+ * after every editor update, so deleting, replacing, or rewriting a hovered
8731
+ * mark emits leave even when the pointer itself never moves. Destroying the
8732
+ * editor or removing the extension emits leave as well.
8733
+ *
8734
+ * With `tap`, a touch tap enters too. The browser is the tap recognizer:
8735
+ * only a recognized stationary single-finger tap synthesizes the
8736
+ * compatibility mouse events and the trailing `click`; scrolls, drags,
8737
+ * long-presses, and multi-finger gestures never produce them.
8738
+ *
8739
+ * The tracker lives in the plugin state, so `key.getState(state)?.dismiss()`
8740
+ * reaches the one tracking that editor.
8741
+ */
8742
+ function defineMarkHoverHandler(config) {
8743
+ const { key } = config;
8581
8744
  return definePlugin(new Plugin({
8582
- key: config.key,
8745
+ key,
8746
+ state: {
8747
+ init: () => createHoverTracker(config),
8748
+ apply: (_tr, tracker) => tracker
8749
+ },
8583
8750
  props: { handleDOMEvents: {
8584
8751
  mouseover: (view, event) => {
8585
- handleOver(view, event);
8752
+ key.getState(view.state)?.handleOver(view, event);
8586
8753
  return false;
8587
8754
  },
8588
- mouseout: (_view, event) => {
8589
- handleOut(event);
8755
+ mouseout: (view, event) => {
8756
+ key.getState(view.state)?.handleOut(event);
8590
8757
  return false;
8591
8758
  },
8592
- ...tap && {
8593
- pointerdown: (_view, event) => {
8594
- lastPointerType = event.pointerType;
8759
+ ...config.tap && {
8760
+ pointerdown: (view, event) => {
8761
+ key.getState(view.state)?.handlePointerDown(event);
8595
8762
  return false;
8596
8763
  },
8597
- mousedown: (_view, event) => {
8598
- if (lastPointerType !== "touch" || !findClosestMark(event.target)) return false;
8599
- event.preventDefault();
8600
- return true;
8764
+ mousedown: (view, event) => {
8765
+ return key.getState(view.state)?.handleMouseDown(event) ?? false;
8601
8766
  },
8602
8767
  click: (view, event) => {
8603
- if (lastPointerType !== "touch") return false;
8604
- const element = findClosestMark(event.target);
8605
- if (!element || !view.dom.contains(element)) {
8606
- emit(void 0);
8607
- return false;
8608
- }
8609
- event.preventDefault();
8610
- const payload = findPayloadForElement(view, element);
8611
- if (payload != null) emit({
8612
- payload,
8613
- element
8614
- });
8615
- return true;
8768
+ return key.getState(view.state)?.handleClick(view, event) ?? false;
8616
8769
  }
8617
8770
  }
8618
8771
  } },
8619
- view: () => ({
8620
- update: (view) => {
8621
- if (!emitted) return;
8622
- if (!emitted.element.isConnected || !view.dom.contains(emitted.element)) {
8623
- emit(void 0);
8624
- return;
8625
- }
8626
- const payload = findPayloadForElement(view, emitted.element);
8627
- if (payload == null || !config.isSamePayload(emitted.payload, payload)) {
8628
- emit(void 0);
8629
- return;
8630
- }
8631
- emitted = {
8632
- ...emitted,
8633
- payload
8634
- };
8635
- },
8636
- destroy: () => emit(void 0)
8637
- })
8772
+ view: (view) => {
8773
+ const tracker = key.getState(view.state);
8774
+ return {
8775
+ update: (view) => tracker?.update(view),
8776
+ destroy: () => tracker?.destroy()
8777
+ };
8778
+ }
8638
8779
  }));
8639
8780
  }
8640
8781
 
@@ -8674,6 +8815,14 @@ function defineLinkHoverHandler(onHoverChange, { canLeave } = {}) {
8674
8815
  onHoverChange
8675
8816
  });
8676
8817
  }
8818
+ /**
8819
+ * Tell the link hover handler that the user dismissed the UI it opened. The
8820
+ * link under the pointer stays silent until the pointer leaves it, so a
8821
+ * pending hover cannot reopen the UI.
8822
+ */
8823
+ function dismissLinkHover(state) {
8824
+ linkHoverKey.getState(state)?.dismiss();
8825
+ }
8677
8826
 
8678
8827
  //#endregion
8679
8828
  //#region src/utils/force-reflow.ts
@@ -8681,69 +8830,6 @@ function forceReflow(element) {
8681
8830
  element.offsetWidth;
8682
8831
  }
8683
8832
 
8684
- //#endregion
8685
- //#region src/utils/input-modality.ts
8686
- const KEYBOARD_MODALITY_KEYS = /* @__PURE__ */ new Set([
8687
- "ArrowLeft",
8688
- "ArrowRight",
8689
- "ArrowUp",
8690
- "ArrowDown",
8691
- "Home",
8692
- "End",
8693
- "PageUp",
8694
- "PageDown"
8695
- ]);
8696
- let lastIsTouchInput = false;
8697
- const listeners = /* @__PURE__ */ new Set();
8698
- function setIsTouchInput(isTouchInput) {
8699
- if (isTouchInput === lastIsTouchInput) return;
8700
- lastIsTouchInput = isTouchInput;
8701
- for (const listener of listeners) listener();
8702
- }
8703
- function handlePointerDown(event) {
8704
- const pointerType = event.pointerType;
8705
- if (pointerType === "mouse") setIsTouchInput(false);
8706
- else if (pointerType === "touch" || pointerType === "pen") setIsTouchInput(true);
8707
- }
8708
- function handleKeyDown(event) {
8709
- if (getIsComposing() || event.isComposing) return;
8710
- if (KEYBOARD_MODALITY_KEYS.has(event.key) || event.metaKey || event.ctrlKey) setIsTouchInput(false);
8711
- }
8712
- if (typeof window !== "undefined") {
8713
- window.addEventListener("pointerdown", handlePointerDown, {
8714
- capture: true,
8715
- passive: true
8716
- });
8717
- window.addEventListener("keydown", handleKeyDown, {
8718
- capture: true,
8719
- passive: true
8720
- });
8721
- }
8722
- /**
8723
- * Whether the user last drove the selection with a finger (or pen) on the
8724
- * screen, as opposed to precise input (hardware keyboard navigation).
8725
- *
8726
- * Starts as `false` and follows the events; a touch device flips it on the
8727
- * first tap, which necessarily precedes any caret. Only navigation keys and
8728
- * modifier combos flip it back: letter keys are ignored because a software
8729
- * keyboard sends them too, and the software keyboard's own caret gestures (a
8730
- * spacebar long-press drag) reach the page as bare `selectionchange` events
8731
- * with no key or touch events at all, so staying on the previous value is the
8732
- * correct reading for them.
8733
- */
8734
- function getIsTouchInput() {
8735
- return lastIsTouchInput;
8736
- }
8737
- /**
8738
- * Calls `listener` whenever {@link getIsTouchInput} may report a new value.
8739
- */
8740
- function onIsTouchInputChange(listener) {
8741
- listeners.add(listener);
8742
- return () => {
8743
- listeners.delete(listener);
8744
- };
8745
- }
8746
-
8747
8833
  //#endregion
8748
8834
  //#region src/extensions/virtual-caret.ts
8749
8835
  const key = new PluginKey("meowdown-virtual-caret");
@@ -9041,4 +9127,4 @@ function getVirtualElementFromRange(view, range) {
9041
9127
  }
9042
9128
 
9043
9129
  //#endregion
9044
- export { EDITOR_KEY_BINDINGS, Priority, buildFileMarkdown, checkRoundTrip, codeBlockLanguages, collectReferenceDefinitions, defaultResolveImageUrl, defaultResolveXPost, defaultResolveYouTubeVideo, defineBulletAfterHeading, defineCodeBlockPreviewPlugin, defineCodeBlockSyntaxHighlight, defineEditorExtension, defineEmbedPaste, defineExitBoundaryHandler, defineFileClickHandler, defineFilePaste, defineFileView, defineFollowLinkHandler, defineHTMLComment, defineImage, defineImageClickHandler, defineLinkClickHandler, defineLinkCommands, defineLinkEditKeymap, defineLinkHoverHandler, defineLinkPaste, defineMath, definePendingReplacementHandler, definePlaceholder, defineReadonly, defineSearchStatusHandler, defineSubstitution, defineTagClickHandler, defineViewAttributes, defineVirtualCaret, defineWikilinkClickHandler, defineWikilinkHoverHandler, defineWikilinkTrigger, defineXPostMediaClickHandler, defineYouTubeVideoClickHandler, docToMarkdown, formatFileSize, formatSizedWikiEmbed, getCodeTokens, getEditorConfig, getFileKind, getIsComposing, getLinkText, getLinkUnitAt, getMarkBuilders, getPendingReplacement, getSearchStatus, getSelectedText, getTableColumnAlign, getTextblockDisplayText, getVirtualElementFromRange, inlineTextToMarkChunks, inlineTextToMarkChunksWithContext, insertLink, isCodeBlockPreviewHiddenDecoration, isLinkTextForHref, isMarkOfType, isModEvent, isNodeOfType, isReferenceDefinitionNode, isSelectionInTableCell, loadKaTeX, markdownToDoc, normalizeHref, parsePostEmbedSnapshot, parseWikiEmbed, removeLink, renderMathInto, updateEditorConfig, updateLink, wikiEmbedBasename, withPriority };
9130
+ export { EDITOR_KEY_BINDINGS, Priority, buildFileMarkdown, checkRoundTrip, codeBlockLanguages, collectReferenceDefinitions, defaultResolveImageUrl, defaultResolveXPost, defaultResolveYouTubeVideo, defineBulletAfterHeading, defineCodeBlockPreviewPlugin, defineCodeBlockSyntaxHighlight, defineEditorExtension, defineEmbedPaste, defineExitBoundaryHandler, defineFileClickHandler, defineFilePaste, defineFileView, defineFollowLinkHandler, defineHTMLComment, defineImage, defineImageClickHandler, defineLinkClickHandler, defineLinkCommands, defineLinkEditKeymap, defineLinkHoverHandler, defineLinkPaste, defineMath, definePendingReplacementHandler, definePlaceholder, defineReadonly, defineSearchStatusHandler, defineSubstitution, defineTagClickHandler, defineViewAttributes, defineVirtualCaret, defineWikilinkClickHandler, defineWikilinkHoverHandler, defineWikilinkTrigger, defineXPostMediaClickHandler, defineYouTubeVideoClickHandler, dismissLinkHover, docToMarkdown, formatFileSize, formatSizedWikiEmbed, getCodeTokens, getEditorConfig, getFileKind, getIsComposing, getLinkText, getLinkUnitAt, getMarkBuilders, getPendingReplacement, getSearchStatus, getSelectedText, getTableColumnAlign, getTextblockDisplayText, getVirtualElementFromRange, inlineTextToMarkChunks, inlineTextToMarkChunksWithContext, insertLink, isCodeBlockPreviewHiddenDecoration, isLinkTextForHref, isMarkOfType, isModEvent, isNodeOfType, isReferenceDefinitionNode, isSelectionInTableCell, loadKaTeX, markdownToDoc, normalizeHref, parsePostEmbedSnapshot, parseWikiEmbed, removeLink, renderMathInto, updateEditorConfig, updateLink, wikiEmbedBasename, withPriority };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@meowdown/core",
3
3
  "type": "module",
4
- "version": "0.74.1",
4
+ "version": "0.74.2",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",