prosemirror-view 1.32.0 → 1.32.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/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## 1.32.2 (2023-10-27)
2
+
3
+ ### Bug fixes
4
+
5
+ Check for text/uri-list data on the clipboard or in the drop event when pasting or dropping content, since some types of copying on Apple devices use this format.
6
+
7
+ ## 1.32.1 (2023-10-13)
8
+
9
+ ### Bug fixes
10
+
11
+ Work around a Chrome issue where it didn't draw a selection for inline leaf nodes when selecting across them.
12
+
13
+ Override the native behavior when shift-selecting horizontally across non-text inline nodes, since most browsers behave poorly here.
14
+
1
15
  ## 1.32.0 (2023-09-27)
2
16
 
3
17
  ### Bug fixes
package/dist/index.cjs CHANGED
@@ -2746,24 +2746,31 @@ function selectHorizontally(view, dir, mods) {
2746
2746
  var sel = view.state.selection;
2747
2747
 
2748
2748
  if (sel instanceof prosemirrorState.TextSelection) {
2749
- if (!sel.empty || mods.indexOf("s") > -1) {
2749
+ if (mods.indexOf("s") > -1) {
2750
+ var $head = sel.$head,
2751
+ node = $head.textOffset ? null : dir < 0 ? $head.nodeBefore : $head.nodeAfter;
2752
+ if (!node || node.isText || !node.isLeaf) return false;
2753
+ var $newHead = view.state.doc.resolve($head.pos + node.nodeSize * (dir < 0 ? -1 : 1));
2754
+ return apply(view, new prosemirrorState.TextSelection(sel.$anchor, $newHead));
2755
+ } else if (!sel.empty) {
2750
2756
  return false;
2751
2757
  } else if (view.endOfTextblock(dir > 0 ? "forward" : "backward")) {
2752
2758
  var next = moveSelectionBlock(view.state, dir);
2753
2759
  if (next && next instanceof prosemirrorState.NodeSelection) return apply(view, next);
2754
2760
  return false;
2755
2761
  } else if (!(mac && mods.indexOf("m") > -1)) {
2756
- var $head = sel.$head,
2757
- node = $head.textOffset ? null : dir < 0 ? $head.nodeBefore : $head.nodeAfter,
2762
+ var _$head = sel.$head,
2763
+ _node = _$head.textOffset ? null : dir < 0 ? _$head.nodeBefore : _$head.nodeAfter,
2758
2764
  desc;
2759
- if (!node || node.isText) return false;
2760
- var nodePos = dir < 0 ? $head.pos - node.nodeSize : $head.pos;
2761
- if (!(node.isAtom || (desc = view.docView.descAt(nodePos)) && !desc.contentDOM)) return false;
2762
2765
 
2763
- if (prosemirrorState.NodeSelection.isSelectable(node)) {
2764
- return apply(view, new prosemirrorState.NodeSelection(dir < 0 ? view.state.doc.resolve($head.pos - node.nodeSize) : $head));
2766
+ if (!_node || _node.isText) return false;
2767
+ var nodePos = dir < 0 ? _$head.pos - _node.nodeSize : _$head.pos;
2768
+ if (!(_node.isAtom || (desc = view.docView.descAt(nodePos)) && !desc.contentDOM)) return false;
2769
+
2770
+ if (prosemirrorState.NodeSelection.isSelectable(_node)) {
2771
+ return apply(view, new prosemirrorState.NodeSelection(dir < 0 ? view.state.doc.resolve(_$head.pos - _node.nodeSize) : _$head));
2765
2772
  } else if (webkit) {
2766
- return apply(view, new prosemirrorState.TextSelection(view.state.doc.resolve(dir < 0 ? nodePos : nodePos + node.nodeSize)));
2773
+ return apply(view, new prosemirrorState.TextSelection(view.state.doc.resolve(dir < 0 ? nodePos : nodePos + _node.nodeSize)));
2767
2774
  } else {
2768
2775
  return false;
2769
2776
  }
@@ -2783,7 +2790,6 @@ function nodeLen(node) {
2783
2790
  }
2784
2791
 
2785
2792
  function isIgnorable(dom, dir) {
2786
- if (dom.contentEditable == "false") return true;
2787
2793
  var desc = dom.pmViewDesc;
2788
2794
  return desc && desc.size == 0 && (dir < 0 || dom.nextSibling || dom.nodeName != "BR");
2789
2795
  }
@@ -3206,7 +3212,7 @@ function parseFromClipboard(view, text, html, plainText, $context) {
3206
3212
 
3207
3213
  for (var node = slice.content.firstChild; openStart < slice.openStart && !node.type.spec.isolating; openStart++, node = node.firstChild) {}
3208
3214
 
3209
- for (var _node = slice.content.lastChild; openEnd < slice.openEnd && !_node.type.spec.isolating; openEnd++, _node = _node.lastChild) {}
3215
+ for (var _node2 = slice.content.lastChild; openEnd < slice.openEnd && !_node2.type.spec.isolating; openEnd++, _node2 = _node2.lastChild) {}
3210
3216
 
3211
3217
  slice = closeSlice(slice, openStart, openEnd);
3212
3218
  }
@@ -3987,12 +3993,19 @@ function doPaste(view, text, html, preferPlain, event) {
3987
3993
  return true;
3988
3994
  }
3989
3995
 
3996
+ function getText(clipboardData) {
3997
+ var text = clipboardData.getData("text/html") || clipboardData.getData("Text");
3998
+ if (text) return text;
3999
+ var uris = clipboardData.getData("text/uri-list");
4000
+ return uris ? uris.replace(/\r?\n/g, " ") : "";
4001
+ }
4002
+
3990
4003
  editHandlers.paste = function (view, _event) {
3991
4004
  var event = _event;
3992
4005
  if (view.composing && !android) return;
3993
4006
  var data = brokenClipboardAPI ? null : event.clipboardData;
3994
4007
  var plain = view.input.shiftKey && view.input.lastKeyCode != 45;
3995
- if (data && doPaste(view, data.getData("text/plain"), data.getData("text/html"), plain, event)) event.preventDefault();else capturePaste(view, event);
4008
+ if (data && doPaste(view, getText(data), data.getData("text/html"), plain, event)) event.preventDefault();else capturePaste(view, event);
3996
4009
  };
3997
4010
 
3998
4011
  var Dragging = _createClass(function Dragging(slice, move) {
@@ -4056,7 +4069,7 @@ editHandlers.drop = function (view, _event) {
4056
4069
  slice = f(slice, view);
4057
4070
  });
4058
4071
  } else {
4059
- slice = parseFromClipboard(view, event.dataTransfer.getData(brokenClipboardAPI ? "Text" : "text/plain"), brokenClipboardAPI ? null : event.dataTransfer.getData("text/html"), false, $mouse);
4072
+ slice = parseFromClipboard(view, getText(event.dataTransfer), brokenClipboardAPI ? null : event.dataTransfer.getData("text/html"), false, $mouse);
4060
4073
  }
4061
4074
 
4062
4075
  var move = !!(dragging && !event[dragCopyModifier]);
package/dist/index.js CHANGED
@@ -2328,7 +2328,14 @@ function apply(view, sel) {
2328
2328
  function selectHorizontally(view, dir, mods) {
2329
2329
  let sel = view.state.selection;
2330
2330
  if (sel instanceof TextSelection) {
2331
- if (!sel.empty || mods.indexOf("s") > -1) {
2331
+ if (mods.indexOf("s") > -1) {
2332
+ let { $head } = sel, node = $head.textOffset ? null : dir < 0 ? $head.nodeBefore : $head.nodeAfter;
2333
+ if (!node || node.isText || !node.isLeaf)
2334
+ return false;
2335
+ let $newHead = view.state.doc.resolve($head.pos + node.nodeSize * (dir < 0 ? -1 : 1));
2336
+ return apply(view, new TextSelection(sel.$anchor, $newHead));
2337
+ }
2338
+ else if (!sel.empty) {
2332
2339
  return false;
2333
2340
  }
2334
2341
  else if (view.endOfTextblock(dir > 0 ? "forward" : "backward")) {
@@ -2372,8 +2379,6 @@ function nodeLen(node) {
2372
2379
  return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length;
2373
2380
  }
2374
2381
  function isIgnorable(dom, dir) {
2375
- if (dom.contentEditable == "false")
2376
- return true;
2377
2382
  let desc = dom.pmViewDesc;
2378
2383
  return desc && desc.size == 0 && (dir < 0 || dom.nextSibling || dom.nodeName != "BR");
2379
2384
  }
@@ -3517,6 +3522,13 @@ function doPaste(view, text, html, preferPlain, event) {
3517
3522
  view.dispatch(tr.scrollIntoView().setMeta("paste", true).setMeta("uiEvent", "paste"));
3518
3523
  return true;
3519
3524
  }
3525
+ function getText(clipboardData) {
3526
+ let text = clipboardData.getData("text/html") || clipboardData.getData("Text");
3527
+ if (text)
3528
+ return text;
3529
+ let uris = clipboardData.getData("text/uri-list");
3530
+ return uris ? uris.replace(/\r?\n/g, " ") : "";
3531
+ }
3520
3532
  editHandlers.paste = (view, _event) => {
3521
3533
  let event = _event;
3522
3534
  // Handling paste from JavaScript during composition is very poorly
@@ -3527,7 +3539,7 @@ editHandlers.paste = (view, _event) => {
3527
3539
  return;
3528
3540
  let data = brokenClipboardAPI ? null : event.clipboardData;
3529
3541
  let plain = view.input.shiftKey && view.input.lastKeyCode != 45;
3530
- if (data && doPaste(view, data.getData("text/plain"), data.getData("text/html"), plain, event))
3542
+ if (data && doPaste(view, getText(data), data.getData("text/html"), plain, event))
3531
3543
  event.preventDefault();
3532
3544
  else
3533
3545
  capturePaste(view, event);
@@ -3589,7 +3601,7 @@ editHandlers.drop = (view, _event) => {
3589
3601
  view.someProp("transformPasted", f => { slice = f(slice, view); });
3590
3602
  }
3591
3603
  else {
3592
- slice = parseFromClipboard(view, event.dataTransfer.getData(brokenClipboardAPI ? "Text" : "text/plain"), brokenClipboardAPI ? null : event.dataTransfer.getData("text/html"), false, $mouse);
3604
+ slice = parseFromClipboard(view, getText(event.dataTransfer), brokenClipboardAPI ? null : event.dataTransfer.getData("text/html"), false, $mouse);
3593
3605
  }
3594
3606
  let move = !!(dragging && !event[dragCopyModifier]);
3595
3607
  if (view.someProp("handleDrop", f => f(view, event, slice || Slice.empty, move))) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prosemirror-view",
3
- "version": "1.32.0",
3
+ "version": "1.32.2",
4
4
  "description": "ProseMirror's view component",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -19,7 +19,12 @@ function apply(view: EditorView, sel: Selection) {
19
19
  function selectHorizontally(view: EditorView, dir: number, mods: string) {
20
20
  let sel = view.state.selection
21
21
  if (sel instanceof TextSelection) {
22
- if (!sel.empty || mods.indexOf("s") > -1) {
22
+ if (mods.indexOf("s") > -1) {
23
+ let {$head} = sel, node = $head.textOffset ? null : dir < 0 ? $head.nodeBefore : $head.nodeAfter
24
+ if (!node || node.isText || !node.isLeaf) return false
25
+ let $newHead = view.state.doc.resolve($head.pos + node.nodeSize * (dir < 0 ? -1 : 1))
26
+ return apply(view, new TextSelection(sel.$anchor, $newHead))
27
+ } else if (!sel.empty) {
23
28
  return false
24
29
  } else if (view.endOfTextblock(dir > 0 ? "forward" : "backward")) {
25
30
  let next = moveSelectionBlock(view.state, dir)
@@ -55,7 +60,6 @@ function nodeLen(node: Node) {
55
60
  }
56
61
 
57
62
  function isIgnorable(dom: Node, dir: number) {
58
- if ((dom as HTMLElement).contentEditable == "false") return true
59
63
  let desc = dom.pmViewDesc
60
64
  return desc && desc.size == 0 && (dir < 0 || dom.nextSibling || dom.nodeName != "BR")
61
65
  }
package/src/input.ts CHANGED
@@ -608,6 +608,13 @@ export function doPaste(view: EditorView, text: string, html: string | null, pre
608
608
  return true
609
609
  }
610
610
 
611
+ function getText(clipboardData: DataTransfer) {
612
+ let text = clipboardData.getData("text/html") || clipboardData.getData("Text")
613
+ if (text) return text
614
+ let uris = clipboardData.getData("text/uri-list")
615
+ return uris ? uris.replace(/\r?\n/g, " ") : ""
616
+ }
617
+
611
618
  editHandlers.paste = (view, _event) => {
612
619
  let event = _event as ClipboardEvent
613
620
  // Handling paste from JavaScript during composition is very poorly
@@ -617,7 +624,7 @@ editHandlers.paste = (view, _event) => {
617
624
  if (view.composing && !browser.android) return
618
625
  let data = brokenClipboardAPI ? null : event.clipboardData
619
626
  let plain = view.input.shiftKey && view.input.lastKeyCode != 45
620
- if (data && doPaste(view, data.getData("text/plain"), data.getData("text/html"), plain, event))
627
+ if (data && doPaste(view, getText(data), data.getData("text/html"), plain, event))
621
628
  event.preventDefault()
622
629
  else
623
630
  capturePaste(view, event)
@@ -678,7 +685,7 @@ editHandlers.drop = (view, _event) => {
678
685
  if (slice) {
679
686
  view.someProp("transformPasted", f => { slice = f(slice!, view) })
680
687
  } else {
681
- slice = parseFromClipboard(view, event.dataTransfer.getData(brokenClipboardAPI ? "Text" : "text/plain"),
688
+ slice = parseFromClipboard(view, getText(event.dataTransfer),
682
689
  brokenClipboardAPI ? null : event.dataTransfer.getData("text/html"), false, $mouse)
683
690
  }
684
691
  let move = !!(dragging && !event[dragCopyModifier])
@@ -23,6 +23,9 @@
23
23
  .ProseMirror-hideselection *::-moz-selection { background: transparent; }
24
24
  .ProseMirror-hideselection { caret-color: transparent; }
25
25
 
26
+ /* See https://github.com/ProseMirror/prosemirror/issues/1421#issuecomment-1759320191 */
27
+ .ProseMirror [draggable][contenteditable=false] { user-select: text }
28
+
26
29
  .ProseMirror-selectednode {
27
30
  outline: 2px solid #8cf;
28
31
  }