prosemirror-view 1.18.4 → 1.18.8

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,39 @@
1
+ ## 1.18.8 (2021-06-23)
2
+
3
+ ### Bug fixes
4
+
5
+ Work around a Safari bug where it draws the cursor at the start of the line when it is after an uneditable node at the end of the line.
6
+
7
+ Fix an issue where the DOM could get out of sync when editing decorated text.
8
+
9
+ Work around an issue where Firefox draws the cursor on the wrong line when after a newline.
10
+
11
+ Fix a bug where double-clicking with the left mouse button and then pressing another mouse button was treated as a triple click.
12
+
13
+ ## 1.18.7 (2021-05-20)
14
+
15
+ ### Bug fixes
16
+
17
+ Fix a bug where clicking on a textblock that had a node-selected parent didn't set a cursor selection.
18
+
19
+ Fix a bug that caused a workaround for a Chrome Android issue to not work correctly, leading to bad cursor placement after some types of text input.
20
+
21
+ ## 1.18.6 (2021-05-17)
22
+
23
+ ### Bug fixes
24
+
25
+ Fix a crash in mouse click handling introduced in the previous version.
26
+
27
+ ## 1.18.5 (2021-05-17)
28
+
29
+ ### Bug fixes
30
+
31
+ Work around a Firefox bug where backspace sometimes deletes the node after the cursor.
32
+
33
+ Fix a bug that prevented `transformPasted` hooks from being called on content dragged within the editor.
34
+
35
+ Fixes an issue where clicking near a node or other special selection on Chrome would in some cases do nothing.
36
+
1
37
  ## 1.18.4 (2021-04-27)
2
38
 
3
39
  ### Bug fixes
package/dist/index.es.js CHANGED
@@ -377,7 +377,10 @@ function posAtCoords(view, coords) {
377
377
  if (!elt) { return null }
378
378
  }
379
379
  // Safari's caretRangeFromPoint returns nonsense when on a draggable element
380
- if (result.safari && elt.draggable) { node = offset = null; }
380
+ if (result.safari) {
381
+ for (var p = elt; node && p; p = parentNode(p))
382
+ { if (p.draggable) { node = offset = null; } }
383
+ }
381
384
  elt = targetKludge(elt, coords);
382
385
  if (node) {
383
386
  if (result.gecko && node.nodeType == 1) {
@@ -691,7 +694,7 @@ var prototypeAccessors = { beforePosition: { configurable: true },size: { config
691
694
  ViewDesc.prototype.matchesWidget = function matchesWidget () { return false };
692
695
  ViewDesc.prototype.matchesMark = function matchesMark () { return false };
693
696
  ViewDesc.prototype.matchesNode = function matchesNode () { return false };
694
- ViewDesc.prototype.matchesHack = function matchesHack () { return false };
697
+ ViewDesc.prototype.matchesHack = function matchesHack (_nodeName) { return false };
695
698
 
696
699
  prototypeAccessors.beforePosition.get = function () { return false };
697
700
 
@@ -957,14 +960,28 @@ ViewDesc.prototype.setSelection = function setSelection (anchor, head, root, for
957
960
  if (node.nodeType == 3) {
958
961
  brKludge = offset$1 && node.nodeValue[offset$1 - 1] == "\n";
959
962
  // Issue #1128
960
- if (brKludge && offset$1 == node.nodeValue.length &&
961
- node.nextSibling && node.nextSibling.nodeName == "BR")
962
- { anchorDOM = headDOM = {node: node.parentNode, offset: domIndex(node) + 1}; }
963
+ if (brKludge && offset$1 == node.nodeValue.length) {
964
+ for (var scan = node, after = (void 0); scan; scan = scan.parentNode) {
965
+ if (after = scan.nextSibling) {
966
+ if (after.nodeName == "BR")
967
+ { anchorDOM = headDOM = {node: after.parentNode, offset: domIndex(after) + 1}; }
968
+ break
969
+ }
970
+ var desc = scan.pmViewDesc;
971
+ if (desc && desc.node && desc.node.isBlock) { break }
972
+ }
973
+ }
963
974
  } else {
964
975
  var prev = node.childNodes[offset$1 - 1];
965
976
  brKludge = prev && (prev.nodeName == "BR" || prev.contentEditable == "false");
966
977
  }
967
978
  }
979
+ // Firefox can act strangely when the selection is in front of an
980
+ // uneditable node. See #1163 and https://bugzilla.mozilla.org/show_bug.cgi?id=1709536
981
+ if (result.gecko && domSel.focusNode && domSel.focusNode != headDOM.node && domSel.focusNode.nodeType == 1) {
982
+ var after$1 = domSel.focusNode.childNodes[domSel.focusOffset];
983
+ if (after$1 && after$1.contentEditable == "false") { force = true; }
984
+ }
968
985
 
969
986
  if (!(force || brKludge && result.safari) &&
970
987
  isEquivalentPosition(anchorDOM.node, anchorDOM.offset, domSel.anchorNode, domSel.anchorOffset) &&
@@ -1473,6 +1490,12 @@ var TextViewDesc = /*@__PURE__*/(function (NodeViewDesc) {
1473
1490
  return new TextViewDesc(this.parent, node, this.outerDeco, this.innerDeco, dom, dom, view)
1474
1491
  };
1475
1492
 
1493
+ TextViewDesc.prototype.markDirty = function markDirty (from, to) {
1494
+ NodeViewDesc.prototype.markDirty.call(this, from, to);
1495
+ if (this.dom != this.nodeDOM && (from == 0 || to == this.nodeDOM.nodeValue.length))
1496
+ { this.dirty = NODE_DIRTY; }
1497
+ };
1498
+
1476
1499
  prototypeAccessors$4.domAtom.get = function () { return false };
1477
1500
 
1478
1501
  Object.defineProperties( TextViewDesc.prototype, prototypeAccessors$4 );
@@ -1480,26 +1503,26 @@ var TextViewDesc = /*@__PURE__*/(function (NodeViewDesc) {
1480
1503
  return TextViewDesc;
1481
1504
  }(NodeViewDesc));
1482
1505
 
1483
- // A dummy desc used to tag trailing BR or span nodes created to work
1506
+ // A dummy desc used to tag trailing BR or IMG nodes created to work
1484
1507
  // around contentEditable terribleness.
1485
- var BRHackViewDesc = /*@__PURE__*/(function (ViewDesc) {
1486
- function BRHackViewDesc () {
1508
+ var TrailingHackViewDesc = /*@__PURE__*/(function (ViewDesc) {
1509
+ function TrailingHackViewDesc () {
1487
1510
  ViewDesc.apply(this, arguments);
1488
1511
  }
1489
1512
 
1490
- if ( ViewDesc ) BRHackViewDesc.__proto__ = ViewDesc;
1491
- BRHackViewDesc.prototype = Object.create( ViewDesc && ViewDesc.prototype );
1492
- BRHackViewDesc.prototype.constructor = BRHackViewDesc;
1513
+ if ( ViewDesc ) TrailingHackViewDesc.__proto__ = ViewDesc;
1514
+ TrailingHackViewDesc.prototype = Object.create( ViewDesc && ViewDesc.prototype );
1515
+ TrailingHackViewDesc.prototype.constructor = TrailingHackViewDesc;
1493
1516
 
1494
1517
  var prototypeAccessors$5 = { domAtom: { configurable: true } };
1495
1518
 
1496
- BRHackViewDesc.prototype.parseRule = function parseRule () { return {ignore: true} };
1497
- BRHackViewDesc.prototype.matchesHack = function matchesHack () { return this.dirty == NOT_DIRTY };
1519
+ TrailingHackViewDesc.prototype.parseRule = function parseRule () { return {ignore: true} };
1520
+ TrailingHackViewDesc.prototype.matchesHack = function matchesHack (nodeName) { return this.dirty == NOT_DIRTY && this.dom.nodeName == nodeName };
1498
1521
  prototypeAccessors$5.domAtom.get = function () { return true };
1499
1522
 
1500
- Object.defineProperties( BRHackViewDesc.prototype, prototypeAccessors$5 );
1523
+ Object.defineProperties( TrailingHackViewDesc.prototype, prototypeAccessors$5 );
1501
1524
 
1502
- return BRHackViewDesc;
1525
+ return TrailingHackViewDesc;
1503
1526
  }(ViewDesc));
1504
1527
 
1505
1528
  // A separate subclass is used for customized node views, so that the
@@ -1838,13 +1861,20 @@ ViewTreeUpdater.prototype.addTextblockHacks = function addTextblockHacks () {
1838
1861
  if (!lastChild || // Empty textblock
1839
1862
  !(lastChild instanceof TextViewDesc) ||
1840
1863
  /\n$/.test(lastChild.node.text)) {
1841
- if (this.index < this.top.children.length && this.top.children[this.index].matchesHack()) {
1842
- this.index++;
1843
- } else {
1844
- var dom = document.createElement("br");
1845
- this.top.children.splice(this.index++, 0, new BRHackViewDesc(this.top, nothing, dom, null));
1846
- this.changed = true;
1847
- }
1864
+ // Avoid a bug in Safari's cursor drawing (#1165)
1865
+ if (result.safari && lastChild && lastChild.dom.contentEditable == "false")
1866
+ { this.addHackNode("IMG"); }
1867
+ this.addHackNode("BR");
1868
+ }
1869
+ };
1870
+
1871
+ ViewTreeUpdater.prototype.addHackNode = function addHackNode (nodeName) {
1872
+ if (this.index < this.top.children.length && this.top.children[this.index].matchesHack(nodeName)) {
1873
+ this.index++;
1874
+ } else {
1875
+ var dom = document.createElement(nodeName);
1876
+ this.top.children.splice(this.index++, 0, new TrailingHackViewDesc(this.top, nothing, dom, null));
1877
+ this.changed = true;
1848
1878
  }
1849
1879
  };
1850
1880
 
@@ -2713,7 +2743,7 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
2713
2743
  // Edge just doesn't move the cursor forward when you start typing
2714
2744
  // in an empty block or between br nodes.
2715
2745
  if (sel$2 && !(result.chrome && result.android && view.composing && sel$2.empty &&
2716
- (change.from != change.toB || view.lastAndroidDelete < Date.now() - 100) &&
2746
+ (change.start != change.endB || view.lastAndroidDelete < Date.now() - 100) &&
2717
2747
  (sel$2.head == chFrom || sel$2.head == tr.mapping.map(chTo) - 1) ||
2718
2748
  result.ie && sel$2.empty && sel$2.head == chFrom))
2719
2749
  { tr.setSelection(sel$2); }
@@ -3355,7 +3385,7 @@ function dispatchEvent(view, event) {
3355
3385
  editHandlers.keydown = function (view, event) {
3356
3386
  view.shiftKey = event.keyCode == 16 || event.shiftKey;
3357
3387
  if (inOrNearComposition(view, event)) { return }
3358
- view.domObserver.forceFlush();
3388
+ if (event.keyCode != 229) { view.domObserver.forceFlush(); }
3359
3389
  view.lastKeyCode = event.keyCode;
3360
3390
  view.lastKeyCodeTime = Date.now();
3361
3391
  // On iOS, if we preventDefault enter key presses, the virtual
@@ -3481,10 +3511,11 @@ function handleDoubleClick(view, pos, inside, event) {
3481
3511
  function handleTripleClick(view, pos, inside, event) {
3482
3512
  return runHandlerOnContext(view, "handleTripleClickOn", pos, inside, event) ||
3483
3513
  view.someProp("handleTripleClick", function (f) { return f(view, pos, event); }) ||
3484
- defaultTripleClick(view, inside)
3514
+ defaultTripleClick(view, inside, event)
3485
3515
  }
3486
3516
 
3487
- function defaultTripleClick(view, inside) {
3517
+ function defaultTripleClick(view, inside, event) {
3518
+ if (event.button != 0) { return false }
3488
3519
  var doc = view.state.doc;
3489
3520
  if (inside == -1) {
3490
3521
  if (doc.inlineContent) {
@@ -3546,7 +3577,7 @@ var MouseDown = function MouseDown(view, pos, event, flushed) {
3546
3577
  this.event = event;
3547
3578
  this.flushed = flushed;
3548
3579
  this.selectNode = event[selectNodeModifier];
3549
- this.allowDefault = event.shiftKey;
3580
+ this.allowDefault = event.shiftKey || event.button != 0;
3550
3581
 
3551
3582
  var targetNode, targetPos;
3552
3583
  if (pos.inside > -1) {
@@ -3564,8 +3595,11 @@ var MouseDown = function MouseDown(view, pos, event, flushed) {
3564
3595
  var targetDesc = target ? view.docView.nearestDesc(target, true) : null;
3565
3596
  this.target = targetDesc ? targetDesc.dom : null;
3566
3597
 
3567
- if (targetNode.type.spec.draggable && targetNode.type.spec.selectable !== false ||
3568
- view.state.selection instanceof NodeSelection && targetPos == view.state.selection.from)
3598
+ var ref = view.state;
3599
+ var selection = ref.selection;
3600
+ if (event.button == 0 &&
3601
+ targetNode.type.spec.draggable && targetNode.type.spec.selectable !== false ||
3602
+ selection instanceof NodeSelection && selection.from <= targetPos && selection.to > targetPos)
3569
3603
  { this.mightDrag = {node: targetNode,
3570
3604
  pos: targetPos,
3571
3605
  addAttr: this.target && !this.target.draggable,
@@ -3622,7 +3656,8 @@ MouseDown.prototype.up = function up (event) {
3622
3656
  // thus doesn't get a reaction from ProseMirror. This
3623
3657
  // works around that.
3624
3658
  (result.chrome && !(this.view.state.selection instanceof TextSelection) &&
3625
- (pos.pos == this.view.state.selection.from || pos.pos == this.view.state.selection.to))) {
3659
+ Math.min(Math.abs(pos.pos - this.view.state.selection.from),
3660
+ Math.abs(pos.pos - this.view.state.selection.to)) <= 2)) {
3626
3661
  updateSelection(this.view, Selection.near(this.view.state.doc.resolve(pos.pos)), "pointer");
3627
3662
  event.preventDefault();
3628
3663
  } else {
@@ -3870,9 +3905,13 @@ editHandlers.drop = function (view, e) {
3870
3905
  if (!eventPos) { return }
3871
3906
  var $mouse = view.state.doc.resolve(eventPos.pos);
3872
3907
  if (!$mouse) { return }
3873
- var slice = dragging && dragging.slice ||
3874
- parseFromClipboard(view, e.dataTransfer.getData(brokenClipboardAPI ? "Text" : "text/plain"),
3875
- brokenClipboardAPI ? null : e.dataTransfer.getData("text/html"), false, $mouse);
3908
+ var slice = dragging && dragging.slice;
3909
+ if (slice) {
3910
+ view.someProp("transformPasted", function (f) { slice = f(slice); });
3911
+ } else {
3912
+ slice = parseFromClipboard(view, e.dataTransfer.getData(brokenClipboardAPI ? "Text" : "text/plain"),
3913
+ brokenClipboardAPI ? null : e.dataTransfer.getData("text/html"), false, $mouse);
3914
+ }
3876
3915
  var move = dragging && !e[dragCopyModifier];
3877
3916
  if (view.someProp("handleDrop", function (f) { return f(view, e, slice || Slice.empty, move); })) {
3878
3917
  e.preventDefault();