prosemirror-view 1.26.4 → 1.27.1

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,31 @@
1
+ ## 1.27.1 (2022-08-16)
2
+
3
+ ### Bug fixes
4
+
5
+ Fix a bug in `DecorationSet.map` that could cause invalid mapping when step maps contain multiple replaced ranges.
6
+
7
+ Make sure that when the editor receives focus via tab or calling `.focus()` on its DOM element, the existing selection is restored.
8
+
9
+ Avoid collapsing of whitespace in Firefox when the editor doesn't have `white-space` set to `pre-wrap`.
10
+
11
+ ## 1.27.0 (2022-07-20)
12
+
13
+ ### Bug fixes
14
+
15
+ Fix a bug that in some situations caused composition to be disrupted on Chrome due to a workaround for another browser issue activating inappropriately.
16
+
17
+ ### New features
18
+
19
+ `EditorProps` now takes an optional type parameter that indicates the type of `this` in prop functions.
20
+
21
+ ## 1.26.5 (2022-07-07)
22
+
23
+ ### Bug fixes
24
+
25
+ Fix an issue where a composition happening at the same time as widget insertion/removal could corrupt the rendered DOM.
26
+
27
+ Fix a problem where `coordsAtPos` would look inside the DOM for atomic nodes, and sometimes return very odd positions that way.
28
+
1
29
  ## 1.26.4 (2022-07-04)
2
30
 
3
31
  ### Bug fixes
package/dist/index.cjs CHANGED
@@ -495,7 +495,8 @@ var BIDI = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;
495
495
  function _coordsAtPos(view, pos, side) {
496
496
  var _view$docView$domFrom = view.docView.domFromPos(pos, side < 0 ? -1 : 1),
497
497
  node = _view$docView$domFrom.node,
498
- offset = _view$docView$domFrom.offset;
498
+ offset = _view$docView$domFrom.offset,
499
+ atom = _view$docView$domFrom.atom;
499
500
 
500
501
  var supportEmptyRange = webkit || gecko;
501
502
 
@@ -530,17 +531,19 @@ function _coordsAtPos(view, pos, side) {
530
531
  to++;
531
532
  }
532
533
 
533
- return flattenV(singleRect(textRange(node, from, to), takeSide), takeSide < 0);
534
+ return flattenV(singleRect(textRange(node, from, to), 1), takeSide < 0);
534
535
  }
535
536
  }
536
537
 
537
- if (!view.state.doc.resolve(pos).parent.inlineContent) {
538
- if (offset && (side < 0 || offset == nodeSize(node))) {
538
+ var $dom = view.state.doc.resolve(pos - (atom || 0));
539
+
540
+ if (!$dom.parent.inlineContent) {
541
+ if (atom == null && offset && (side < 0 || offset == nodeSize(node))) {
539
542
  var before = node.childNodes[offset - 1];
540
543
  if (before.nodeType == 1) return flattenH(before.getBoundingClientRect(), false);
541
544
  }
542
545
 
543
- if (offset < nodeSize(node)) {
546
+ if (atom == null && offset < nodeSize(node)) {
544
547
  var after = node.childNodes[offset];
545
548
  if (after.nodeType == 1) return flattenH(after.getBoundingClientRect(), true);
546
549
  }
@@ -548,13 +551,13 @@ function _coordsAtPos(view, pos, side) {
548
551
  return flattenH(node.getBoundingClientRect(), side >= 0);
549
552
  }
550
553
 
551
- if (offset && (side < 0 || offset == nodeSize(node))) {
554
+ if (atom == null && offset && (side < 0 || offset == nodeSize(node))) {
552
555
  var _before = node.childNodes[offset - 1];
553
556
  var target = _before.nodeType == 3 ? textRange(_before, nodeSize(_before) - (supportEmptyRange ? 0 : 1)) : _before.nodeType == 1 && (_before.nodeName != "BR" || !_before.nextSibling) ? _before : null;
554
557
  if (target) return flattenV(singleRect(target, 1), false);
555
558
  }
556
559
 
557
- if (offset < nodeSize(node)) {
560
+ if (atom == null && offset < nodeSize(node)) {
558
561
  var _after = node.childNodes[offset];
559
562
 
560
563
  while (_after.pmViewDesc && _after.pmViewDesc.ignoreForCoords) {
@@ -905,7 +908,8 @@ var ViewDesc = function () {
905
908
  value: function domFromPos(pos, side) {
906
909
  if (!this.contentDOM) return {
907
910
  node: this.dom,
908
- offset: 0
911
+ offset: 0,
912
+ atom: pos + 1
909
913
  };
910
914
  var i = 0,
911
915
  offset = 0;
@@ -1458,7 +1462,7 @@ var NodeViewDesc = function (_ViewDesc4) {
1458
1462
  var composition = view.composing ? this.localCompositionInfo(view, pos) : null;
1459
1463
  var localComposition = composition && composition.pos > -1 ? composition : null;
1460
1464
  var compositionInChild = composition && composition.pos < 0;
1461
- var updater = new ViewTreeUpdater(this, localComposition && localComposition.node);
1465
+ var updater = new ViewTreeUpdater(this, localComposition && localComposition.node, view);
1462
1466
  iterDeco(this.node, this.innerDeco, function (widget, i, insideNode) {
1463
1467
  if (widget.spec.marks) updater.syncToMarks(widget.spec.marks, inline, view);else if (widget.type.side >= 0 && !insideNode) updater.syncToMarks(i == _this6.node.childCount ? prosemirrorModel.Mark.none : _this6.node.child(i).marks, inline, view);
1464
1468
  updater.placeWidget(widget, view, off);
@@ -1970,10 +1974,11 @@ function rm(dom) {
1970
1974
  }
1971
1975
 
1972
1976
  var ViewTreeUpdater = function () {
1973
- function ViewTreeUpdater(top, lock) {
1977
+ function ViewTreeUpdater(top, lock, view) {
1974
1978
  _classCallCheck(this, ViewTreeUpdater);
1975
1979
 
1976
1980
  this.lock = lock;
1981
+ this.view = view;
1977
1982
  this.index = 0;
1978
1983
  this.stack = [];
1979
1984
  this.changed = false;
@@ -2077,7 +2082,7 @@ var ViewTreeUpdater = function () {
2077
2082
  if (child.dirty == NODE_DIRTY && child.dom == child.contentDOM) child.dirty = CONTENT_DIRTY;
2078
2083
  if (!child.update(node, outerDeco, innerDeco, view)) return false;
2079
2084
  this.destroyBetween(this.index, index);
2080
- this.index = index + 1;
2085
+ this.index++;
2081
2086
  return true;
2082
2087
  }
2083
2088
  }, {
@@ -2154,7 +2159,7 @@ var ViewTreeUpdater = function () {
2154
2159
  lastChild = parent.children[parent.children.length - 1];
2155
2160
  }
2156
2161
 
2157
- if (!lastChild || !(lastChild instanceof TextViewDesc) || /\n$/.test(lastChild.node.text)) {
2162
+ if (!lastChild || !(lastChild instanceof TextViewDesc) || /\n$/.test(lastChild.node.text) || this.view.requiresGeckoHackNode && /\s$/.test(lastChild.node.text)) {
2158
2163
  if ((safari || chrome) && lastChild && lastChild.dom.contentEditable == "false") this.addHackNode("IMG", parent);
2159
2164
  this.addHackNode("BR", this.top);
2160
2165
  }
@@ -3160,6 +3165,10 @@ function addContext(slice, context) {
3160
3165
 
3161
3166
  var handlers = {};
3162
3167
  var editHandlers = {};
3168
+ var passiveHandlers = {
3169
+ touchstart: true,
3170
+ touchmove: true
3171
+ };
3163
3172
 
3164
3173
  var InputState = _createClass(function InputState() {
3165
3174
  _classCallCheck(this, InputState);
@@ -3178,6 +3187,8 @@ var InputState = _createClass(function InputState() {
3178
3187
  this.lastSelectionTime = 0;
3179
3188
  this.lastIOSEnter = 0;
3180
3189
  this.lastIOSEnterFallbackTimeout = -1;
3190
+ this.lastFocus = 0;
3191
+ this.lastTouch = 0;
3181
3192
  this.lastAndroidDelete = 0;
3182
3193
  this.composing = false;
3183
3194
  this.composingTimeout = -1;
@@ -3193,7 +3204,9 @@ function initInput(view) {
3193
3204
  var handler = handlers[event];
3194
3205
  view.dom.addEventListener(event, view.input.eventHandlers[event] = function (event) {
3195
3206
  if (eventBelongsToView(view, event) && !runCustomHandler(view, event) && (view.editable || !(event.type in editHandlers))) handler(view, event);
3196
- });
3207
+ }, passiveHandlers[event] ? {
3208
+ passive: true
3209
+ } : undefined);
3197
3210
  };
3198
3211
 
3199
3212
  for (var event in handlers) {
@@ -3567,11 +3580,17 @@ var MouseDown = function () {
3567
3580
  return MouseDown;
3568
3581
  }();
3569
3582
 
3570
- handlers.touchdown = function (view) {
3583
+ handlers.touchstart = function (view) {
3584
+ view.input.lastTouch = Date.now();
3571
3585
  forceDOMFlush(view);
3572
3586
  setSelectionOrigin(view, "pointer");
3573
3587
  };
3574
3588
 
3589
+ handlers.touchmove = function (view) {
3590
+ view.input.lastTouch = Date.now();
3591
+ setSelectionOrigin(view, "pointer");
3592
+ };
3593
+
3575
3594
  handlers.contextmenu = function (view) {
3576
3595
  return forceDOMFlush(view);
3577
3596
  };
@@ -3809,7 +3828,6 @@ editHandlers.drop = function (view, _event) {
3809
3828
  var eventPos = view.posAtCoords(eventCoords(event));
3810
3829
  if (!eventPos) return;
3811
3830
  var $mouse = view.state.doc.resolve(eventPos.pos);
3812
- if (!$mouse) return;
3813
3831
  var slice = dragging && dragging.slice;
3814
3832
 
3815
3833
  if (slice) {
@@ -3857,6 +3875,8 @@ editHandlers.drop = function (view, _event) {
3857
3875
  };
3858
3876
 
3859
3877
  handlers.focus = function (view) {
3878
+ view.input.lastFocus = Date.now();
3879
+
3860
3880
  if (!view.focused) {
3861
3881
  view.domObserver.stop();
3862
3882
  view.dom.classList.add("ProseMirror-focused");
@@ -4396,24 +4416,30 @@ var DecorationGroup = function () {
4396
4416
  function mapChildren(oldChildren, newLocal, mapping, node, offset, oldOffset, options) {
4397
4417
  var children = oldChildren.slice();
4398
4418
 
4399
- var shift = function shift(oldStart, oldEnd, newStart, newEnd) {
4400
- for (var i = 0; i < children.length; i += 3) {
4401
- var end = children[i + 1],
4402
- dSize = void 0;
4403
- if (end < 0 || oldStart > end + oldOffset) continue;
4404
- var start = children[i] + oldOffset;
4405
-
4406
- if (oldEnd >= start) {
4407
- children[i + 1] = oldStart <= start ? -2 : -1;
4408
- } else if (newStart >= offset && (dSize = newEnd - newStart - (oldEnd - oldStart))) {
4409
- children[i] += dSize;
4410
- children[i + 1] += dSize;
4419
+ var _loop4 = function _loop4(i) {
4420
+ var moved = 0;
4421
+ mapping.maps[i].forEach(function (oldStart, oldEnd, newStart, newEnd) {
4422
+ var dSize = newEnd - newStart - (oldEnd - oldStart);
4423
+
4424
+ for (var _i12 = 0; _i12 < children.length; _i12 += 3) {
4425
+ var end = children[_i12 + 1];
4426
+ if (end < 0 || oldStart > end + oldOffset - moved) continue;
4427
+ var start = children[_i12] + oldOffset - moved;
4428
+
4429
+ if (oldEnd >= start) {
4430
+ children[_i12 + 1] = oldStart <= start ? -2 : -1;
4431
+ } else if (newStart >= offset && dSize) {
4432
+ children[_i12] += dSize;
4433
+ children[_i12 + 1] += dSize;
4434
+ }
4411
4435
  }
4412
- }
4436
+
4437
+ moved += dSize;
4438
+ });
4413
4439
  };
4414
4440
 
4415
4441
  for (var i = 0; i < mapping.maps.length; i++) {
4416
- mapping.maps[i].forEach(shift);
4442
+ _loop4(i);
4417
4443
  }
4418
4444
 
4419
4445
  var mustRebuild = false;
@@ -4505,8 +4531,8 @@ function mapAndGatherRemainingDecorations(children, oldChildren, decorations, ma
4505
4531
  if (mapped) decorations.push(mapped);else if (options.onRemove) options.onRemove(set.local[i].spec);
4506
4532
  }
4507
4533
 
4508
- for (var _i12 = 0; _i12 < set.children.length; _i12 += 3) {
4509
- gather(set.children[_i12 + 2], set.children[_i12] + oldOffset + 1);
4534
+ for (var _i13 = 0; _i13 < set.children.length; _i13 += 3) {
4535
+ gather(set.children[_i13 + 2], set.children[_i13] + oldOffset + 1);
4510
4536
  }
4511
4537
  }
4512
4538
 
@@ -4812,7 +4838,8 @@ var DOMObserver = function () {
4812
4838
  }, {
4813
4839
  key: "flush",
4814
4840
  value: function flush() {
4815
- if (!this.view.docView || this.flushingSoon > -1) return;
4841
+ var view = this.view;
4842
+ if (!view.docView || this.flushingSoon > -1) return;
4816
4843
  var mutations = this.observer ? this.observer.takeRecords() : [];
4817
4844
 
4818
4845
  if (this.queue.length) {
@@ -4820,14 +4847,14 @@ var DOMObserver = function () {
4820
4847
  this.queue.length = 0;
4821
4848
  }
4822
4849
 
4823
- var sel = this.view.domSelection();
4824
- var newSel = !this.suppressingSelectionUpdates && !this.currentSelection.eq(sel) && hasFocusAndSelection(this.view) && !this.ignoreSelectionChange(sel);
4850
+ var sel = view.domSelection();
4851
+ var newSel = !this.suppressingSelectionUpdates && !this.currentSelection.eq(sel) && hasFocusAndSelection(view) && !this.ignoreSelectionChange(sel);
4825
4852
  var from = -1,
4826
4853
  to = -1,
4827
4854
  typeOver = false,
4828
4855
  added = [];
4829
4856
 
4830
- if (this.view.editable) {
4857
+ if (view.editable) {
4831
4858
  for (var i = 0; i < mutations.length; i++) {
4832
4859
  var result = this.registerMutation(mutations[i], added);
4833
4860
 
@@ -4851,14 +4878,21 @@ var DOMObserver = function () {
4851
4878
  }
4852
4879
  }
4853
4880
 
4854
- if (from > -1 || newSel) {
4881
+ var readSel = null;
4882
+
4883
+ if (from < 0 && newSel && view.input.lastFocus > Date.now() - 200 && view.input.lastTouch < Date.now() - 300 && selectionCollapsed(sel) && (readSel = selectionFromDOM(view)) && readSel.eq(prosemirrorState.Selection.near(view.state.doc.resolve(0), 1))) {
4884
+ view.input.lastFocus = 0;
4885
+ selectionToDOM(view);
4886
+ this.currentSelection.set(sel);
4887
+ view.scrollToSelection();
4888
+ } else if (from > -1 || newSel) {
4855
4889
  if (from > -1) {
4856
- this.view.docView.markDirty(from, to);
4857
- checkCSS(this.view);
4890
+ view.docView.markDirty(from, to);
4891
+ checkCSS(view);
4858
4892
  }
4859
4893
 
4860
4894
  this.handleDOMChange(from, to, typeOver, added);
4861
- if (this.view.docView && this.view.docView.dirty) this.view.updateState(this.view.state);else if (!this.currentSelection.eq(sel)) selectionToDOM(this.view);
4895
+ if (view.docView && view.docView.dirty) view.updateState(view.state);else if (!this.currentSelection.eq(sel)) selectionToDOM(view);
4862
4896
  this.currentSelection.set(sel);
4863
4897
  }
4864
4898
  }
@@ -4883,8 +4917,8 @@ var DOMObserver = function () {
4883
4917
  next = mut.nextSibling;
4884
4918
 
4885
4919
  if (ie && ie_version <= 11 && mut.addedNodes.length) {
4886
- for (var _i13 = 0; _i13 < mut.addedNodes.length; _i13++) {
4887
- var _mut$addedNodes$_i = mut.addedNodes[_i13],
4920
+ for (var _i14 = 0; _i14 < mut.addedNodes.length; _i14++) {
4921
+ var _mut$addedNodes$_i = mut.addedNodes[_i14],
4888
4922
  previousSibling = _mut$addedNodes$_i.previousSibling,
4889
4923
  nextSibling = _mut$addedNodes$_i.nextSibling;
4890
4924
  if (!previousSibling || Array.prototype.indexOf.call(mut.addedNodes, previousSibling) < 0) prev = previousSibling;
@@ -4918,12 +4952,19 @@ var DOMObserver = function () {
4918
4952
  return DOMObserver;
4919
4953
  }();
4920
4954
 
4921
- var cssChecked = false;
4955
+ var cssChecked = new WeakMap();
4956
+ var cssCheckWarned = false;
4922
4957
 
4923
4958
  function checkCSS(view) {
4924
- if (cssChecked) return;
4925
- cssChecked = true;
4926
- if (getComputedStyle(view.dom).whiteSpace == "normal") console["warn"]("ProseMirror expects the CSS white-space property to be set, preferably to 'pre-wrap'. It is recommended to load style/prosemirror.css from the prosemirror-view package.");
4959
+ if (cssChecked.has(view)) return;
4960
+ cssChecked.set(view, null);
4961
+
4962
+ if (['normal', 'nowrap', 'pre-line'].indexOf(getComputedStyle(view.dom).whiteSpace) !== -1) {
4963
+ view.requiresGeckoHackNode = gecko;
4964
+ if (cssCheckWarned) return;
4965
+ console["warn"]("ProseMirror expects the CSS white-space property to be set, preferably to 'pre-wrap'. It is recommended to load style/prosemirror.css from the prosemirror-view package.");
4966
+ cssCheckWarned = true;
4967
+ }
4927
4968
  }
4928
4969
 
4929
4970
  function parseBetween(view, from_, to_) {
@@ -5045,7 +5086,7 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
5045
5086
  var sel = view.state.selection;
5046
5087
  var parse = parseBetween(view, from, to);
5047
5088
 
5048
- if (chrome && view.cursorWrapper && parse.sel && parse.sel.anchor == view.cursorWrapper.deco.from) {
5089
+ if (chrome && view.cursorWrapper && parse.sel && parse.sel.anchor == view.cursorWrapper.deco.from && parse.sel.head == parse.sel.anchor) {
5049
5090
  var text = view.cursorWrapper.deco.type.toDOM.nextSibling;
5050
5091
  var size = text && text.nodeValue ? text.nodeValue.length : 1;
5051
5092
  parse.sel = {
@@ -5205,8 +5246,8 @@ function isMarkChange(cur, prev) {
5205
5246
  added = prevMarks[i].removeFromSet(added);
5206
5247
  }
5207
5248
 
5208
- for (var _i14 = 0; _i14 < curMarks.length; _i14++) {
5209
- removed = curMarks[_i14].removeFromSet(removed);
5249
+ for (var _i15 = 0; _i15 < curMarks.length; _i15++) {
5250
+ removed = curMarks[_i15].removeFromSet(removed);
5210
5251
  }
5211
5252
 
5212
5253
  if (added.length == 1 && removed.length == 0) {
@@ -5229,8 +5270,8 @@ function isMarkChange(cur, prev) {
5229
5270
 
5230
5271
  var updated = [];
5231
5272
 
5232
- for (var _i15 = 0; _i15 < prev.childCount; _i15++) {
5233
- updated.push(update(prev.child(_i15)));
5273
+ for (var _i16 = 0; _i16 < prev.childCount; _i16++) {
5274
+ updated.push(update(prev.child(_i16)));
5234
5275
  }
5235
5276
 
5236
5277
  if (prosemirrorModel.Fragment.from(updated).eq(cur)) return {
@@ -5323,6 +5364,7 @@ var EditorView = function () {
5323
5364
  this.input = new InputState();
5324
5365
  this.prevDirectPlugins = [];
5325
5366
  this.pluginViews = [];
5367
+ this.requiresGeckoHackNode = false;
5326
5368
  this.dragging = null;
5327
5369
  this._props = props;
5328
5370
  this.state = props.state;
@@ -5406,8 +5448,6 @@ var EditorView = function () {
5406
5448
  }, {
5407
5449
  key: "updateStateInner",
5408
5450
  value: function updateStateInner(state, reconfigured) {
5409
- var _this16 = this;
5410
-
5411
5451
  var prev = this.state,
5412
5452
  redraw = false,
5413
5453
  updateSel = false;
@@ -5470,19 +5510,26 @@ var EditorView = function () {
5470
5510
  if (scroll == "reset") {
5471
5511
  this.dom.scrollTop = 0;
5472
5512
  } else if (scroll == "to selection") {
5473
- var startDOM = this.domSelection().focusNode;
5474
- if (this.someProp("handleScrollToSelection", function (f) {
5475
- return f(_this16);
5476
- })) ;else if (state.selection instanceof prosemirrorState.NodeSelection) {
5477
- var target = this.docView.domAfterPos(state.selection.from);
5478
- if (target.nodeType == 1) scrollRectIntoView(this, target.getBoundingClientRect(), startDOM);
5479
- } else {
5480
- scrollRectIntoView(this, this.coordsAtPos(state.selection.head, 1), startDOM);
5481
- }
5513
+ this.scrollToSelection();
5482
5514
  } else if (oldScrollPos) {
5483
5515
  resetScrollPos(oldScrollPos);
5484
5516
  }
5485
5517
  }
5518
+ }, {
5519
+ key: "scrollToSelection",
5520
+ value: function scrollToSelection() {
5521
+ var _this16 = this;
5522
+
5523
+ var startDOM = this.domSelection().focusNode;
5524
+ if (this.someProp("handleScrollToSelection", function (f) {
5525
+ return f(_this16);
5526
+ })) ;else if (this.state.selection instanceof prosemirrorState.NodeSelection) {
5527
+ var target = this.docView.domAfterPos(this.state.selection.from);
5528
+ if (target.nodeType == 1) scrollRectIntoView(this, target.getBoundingClientRect(), startDOM);
5529
+ } else {
5530
+ scrollRectIntoView(this, this.coordsAtPos(this.state.selection.head, 1), startDOM);
5531
+ }
5532
+ }
5486
5533
  }, {
5487
5534
  key: "destroyPluginViews",
5488
5535
  value: function destroyPluginViews() {
@@ -5504,13 +5551,13 @@ var EditorView = function () {
5504
5551
  if (plugin.spec.view) this.pluginViews.push(plugin.spec.view(this));
5505
5552
  }
5506
5553
 
5507
- for (var _i16 = 0; _i16 < this.state.plugins.length; _i16++) {
5508
- var _plugin = this.state.plugins[_i16];
5554
+ for (var _i17 = 0; _i17 < this.state.plugins.length; _i17++) {
5555
+ var _plugin = this.state.plugins[_i17];
5509
5556
  if (_plugin.spec.view) this.pluginViews.push(_plugin.spec.view(this));
5510
5557
  }
5511
5558
  } else {
5512
- for (var _i17 = 0; _i17 < this.pluginViews.length; _i17++) {
5513
- var pluginView = this.pluginViews[_i17];
5559
+ for (var _i18 = 0; _i18 < this.pluginViews.length; _i18++) {
5560
+ var pluginView = this.pluginViews[_i18];
5514
5561
  if (pluginView.update) pluginView.update(this, prevState);
5515
5562
  }
5516
5563
  }
@@ -5528,8 +5575,8 @@ var EditorView = function () {
5528
5575
  }
5529
5576
 
5530
5577
  var plugins = this.state.plugins;
5531
- if (plugins) for (var _i18 = 0; _i18 < plugins.length; _i18++) {
5532
- var _prop2 = plugins[_i18].props[propName];
5578
+ if (plugins) for (var _i19 = 0; _i19 < plugins.length; _i19++) {
5579
+ var _prop2 = plugins[_i19].props[propName];
5533
5580
  if (_prop2 != null && (value = f ? f(_prop2) : _prop2)) return value;
5534
5581
  }
5535
5582
  }
@@ -5554,7 +5601,7 @@ var EditorView = function () {
5554
5601
  var cached = this._root;
5555
5602
 
5556
5603
  if (cached == null) {
5557
- var _loop4 = function _loop4(search) {
5604
+ var _loop5 = function _loop5(search) {
5558
5605
  if (search.nodeType == 9 || search.nodeType == 11 && search.host) {
5559
5606
  if (!search.getSelection) Object.getPrototypeOf(search).getSelection = function () {
5560
5607
  return search.ownerDocument.getSelection();
@@ -5566,7 +5613,7 @@ var EditorView = function () {
5566
5613
  };
5567
5614
 
5568
5615
  for (var search = this.dom.parentNode; search; search = search.parentNode) {
5569
- var _ret3 = _loop4(search);
5616
+ var _ret3 = _loop5(search);
5570
5617
 
5571
5618
  if (_typeof(_ret3) === "object") return _ret3.v;
5572
5619
  }
package/dist/index.d.ts CHANGED
@@ -326,6 +326,7 @@ declare class ViewDesc {
326
326
  domFromPos(pos: number, side: number): {
327
327
  node: DOMNode;
328
328
  offset: number;
329
+ atom?: number;
329
330
  };
330
331
  parseRange(from: number, to: number, base?: number): {
331
332
  node: DOMNode;
@@ -579,8 +580,12 @@ called one at a time, starting with the base props and then
579
580
  searching through the plugins (in order of appearance) until one of
580
581
  them returns true. For some props, the first plugin that yields a
581
582
  value gets precedence.
583
+
584
+ The optional type parameter refers to the type of `this` in prop
585
+ functions, and is used to pass in the plugin type when defining a
586
+ [plugin](https://prosemirror.net/docs/ref/#state.Plugin).
582
587
  */
583
- interface EditorProps {
588
+ interface EditorProps<P = any> {
584
589
  /**
585
590
  Can be an object mapping DOM event type names to functions that
586
591
  handle them. Such functions will be called before any handling
@@ -591,72 +596,72 @@ interface EditorProps {
591
596
  default behavior).
592
597
  */
593
598
  handleDOMEvents?: {
594
- [event in keyof DOMEventMap]?: (view: EditorView, event: DOMEventMap[event]) => boolean | void;
599
+ [event in keyof DOMEventMap]?: (this: P, view: EditorView, event: DOMEventMap[event]) => boolean | void;
595
600
  };
596
601
  /**
597
602
  Called when the editor receives a `keydown` event.
598
603
  */
599
- handleKeyDown?: (view: EditorView, event: KeyboardEvent) => boolean | void;
604
+ handleKeyDown?: (this: P, view: EditorView, event: KeyboardEvent) => boolean | void;
600
605
  /**
601
606
  Handler for `keypress` events.
602
607
  */
603
- handleKeyPress?: (view: EditorView, event: KeyboardEvent) => boolean | void;
608
+ handleKeyPress?: (this: P, view: EditorView, event: KeyboardEvent) => boolean | void;
604
609
  /**
605
610
  Whenever the user directly input text, this handler is called
606
611
  before the input is applied. If it returns `true`, the default
607
612
  behavior of actually inserting the text is suppressed.
608
613
  */
609
- handleTextInput?: (view: EditorView, from: number, to: number, text: string) => boolean | void;
614
+ handleTextInput?: (this: P, view: EditorView, from: number, to: number, text: string) => boolean | void;
610
615
  /**
611
616
  Called for each node around a click, from the inside out. The
612
617
  `direct` flag will be true for the inner node.
613
618
  */
614
- handleClickOn?: (view: EditorView, pos: number, node: Node, nodePos: number, event: MouseEvent, direct: boolean) => boolean | void;
619
+ handleClickOn?: (this: P, view: EditorView, pos: number, node: Node, nodePos: number, event: MouseEvent, direct: boolean) => boolean | void;
615
620
  /**
616
621
  Called when the editor is clicked, after `handleClickOn` handlers
617
622
  have been called.
618
623
  */
619
- handleClick?: (view: EditorView, pos: number, event: MouseEvent) => boolean | void;
624
+ handleClick?: (this: P, view: EditorView, pos: number, event: MouseEvent) => boolean | void;
620
625
  /**
621
626
  Called for each node around a double click.
622
627
  */
623
- handleDoubleClickOn?: (view: EditorView, pos: number, node: Node, nodePos: number, event: MouseEvent, direct: boolean) => boolean | void;
628
+ handleDoubleClickOn?: (this: P, view: EditorView, pos: number, node: Node, nodePos: number, event: MouseEvent, direct: boolean) => boolean | void;
624
629
  /**
625
630
  Called when the editor is double-clicked, after `handleDoubleClickOn`.
626
631
  */
627
- handleDoubleClick?: (view: EditorView, pos: number, event: MouseEvent) => boolean | void;
632
+ handleDoubleClick?: (this: P, view: EditorView, pos: number, event: MouseEvent) => boolean | void;
628
633
  /**
629
634
  Called for each node around a triple click.
630
635
  */
631
- handleTripleClickOn?: (view: EditorView, pos: number, node: Node, nodePos: number, event: MouseEvent, direct: boolean) => boolean | void;
636
+ handleTripleClickOn?: (this: P, view: EditorView, pos: number, node: Node, nodePos: number, event: MouseEvent, direct: boolean) => boolean | void;
632
637
  /**
633
638
  Called when the editor is triple-clicked, after `handleTripleClickOn`.
634
639
  */
635
- handleTripleClick?: (view: EditorView, pos: number, event: MouseEvent) => boolean | void;
640
+ handleTripleClick?: (this: P, view: EditorView, pos: number, event: MouseEvent) => boolean | void;
636
641
  /**
637
642
  Can be used to override the behavior of pasting. `slice` is the
638
643
  pasted content parsed by the editor, but you can directly access
639
644
  the event to get at the raw content.
640
645
  */
641
- handlePaste?: (view: EditorView, event: ClipboardEvent, slice: Slice) => boolean | void;
646
+ handlePaste?: (this: P, view: EditorView, event: ClipboardEvent, slice: Slice) => boolean | void;
642
647
  /**
643
648
  Called when something is dropped on the editor. `moved` will be
644
649
  true if this drop moves from the current selection (which should
645
650
  thus be deleted).
646
651
  */
647
- handleDrop?: (view: EditorView, event: DragEvent, slice: Slice, moved: boolean) => boolean | void;
652
+ handleDrop?: (this: P, view: EditorView, event: DragEvent, slice: Slice, moved: boolean) => boolean | void;
648
653
  /**
649
654
  Called when the view, after updating its state, tries to scroll
650
655
  the selection into view. A handler function may return false to
651
656
  indicate that it did not handle the scrolling and further
652
657
  handlers or the default behavior should be tried.
653
658
  */
654
- handleScrollToSelection?: (view: EditorView) => boolean;
659
+ handleScrollToSelection?: (this: P, view: EditorView) => boolean;
655
660
  /**
656
661
  Can be used to override the way a selection is created when
657
662
  reading a DOM selection between the given anchor and head.
658
663
  */
659
- createSelectionBetween?: (view: EditorView, anchor: ResolvedPos, head: ResolvedPos) => Selection | null;
664
+ createSelectionBetween?: (this: P, view: EditorView, anchor: ResolvedPos, head: ResolvedPos) => Selection | null;
660
665
  /**
661
666
  The [parser](https://prosemirror.net/docs/ref/#model.DOMParser) to use when reading editor changes
662
667
  from the DOM. Defaults to calling
@@ -668,7 +673,7 @@ interface EditorProps {
668
673
  Can be used to transform pasted HTML text, _before_ it is parsed,
669
674
  for example to clean it up.
670
675
  */
671
- transformPastedHTML?: (html: string) => string;
676
+ transformPastedHTML?: (this: P, html: string) => string;
672
677
  /**
673
678
  The [parser](https://prosemirror.net/docs/ref/#model.DOMParser) to use when reading content from
674
679
  the clipboard. When not given, the value of the
@@ -679,7 +684,7 @@ interface EditorProps {
679
684
  Transform pasted plain text. The `plain` flag will be true when
680
685
  the text is pasted as plain text.
681
686
  */
682
- transformPastedText?: (text: string, plain: boolean) => string;
687
+ transformPastedText?: (this: P, text: string, plain: boolean) => string;
683
688
  /**
684
689
  A function to parse text from the clipboard into a document
685
690
  slice. Called after
@@ -689,12 +694,12 @@ interface EditorProps {
689
694
  [`clipboardParser`](https://prosemirror.net/docs/ref/#view.EditorProps.clipboardParser) on it.
690
695
  The `plain` flag will be true when the text is pasted as plain text.
691
696
  */
692
- clipboardTextParser?: (text: string, $context: ResolvedPos, plain: boolean) => Slice;
697
+ clipboardTextParser?: (this: P, text: string, $context: ResolvedPos, plain: boolean) => Slice;
693
698
  /**
694
- Can be used to transform pasted content before it is applied to
695
- the document.
699
+ Can be used to transform pasted or dragged-and-dropped content
700
+ before it is applied to the document.
696
701
  */
697
- transformPasted?: (slice: Slice) => Slice;
702
+ transformPasted?: (this: P, slice: Slice) => Slice;
698
703
  /**
699
704
  Allows you to pass custom rendering and behavior logic for
700
705
  nodes. Should map node names to constructor functions that
@@ -749,17 +754,17 @@ interface EditorProps {
749
754
  editor will use [`textBetween`](https://prosemirror.net/docs/ref/#model.Node.textBetween) on the
750
755
  selected range.
751
756
  */
752
- clipboardTextSerializer?: (content: Slice) => string;
757
+ clipboardTextSerializer?: (this: P, content: Slice) => string;
753
758
  /**
754
759
  A set of [document decorations](https://prosemirror.net/docs/ref/#view.Decoration) to show in the
755
760
  view.
756
761
  */
757
- decorations?: (state: EditorState) => DecorationSource | null | undefined;
762
+ decorations?: (this: P, state: EditorState) => DecorationSource | null | undefined;
758
763
  /**
759
764
  When this returns false, the content of the view is not directly
760
765
  editable.
761
766
  */
762
- editable?: (state: EditorState) => boolean;
767
+ editable?: (this: P, state: EditorState) => boolean;
763
768
  /**
764
769
  Control the DOM attributes of the editable element. May be either
765
770
  an object or a function going from an editor state to an object.