prosemirror-view 1.26.5 → 1.27.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,31 @@
1
+ ## 1.27.2 (2022-08-19)
2
+
3
+ ### Bug fixes
4
+
5
+ Fix an issue where `DecorationSet.map`, given a mapping with multiple steps, could in some cases corrupt the decorations.
6
+
7
+ Stop calling `handleClick` when the mouse moved but failed to fire mousemove events (for example when dragging a scrollbar).
8
+
9
+ ## 1.27.1 (2022-08-16)
10
+
11
+ ### Bug fixes
12
+
13
+ Fix a bug in `DecorationSet.map` that could cause invalid mapping when step maps contain multiple replaced ranges.
14
+
15
+ Make sure that when the editor receives focus via tab or calling `.focus()` on its DOM element, the existing selection is restored.
16
+
17
+ Avoid collapsing of whitespace in Firefox when the editor doesn't have `white-space` set to `pre-wrap`.
18
+
19
+ ## 1.27.0 (2022-07-20)
20
+
21
+ ### Bug fixes
22
+
23
+ Fix a bug that in some situations caused composition to be disrupted on Chrome due to a workaround for another browser issue activating inappropriately.
24
+
25
+ ### New features
26
+
27
+ `EditorProps` now takes an optional type parameter that indicates the type of `this` in prop functions.
28
+
1
29
  ## 1.26.5 (2022-07-07)
2
30
 
3
31
  ### Bug fixes
package/dist/index.cjs CHANGED
@@ -531,7 +531,7 @@ function _coordsAtPos(view, pos, side) {
531
531
  to++;
532
532
  }
533
533
 
534
- return flattenV(singleRect(textRange(node, from, to), takeSide), takeSide < 0);
534
+ return flattenV(singleRect(textRange(node, from, to), 1), takeSide < 0);
535
535
  }
536
536
  }
537
537
 
@@ -1462,7 +1462,7 @@ var NodeViewDesc = function (_ViewDesc4) {
1462
1462
  var composition = view.composing ? this.localCompositionInfo(view, pos) : null;
1463
1463
  var localComposition = composition && composition.pos > -1 ? composition : null;
1464
1464
  var compositionInChild = composition && composition.pos < 0;
1465
- var updater = new ViewTreeUpdater(this, localComposition && localComposition.node);
1465
+ var updater = new ViewTreeUpdater(this, localComposition && localComposition.node, view);
1466
1466
  iterDeco(this.node, this.innerDeco, function (widget, i, insideNode) {
1467
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);
1468
1468
  updater.placeWidget(widget, view, off);
@@ -1974,10 +1974,11 @@ function rm(dom) {
1974
1974
  }
1975
1975
 
1976
1976
  var ViewTreeUpdater = function () {
1977
- function ViewTreeUpdater(top, lock) {
1977
+ function ViewTreeUpdater(top, lock, view) {
1978
1978
  _classCallCheck(this, ViewTreeUpdater);
1979
1979
 
1980
1980
  this.lock = lock;
1981
+ this.view = view;
1981
1982
  this.index = 0;
1982
1983
  this.stack = [];
1983
1984
  this.changed = false;
@@ -2158,7 +2159,7 @@ var ViewTreeUpdater = function () {
2158
2159
  lastChild = parent.children[parent.children.length - 1];
2159
2160
  }
2160
2161
 
2161
- 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)) {
2162
2163
  if ((safari || chrome) && lastChild && lastChild.dom.contentEditable == "false") this.addHackNode("IMG", parent);
2163
2164
  this.addHackNode("BR", this.top);
2164
2165
  }
@@ -3164,6 +3165,10 @@ function addContext(slice, context) {
3164
3165
 
3165
3166
  var handlers = {};
3166
3167
  var editHandlers = {};
3168
+ var passiveHandlers = {
3169
+ touchstart: true,
3170
+ touchmove: true
3171
+ };
3167
3172
 
3168
3173
  var InputState = _createClass(function InputState() {
3169
3174
  _classCallCheck(this, InputState);
@@ -3182,6 +3187,8 @@ var InputState = _createClass(function InputState() {
3182
3187
  this.lastSelectionTime = 0;
3183
3188
  this.lastIOSEnter = 0;
3184
3189
  this.lastIOSEnterFallbackTimeout = -1;
3190
+ this.lastFocus = 0;
3191
+ this.lastTouch = 0;
3185
3192
  this.lastAndroidDelete = 0;
3186
3193
  this.composing = false;
3187
3194
  this.composingTimeout = -1;
@@ -3197,7 +3204,9 @@ function initInput(view) {
3197
3204
  var handler = handlers[event];
3198
3205
  view.dom.addEventListener(event, view.input.eventHandlers[event] = function (event) {
3199
3206
  if (eventBelongsToView(view, event) && !runCustomHandler(view, event) && (view.editable || !(event.type in editHandlers))) handler(view, event);
3200
- });
3207
+ }, passiveHandlers[event] ? {
3208
+ passive: true
3209
+ } : undefined);
3201
3210
  };
3202
3211
 
3203
3212
  for (var event in handlers) {
@@ -3547,6 +3556,7 @@ var MouseDown = function () {
3547
3556
  if (!this.view.dom.contains(event.target)) return;
3548
3557
  var pos = this.pos;
3549
3558
  if (this.view.state.doc != this.startDoc) pos = this.view.posAtCoords(eventCoords(event));
3559
+ this.updateAllowDefault(event);
3550
3560
 
3551
3561
  if (this.allowDefault || !pos) {
3552
3562
  setSelectionOrigin(this.view, "pointer");
@@ -3562,20 +3572,31 @@ var MouseDown = function () {
3562
3572
  }, {
3563
3573
  key: "move",
3564
3574
  value: function move(event) {
3565
- if (!this.allowDefault && (Math.abs(this.event.x - event.clientX) > 4 || Math.abs(this.event.y - event.clientY) > 4)) this.allowDefault = true;
3575
+ this.updateAllowDefault(event);
3566
3576
  setSelectionOrigin(this.view, "pointer");
3567
3577
  if (event.buttons == 0) this.done();
3568
3578
  }
3579
+ }, {
3580
+ key: "updateAllowDefault",
3581
+ value: function updateAllowDefault(event) {
3582
+ if (!this.allowDefault && (Math.abs(this.event.x - event.clientX) > 4 || Math.abs(this.event.y - event.clientY) > 4)) this.allowDefault = true;
3583
+ }
3569
3584
  }]);
3570
3585
 
3571
3586
  return MouseDown;
3572
3587
  }();
3573
3588
 
3574
- handlers.touchdown = function (view) {
3589
+ handlers.touchstart = function (view) {
3590
+ view.input.lastTouch = Date.now();
3575
3591
  forceDOMFlush(view);
3576
3592
  setSelectionOrigin(view, "pointer");
3577
3593
  };
3578
3594
 
3595
+ handlers.touchmove = function (view) {
3596
+ view.input.lastTouch = Date.now();
3597
+ setSelectionOrigin(view, "pointer");
3598
+ };
3599
+
3579
3600
  handlers.contextmenu = function (view) {
3580
3601
  return forceDOMFlush(view);
3581
3602
  };
@@ -3813,7 +3834,6 @@ editHandlers.drop = function (view, _event) {
3813
3834
  var eventPos = view.posAtCoords(eventCoords(event));
3814
3835
  if (!eventPos) return;
3815
3836
  var $mouse = view.state.doc.resolve(eventPos.pos);
3816
- if (!$mouse) return;
3817
3837
  var slice = dragging && dragging.slice;
3818
3838
 
3819
3839
  if (slice) {
@@ -3861,6 +3881,8 @@ editHandlers.drop = function (view, _event) {
3861
3881
  };
3862
3882
 
3863
3883
  handlers.focus = function (view) {
3884
+ view.input.lastFocus = Date.now();
3885
+
3864
3886
  if (!view.focused) {
3865
3887
  view.domObserver.stop();
3866
3888
  view.dom.classList.add("ProseMirror-focused");
@@ -4400,24 +4422,32 @@ var DecorationGroup = function () {
4400
4422
  function mapChildren(oldChildren, newLocal, mapping, node, offset, oldOffset, options) {
4401
4423
  var children = oldChildren.slice();
4402
4424
 
4403
- var shift = function shift(oldStart, oldEnd, newStart, newEnd) {
4404
- for (var i = 0; i < children.length; i += 3) {
4405
- var end = children[i + 1],
4406
- dSize = void 0;
4407
- if (end < 0 || oldStart > end + oldOffset) continue;
4408
- var start = children[i] + oldOffset;
4409
-
4410
- if (oldEnd >= start) {
4411
- children[i + 1] = oldStart <= start ? -2 : -1;
4412
- } else if (newStart >= offset && (dSize = newEnd - newStart - (oldEnd - oldStart))) {
4413
- children[i] += dSize;
4414
- children[i + 1] += dSize;
4425
+ var _loop4 = function _loop4(i, _baseOffset) {
4426
+ var moved = 0;
4427
+ mapping.maps[i].forEach(function (oldStart, oldEnd, newStart, newEnd) {
4428
+ var dSize = newEnd - newStart - (oldEnd - oldStart);
4429
+
4430
+ for (var _i12 = 0; _i12 < children.length; _i12 += 3) {
4431
+ var end = children[_i12 + 1];
4432
+ if (end < 0 || oldStart > end + _baseOffset - moved) continue;
4433
+ var start = children[_i12] + _baseOffset - moved;
4434
+
4435
+ if (oldEnd >= start) {
4436
+ children[_i12 + 1] = oldStart <= start ? -2 : -1;
4437
+ } else if (newStart >= offset && dSize) {
4438
+ children[_i12] += dSize;
4439
+ children[_i12 + 1] += dSize;
4440
+ }
4415
4441
  }
4416
- }
4442
+
4443
+ moved += dSize;
4444
+ });
4445
+ _baseOffset = mapping.maps[i].map(_baseOffset, -1);
4446
+ baseOffset = _baseOffset;
4417
4447
  };
4418
4448
 
4419
- for (var i = 0; i < mapping.maps.length; i++) {
4420
- mapping.maps[i].forEach(shift);
4449
+ for (var i = 0, baseOffset = oldOffset; i < mapping.maps.length; i++) {
4450
+ _loop4(i, baseOffset);
4421
4451
  }
4422
4452
 
4423
4453
  var mustRebuild = false;
@@ -4509,8 +4539,8 @@ function mapAndGatherRemainingDecorations(children, oldChildren, decorations, ma
4509
4539
  if (mapped) decorations.push(mapped);else if (options.onRemove) options.onRemove(set.local[i].spec);
4510
4540
  }
4511
4541
 
4512
- for (var _i12 = 0; _i12 < set.children.length; _i12 += 3) {
4513
- gather(set.children[_i12 + 2], set.children[_i12] + oldOffset + 1);
4542
+ for (var _i13 = 0; _i13 < set.children.length; _i13 += 3) {
4543
+ gather(set.children[_i13 + 2], set.children[_i13] + oldOffset + 1);
4514
4544
  }
4515
4545
  }
4516
4546
 
@@ -4816,7 +4846,8 @@ var DOMObserver = function () {
4816
4846
  }, {
4817
4847
  key: "flush",
4818
4848
  value: function flush() {
4819
- if (!this.view.docView || this.flushingSoon > -1) return;
4849
+ var view = this.view;
4850
+ if (!view.docView || this.flushingSoon > -1) return;
4820
4851
  var mutations = this.observer ? this.observer.takeRecords() : [];
4821
4852
 
4822
4853
  if (this.queue.length) {
@@ -4824,14 +4855,14 @@ var DOMObserver = function () {
4824
4855
  this.queue.length = 0;
4825
4856
  }
4826
4857
 
4827
- var sel = this.view.domSelection();
4828
- var newSel = !this.suppressingSelectionUpdates && !this.currentSelection.eq(sel) && hasFocusAndSelection(this.view) && !this.ignoreSelectionChange(sel);
4858
+ var sel = view.domSelection();
4859
+ var newSel = !this.suppressingSelectionUpdates && !this.currentSelection.eq(sel) && hasFocusAndSelection(view) && !this.ignoreSelectionChange(sel);
4829
4860
  var from = -1,
4830
4861
  to = -1,
4831
4862
  typeOver = false,
4832
4863
  added = [];
4833
4864
 
4834
- if (this.view.editable) {
4865
+ if (view.editable) {
4835
4866
  for (var i = 0; i < mutations.length; i++) {
4836
4867
  var result = this.registerMutation(mutations[i], added);
4837
4868
 
@@ -4855,14 +4886,21 @@ var DOMObserver = function () {
4855
4886
  }
4856
4887
  }
4857
4888
 
4858
- if (from > -1 || newSel) {
4889
+ var readSel = null;
4890
+
4891
+ 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))) {
4892
+ view.input.lastFocus = 0;
4893
+ selectionToDOM(view);
4894
+ this.currentSelection.set(sel);
4895
+ view.scrollToSelection();
4896
+ } else if (from > -1 || newSel) {
4859
4897
  if (from > -1) {
4860
- this.view.docView.markDirty(from, to);
4861
- checkCSS(this.view);
4898
+ view.docView.markDirty(from, to);
4899
+ checkCSS(view);
4862
4900
  }
4863
4901
 
4864
4902
  this.handleDOMChange(from, to, typeOver, added);
4865
- if (this.view.docView && this.view.docView.dirty) this.view.updateState(this.view.state);else if (!this.currentSelection.eq(sel)) selectionToDOM(this.view);
4903
+ if (view.docView && view.docView.dirty) view.updateState(view.state);else if (!this.currentSelection.eq(sel)) selectionToDOM(view);
4866
4904
  this.currentSelection.set(sel);
4867
4905
  }
4868
4906
  }
@@ -4887,8 +4925,8 @@ var DOMObserver = function () {
4887
4925
  next = mut.nextSibling;
4888
4926
 
4889
4927
  if (ie && ie_version <= 11 && mut.addedNodes.length) {
4890
- for (var _i13 = 0; _i13 < mut.addedNodes.length; _i13++) {
4891
- var _mut$addedNodes$_i = mut.addedNodes[_i13],
4928
+ for (var _i14 = 0; _i14 < mut.addedNodes.length; _i14++) {
4929
+ var _mut$addedNodes$_i = mut.addedNodes[_i14],
4892
4930
  previousSibling = _mut$addedNodes$_i.previousSibling,
4893
4931
  nextSibling = _mut$addedNodes$_i.nextSibling;
4894
4932
  if (!previousSibling || Array.prototype.indexOf.call(mut.addedNodes, previousSibling) < 0) prev = previousSibling;
@@ -4922,12 +4960,19 @@ var DOMObserver = function () {
4922
4960
  return DOMObserver;
4923
4961
  }();
4924
4962
 
4925
- var cssChecked = false;
4963
+ var cssChecked = new WeakMap();
4964
+ var cssCheckWarned = false;
4926
4965
 
4927
4966
  function checkCSS(view) {
4928
- if (cssChecked) return;
4929
- cssChecked = true;
4930
- 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.");
4967
+ if (cssChecked.has(view)) return;
4968
+ cssChecked.set(view, null);
4969
+
4970
+ if (['normal', 'nowrap', 'pre-line'].indexOf(getComputedStyle(view.dom).whiteSpace) !== -1) {
4971
+ view.requiresGeckoHackNode = gecko;
4972
+ if (cssCheckWarned) return;
4973
+ 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.");
4974
+ cssCheckWarned = true;
4975
+ }
4931
4976
  }
4932
4977
 
4933
4978
  function parseBetween(view, from_, to_) {
@@ -5048,16 +5093,6 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
5048
5093
  to = view.state.doc.resolve(to).after(shared + 1);
5049
5094
  var sel = view.state.selection;
5050
5095
  var parse = parseBetween(view, from, to);
5051
-
5052
- if (chrome && view.cursorWrapper && parse.sel && parse.sel.anchor == view.cursorWrapper.deco.from) {
5053
- var text = view.cursorWrapper.deco.type.toDOM.nextSibling;
5054
- var size = text && text.nodeValue ? text.nodeValue.length : 1;
5055
- parse.sel = {
5056
- anchor: parse.sel.anchor + size,
5057
- head: parse.sel.anchor + size
5058
- };
5059
- }
5060
-
5061
5096
  var doc = view.state.doc,
5062
5097
  compare = doc.slice(parse.from, parse.to);
5063
5098
  var preferredPos, preferredSide;
@@ -5100,6 +5135,14 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
5100
5135
  }
5101
5136
  }
5102
5137
 
5138
+ if (chrome && view.cursorWrapper && parse.sel && parse.sel.anchor == view.cursorWrapper.deco.from && parse.sel.head == parse.sel.anchor) {
5139
+ var size = change.endB - change.start;
5140
+ parse.sel = {
5141
+ anchor: parse.sel.anchor + size,
5142
+ head: parse.sel.anchor + size
5143
+ };
5144
+ }
5145
+
5103
5146
  view.input.domChangeCount++;
5104
5147
 
5105
5148
  if (view.state.selection.from < view.state.selection.to && change.start == change.endB && view.state.selection instanceof prosemirrorState.TextSelection) {
@@ -5170,12 +5213,11 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
5170
5213
  tr = view.state.tr;
5171
5214
  if (markChange.type == "add") tr.addMark(chFrom, chTo, markChange.mark);else tr.removeMark(chFrom, chTo, markChange.mark);
5172
5215
  } else if ($from.parent.child($from.index()).isText && $from.index() == $to.index() - ($to.textOffset ? 0 : 1)) {
5173
- var _text = $from.parent.textBetween($from.parentOffset, $to.parentOffset);
5174
-
5216
+ var text = $from.parent.textBetween($from.parentOffset, $to.parentOffset);
5175
5217
  if (view.someProp("handleTextInput", function (f) {
5176
- return f(view, chFrom, chTo, _text);
5218
+ return f(view, chFrom, chTo, text);
5177
5219
  })) return;
5178
- tr = view.state.tr.insertText(_text, chFrom, chTo);
5220
+ tr = view.state.tr.insertText(text, chFrom, chTo);
5179
5221
  }
5180
5222
  }
5181
5223
 
@@ -5209,8 +5251,8 @@ function isMarkChange(cur, prev) {
5209
5251
  added = prevMarks[i].removeFromSet(added);
5210
5252
  }
5211
5253
 
5212
- for (var _i14 = 0; _i14 < curMarks.length; _i14++) {
5213
- removed = curMarks[_i14].removeFromSet(removed);
5254
+ for (var _i15 = 0; _i15 < curMarks.length; _i15++) {
5255
+ removed = curMarks[_i15].removeFromSet(removed);
5214
5256
  }
5215
5257
 
5216
5258
  if (added.length == 1 && removed.length == 0) {
@@ -5233,8 +5275,8 @@ function isMarkChange(cur, prev) {
5233
5275
 
5234
5276
  var updated = [];
5235
5277
 
5236
- for (var _i15 = 0; _i15 < prev.childCount; _i15++) {
5237
- updated.push(update(prev.child(_i15)));
5278
+ for (var _i16 = 0; _i16 < prev.childCount; _i16++) {
5279
+ updated.push(update(prev.child(_i16)));
5238
5280
  }
5239
5281
 
5240
5282
  if (prosemirrorModel.Fragment.from(updated).eq(cur)) return {
@@ -5327,6 +5369,7 @@ var EditorView = function () {
5327
5369
  this.input = new InputState();
5328
5370
  this.prevDirectPlugins = [];
5329
5371
  this.pluginViews = [];
5372
+ this.requiresGeckoHackNode = false;
5330
5373
  this.dragging = null;
5331
5374
  this._props = props;
5332
5375
  this.state = props.state;
@@ -5410,8 +5453,6 @@ var EditorView = function () {
5410
5453
  }, {
5411
5454
  key: "updateStateInner",
5412
5455
  value: function updateStateInner(state, reconfigured) {
5413
- var _this16 = this;
5414
-
5415
5456
  var prev = this.state,
5416
5457
  redraw = false,
5417
5458
  updateSel = false;
@@ -5474,19 +5515,26 @@ var EditorView = function () {
5474
5515
  if (scroll == "reset") {
5475
5516
  this.dom.scrollTop = 0;
5476
5517
  } else if (scroll == "to selection") {
5477
- var startDOM = this.domSelection().focusNode;
5478
- if (this.someProp("handleScrollToSelection", function (f) {
5479
- return f(_this16);
5480
- })) ;else if (state.selection instanceof prosemirrorState.NodeSelection) {
5481
- var target = this.docView.domAfterPos(state.selection.from);
5482
- if (target.nodeType == 1) scrollRectIntoView(this, target.getBoundingClientRect(), startDOM);
5483
- } else {
5484
- scrollRectIntoView(this, this.coordsAtPos(state.selection.head, 1), startDOM);
5485
- }
5518
+ this.scrollToSelection();
5486
5519
  } else if (oldScrollPos) {
5487
5520
  resetScrollPos(oldScrollPos);
5488
5521
  }
5489
5522
  }
5523
+ }, {
5524
+ key: "scrollToSelection",
5525
+ value: function scrollToSelection() {
5526
+ var _this16 = this;
5527
+
5528
+ var startDOM = this.domSelection().focusNode;
5529
+ if (this.someProp("handleScrollToSelection", function (f) {
5530
+ return f(_this16);
5531
+ })) ;else if (this.state.selection instanceof prosemirrorState.NodeSelection) {
5532
+ var target = this.docView.domAfterPos(this.state.selection.from);
5533
+ if (target.nodeType == 1) scrollRectIntoView(this, target.getBoundingClientRect(), startDOM);
5534
+ } else {
5535
+ scrollRectIntoView(this, this.coordsAtPos(this.state.selection.head, 1), startDOM);
5536
+ }
5537
+ }
5490
5538
  }, {
5491
5539
  key: "destroyPluginViews",
5492
5540
  value: function destroyPluginViews() {
@@ -5508,13 +5556,13 @@ var EditorView = function () {
5508
5556
  if (plugin.spec.view) this.pluginViews.push(plugin.spec.view(this));
5509
5557
  }
5510
5558
 
5511
- for (var _i16 = 0; _i16 < this.state.plugins.length; _i16++) {
5512
- var _plugin = this.state.plugins[_i16];
5559
+ for (var _i17 = 0; _i17 < this.state.plugins.length; _i17++) {
5560
+ var _plugin = this.state.plugins[_i17];
5513
5561
  if (_plugin.spec.view) this.pluginViews.push(_plugin.spec.view(this));
5514
5562
  }
5515
5563
  } else {
5516
- for (var _i17 = 0; _i17 < this.pluginViews.length; _i17++) {
5517
- var pluginView = this.pluginViews[_i17];
5564
+ for (var _i18 = 0; _i18 < this.pluginViews.length; _i18++) {
5565
+ var pluginView = this.pluginViews[_i18];
5518
5566
  if (pluginView.update) pluginView.update(this, prevState);
5519
5567
  }
5520
5568
  }
@@ -5532,8 +5580,8 @@ var EditorView = function () {
5532
5580
  }
5533
5581
 
5534
5582
  var plugins = this.state.plugins;
5535
- if (plugins) for (var _i18 = 0; _i18 < plugins.length; _i18++) {
5536
- var _prop2 = plugins[_i18].props[propName];
5583
+ if (plugins) for (var _i19 = 0; _i19 < plugins.length; _i19++) {
5584
+ var _prop2 = plugins[_i19].props[propName];
5537
5585
  if (_prop2 != null && (value = f ? f(_prop2) : _prop2)) return value;
5538
5586
  }
5539
5587
  }
@@ -5558,7 +5606,7 @@ var EditorView = function () {
5558
5606
  var cached = this._root;
5559
5607
 
5560
5608
  if (cached == null) {
5561
- var _loop4 = function _loop4(search) {
5609
+ var _loop5 = function _loop5(search) {
5562
5610
  if (search.nodeType == 9 || search.nodeType == 11 && search.host) {
5563
5611
  if (!search.getSelection) Object.getPrototypeOf(search).getSelection = function () {
5564
5612
  return search.ownerDocument.getSelection();
@@ -5570,7 +5618,7 @@ var EditorView = function () {
5570
5618
  };
5571
5619
 
5572
5620
  for (var search = this.dom.parentNode; search; search = search.parentNode) {
5573
- var _ret3 = _loop4(search);
5621
+ var _ret3 = _loop5(search);
5574
5622
 
5575
5623
  if (_typeof(_ret3) === "object") return _ret3.v;
5576
5624
  }
package/dist/index.d.ts CHANGED
@@ -580,8 +580,12 @@ called one at a time, starting with the base props and then
580
580
  searching through the plugins (in order of appearance) until one of
581
581
  them returns true. For some props, the first plugin that yields a
582
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).
583
587
  */
584
- interface EditorProps {
588
+ interface EditorProps<P = any> {
585
589
  /**
586
590
  Can be an object mapping DOM event type names to functions that
587
591
  handle them. Such functions will be called before any handling
@@ -592,72 +596,72 @@ interface EditorProps {
592
596
  default behavior).
593
597
  */
594
598
  handleDOMEvents?: {
595
- [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;
596
600
  };
597
601
  /**
598
602
  Called when the editor receives a `keydown` event.
599
603
  */
600
- handleKeyDown?: (view: EditorView, event: KeyboardEvent) => boolean | void;
604
+ handleKeyDown?: (this: P, view: EditorView, event: KeyboardEvent) => boolean | void;
601
605
  /**
602
606
  Handler for `keypress` events.
603
607
  */
604
- handleKeyPress?: (view: EditorView, event: KeyboardEvent) => boolean | void;
608
+ handleKeyPress?: (this: P, view: EditorView, event: KeyboardEvent) => boolean | void;
605
609
  /**
606
610
  Whenever the user directly input text, this handler is called
607
611
  before the input is applied. If it returns `true`, the default
608
612
  behavior of actually inserting the text is suppressed.
609
613
  */
610
- 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;
611
615
  /**
612
616
  Called for each node around a click, from the inside out. The
613
617
  `direct` flag will be true for the inner node.
614
618
  */
615
- 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;
616
620
  /**
617
621
  Called when the editor is clicked, after `handleClickOn` handlers
618
622
  have been called.
619
623
  */
620
- handleClick?: (view: EditorView, pos: number, event: MouseEvent) => boolean | void;
624
+ handleClick?: (this: P, view: EditorView, pos: number, event: MouseEvent) => boolean | void;
621
625
  /**
622
626
  Called for each node around a double click.
623
627
  */
624
- 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;
625
629
  /**
626
630
  Called when the editor is double-clicked, after `handleDoubleClickOn`.
627
631
  */
628
- handleDoubleClick?: (view: EditorView, pos: number, event: MouseEvent) => boolean | void;
632
+ handleDoubleClick?: (this: P, view: EditorView, pos: number, event: MouseEvent) => boolean | void;
629
633
  /**
630
634
  Called for each node around a triple click.
631
635
  */
632
- 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;
633
637
  /**
634
638
  Called when the editor is triple-clicked, after `handleTripleClickOn`.
635
639
  */
636
- handleTripleClick?: (view: EditorView, pos: number, event: MouseEvent) => boolean | void;
640
+ handleTripleClick?: (this: P, view: EditorView, pos: number, event: MouseEvent) => boolean | void;
637
641
  /**
638
642
  Can be used to override the behavior of pasting. `slice` is the
639
643
  pasted content parsed by the editor, but you can directly access
640
644
  the event to get at the raw content.
641
645
  */
642
- handlePaste?: (view: EditorView, event: ClipboardEvent, slice: Slice) => boolean | void;
646
+ handlePaste?: (this: P, view: EditorView, event: ClipboardEvent, slice: Slice) => boolean | void;
643
647
  /**
644
648
  Called when something is dropped on the editor. `moved` will be
645
649
  true if this drop moves from the current selection (which should
646
650
  thus be deleted).
647
651
  */
648
- 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;
649
653
  /**
650
654
  Called when the view, after updating its state, tries to scroll
651
655
  the selection into view. A handler function may return false to
652
656
  indicate that it did not handle the scrolling and further
653
657
  handlers or the default behavior should be tried.
654
658
  */
655
- handleScrollToSelection?: (view: EditorView) => boolean;
659
+ handleScrollToSelection?: (this: P, view: EditorView) => boolean;
656
660
  /**
657
661
  Can be used to override the way a selection is created when
658
662
  reading a DOM selection between the given anchor and head.
659
663
  */
660
- createSelectionBetween?: (view: EditorView, anchor: ResolvedPos, head: ResolvedPos) => Selection | null;
664
+ createSelectionBetween?: (this: P, view: EditorView, anchor: ResolvedPos, head: ResolvedPos) => Selection | null;
661
665
  /**
662
666
  The [parser](https://prosemirror.net/docs/ref/#model.DOMParser) to use when reading editor changes
663
667
  from the DOM. Defaults to calling
@@ -669,7 +673,7 @@ interface EditorProps {
669
673
  Can be used to transform pasted HTML text, _before_ it is parsed,
670
674
  for example to clean it up.
671
675
  */
672
- transformPastedHTML?: (html: string) => string;
676
+ transformPastedHTML?: (this: P, html: string) => string;
673
677
  /**
674
678
  The [parser](https://prosemirror.net/docs/ref/#model.DOMParser) to use when reading content from
675
679
  the clipboard. When not given, the value of the
@@ -680,7 +684,7 @@ interface EditorProps {
680
684
  Transform pasted plain text. The `plain` flag will be true when
681
685
  the text is pasted as plain text.
682
686
  */
683
- transformPastedText?: (text: string, plain: boolean) => string;
687
+ transformPastedText?: (this: P, text: string, plain: boolean) => string;
684
688
  /**
685
689
  A function to parse text from the clipboard into a document
686
690
  slice. Called after
@@ -690,12 +694,12 @@ interface EditorProps {
690
694
  [`clipboardParser`](https://prosemirror.net/docs/ref/#view.EditorProps.clipboardParser) on it.
691
695
  The `plain` flag will be true when the text is pasted as plain text.
692
696
  */
693
- clipboardTextParser?: (text: string, $context: ResolvedPos, plain: boolean) => Slice;
697
+ clipboardTextParser?: (this: P, text: string, $context: ResolvedPos, plain: boolean) => Slice;
694
698
  /**
695
- Can be used to transform pasted content before it is applied to
696
- the document.
699
+ Can be used to transform pasted or dragged-and-dropped content
700
+ before it is applied to the document.
697
701
  */
698
- transformPasted?: (slice: Slice) => Slice;
702
+ transformPasted?: (this: P, slice: Slice) => Slice;
699
703
  /**
700
704
  Allows you to pass custom rendering and behavior logic for
701
705
  nodes. Should map node names to constructor functions that
@@ -750,17 +754,17 @@ interface EditorProps {
750
754
  editor will use [`textBetween`](https://prosemirror.net/docs/ref/#model.Node.textBetween) on the
751
755
  selected range.
752
756
  */
753
- clipboardTextSerializer?: (content: Slice) => string;
757
+ clipboardTextSerializer?: (this: P, content: Slice) => string;
754
758
  /**
755
759
  A set of [document decorations](https://prosemirror.net/docs/ref/#view.Decoration) to show in the
756
760
  view.
757
761
  */
758
- decorations?: (state: EditorState) => DecorationSource | null | undefined;
762
+ decorations?: (this: P, state: EditorState) => DecorationSource | null | undefined;
759
763
  /**
760
764
  When this returns false, the content of the view is not directly
761
765
  editable.
762
766
  */
763
- editable?: (state: EditorState) => boolean;
767
+ editable?: (this: P, state: EditorState) => boolean;
764
768
  /**
765
769
  Control the DOM attributes of the editable element. May be either
766
770
  an object or a function going from an editor state to an object.