prosemirror-view 1.20.1 → 1.22.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prosemirror-view",
3
- "version": "1.20.1",
3
+ "version": "1.22.0",
4
4
  "description": "ProseMirror's view component",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.es.js",
@@ -24,7 +24,7 @@
24
24
  },
25
25
  "devDependencies": {
26
26
  "ist": "^1.0.0",
27
- "mocha": "^3.0.2",
27
+ "mocha": "^9.1.2",
28
28
  "moduleserve": "^0.7.0",
29
29
  "prosemirror-test-builder": "^1.0.0",
30
30
  "rollup": "^2.26.3",
package/src/browser.js CHANGED
@@ -6,7 +6,6 @@ if (typeof navigator != "undefined" && typeof document != "undefined") {
6
6
  const ie_upto10 = /MSIE \d/.test(navigator.userAgent)
7
7
  const ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent)
8
8
 
9
- result.mac = /Mac/.test(navigator.platform)
10
9
  let ie = result.ie = !!(ie_upto10 || ie_11up || ie_edge)
11
10
  result.ie_version = ie_upto10 ? document.documentMode || 6 : ie_11up ? +ie_11up[1] : ie_edge ? +ie_edge[1] : null
12
11
  result.gecko = !ie && /gecko\/(\d+)/i.test(navigator.userAgent)
@@ -17,6 +16,7 @@ if (typeof navigator != "undefined" && typeof document != "undefined") {
17
16
  // Is true for both iOS and iPadOS for convenience
18
17
  result.safari = !ie && /Apple Computer/.test(navigator.vendor)
19
18
  result.ios = result.safari && (/Mobile\/\w+/.test(navigator.userAgent) || navigator.maxTouchPoints > 2)
19
+ result.mac = result.ios || /Mac/.test(navigator.platform)
20
20
  result.android = /Android \d/.test(navigator.userAgent)
21
21
  result.webkit = "webkitFontSmoothing" in document.documentElement.style
22
22
  result.webkit_version = result.webkit && +(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent) || [0, 0])[1]
package/src/clipboard.js CHANGED
@@ -46,7 +46,7 @@ export function parseFromClipboard(view, text, html, plainText, $context) {
46
46
  let asText = text && (plainText || inCode || !html)
47
47
  if (asText) {
48
48
  view.someProp("transformPastedText", f => { text = f(text, inCode || plainText) })
49
- if (inCode) return new Slice(Fragment.from(view.state.schema.text(text.replace(/\r\n?/g, "\n"))), 0, 0)
49
+ if (inCode) return text ? new Slice(Fragment.from(view.state.schema.text(text.replace(/\r\n?/g, "\n"))), 0, 0) : Slice.empty
50
50
  let parsed = view.someProp("clipboardTextParser", f => f(text, $context, plainText))
51
51
  if (parsed) {
52
52
  slice = parsed
@@ -54,8 +54,9 @@ export function parseFromClipboard(view, text, html, plainText, $context) {
54
54
  let marks = $context.marks()
55
55
  let {schema} = view.state, serializer = DOMSerializer.fromSchema(schema)
56
56
  dom = document.createElement("div")
57
- text.trim().split(/(?:\r\n?|\n)+/).forEach(block => {
58
- dom.appendChild(document.createElement("p")).appendChild(serializer.serializeNode(schema.text(block, marks)))
57
+ text.split(/(?:\r\n?|\n)+/).forEach(block => {
58
+ let p = dom.appendChild(document.createElement("p"))
59
+ if (block) p.appendChild(serializer.serializeNode(schema.text(block, marks)))
59
60
  })
60
61
  }
61
62
  } else {
@@ -70,10 +71,19 @@ export function parseFromClipboard(view, text, html, plainText, $context) {
70
71
  let parser = view.someProp("clipboardParser") || view.someProp("domParser") || DOMParser.fromSchema(view.state.schema)
71
72
  slice = parser.parseSlice(dom, {preserveWhitespace: !!(asText || sliceData), context: $context})
72
73
  }
73
- if (sliceData)
74
+ if (sliceData) {
74
75
  slice = addContext(closeSlice(slice, +sliceData[1], +sliceData[2]), sliceData[3])
75
- else // HTML wasn't created by ProseMirror. Make sure top-level siblings are coherent
76
- slice = Slice.maxOpen(normalizeSiblings(slice.content, $context), false)
76
+ } else { // HTML wasn't created by ProseMirror. Make sure top-level siblings are coherent
77
+ slice = Slice.maxOpen(normalizeSiblings(slice.content, $context), true)
78
+ if (slice.openStart || slice.openEnd) {
79
+ let openStart = 0, openEnd = 0
80
+ for (let node = slice.content.firstChild; openStart < slice.openStart && !node.type.spec.isolating;
81
+ openStart++, node = node.firstChild) {}
82
+ for (let node = slice.content.lastChild; openEnd < slice.openEnd && !node.type.spec.isolating;
83
+ openEnd++, node = node.lastChild) {}
84
+ slice = closeSlice(slice, openStart, openEnd)
85
+ }
86
+ }
77
87
 
78
88
  view.someProp("transformPasted", f => { slice = f(slice) })
79
89
  return slice
package/src/decoration.js CHANGED
@@ -25,6 +25,10 @@ class WidgetType {
25
25
  (this.spec.key && this.spec.key == other.spec.key ||
26
26
  this.toDOM == other.toDOM && compareObjs(this.spec, other.spec)))
27
27
  }
28
+
29
+ destroy(node) {
30
+ if (this.spec.destroy) this.spec.destroy(node)
31
+ }
28
32
  }
29
33
 
30
34
  class InlineType {
@@ -152,6 +156,10 @@ export class Decoration {
152
156
  // key are interchangeable—if widgets differ in, for example,
153
157
  // the behavior of some event handler, they should get
154
158
  // different keys.
159
+ //
160
+ // destroy:: ?(node: dom.Node)
161
+ // Called when the widget decoration is removed as a result of
162
+ // mapping
155
163
  static widget(pos, toDOM, spec) {
156
164
  return new Decoration(pos, pos, new WidgetType(toDOM, spec))
157
165
  }
package/src/domcoords.js CHANGED
@@ -230,19 +230,19 @@ function elementFromPoint(element, coords, box) {
230
230
 
231
231
  // Given an x,y position on the editor, get the position in the document.
232
232
  export function posAtCoords(view, coords) {
233
- let root = view.root, node, offset
234
- if (root.caretPositionFromPoint) {
233
+ let doc = view.dom.ownerDocument, node, offset
234
+ if (doc.caretPositionFromPoint) {
235
235
  try { // Firefox throws for this call in hard-to-predict circumstances (#994)
236
- let pos = root.caretPositionFromPoint(coords.left, coords.top)
236
+ let pos = doc.caretPositionFromPoint(coords.left, coords.top)
237
237
  if (pos) ({offsetNode: node, offset} = pos)
238
238
  } catch (_) {}
239
239
  }
240
- if (!node && root.caretRangeFromPoint) {
241
- let range = root.caretRangeFromPoint(coords.left, coords.top)
240
+ if (!node && doc.caretRangeFromPoint) {
241
+ let range = doc.caretRangeFromPoint(coords.left, coords.top)
242
242
  if (range) ({startContainer: node, startOffset: offset} = range)
243
243
  }
244
244
 
245
- let elt = root.elementFromPoint(coords.left, coords.top + 1), pos
245
+ let elt = (view.root.elementFromPoint ? view.root : doc).elementFromPoint(coords.left, coords.top + 1), pos
246
246
  if (!elt || !view.dom.contains(elt.nodeType != 1 ? elt.parentNode : elt)) {
247
247
  let box = view.dom.getBoundingClientRect()
248
248
  if (!inRect(coords, box)) return null
package/src/index.js CHANGED
@@ -404,6 +404,9 @@ function computeDocDeco(view) {
404
404
  if (value) for (let attr in value) {
405
405
  if (attr == "class")
406
406
  attrs.class += " " + value[attr]
407
+ if (attr == "style") {
408
+ attrs.style = (attrs.style ? attrs.style + ";" : "") + value[attr]
409
+ }
407
410
  else if (!attrs[attr] && attr != "contenteditable" && attr != "nodeName")
408
411
  attrs[attr] = String(value[attr])
409
412
  }
@@ -639,7 +642,7 @@ function checkStateComponent(plugin) {
639
642
  // view](#state.PluginSpec.view) and
640
643
  // [props](#state.PluginSpec.props). Passing plugins with a state
641
644
  // component (a [state field](#state.PluginSpec.state) field or a
642
- // [transaction)[#state.PluginSpec.filterTransaction] filter or
645
+ // [transaction](#state.PluginSpec.filterTransaction) filter or
643
646
  // appender) will result in an error, since such plugins must be
644
647
  // present in the state to work.
645
648
  //
package/src/viewdesc.js CHANGED
@@ -526,6 +526,11 @@ class WidgetViewDesc extends ViewDesc {
526
526
  return mutation.type != "selection" || this.widget.spec.ignoreSelection
527
527
  }
528
528
 
529
+ destroy() {
530
+ this.widget.type.destroy(this.dom)
531
+ super.destroy()
532
+ }
533
+
529
534
  get domAtom() { return true }
530
535
  }
531
536
 
@@ -1038,6 +1043,8 @@ function patchAttributes(dom, prev, cur) {
1038
1043
  dom.classList.remove(prevList[i])
1039
1044
  for (let i = 0; i < curList.length; i++) if (prevList.indexOf(curList[i]) == -1)
1040
1045
  dom.classList.add(curList[i])
1046
+ if (dom.classList.length == 0)
1047
+ dom.removeAttribute("class")
1041
1048
  }
1042
1049
  if (prev.style != cur.style) {
1043
1050
  if (prev.style) {
@@ -1147,9 +1154,11 @@ class ViewTreeUpdater {
1147
1154
  findNodeMatch(node, outerDeco, innerDeco, index) {
1148
1155
  let children = this.top.children, found = -1
1149
1156
  if (index >= this.preMatch.index) {
1150
- for (let i = this.index; i < children.length; i++) if (children[i].matchesNode(node, outerDeco, innerDeco)) {
1151
- found = i
1152
- break
1157
+ for (let i = this.index; i < children.length; i++) {
1158
+ if (this.preMatch.matched.get(children[i]) == index) {
1159
+ if (children[i].matchesNode(node, outerDeco, innerDeco)) found = i
1160
+ break
1161
+ }
1153
1162
  }
1154
1163
  } else {
1155
1164
  for (let i = this.index, e = Math.min(children.length, i + 1); i < e; i++) {
@@ -1258,6 +1267,7 @@ class ViewTreeUpdater {
1258
1267
  } else {
1259
1268
  let dom = document.createElement(nodeName)
1260
1269
  if (nodeName == "IMG") dom.className = "ProseMirror-separator"
1270
+ if (nodeName == "BR") dom.className = "ProseMirror-trailingBreak"
1261
1271
  this.top.children.splice(this.index++, 0, new TrailingHackViewDesc(this.top, nothing, dom, null))
1262
1272
  this.changed = true
1263
1273
  }