prosemirror-view 1.23.1 → 1.23.5

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.js CHANGED
@@ -1294,7 +1294,7 @@ var NodeViewDesc = /*@__PURE__*/(function (ViewDesc) {
1294
1294
  // attrs in the dom, that won't be picked up. Not entirely sure
1295
1295
  // whether this is a problem
1296
1296
  var rule = {node: this.node.type.name, attrs: this.node.attrs};
1297
- if (this.node.type.spec.code) { rule.preserveWhitespace = "full"; }
1297
+ if (this.node.type.whitespace == "pre") { rule.preserveWhitespace = "full"; }
1298
1298
  if (this.contentDOM && !this.contentLost) { rule.contentElement = this.contentDOM; }
1299
1299
  else { rule.getContent = function () { return this$1.contentDOM ? prosemirrorModel.Fragment.empty : this$1.node.content; }; }
1300
1300
  return rule
@@ -1751,7 +1751,7 @@ var ViewTreeUpdater = function ViewTreeUpdater(top, lockedNode) {
1751
1751
  // Tracks whether anything was changed
1752
1752
  this.changed = false;
1753
1753
 
1754
- this.preMatch = preMatch(top.node.content, top.children);
1754
+ this.preMatch = preMatch(top.node.content, top);
1755
1755
  };
1756
1756
 
1757
1757
  // Destroy and remove the children between the given indices in
@@ -1812,19 +1812,16 @@ ViewTreeUpdater.prototype.syncToMarks = function syncToMarks (marks, inline, vie
1812
1812
  // Try to find a node desc matching the given data. Skip over it and
1813
1813
  // return true when successful.
1814
1814
  ViewTreeUpdater.prototype.findNodeMatch = function findNodeMatch (node, outerDeco, innerDeco, index) {
1815
- var children = this.top.children, found = -1;
1816
- if (index >= this.preMatch.index) {
1817
- for (var i = this.index; i < children.length; i++) {
1818
- if (this.preMatch.matched.get(children[i]) == index) {
1819
- if (children[i].matchesNode(node, outerDeco, innerDeco)) { found = i; }
1820
- break
1821
- }
1822
- }
1815
+ var found = -1, targetDesc;
1816
+ if (index >= this.preMatch.index &&
1817
+ (targetDesc = this.preMatch.matches[index - this.preMatch.index]).parent == this.top &&
1818
+ targetDesc.matchesNode(node, outerDeco, innerDeco)) {
1819
+ found = this.top.children.indexOf(targetDesc, this.index);
1823
1820
  } else {
1824
- for (var i$1 = this.index, e = Math.min(children.length, i$1 + 5); i$1 < e; i$1++) {
1825
- var child = children[i$1];
1821
+ for (var i = this.index, e = Math.min(this.top.children.length, i + 5); i < e; i++) {
1822
+ var child = this.top.children[i];
1826
1823
  if (child.matchesNode(node, outerDeco, innerDeco) && !this.preMatch.matched.has(child)) {
1827
- found = i$1;
1824
+ found = i;
1828
1825
  break
1829
1826
  }
1830
1827
  }
@@ -1933,22 +1930,44 @@ ViewTreeUpdater.prototype.addHackNode = function addHackNode (nodeName) {
1933
1930
  }
1934
1931
  };
1935
1932
 
1936
- // : (Fragment, [ViewDesc]) → {index: number, matched: Map<ViewDesc, number>}
1933
+ // : (Fragment, [ViewDesc]) → {index: number, matched: Map<ViewDesc, number>, matches: ViewDesc[]}
1937
1934
  // Iterate from the end of the fragment and array of descs to find
1938
1935
  // directly matching ones, in order to avoid overeagerly reusing those
1939
1936
  // for other nodes. Returns the fragment index of the first node that
1940
1937
  // is part of the sequence of matched nodes at the end of the
1941
1938
  // fragment.
1942
- function preMatch(frag, descs) {
1943
- var fI = frag.childCount, dI = descs.length, matched = new Map;
1944
- for (; fI > 0 && dI > 0; dI--) {
1945
- var desc = descs[dI - 1], node = desc.node;
1939
+ function preMatch(frag, parentDesc) {
1940
+ var curDesc = parentDesc, descI = curDesc.children.length;
1941
+ var fI = frag.childCount, matched = new Map, matches = [];
1942
+ outer: while (fI > 0) {
1943
+ var desc = (void 0);
1944
+ for (;;) {
1945
+ if (descI) {
1946
+ var next = curDesc.children[descI - 1];
1947
+ if (next instanceof MarkViewDesc) {
1948
+ curDesc = next;
1949
+ descI = next.children.length;
1950
+ } else {
1951
+ desc = next;
1952
+ descI--;
1953
+ break
1954
+ }
1955
+ } else if (curDesc == parentDesc) {
1956
+ break outer
1957
+ } else {
1958
+ // FIXME
1959
+ descI = curDesc.parent.children.indexOf(curDesc);
1960
+ curDesc = curDesc.parent;
1961
+ }
1962
+ }
1963
+ var node = desc.node;
1946
1964
  if (!node) { continue }
1947
1965
  if (node != frag.child(fI - 1)) { break }
1948
1966
  --fI;
1949
1967
  matched.set(desc, fI);
1968
+ matches.push(desc);
1950
1969
  }
1951
- return {index: fI, matched: matched}
1970
+ return {index: fI, matched: matched, matches: matches.reverse()}
1952
1971
  }
1953
1972
 
1954
1973
  function compareSide(a, b) { return a.type.side - b.type.side }
@@ -2062,8 +2081,8 @@ function findTextInFragment(frag, text, from, to) {
2062
2081
  if (!next.isText) { break }
2063
2082
  str += next.text;
2064
2083
  }
2065
- if (pos >= from) {
2066
- var found = str.lastIndexOf(text, to - childStart);
2084
+ if (pos >= from && childStart < to) {
2085
+ var found = str.lastIndexOf(text, to - childStart - 1);
2067
2086
  if (found >= 0 && found + text.length + childStart >= from)
2068
2087
  { return childStart + found }
2069
2088
  }
@@ -2134,9 +2153,13 @@ function selectionToDOM(view, force) {
2134
2153
  if (!editorOwnsSelection(view)) { return }
2135
2154
 
2136
2155
  if (!force && view.mouseDown && view.mouseDown.allowDefault) {
2137
- view.mouseDown.delayedSelectionSync = true;
2138
- view.domObserver.setCurSelection();
2139
- return
2156
+ var domSel = view.root.getSelection(), curSel = view.domObserver.currentSelection;
2157
+ if (domSel.anchorNode && isEquivalentPosition(domSel.anchorNode, domSel.anchorOffset,
2158
+ curSel.anchorNode, curSel.anchorOffset)) {
2159
+ view.mouseDown.delayedSelectionSync = true;
2160
+ view.domObserver.setCurSelection();
2161
+ return
2162
+ }
2140
2163
  }
2141
2164
 
2142
2165
  view.domObserver.disconnectSelection();
@@ -2601,7 +2624,7 @@ function parseBetween(view, from_, to_) {
2601
2624
  topOpen: true,
2602
2625
  from: fromOffset,
2603
2626
  to: toOffset,
2604
- preserveWhitespace: $from.parent.type.spec.code ? "full" : true,
2627
+ preserveWhitespace: $from.parent.type.whitespace == "pre" ? "full" : true,
2605
2628
  editableContent: true,
2606
2629
  findPositions: find,
2607
2630
  ruleFromNode: ruleFromNode,
@@ -2983,7 +3006,8 @@ function parseFromClipboard(view, text, html, plainText, $context) {
2983
3006
  preserveWhitespace: !!(asText || sliceData),
2984
3007
  context: $context,
2985
3008
  ruleFromNode: function ruleFromNode(dom) {
2986
- if (dom.nodeName == "BR" && !dom.nextSibling) { return {ignore: true} }
3009
+ if (dom.nodeName == "BR" && !dom.nextSibling &&
3010
+ dom.parentNode && !inlineParents.test(dom.parentNode.nodeName)) { return {ignore: true} }
2987
3011
  }
2988
3012
  });
2989
3013
  }
@@ -3005,6 +3029,8 @@ function parseFromClipboard(view, text, html, plainText, $context) {
3005
3029
  return slice
3006
3030
  }
3007
3031
 
3032
+ var inlineParents = /^(a|abbr|acronym|b|cite|code|del|em|i|ins|kbd|label|output|q|ruby|s|samp|span|strong|sub|sup|time|u|tt|var)$/i;
3033
+
3008
3034
  // Takes a slice parsed with parseSlice, which means there hasn't been
3009
3035
  // any content-expression checking done on the top nodes, tries to
3010
3036
  // find a parent node in the current context that might fit the nodes,
@@ -3485,9 +3511,14 @@ function dispatchEvent(view, event) {
3485
3511
  editHandlers.keydown = function (view, event) {
3486
3512
  view.shiftKey = event.keyCode == 16 || event.shiftKey;
3487
3513
  if (inOrNearComposition(view, event)) { return }
3488
- if (event.keyCode != 229) { view.domObserver.forceFlush(); }
3489
3514
  view.lastKeyCode = event.keyCode;
3490
3515
  view.lastKeyCodeTime = Date.now();
3516
+ // Suppress enter key events on Chrome Android, because those tend
3517
+ // to be part of a confused sequence of composition events fired,
3518
+ // and handling them eagerly tends to corrupt the input.
3519
+ if (result.android && result.chrome && event.keyCode == 13) { return }
3520
+ if (event.keyCode != 229) { view.domObserver.forceFlush(); }
3521
+
3491
3522
  // On iOS, if we preventDefault enter key presses, the virtual
3492
3523
  // keyboard gets confused. So the hack here is to set a flag that
3493
3524
  // makes the DOM change code recognize that what just happens should
@@ -3872,6 +3903,7 @@ function timestampFromCustomEvent() {
3872
3903
  }
3873
3904
 
3874
3905
  function endComposition(view, forceUpdate) {
3906
+ if (result.android && view.domObserver.flushingSoon >= 0) { return }
3875
3907
  view.domObserver.forceFlush();
3876
3908
  clearComposition(view);
3877
3909
  if (forceUpdate || view.docView.dirty) {
@@ -3962,6 +3994,11 @@ function doPaste(view, text, html, e) {
3962
3994
  }
3963
3995
 
3964
3996
  editHandlers.paste = function (view, e) {
3997
+ // Handling paste from JavaScript during composition is very poorly
3998
+ // handled by browsers, so as a dodgy but preferable kludge, we just
3999
+ // let the browser do its native thing there, except on Android,
4000
+ // where the editor is almost always composing.
4001
+ if (view.composing && !result.android) { return }
3965
4002
  var data = brokenClipboardAPI ? null : e.clipboardData;
3966
4003
  if (data && doPaste(view, data.getData("text/plain"), data.getData("text/html"), e)) { e.preventDefault(); }
3967
4004
  else { capturePaste(view, e); }
@@ -4093,6 +4130,7 @@ handlers.beforeinput = function (view, event) {
4093
4130
  // Very specific hack to deal with backspace sometimes failing on
4094
4131
  // Chrome Android when after an uneditable node.
4095
4132
  if (result.chrome && result.android && event.inputType == "deleteContentBackward") {
4133
+ view.domObserver.flushSoon();
4096
4134
  var domChangeCount = view.domChangeCount;
4097
4135
  setTimeout(function () {
4098
4136
  if (view.domChangeCount != domChangeCount) { return } // Event already had some effect