prosemirror-view 1.28.0 → 1.28.2

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,15 @@
1
+ ## 1.28.2 (2022-09-24)
2
+
3
+ ### Bug fixes
4
+
5
+ Avoid a crash in selection updates in a hidden editor on Safari.
6
+
7
+ ## 1.28.1 (2022-09-21)
8
+
9
+ ### Bug fixes
10
+
11
+ Fix an issue where the editor would reset its scroll position to the top of the document for any state reconfiguration, even if the document was unchanged.
12
+
1
13
  ## 1.28.0 (2022-09-09)
2
14
 
3
15
  ### Bug fixes
package/dist/index.cjs CHANGED
@@ -1102,7 +1102,12 @@ var ViewDesc = function () {
1102
1102
  domSel.collapse(anchorDOM.node, anchorDOM.offset);
1103
1103
 
1104
1104
  try {
1105
- if (anchor != head) domSel.extend(headDOM.node, headDOM.offset);
1105
+ if (anchor != head) {
1106
+ try {
1107
+ domSel.extend(headDOM.node, headDOM.offset);
1108
+ } catch (_) {}
1109
+ }
1110
+
1106
1111
  domSelExtended = true;
1107
1112
  } catch (err) {
1108
1113
  if (!(err instanceof DOMException)) throw err;
@@ -5423,6 +5428,7 @@ var EditorView = function () {
5423
5428
  key: "update",
5424
5429
  value: function update(props) {
5425
5430
  if (props.handleDOMEvents != this._props.handleDOMEvents) ensureListeners(this);
5431
+ var prevProps = this._props;
5426
5432
  this._props = props;
5427
5433
 
5428
5434
  if (props.plugins) {
@@ -5430,7 +5436,7 @@ var EditorView = function () {
5430
5436
  this.directPlugins = props.plugins;
5431
5437
  }
5432
5438
 
5433
- this.updateStateInner(props.state, true);
5439
+ this.updateStateInner(props.state, prevProps);
5434
5440
  }
5435
5441
  }, {
5436
5442
  key: "setProps",
@@ -5452,11 +5458,11 @@ var EditorView = function () {
5452
5458
  }, {
5453
5459
  key: "updateState",
5454
5460
  value: function updateState(state) {
5455
- this.updateStateInner(state, this.state.plugins != state.plugins);
5461
+ this.updateStateInner(state, this._props);
5456
5462
  }
5457
5463
  }, {
5458
5464
  key: "updateStateInner",
5459
- value: function updateStateInner(state, reconfigured) {
5465
+ value: function updateStateInner(state, prevProps) {
5460
5466
  var prev = this.state,
5461
5467
  redraw = false,
5462
5468
  updateSel = false;
@@ -5467,15 +5473,18 @@ var EditorView = function () {
5467
5473
  }
5468
5474
 
5469
5475
  this.state = state;
5476
+ var pluginsChanged = prev.plugins != state.plugins || this._props.plugins != prevProps.plugins;
5470
5477
 
5471
- if (reconfigured) {
5478
+ if (pluginsChanged || this._props.plugins != prevProps.plugins || this._props.nodeViews != prevProps.nodeViews) {
5472
5479
  var nodeViews = buildNodeViews(this);
5473
5480
 
5474
5481
  if (changedNodeViews(nodeViews, this.nodeViews)) {
5475
5482
  this.nodeViews = nodeViews;
5476
5483
  redraw = true;
5477
5484
  }
5485
+ }
5478
5486
 
5487
+ if (pluginsChanged || prevProps.handleDOMEvents != this._props.handleDOMEvents) {
5479
5488
  ensureListeners(this);
5480
5489
  }
5481
5490
 
@@ -5483,7 +5492,7 @@ var EditorView = function () {
5483
5492
  updateCursorWrapper(this);
5484
5493
  var innerDeco = viewDecorations(this),
5485
5494
  outerDeco = computeDocDeco(this);
5486
- var scroll = reconfigured ? "reset" : state.scrollToSelection > prev.scrollToSelection ? "to selection" : "preserve";
5495
+ var scroll = prev.plugins != state.plugins && !prev.doc.eq(state.doc) ? "reset" : state.scrollToSelection > prev.scrollToSelection ? "to selection" : "preserve";
5487
5496
  var updateDoc = redraw || !this.docView.matchesNode(state.doc, outerDeco, innerDeco);
5488
5497
  if (updateDoc || !state.selection.eq(prev.selection)) updateSel = true;
5489
5498
  var oldScrollPos = scroll == "preserve" && updateSel && this.dom.style.overflowAnchor == null && storeScrollPos(this);
package/dist/index.js CHANGED
@@ -957,8 +957,14 @@ class ViewDesc {
957
957
  if ((domSel.extend || anchor == head) && !brKludge) {
958
958
  domSel.collapse(anchorDOM.node, anchorDOM.offset);
959
959
  try {
960
- if (anchor != head)
961
- domSel.extend(headDOM.node, headDOM.offset);
960
+ if (anchor != head) {
961
+ // This can crash on Safari if the editor is hidden, and
962
+ // there was no selection. (#1308)
963
+ try {
964
+ domSel.extend(headDOM.node, headDOM.offset);
965
+ }
966
+ catch (_) { }
967
+ }
962
968
  domSelExtended = true;
963
969
  }
964
970
  catch (err) {
@@ -4907,12 +4913,13 @@ class EditorView {
4907
4913
  update(props) {
4908
4914
  if (props.handleDOMEvents != this._props.handleDOMEvents)
4909
4915
  ensureListeners(this);
4916
+ let prevProps = this._props;
4910
4917
  this._props = props;
4911
4918
  if (props.plugins) {
4912
4919
  props.plugins.forEach(checkStateComponent);
4913
4920
  this.directPlugins = props.plugins;
4914
4921
  }
4915
- this.updateStateInner(props.state, true);
4922
+ this.updateStateInner(props.state, prevProps);
4916
4923
  }
4917
4924
  /**
4918
4925
  Update the view by updating existing props object with the object
@@ -4933,9 +4940,9 @@ class EditorView {
4933
4940
  other props.
4934
4941
  */
4935
4942
  updateState(state) {
4936
- this.updateStateInner(state, this.state.plugins != state.plugins);
4943
+ this.updateStateInner(state, this._props);
4937
4944
  }
4938
- updateStateInner(state, reconfigured) {
4945
+ updateStateInner(state, prevProps) {
4939
4946
  let prev = this.state, redraw = false, updateSel = false;
4940
4947
  // When stored marks are added, stop composition, so that they can
4941
4948
  // be displayed.
@@ -4944,18 +4951,21 @@ class EditorView {
4944
4951
  updateSel = true;
4945
4952
  }
4946
4953
  this.state = state;
4947
- if (reconfigured) {
4954
+ let pluginsChanged = prev.plugins != state.plugins || this._props.plugins != prevProps.plugins;
4955
+ if (pluginsChanged || this._props.plugins != prevProps.plugins || this._props.nodeViews != prevProps.nodeViews) {
4948
4956
  let nodeViews = buildNodeViews(this);
4949
4957
  if (changedNodeViews(nodeViews, this.nodeViews)) {
4950
4958
  this.nodeViews = nodeViews;
4951
4959
  redraw = true;
4952
4960
  }
4961
+ }
4962
+ if (pluginsChanged || prevProps.handleDOMEvents != this._props.handleDOMEvents) {
4953
4963
  ensureListeners(this);
4954
4964
  }
4955
4965
  this.editable = getEditable(this);
4956
4966
  updateCursorWrapper(this);
4957
4967
  let innerDeco = viewDecorations(this), outerDeco = computeDocDeco(this);
4958
- let scroll = reconfigured ? "reset"
4968
+ let scroll = prev.plugins != state.plugins && !prev.doc.eq(state.doc) ? "reset"
4959
4969
  : state.scrollToSelection > prev.scrollToSelection ? "to selection" : "preserve";
4960
4970
  let updateDoc = redraw || !this.docView.matchesNode(state.doc, outerDeco, innerDeco);
4961
4971
  if (updateDoc || !state.selection.eq(prev.selection))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prosemirror-view",
3
- "version": "1.28.0",
3
+ "version": "1.28.2",
4
4
  "description": "ProseMirror's view component",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
package/src/index.ts CHANGED
@@ -124,12 +124,13 @@ export class EditorView {
124
124
  /// the DOM.
125
125
  update(props: DirectEditorProps) {
126
126
  if (props.handleDOMEvents != this._props.handleDOMEvents) ensureListeners(this)
127
+ let prevProps = this._props
127
128
  this._props = props
128
129
  if (props.plugins) {
129
130
  props.plugins.forEach(checkStateComponent)
130
131
  this.directPlugins = props.plugins
131
132
  }
132
- this.updateStateInner(props.state, true)
133
+ this.updateStateInner(props.state, prevProps)
133
134
  }
134
135
 
135
136
  /// Update the view by updating existing props object with the object
@@ -146,10 +147,10 @@ export class EditorView {
146
147
  /// Update the editor's `state` prop, without touching any of the
147
148
  /// other props.
148
149
  updateState(state: EditorState) {
149
- this.updateStateInner(state, this.state.plugins != state.plugins)
150
+ this.updateStateInner(state, this._props)
150
151
  }
151
152
 
152
- private updateStateInner(state: EditorState, reconfigured: boolean) {
153
+ private updateStateInner(state: EditorState, prevProps: DirectEditorProps) {
153
154
  let prev = this.state, redraw = false, updateSel = false
154
155
  // When stored marks are added, stop composition, so that they can
155
156
  // be displayed.
@@ -158,12 +159,15 @@ export class EditorView {
158
159
  updateSel = true
159
160
  }
160
161
  this.state = state
161
- if (reconfigured) {
162
+ let pluginsChanged = prev.plugins != state.plugins || this._props.plugins != prevProps.plugins
163
+ if (pluginsChanged || this._props.plugins != prevProps.plugins || this._props.nodeViews != prevProps.nodeViews) {
162
164
  let nodeViews = buildNodeViews(this)
163
165
  if (changedNodeViews(nodeViews, this.nodeViews)) {
164
166
  this.nodeViews = nodeViews
165
167
  redraw = true
166
168
  }
169
+ }
170
+ if (pluginsChanged || prevProps.handleDOMEvents != this._props.handleDOMEvents) {
167
171
  ensureListeners(this)
168
172
  }
169
173
 
@@ -171,7 +175,7 @@ export class EditorView {
171
175
  updateCursorWrapper(this)
172
176
  let innerDeco = viewDecorations(this), outerDeco = computeDocDeco(this)
173
177
 
174
- let scroll = reconfigured ? "reset"
178
+ let scroll = prev.plugins != state.plugins && !prev.doc.eq(state.doc) ? "reset"
175
179
  : (state as any).scrollToSelection > (prev as any).scrollToSelection ? "to selection" : "preserve"
176
180
  let updateDoc = redraw || !this.docView.matchesNode(state.doc, outerDeco, innerDeco)
177
181
  if (updateDoc || !state.selection.eq(prev.selection)) updateSel = true
package/src/viewdesc.ts CHANGED
@@ -419,7 +419,12 @@ export class ViewDesc {
419
419
  if ((domSel.extend || anchor == head) && !brKludge) {
420
420
  domSel.collapse(anchorDOM.node, anchorDOM.offset)
421
421
  try {
422
- if (anchor != head) domSel.extend(headDOM.node, headDOM.offset)
422
+ if (anchor != head) {
423
+ // This can crash on Safari if the editor is hidden, and
424
+ // there was no selection. (#1308)
425
+ try { domSel.extend(headDOM.node, headDOM.offset) }
426
+ catch (_) {}
427
+ }
423
428
  domSelExtended = true
424
429
  } catch (err) {
425
430
  // In some cases with Chrome the selection is empty after calling