prosemirror-view 1.34.2 → 1.34.3

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,11 @@
1
+ ## 1.34.3 (2024-09-19)
2
+
3
+ ### Bug fixes
4
+
5
+ Fix an issue that would, during some types of document updates, leave the document DOM in an improper form.
6
+
7
+ Handle the case where drag-selecting in Firefox creates a selection with multiple distinct ranges.
8
+
1
9
  ## 1.34.2 (2024-09-03)
2
10
 
3
11
  ### Bug fixes
package/dist/index.cjs CHANGED
@@ -1840,6 +1840,7 @@ var ViewTreeUpdater = function () {
1840
1840
  this.index++;
1841
1841
  return true;
1842
1842
  } else if (!locked && (updated = this.recreateWrapper(next, node, outerDeco, innerDeco, view, pos))) {
1843
+ this.destroyBetween(this.index, i);
1843
1844
  this.top.children[this.index] = updated;
1844
1845
  if (updated.contentDOM) {
1845
1846
  updated.dirty = CONTENT_DIRTY;
@@ -1858,7 +1859,7 @@ var ViewTreeUpdater = function () {
1858
1859
  }, {
1859
1860
  key: "recreateWrapper",
1860
1861
  value: function recreateWrapper(next, node, outerDeco, innerDeco, view, pos) {
1861
- if (next.dirty || node.isAtom || !next.children.length || !next.node.content.eq(node.content)) return null;
1862
+ if (next.dirty || node.isAtom || !next.children.length || !next.node.content.eq(node.content) || !sameOuterDeco(outerDeco, next.outerDeco) || !innerDeco.eq(next.innerDeco)) return null;
1862
1863
  var wrapper = NodeViewDesc.create(this.top, node, outerDeco, innerDeco, view, pos);
1863
1864
  if (wrapper.contentDOM) {
1864
1865
  wrapper.children = next.children;
@@ -2105,10 +2106,10 @@ function selectionFromDOM(view) {
2105
2106
  var head = view.docView.posFromDOM(domSel.focusNode, domSel.focusOffset, 1);
2106
2107
  if (head < 0) return null;
2107
2108
  var $head = doc.resolve(head),
2108
- $anchor,
2109
+ anchor,
2109
2110
  selection;
2110
2111
  if (selectionCollapsed(domSel)) {
2111
- $anchor = $head;
2112
+ anchor = head;
2112
2113
  while (nearestDesc && !nearestDesc.node) nearestDesc = nearestDesc.parent;
2113
2114
  var nearestDescNode = nearestDesc.node;
2114
2115
  if (nearestDesc && nearestDescNode.isAtom && prosemirrorState.NodeSelection.isSelectable(nearestDescNode) && nearestDesc.parent && !(nearestDescNode.isInline && isOnEdge(domSel.focusNode, domSel.focusOffset, nearestDesc.dom))) {
@@ -2116,10 +2117,26 @@ function selectionFromDOM(view) {
2116
2117
  selection = new prosemirrorState.NodeSelection(head == pos ? $head : doc.resolve(pos));
2117
2118
  }
2118
2119
  } else {
2119
- var anchor = view.docView.posFromDOM(domSel.anchorNode, domSel.anchorOffset, 1);
2120
+ if (domSel instanceof view.dom.ownerDocument.defaultView.Selection && domSel.rangeCount > 1) {
2121
+ var min = head,
2122
+ max = head;
2123
+ for (var i = 0; i < domSel.rangeCount; i++) {
2124
+ var range = domSel.getRangeAt(i);
2125
+ min = Math.min(min, view.docView.posFromDOM(range.startContainer, range.startOffset, 1));
2126
+ max = Math.max(max, view.docView.posFromDOM(range.endContainer, range.endOffset, -1));
2127
+ }
2128
+ if (min < 0) return null;
2129
+ var _ref3 = max == view.state.selection.anchor ? [max, min] : [min, max];
2130
+ var _ref4 = _slicedToArray(_ref3, 2);
2131
+ anchor = _ref4[0];
2132
+ head = _ref4[1];
2133
+ $head = doc.resolve(head);
2134
+ } else {
2135
+ anchor = view.docView.posFromDOM(domSel.anchorNode, domSel.anchorOffset, 1);
2136
+ }
2120
2137
  if (anchor < 0) return null;
2121
- $anchor = doc.resolve(anchor);
2122
2138
  }
2139
+ var $anchor = doc.resolve(anchor);
2123
2140
  if (!selection) {
2124
2141
  var bias = origin == "pointer" || view.state.selection.head < $head.pos && !inWidget ? 1 : -1;
2125
2142
  selection = selectionBetween(view, $anchor, $head, bias);
@@ -4417,11 +4434,11 @@ function rangeToSelectionRange(view, range) {
4417
4434
  focusOffset = range.endOffset;
4418
4435
  var currentAnchor = view.domAtPos(view.state.selection.anchor);
4419
4436
  if (isEquivalentPosition(currentAnchor.node, currentAnchor.offset, focusNode, focusOffset)) {
4420
- var _ref3 = [focusNode, focusOffset, anchorNode, anchorOffset];
4421
- anchorNode = _ref3[0];
4422
- anchorOffset = _ref3[1];
4423
- focusNode = _ref3[2];
4424
- focusOffset = _ref3[3];
4437
+ var _ref5 = [focusNode, focusOffset, anchorNode, anchorOffset];
4438
+ anchorNode = _ref5[0];
4439
+ anchorOffset = _ref5[1];
4440
+ focusNode = _ref5[2];
4441
+ focusOffset = _ref5[3];
4425
4442
  }
4426
4443
  return {
4427
4444
  anchorNode: anchorNode,
package/dist/index.js CHANGED
@@ -1870,6 +1870,7 @@ class ViewTreeUpdater {
1870
1870
  return true;
1871
1871
  }
1872
1872
  else if (!locked && (updated = this.recreateWrapper(next, node, outerDeco, innerDeco, view, pos))) {
1873
+ this.destroyBetween(this.index, i);
1873
1874
  this.top.children[this.index] = updated;
1874
1875
  if (updated.contentDOM) {
1875
1876
  updated.dirty = CONTENT_DIRTY;
@@ -1889,7 +1890,8 @@ class ViewTreeUpdater {
1889
1890
  // identical content, move over its children.
1890
1891
  recreateWrapper(next, node, outerDeco, innerDeco, view, pos) {
1891
1892
  if (next.dirty || node.isAtom || !next.children.length ||
1892
- !next.node.content.eq(node.content))
1893
+ !next.node.content.eq(node.content) ||
1894
+ !sameOuterDeco(outerDeco, next.outerDeco) || !innerDeco.eq(next.innerDeco))
1893
1895
  return null;
1894
1896
  let wrapper = NodeViewDesc.create(this.top, node, outerDeco, innerDeco, view, pos);
1895
1897
  if (wrapper.contentDOM) {
@@ -2160,9 +2162,9 @@ function selectionFromDOM(view, origin = null) {
2160
2162
  let head = view.docView.posFromDOM(domSel.focusNode, domSel.focusOffset, 1);
2161
2163
  if (head < 0)
2162
2164
  return null;
2163
- let $head = doc.resolve(head), $anchor, selection;
2165
+ let $head = doc.resolve(head), anchor, selection;
2164
2166
  if (selectionCollapsed(domSel)) {
2165
- $anchor = $head;
2167
+ anchor = head;
2166
2168
  while (nearestDesc && !nearestDesc.node)
2167
2169
  nearestDesc = nearestDesc.parent;
2168
2170
  let nearestDescNode = nearestDesc.node;
@@ -2173,11 +2175,25 @@ function selectionFromDOM(view, origin = null) {
2173
2175
  }
2174
2176
  }
2175
2177
  else {
2176
- let anchor = view.docView.posFromDOM(domSel.anchorNode, domSel.anchorOffset, 1);
2178
+ if (domSel instanceof view.dom.ownerDocument.defaultView.Selection && domSel.rangeCount > 1) {
2179
+ let min = head, max = head;
2180
+ for (let i = 0; i < domSel.rangeCount; i++) {
2181
+ let range = domSel.getRangeAt(i);
2182
+ min = Math.min(min, view.docView.posFromDOM(range.startContainer, range.startOffset, 1));
2183
+ max = Math.max(max, view.docView.posFromDOM(range.endContainer, range.endOffset, -1));
2184
+ }
2185
+ if (min < 0)
2186
+ return null;
2187
+ [anchor, head] = max == view.state.selection.anchor ? [max, min] : [min, max];
2188
+ $head = doc.resolve(head);
2189
+ }
2190
+ else {
2191
+ anchor = view.docView.posFromDOM(domSel.anchorNode, domSel.anchorOffset, 1);
2192
+ }
2177
2193
  if (anchor < 0)
2178
2194
  return null;
2179
- $anchor = doc.resolve(anchor);
2180
2195
  }
2196
+ let $anchor = doc.resolve(anchor);
2181
2197
  if (!selection) {
2182
2198
  let bias = origin == "pointer" || (view.state.selection.head < $head.pos && !inWidget) ? 1 : -1;
2183
2199
  selection = selectionBetween(view, $anchor, $head, bias);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prosemirror-view",
3
- "version": "1.34.2",
3
+ "version": "1.34.3",
4
4
  "description": "ProseMirror's view component",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
package/src/selection.ts CHANGED
@@ -12,9 +12,9 @@ export function selectionFromDOM(view: EditorView, origin: string | null = null)
12
12
  let nearestDesc = view.docView.nearestDesc(domSel.focusNode), inWidget = nearestDesc && nearestDesc.size == 0
13
13
  let head = view.docView.posFromDOM(domSel.focusNode, domSel.focusOffset, 1)
14
14
  if (head < 0) return null
15
- let $head = doc.resolve(head), $anchor, selection
15
+ let $head = doc.resolve(head), anchor, selection
16
16
  if (selectionCollapsed(domSel)) {
17
- $anchor = $head
17
+ anchor = head
18
18
  while (nearestDesc && !nearestDesc.node) nearestDesc = nearestDesc.parent
19
19
  let nearestDescNode = (nearestDesc as NodeViewDesc).node
20
20
  if (nearestDesc && nearestDescNode.isAtom && NodeSelection.isSelectable(nearestDescNode) && nearestDesc.parent
@@ -23,10 +23,22 @@ export function selectionFromDOM(view: EditorView, origin: string | null = null)
23
23
  selection = new NodeSelection(head == pos ? $head : doc.resolve(pos))
24
24
  }
25
25
  } else {
26
- let anchor = view.docView.posFromDOM(domSel.anchorNode!, domSel.anchorOffset, 1)
26
+ if (domSel instanceof view.dom.ownerDocument.defaultView!.Selection && domSel.rangeCount > 1) {
27
+ let min = head, max = head
28
+ for (let i = 0; i < domSel.rangeCount; i++) {
29
+ let range = domSel.getRangeAt(i)
30
+ min = Math.min(min, view.docView.posFromDOM(range.startContainer, range.startOffset, 1))
31
+ max = Math.max(max, view.docView.posFromDOM(range.endContainer, range.endOffset, -1))
32
+ }
33
+ if (min < 0) return null
34
+ ;[anchor, head] = max == view.state.selection.anchor ? [max, min] : [min, max]
35
+ $head = doc.resolve(head)
36
+ } else {
37
+ anchor = view.docView.posFromDOM(domSel.anchorNode!, domSel.anchorOffset, 1)
38
+ }
27
39
  if (anchor < 0) return null
28
- $anchor = doc.resolve(anchor)
29
40
  }
41
+ let $anchor = doc.resolve(anchor)
30
42
 
31
43
  if (!selection) {
32
44
  let bias = origin == "pointer" || (view.state.selection.head < $head.pos && !inWidget) ? 1 : -1
package/src/viewdesc.ts CHANGED
@@ -1249,6 +1249,7 @@ class ViewTreeUpdater {
1249
1249
  this.index++
1250
1250
  return true
1251
1251
  } else if (!locked && (updated = this.recreateWrapper(next, node, outerDeco, innerDeco, view, pos))) {
1252
+ this.destroyBetween(this.index, i)
1252
1253
  this.top.children[this.index] = updated
1253
1254
  if (updated.contentDOM) {
1254
1255
  updated.dirty = CONTENT_DIRTY
@@ -1270,7 +1271,8 @@ class ViewTreeUpdater {
1270
1271
  recreateWrapper(next: NodeViewDesc, node: Node, outerDeco: readonly Decoration[], innerDeco: DecorationSource,
1271
1272
  view: EditorView, pos: number) {
1272
1273
  if (next.dirty || node.isAtom || !next.children.length ||
1273
- !next.node.content.eq(node.content)) return null
1274
+ !next.node.content.eq(node.content) ||
1275
+ !sameOuterDeco(outerDeco, next.outerDeco) || !innerDeco.eq(next.innerDeco)) return null
1274
1276
  let wrapper = NodeViewDesc.create(this.top, node, outerDeco, innerDeco, view, pos)
1275
1277
  if (wrapper.contentDOM) {
1276
1278
  wrapper.children = next.children