@codemirror/view 6.32.0 → 6.33.0

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/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ ## 6.33.0 (2024-08-24)
2
+
3
+ ### Bug fixes
4
+
5
+ Make it easier to move the pointer over a hover tooltip with an arrow by not closing the tooltip when the pointer is moving over the gap for the arrow.
6
+
7
+ ### New features
8
+
9
+ The new `EditorView.clipboardInputFilter` and `clipboardOutputFilter` facets allow you to register filter functions that change text taken from or sent to the clipboard.
10
+
1
11
  ## 6.32.0 (2024-08-12)
2
12
 
3
13
  ### Bug fixes
package/dist/index.cjs CHANGED
@@ -2365,6 +2365,8 @@ const exceptionSink = state.Facet.define();
2365
2365
  const updateListener = state.Facet.define();
2366
2366
  const inputHandler = state.Facet.define();
2367
2367
  const focusChangeEffect = state.Facet.define();
2368
+ const clipboardInputFilter = state.Facet.define();
2369
+ const clipboardOutputFilter = state.Facet.define();
2368
2370
  const perLineTextDirection = state.Facet.define({
2369
2371
  combine: values => values.some(x => x)
2370
2372
  });
@@ -4546,7 +4548,13 @@ function capturePaste(view) {
4546
4548
  doPaste(view, target.value);
4547
4549
  }, 50);
4548
4550
  }
4551
+ function textFilter(state, facet, text) {
4552
+ for (let filter of state.facet(facet))
4553
+ text = filter(text, state);
4554
+ return text;
4555
+ }
4549
4556
  function doPaste(view, input) {
4557
+ input = textFilter(view.state, clipboardInputFilter, input);
4550
4558
  let { state: state$1 } = view, changes, i = 1, text = state$1.toText(input);
4551
4559
  let byLine = text.lines == state$1.selection.ranges.length;
4552
4560
  let linewise = lastLinewiseCopy != null && state$1.selection.ranges.every(r => r.empty) && lastLinewiseCopy == text.toString();
@@ -4731,7 +4739,7 @@ handlers.dragstart = (view, event) => {
4731
4739
  inputState.mouseSelection.dragging = true;
4732
4740
  inputState.draggedContent = range;
4733
4741
  if (event.dataTransfer) {
4734
- event.dataTransfer.setData("Text", view.state.sliceDoc(range.from, range.to));
4742
+ event.dataTransfer.setData("Text", textFilter(view.state, clipboardOutputFilter, view.state.sliceDoc(range.from, range.to)));
4735
4743
  event.dataTransfer.effectAllowed = "copyMove";
4736
4744
  }
4737
4745
  return false;
@@ -4741,6 +4749,7 @@ handlers.dragend = view => {
4741
4749
  return false;
4742
4750
  };
4743
4751
  function dropText(view, event, text, direct) {
4752
+ text = textFilter(view.state, clipboardInputFilter, text);
4744
4753
  if (!text)
4745
4754
  return;
4746
4755
  let dropPos = view.posAtCoords({ x: event.clientX, y: event.clientY }, false);
@@ -4841,7 +4850,7 @@ function copiedRange(state) {
4841
4850
  }
4842
4851
  linewise = true;
4843
4852
  }
4844
- return { text: content.join(state.lineBreak), ranges, linewise };
4853
+ return { text: textFilter(state, clipboardOutputFilter, content.join(state.lineBreak)), ranges, linewise };
4845
4854
  }
4846
4855
  let lastLinewiseCopy = null;
4847
4856
  handlers.copy = handlers.cut = (view, event) => {
@@ -8264,6 +8273,15 @@ dispatching the custom behavior as a separate transaction.
8264
8273
  */
8265
8274
  EditorView.inputHandler = inputHandler;
8266
8275
  /**
8276
+ Functions provided in this facet will be used to transform text
8277
+ pasted or dropped into the editor.
8278
+ */
8279
+ EditorView.clipboardInputFilter = clipboardInputFilter;
8280
+ /**
8281
+ Transform text copied or dragged from the editor.
8282
+ */
8283
+ EditorView.clipboardOutputFilter = clipboardOutputFilter;
8284
+ /**
8267
8285
  Scroll handlers can override how things are scrolled into view.
8268
8286
  If they return `true`, no further handling happens for the
8269
8287
  scrolling. If they return false, the default scroll behavior is
@@ -10235,9 +10253,14 @@ class HoverPlugin {
10235
10253
  }
10236
10254
  const tooltipMargin = 4;
10237
10255
  function isInTooltip(tooltip, event) {
10238
- let rect = tooltip.getBoundingClientRect();
10239
- return event.clientX >= rect.left - tooltipMargin && event.clientX <= rect.right + tooltipMargin &&
10240
- event.clientY >= rect.top - tooltipMargin && event.clientY <= rect.bottom + tooltipMargin;
10256
+ let { left, right, top, bottom } = tooltip.getBoundingClientRect(), arrow;
10257
+ if (arrow = tooltip.querySelector(".cm-tooltip-arrow")) {
10258
+ let arrowRect = arrow.getBoundingClientRect();
10259
+ top = Math.min(arrowRect.top, top);
10260
+ bottom = Math.max(arrowRect.bottom, bottom);
10261
+ }
10262
+ return event.clientX >= left - tooltipMargin && event.clientX <= right + tooltipMargin &&
10263
+ event.clientY >= top - tooltipMargin && event.clientY <= bottom + tooltipMargin;
10241
10264
  }
10242
10265
  function isOverRange(view, from, to, x, y, margin) {
10243
10266
  let rect = view.scrollDOM.getBoundingClientRect();
package/dist/index.d.cts CHANGED
@@ -1146,6 +1146,15 @@ declare class EditorView {
1146
1146
  */
1147
1147
  static inputHandler: Facet<(view: EditorView, from: number, to: number, text: string, insert: () => Transaction) => boolean, readonly ((view: EditorView, from: number, to: number, text: string, insert: () => Transaction) => boolean)[]>;
1148
1148
  /**
1149
+ Functions provided in this facet will be used to transform text
1150
+ pasted or dropped into the editor.
1151
+ */
1152
+ static clipboardInputFilter: Facet<(text: string, state: EditorState) => string, readonly ((text: string, state: EditorState) => string)[]>;
1153
+ /**
1154
+ Transform text copied or dragged from the editor.
1155
+ */
1156
+ static clipboardOutputFilter: Facet<(text: string, state: EditorState) => string, readonly ((text: string, state: EditorState) => string)[]>;
1157
+ /**
1149
1158
  Scroll handlers can override how things are scrolled into view.
1150
1159
  If they return `true`, no further handling happens for the
1151
1160
  scrolling. If they return false, the default scroll behavior is
package/dist/index.d.ts CHANGED
@@ -1146,6 +1146,15 @@ declare class EditorView {
1146
1146
  */
1147
1147
  static inputHandler: Facet<(view: EditorView, from: number, to: number, text: string, insert: () => Transaction) => boolean, readonly ((view: EditorView, from: number, to: number, text: string, insert: () => Transaction) => boolean)[]>;
1148
1148
  /**
1149
+ Functions provided in this facet will be used to transform text
1150
+ pasted or dropped into the editor.
1151
+ */
1152
+ static clipboardInputFilter: Facet<(text: string, state: EditorState) => string, readonly ((text: string, state: EditorState) => string)[]>;
1153
+ /**
1154
+ Transform text copied or dragged from the editor.
1155
+ */
1156
+ static clipboardOutputFilter: Facet<(text: string, state: EditorState) => string, readonly ((text: string, state: EditorState) => string)[]>;
1157
+ /**
1149
1158
  Scroll handlers can override how things are scrolled into view.
1150
1159
  If they return `true`, no further handling happens for the
1151
1160
  scrolling. If they return false, the default scroll behavior is
package/dist/index.js CHANGED
@@ -2361,6 +2361,8 @@ const exceptionSink = /*@__PURE__*/Facet.define();
2361
2361
  const updateListener = /*@__PURE__*/Facet.define();
2362
2362
  const inputHandler = /*@__PURE__*/Facet.define();
2363
2363
  const focusChangeEffect = /*@__PURE__*/Facet.define();
2364
+ const clipboardInputFilter = /*@__PURE__*/Facet.define();
2365
+ const clipboardOutputFilter = /*@__PURE__*/Facet.define();
2364
2366
  const perLineTextDirection = /*@__PURE__*/Facet.define({
2365
2367
  combine: values => values.some(x => x)
2366
2368
  });
@@ -4542,7 +4544,13 @@ function capturePaste(view) {
4542
4544
  doPaste(view, target.value);
4543
4545
  }, 50);
4544
4546
  }
4547
+ function textFilter(state, facet, text) {
4548
+ for (let filter of state.facet(facet))
4549
+ text = filter(text, state);
4550
+ return text;
4551
+ }
4545
4552
  function doPaste(view, input) {
4553
+ input = textFilter(view.state, clipboardInputFilter, input);
4546
4554
  let { state } = view, changes, i = 1, text = state.toText(input);
4547
4555
  let byLine = text.lines == state.selection.ranges.length;
4548
4556
  let linewise = lastLinewiseCopy != null && state.selection.ranges.every(r => r.empty) && lastLinewiseCopy == text.toString();
@@ -4727,7 +4735,7 @@ handlers.dragstart = (view, event) => {
4727
4735
  inputState.mouseSelection.dragging = true;
4728
4736
  inputState.draggedContent = range;
4729
4737
  if (event.dataTransfer) {
4730
- event.dataTransfer.setData("Text", view.state.sliceDoc(range.from, range.to));
4738
+ event.dataTransfer.setData("Text", textFilter(view.state, clipboardOutputFilter, view.state.sliceDoc(range.from, range.to)));
4731
4739
  event.dataTransfer.effectAllowed = "copyMove";
4732
4740
  }
4733
4741
  return false;
@@ -4737,6 +4745,7 @@ handlers.dragend = view => {
4737
4745
  return false;
4738
4746
  };
4739
4747
  function dropText(view, event, text, direct) {
4748
+ text = textFilter(view.state, clipboardInputFilter, text);
4740
4749
  if (!text)
4741
4750
  return;
4742
4751
  let dropPos = view.posAtCoords({ x: event.clientX, y: event.clientY }, false);
@@ -4837,7 +4846,7 @@ function copiedRange(state) {
4837
4846
  }
4838
4847
  linewise = true;
4839
4848
  }
4840
- return { text: content.join(state.lineBreak), ranges, linewise };
4849
+ return { text: textFilter(state, clipboardOutputFilter, content.join(state.lineBreak)), ranges, linewise };
4841
4850
  }
4842
4851
  let lastLinewiseCopy = null;
4843
4852
  handlers.copy = handlers.cut = (view, event) => {
@@ -8259,6 +8268,15 @@ dispatching the custom behavior as a separate transaction.
8259
8268
  */
8260
8269
  EditorView.inputHandler = inputHandler;
8261
8270
  /**
8271
+ Functions provided in this facet will be used to transform text
8272
+ pasted or dropped into the editor.
8273
+ */
8274
+ EditorView.clipboardInputFilter = clipboardInputFilter;
8275
+ /**
8276
+ Transform text copied or dragged from the editor.
8277
+ */
8278
+ EditorView.clipboardOutputFilter = clipboardOutputFilter;
8279
+ /**
8262
8280
  Scroll handlers can override how things are scrolled into view.
8263
8281
  If they return `true`, no further handling happens for the
8264
8282
  scrolling. If they return false, the default scroll behavior is
@@ -10230,9 +10248,14 @@ class HoverPlugin {
10230
10248
  }
10231
10249
  const tooltipMargin = 4;
10232
10250
  function isInTooltip(tooltip, event) {
10233
- let rect = tooltip.getBoundingClientRect();
10234
- return event.clientX >= rect.left - tooltipMargin && event.clientX <= rect.right + tooltipMargin &&
10235
- event.clientY >= rect.top - tooltipMargin && event.clientY <= rect.bottom + tooltipMargin;
10251
+ let { left, right, top, bottom } = tooltip.getBoundingClientRect(), arrow;
10252
+ if (arrow = tooltip.querySelector(".cm-tooltip-arrow")) {
10253
+ let arrowRect = arrow.getBoundingClientRect();
10254
+ top = Math.min(arrowRect.top, top);
10255
+ bottom = Math.max(arrowRect.bottom, bottom);
10256
+ }
10257
+ return event.clientX >= left - tooltipMargin && event.clientX <= right + tooltipMargin &&
10258
+ event.clientY >= top - tooltipMargin && event.clientY <= bottom + tooltipMargin;
10236
10259
  }
10237
10260
  function isOverRange(view, from, to, x, y, margin) {
10238
10261
  let rect = view.scrollDOM.getBoundingClientRect();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemirror/view",
3
- "version": "6.32.0",
3
+ "version": "6.33.0",
4
4
  "description": "DOM view component for the CodeMirror code editor",
5
5
  "scripts": {
6
6
  "test": "cm-runtests",