prosemirror-view 1.23.2 → 1.23.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prosemirror-view",
3
- "version": "1.23.2",
3
+ "version": "1.23.6",
4
4
  "description": "ProseMirror's view component",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.es.js",
@@ -18,7 +18,7 @@
18
18
  "url": "git://github.com/prosemirror/prosemirror-view.git"
19
19
  },
20
20
  "dependencies": {
21
- "prosemirror-model": "^1.14.3",
21
+ "prosemirror-model": "^1.16.0",
22
22
  "prosemirror-state": "^1.0.0",
23
23
  "prosemirror-transform": "^1.1.0"
24
24
  },
package/src/clipboard.js CHANGED
@@ -73,7 +73,8 @@ export function parseFromClipboard(view, text, html, plainText, $context) {
73
73
  preserveWhitespace: !!(asText || sliceData),
74
74
  context: $context,
75
75
  ruleFromNode(dom) {
76
- if (dom.nodeName == "BR" && !dom.nextSibling) return {ignore: true}
76
+ if (dom.nodeName == "BR" && !dom.nextSibling &&
77
+ dom.parentNode && !inlineParents.test(dom.parentNode.nodeName)) return {ignore: true}
77
78
  }
78
79
  })
79
80
  }
@@ -95,6 +96,8 @@ export function parseFromClipboard(view, text, html, plainText, $context) {
95
96
  return slice
96
97
  }
97
98
 
99
+ const 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
100
+
98
101
  // Takes a slice parsed with parseSlice, which means there hasn't been
99
102
  // any content-expression checking done on the top nodes, tries to
100
103
  // find a parent node in the current context that might fit the nodes,
package/src/domchange.js CHANGED
@@ -39,7 +39,7 @@ function parseBetween(view, from_, to_) {
39
39
  topOpen: true,
40
40
  from: fromOffset,
41
41
  to: toOffset,
42
- preserveWhitespace: $from.parent.type.spec.code ? "full" : true,
42
+ preserveWhitespace: $from.parent.type.whitespace == "pre" ? "full" : true,
43
43
  editableContent: true,
44
44
  findPositions: find,
45
45
  ruleFromNode,
package/src/input.js CHANGED
@@ -100,9 +100,14 @@ export function dispatchEvent(view, event) {
100
100
  editHandlers.keydown = (view, event) => {
101
101
  view.shiftKey = event.keyCode == 16 || event.shiftKey
102
102
  if (inOrNearComposition(view, event)) return
103
- if (event.keyCode != 229) view.domObserver.forceFlush()
104
103
  view.lastKeyCode = event.keyCode
105
104
  view.lastKeyCodeTime = Date.now()
105
+ // Suppress enter key events on Chrome Android, because those tend
106
+ // to be part of a confused sequence of composition events fired,
107
+ // and handling them eagerly tends to corrupt the input.
108
+ if (browser.android && browser.chrome && event.keyCode == 13) return
109
+ if (event.keyCode != 229) view.domObserver.forceFlush()
110
+
106
111
  // On iOS, if we preventDefault enter key presses, the virtual
107
112
  // keyboard gets confused. So the hack here is to set a flag that
108
113
  // makes the DOM change code recognize that what just happens should
@@ -477,6 +482,7 @@ function timestampFromCustomEvent() {
477
482
  }
478
483
 
479
484
  export function endComposition(view, forceUpdate) {
485
+ if (browser.android && view.domObserver.flushingSoon >= 0) return
480
486
  view.domObserver.forceFlush()
481
487
  clearComposition(view)
482
488
  if (forceUpdate || view.docView.dirty) {
@@ -564,6 +570,11 @@ function doPaste(view, text, html, e) {
564
570
  }
565
571
 
566
572
  editHandlers.paste = (view, e) => {
573
+ // Handling paste from JavaScript during composition is very poorly
574
+ // handled by browsers, so as a dodgy but preferable kludge, we just
575
+ // let the browser do its native thing there, except on Android,
576
+ // where the editor is almost always composing.
577
+ if (view.composing && !browser.android) return
567
578
  let data = brokenClipboardAPI ? null : e.clipboardData
568
579
  if (data && doPaste(view, data.getData("text/plain"), data.getData("text/html"), e)) e.preventDefault()
569
580
  else capturePaste(view, e)
@@ -696,6 +707,7 @@ handlers.beforeinput = (view, event) => {
696
707
  // Very specific hack to deal with backspace sometimes failing on
697
708
  // Chrome Android when after an uneditable node.
698
709
  if (browser.chrome && browser.android && event.inputType == "deleteContentBackward") {
710
+ view.domObserver.flushSoon()
699
711
  let {domChangeCount} = view
700
712
  setTimeout(() => {
701
713
  if (view.domChangeCount != domChangeCount) return // Event already had some effect
package/src/selection.js CHANGED
@@ -42,10 +42,17 @@ export function selectionToDOM(view, force) {
42
42
 
43
43
  if (!editorOwnsSelection(view)) return
44
44
 
45
- if (!force && view.mouseDown && view.mouseDown.allowDefault) {
46
- view.mouseDown.delayedSelectionSync = true
47
- view.domObserver.setCurSelection()
48
- return
45
+ // The delayed drag selection causes issues with Cell Selections
46
+ // in Safari. And the drag selection delay is to workarond issues
47
+ // which only present in Chrome.
48
+ if (!force && view.mouseDown && view.mouseDown.allowDefault && browser.chrome) {
49
+ let domSel = view.root.getSelection(), curSel = view.domObserver.currentSelection
50
+ if (domSel.anchorNode && isEquivalentPosition(domSel.anchorNode, domSel.anchorOffset,
51
+ curSel.anchorNode, curSel.anchorOffset)) {
52
+ view.mouseDown.delayedSelectionSync = true
53
+ view.domObserver.setCurSelection()
54
+ return
55
+ }
49
56
  }
50
57
 
51
58
  view.domObserver.disconnectSelection()
package/src/viewdesc.js CHANGED
@@ -462,7 +462,8 @@ class ViewDesc {
462
462
  else child.markDirty(from - startInside, to - startInside)
463
463
  return
464
464
  } else {
465
- child.dirty = child.dom == child.contentDOM && child.dom.parentNode == this.contentDOM ? CONTENT_DIRTY : NODE_DIRTY
465
+ child.dirty = child.dom == child.contentDOM && child.dom.parentNode == this.contentDOM && !child.children.length
466
+ ? CONTENT_DIRTY : NODE_DIRTY
466
467
  }
467
468
  }
468
469
  offset = end
@@ -577,7 +578,10 @@ class MarkViewDesc extends ViewDesc {
577
578
  return new MarkViewDesc(parent, mark, spec.dom, spec.contentDOM || spec.dom)
578
579
  }
579
580
 
580
- parseRule() { return {mark: this.mark.type.name, attrs: this.mark.attrs, contentElement: this.contentDOM} }
581
+ parseRule() {
582
+ if ((this.dirty & NODE_DIRTY) || this.mark.type.spec.reparseInView) return null
583
+ return {mark: this.mark.type.name, attrs: this.mark.attrs, contentElement: this.contentDOM}
584
+ }
581
585
 
582
586
  matchesMark(mark) { return this.dirty != NODE_DIRTY && this.mark.eq(mark) }
583
587
 
@@ -667,7 +671,7 @@ class NodeViewDesc extends ViewDesc {
667
671
  // attrs in the dom, that won't be picked up. Not entirely sure
668
672
  // whether this is a problem
669
673
  let rule = {node: this.node.type.name, attrs: this.node.attrs}
670
- if (this.node.type.spec.code) rule.preserveWhitespace = "full"
674
+ if (this.node.type.whitespace == "pre") rule.preserveWhitespace = "full"
671
675
  if (this.contentDOM && !this.contentLost) rule.contentElement = this.contentDOM
672
676
  else rule.getContent = () => this.contentDOM ? Fragment.empty : this.node.content
673
677
  return rule
@@ -1422,8 +1426,8 @@ function findTextInFragment(frag, text, from, to) {
1422
1426
  if (!next.isText) break
1423
1427
  str += next.text
1424
1428
  }
1425
- if (pos >= from) {
1426
- let found = str.lastIndexOf(text, to - childStart)
1429
+ if (pos >= from && childStart < to) {
1430
+ let found = str.lastIndexOf(text, to - childStart - 1)
1427
1431
  if (found >= 0 && found + text.length + childStart >= from)
1428
1432
  return childStart + found
1429
1433
  }