prosemirror-view 1.27.0 → 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 +10 -0
- package/dist/index.cjs +103 -60
- package/dist/index.d.ts +2 -2
- package/dist/index.js +93 -49
- package/package.json +1 -1
- package/src/decoration.ts +16 -12
- package/src/domcoords.ts +1 -1
- package/src/domobserver.ts +37 -18
- package/src/index.ts +20 -11
- package/src/input.ts +13 -4
- package/src/viewdesc.ts +4 -3
- package/dist/index.es.js +0 -5558
- package/dist/index.es.js.map +0 -1
- package/dist/index.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
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
|
+
|
|
1
11
|
## 1.27.0 (2022-07-20)
|
|
2
12
|
|
|
3
13
|
### 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),
|
|
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) {
|
|
@@ -3571,11 +3580,17 @@ var MouseDown = function () {
|
|
|
3571
3580
|
return MouseDown;
|
|
3572
3581
|
}();
|
|
3573
3582
|
|
|
3574
|
-
handlers.
|
|
3583
|
+
handlers.touchstart = function (view) {
|
|
3584
|
+
view.input.lastTouch = Date.now();
|
|
3575
3585
|
forceDOMFlush(view);
|
|
3576
3586
|
setSelectionOrigin(view, "pointer");
|
|
3577
3587
|
};
|
|
3578
3588
|
|
|
3589
|
+
handlers.touchmove = function (view) {
|
|
3590
|
+
view.input.lastTouch = Date.now();
|
|
3591
|
+
setSelectionOrigin(view, "pointer");
|
|
3592
|
+
};
|
|
3593
|
+
|
|
3579
3594
|
handlers.contextmenu = function (view) {
|
|
3580
3595
|
return forceDOMFlush(view);
|
|
3581
3596
|
};
|
|
@@ -3813,7 +3828,6 @@ editHandlers.drop = function (view, _event) {
|
|
|
3813
3828
|
var eventPos = view.posAtCoords(eventCoords(event));
|
|
3814
3829
|
if (!eventPos) return;
|
|
3815
3830
|
var $mouse = view.state.doc.resolve(eventPos.pos);
|
|
3816
|
-
if (!$mouse) return;
|
|
3817
3831
|
var slice = dragging && dragging.slice;
|
|
3818
3832
|
|
|
3819
3833
|
if (slice) {
|
|
@@ -3861,6 +3875,8 @@ editHandlers.drop = function (view, _event) {
|
|
|
3861
3875
|
};
|
|
3862
3876
|
|
|
3863
3877
|
handlers.focus = function (view) {
|
|
3878
|
+
view.input.lastFocus = Date.now();
|
|
3879
|
+
|
|
3864
3880
|
if (!view.focused) {
|
|
3865
3881
|
view.domObserver.stop();
|
|
3866
3882
|
view.dom.classList.add("ProseMirror-focused");
|
|
@@ -4400,24 +4416,30 @@ var DecorationGroup = function () {
|
|
|
4400
4416
|
function mapChildren(oldChildren, newLocal, mapping, node, offset, oldOffset, options) {
|
|
4401
4417
|
var children = oldChildren.slice();
|
|
4402
4418
|
|
|
4403
|
-
var
|
|
4404
|
-
|
|
4405
|
-
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
var
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
|
|
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
|
+
}
|
|
4415
4435
|
}
|
|
4416
|
-
|
|
4436
|
+
|
|
4437
|
+
moved += dSize;
|
|
4438
|
+
});
|
|
4417
4439
|
};
|
|
4418
4440
|
|
|
4419
4441
|
for (var i = 0; i < mapping.maps.length; i++) {
|
|
4420
|
-
|
|
4442
|
+
_loop4(i);
|
|
4421
4443
|
}
|
|
4422
4444
|
|
|
4423
4445
|
var mustRebuild = false;
|
|
@@ -4509,8 +4531,8 @@ function mapAndGatherRemainingDecorations(children, oldChildren, decorations, ma
|
|
|
4509
4531
|
if (mapped) decorations.push(mapped);else if (options.onRemove) options.onRemove(set.local[i].spec);
|
|
4510
4532
|
}
|
|
4511
4533
|
|
|
4512
|
-
for (var
|
|
4513
|
-
gather(set.children[
|
|
4534
|
+
for (var _i13 = 0; _i13 < set.children.length; _i13 += 3) {
|
|
4535
|
+
gather(set.children[_i13 + 2], set.children[_i13] + oldOffset + 1);
|
|
4514
4536
|
}
|
|
4515
4537
|
}
|
|
4516
4538
|
|
|
@@ -4816,7 +4838,8 @@ var DOMObserver = function () {
|
|
|
4816
4838
|
}, {
|
|
4817
4839
|
key: "flush",
|
|
4818
4840
|
value: function flush() {
|
|
4819
|
-
|
|
4841
|
+
var view = this.view;
|
|
4842
|
+
if (!view.docView || this.flushingSoon > -1) return;
|
|
4820
4843
|
var mutations = this.observer ? this.observer.takeRecords() : [];
|
|
4821
4844
|
|
|
4822
4845
|
if (this.queue.length) {
|
|
@@ -4824,14 +4847,14 @@ var DOMObserver = function () {
|
|
|
4824
4847
|
this.queue.length = 0;
|
|
4825
4848
|
}
|
|
4826
4849
|
|
|
4827
|
-
var sel =
|
|
4828
|
-
var newSel = !this.suppressingSelectionUpdates && !this.currentSelection.eq(sel) && hasFocusAndSelection(
|
|
4850
|
+
var sel = view.domSelection();
|
|
4851
|
+
var newSel = !this.suppressingSelectionUpdates && !this.currentSelection.eq(sel) && hasFocusAndSelection(view) && !this.ignoreSelectionChange(sel);
|
|
4829
4852
|
var from = -1,
|
|
4830
4853
|
to = -1,
|
|
4831
4854
|
typeOver = false,
|
|
4832
4855
|
added = [];
|
|
4833
4856
|
|
|
4834
|
-
if (
|
|
4857
|
+
if (view.editable) {
|
|
4835
4858
|
for (var i = 0; i < mutations.length; i++) {
|
|
4836
4859
|
var result = this.registerMutation(mutations[i], added);
|
|
4837
4860
|
|
|
@@ -4855,14 +4878,21 @@ var DOMObserver = function () {
|
|
|
4855
4878
|
}
|
|
4856
4879
|
}
|
|
4857
4880
|
|
|
4858
|
-
|
|
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) {
|
|
4859
4889
|
if (from > -1) {
|
|
4860
|
-
|
|
4861
|
-
checkCSS(
|
|
4890
|
+
view.docView.markDirty(from, to);
|
|
4891
|
+
checkCSS(view);
|
|
4862
4892
|
}
|
|
4863
4893
|
|
|
4864
4894
|
this.handleDOMChange(from, to, typeOver, added);
|
|
4865
|
-
if (
|
|
4895
|
+
if (view.docView && view.docView.dirty) view.updateState(view.state);else if (!this.currentSelection.eq(sel)) selectionToDOM(view);
|
|
4866
4896
|
this.currentSelection.set(sel);
|
|
4867
4897
|
}
|
|
4868
4898
|
}
|
|
@@ -4887,8 +4917,8 @@ var DOMObserver = function () {
|
|
|
4887
4917
|
next = mut.nextSibling;
|
|
4888
4918
|
|
|
4889
4919
|
if (ie && ie_version <= 11 && mut.addedNodes.length) {
|
|
4890
|
-
for (var
|
|
4891
|
-
var _mut$addedNodes$_i = mut.addedNodes[
|
|
4920
|
+
for (var _i14 = 0; _i14 < mut.addedNodes.length; _i14++) {
|
|
4921
|
+
var _mut$addedNodes$_i = mut.addedNodes[_i14],
|
|
4892
4922
|
previousSibling = _mut$addedNodes$_i.previousSibling,
|
|
4893
4923
|
nextSibling = _mut$addedNodes$_i.nextSibling;
|
|
4894
4924
|
if (!previousSibling || Array.prototype.indexOf.call(mut.addedNodes, previousSibling) < 0) prev = previousSibling;
|
|
@@ -4922,12 +4952,19 @@ var DOMObserver = function () {
|
|
|
4922
4952
|
return DOMObserver;
|
|
4923
4953
|
}();
|
|
4924
4954
|
|
|
4925
|
-
var cssChecked =
|
|
4955
|
+
var cssChecked = new WeakMap();
|
|
4956
|
+
var cssCheckWarned = false;
|
|
4926
4957
|
|
|
4927
4958
|
function checkCSS(view) {
|
|
4928
|
-
if (cssChecked) return;
|
|
4929
|
-
cssChecked
|
|
4930
|
-
|
|
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
|
+
}
|
|
4931
4968
|
}
|
|
4932
4969
|
|
|
4933
4970
|
function parseBetween(view, from_, to_) {
|
|
@@ -5209,8 +5246,8 @@ function isMarkChange(cur, prev) {
|
|
|
5209
5246
|
added = prevMarks[i].removeFromSet(added);
|
|
5210
5247
|
}
|
|
5211
5248
|
|
|
5212
|
-
for (var
|
|
5213
|
-
removed = curMarks[
|
|
5249
|
+
for (var _i15 = 0; _i15 < curMarks.length; _i15++) {
|
|
5250
|
+
removed = curMarks[_i15].removeFromSet(removed);
|
|
5214
5251
|
}
|
|
5215
5252
|
|
|
5216
5253
|
if (added.length == 1 && removed.length == 0) {
|
|
@@ -5233,8 +5270,8 @@ function isMarkChange(cur, prev) {
|
|
|
5233
5270
|
|
|
5234
5271
|
var updated = [];
|
|
5235
5272
|
|
|
5236
|
-
for (var
|
|
5237
|
-
updated.push(update(prev.child(
|
|
5273
|
+
for (var _i16 = 0; _i16 < prev.childCount; _i16++) {
|
|
5274
|
+
updated.push(update(prev.child(_i16)));
|
|
5238
5275
|
}
|
|
5239
5276
|
|
|
5240
5277
|
if (prosemirrorModel.Fragment.from(updated).eq(cur)) return {
|
|
@@ -5327,6 +5364,7 @@ var EditorView = function () {
|
|
|
5327
5364
|
this.input = new InputState();
|
|
5328
5365
|
this.prevDirectPlugins = [];
|
|
5329
5366
|
this.pluginViews = [];
|
|
5367
|
+
this.requiresGeckoHackNode = false;
|
|
5330
5368
|
this.dragging = null;
|
|
5331
5369
|
this._props = props;
|
|
5332
5370
|
this.state = props.state;
|
|
@@ -5410,8 +5448,6 @@ var EditorView = function () {
|
|
|
5410
5448
|
}, {
|
|
5411
5449
|
key: "updateStateInner",
|
|
5412
5450
|
value: function updateStateInner(state, reconfigured) {
|
|
5413
|
-
var _this16 = this;
|
|
5414
|
-
|
|
5415
5451
|
var prev = this.state,
|
|
5416
5452
|
redraw = false,
|
|
5417
5453
|
updateSel = false;
|
|
@@ -5474,19 +5510,26 @@ var EditorView = function () {
|
|
|
5474
5510
|
if (scroll == "reset") {
|
|
5475
5511
|
this.dom.scrollTop = 0;
|
|
5476
5512
|
} else if (scroll == "to selection") {
|
|
5477
|
-
|
|
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
|
-
}
|
|
5513
|
+
this.scrollToSelection();
|
|
5486
5514
|
} else if (oldScrollPos) {
|
|
5487
5515
|
resetScrollPos(oldScrollPos);
|
|
5488
5516
|
}
|
|
5489
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
|
+
}
|
|
5490
5533
|
}, {
|
|
5491
5534
|
key: "destroyPluginViews",
|
|
5492
5535
|
value: function destroyPluginViews() {
|
|
@@ -5508,13 +5551,13 @@ var EditorView = function () {
|
|
|
5508
5551
|
if (plugin.spec.view) this.pluginViews.push(plugin.spec.view(this));
|
|
5509
5552
|
}
|
|
5510
5553
|
|
|
5511
|
-
for (var
|
|
5512
|
-
var _plugin = this.state.plugins[
|
|
5554
|
+
for (var _i17 = 0; _i17 < this.state.plugins.length; _i17++) {
|
|
5555
|
+
var _plugin = this.state.plugins[_i17];
|
|
5513
5556
|
if (_plugin.spec.view) this.pluginViews.push(_plugin.spec.view(this));
|
|
5514
5557
|
}
|
|
5515
5558
|
} else {
|
|
5516
|
-
for (var
|
|
5517
|
-
var pluginView = this.pluginViews[
|
|
5559
|
+
for (var _i18 = 0; _i18 < this.pluginViews.length; _i18++) {
|
|
5560
|
+
var pluginView = this.pluginViews[_i18];
|
|
5518
5561
|
if (pluginView.update) pluginView.update(this, prevState);
|
|
5519
5562
|
}
|
|
5520
5563
|
}
|
|
@@ -5532,8 +5575,8 @@ var EditorView = function () {
|
|
|
5532
5575
|
}
|
|
5533
5576
|
|
|
5534
5577
|
var plugins = this.state.plugins;
|
|
5535
|
-
if (plugins) for (var
|
|
5536
|
-
var _prop2 = plugins[
|
|
5578
|
+
if (plugins) for (var _i19 = 0; _i19 < plugins.length; _i19++) {
|
|
5579
|
+
var _prop2 = plugins[_i19].props[propName];
|
|
5537
5580
|
if (_prop2 != null && (value = f ? f(_prop2) : _prop2)) return value;
|
|
5538
5581
|
}
|
|
5539
5582
|
}
|
|
@@ -5558,7 +5601,7 @@ var EditorView = function () {
|
|
|
5558
5601
|
var cached = this._root;
|
|
5559
5602
|
|
|
5560
5603
|
if (cached == null) {
|
|
5561
|
-
var
|
|
5604
|
+
var _loop5 = function _loop5(search) {
|
|
5562
5605
|
if (search.nodeType == 9 || search.nodeType == 11 && search.host) {
|
|
5563
5606
|
if (!search.getSelection) Object.getPrototypeOf(search).getSelection = function () {
|
|
5564
5607
|
return search.ownerDocument.getSelection();
|
|
@@ -5570,7 +5613,7 @@ var EditorView = function () {
|
|
|
5570
5613
|
};
|
|
5571
5614
|
|
|
5572
5615
|
for (var search = this.dom.parentNode; search; search = search.parentNode) {
|
|
5573
|
-
var _ret3 =
|
|
5616
|
+
var _ret3 = _loop5(search);
|
|
5574
5617
|
|
|
5575
5618
|
if (_typeof(_ret3) === "object") return _ret3.v;
|
|
5576
5619
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -696,8 +696,8 @@ interface EditorProps<P = any> {
|
|
|
696
696
|
*/
|
|
697
697
|
clipboardTextParser?: (this: P, text: string, $context: ResolvedPos, plain: boolean) => Slice;
|
|
698
698
|
/**
|
|
699
|
-
Can be used to transform pasted
|
|
700
|
-
the document.
|
|
699
|
+
Can be used to transform pasted or dragged-and-dropped content
|
|
700
|
+
before it is applied to the document.
|
|
701
701
|
*/
|
|
702
702
|
transformPasted?: (this: P, slice: Slice) => Slice;
|
|
703
703
|
/**
|
package/dist/index.js
CHANGED
|
@@ -458,7 +458,7 @@ function coordsAtPos(view, pos, side) {
|
|
|
458
458
|
else {
|
|
459
459
|
to++;
|
|
460
460
|
}
|
|
461
|
-
return flattenV(singleRect(textRange(node, from, to),
|
|
461
|
+
return flattenV(singleRect(textRange(node, from, to), 1), takeSide < 0);
|
|
462
462
|
}
|
|
463
463
|
}
|
|
464
464
|
let $dom = view.state.doc.resolve(pos - (atom || 0));
|
|
@@ -1242,7 +1242,7 @@ class NodeViewDesc extends ViewDesc {
|
|
|
1242
1242
|
let composition = view.composing ? this.localCompositionInfo(view, pos) : null;
|
|
1243
1243
|
let localComposition = composition && composition.pos > -1 ? composition : null;
|
|
1244
1244
|
let compositionInChild = composition && composition.pos < 0;
|
|
1245
|
-
let updater = new ViewTreeUpdater(this, localComposition && localComposition.node);
|
|
1245
|
+
let updater = new ViewTreeUpdater(this, localComposition && localComposition.node, view);
|
|
1246
1246
|
iterDeco(this.node, this.innerDeco, (widget, i, insideNode) => {
|
|
1247
1247
|
if (widget.spec.marks)
|
|
1248
1248
|
updater.syncToMarks(widget.spec.marks, inline, view);
|
|
@@ -1624,8 +1624,9 @@ function rm(dom) {
|
|
|
1624
1624
|
// Helper class for incrementally updating a tree of mark descs and
|
|
1625
1625
|
// the widget and node descs inside of them.
|
|
1626
1626
|
class ViewTreeUpdater {
|
|
1627
|
-
constructor(top, lock) {
|
|
1627
|
+
constructor(top, lock, view) {
|
|
1628
1628
|
this.lock = lock;
|
|
1629
|
+
this.view = view;
|
|
1629
1630
|
// Index into `this.top`'s child array, represents the current
|
|
1630
1631
|
// update position.
|
|
1631
1632
|
this.index = 0;
|
|
@@ -1799,7 +1800,8 @@ class ViewTreeUpdater {
|
|
|
1799
1800
|
}
|
|
1800
1801
|
if (!lastChild || // Empty textblock
|
|
1801
1802
|
!(lastChild instanceof TextViewDesc) ||
|
|
1802
|
-
/\n$/.test(lastChild.node.text)
|
|
1803
|
+
/\n$/.test(lastChild.node.text) ||
|
|
1804
|
+
(this.view.requiresGeckoHackNode && /\s$/.test(lastChild.node.text))) {
|
|
1803
1805
|
// Avoid bugs in Safari's cursor drawing (#1165) and Chrome's mouse selection (#1152)
|
|
1804
1806
|
if ((safari || chrome) && lastChild && lastChild.dom.contentEditable == "false")
|
|
1805
1807
|
this.addHackNode("IMG", parent);
|
|
@@ -2772,7 +2774,8 @@ function addContext(slice, context) {
|
|
|
2772
2774
|
// A collection of DOM events that occur within the editor, and callback functions
|
|
2773
2775
|
// to invoke when the event fires.
|
|
2774
2776
|
const handlers = {};
|
|
2775
|
-
|
|
2777
|
+
const editHandlers = {};
|
|
2778
|
+
const passiveHandlers = { touchstart: true, touchmove: true };
|
|
2776
2779
|
class InputState {
|
|
2777
2780
|
constructor() {
|
|
2778
2781
|
this.shiftKey = false;
|
|
@@ -2784,6 +2787,8 @@ class InputState {
|
|
|
2784
2787
|
this.lastSelectionTime = 0;
|
|
2785
2788
|
this.lastIOSEnter = 0;
|
|
2786
2789
|
this.lastIOSEnterFallbackTimeout = -1;
|
|
2790
|
+
this.lastFocus = 0;
|
|
2791
|
+
this.lastTouch = 0;
|
|
2787
2792
|
this.lastAndroidDelete = 0;
|
|
2788
2793
|
this.composing = false;
|
|
2789
2794
|
this.composingTimeout = -1;
|
|
@@ -2801,7 +2806,7 @@ function initInput(view) {
|
|
|
2801
2806
|
if (eventBelongsToView(view, event) && !runCustomHandler(view, event) &&
|
|
2802
2807
|
(view.editable || !(event.type in editHandlers)))
|
|
2803
2808
|
handler(view, event);
|
|
2804
|
-
});
|
|
2809
|
+
}, passiveHandlers[event] ? { passive: true } : undefined);
|
|
2805
2810
|
}
|
|
2806
2811
|
// On Safari, for reasons beyond my understanding, adding an input
|
|
2807
2812
|
// event handler makes an issue where the composition vanishes when
|
|
@@ -3141,10 +3146,15 @@ class MouseDown {
|
|
|
3141
3146
|
this.done();
|
|
3142
3147
|
}
|
|
3143
3148
|
}
|
|
3144
|
-
handlers.
|
|
3149
|
+
handlers.touchstart = view => {
|
|
3150
|
+
view.input.lastTouch = Date.now();
|
|
3145
3151
|
forceDOMFlush(view);
|
|
3146
3152
|
setSelectionOrigin(view, "pointer");
|
|
3147
3153
|
};
|
|
3154
|
+
handlers.touchmove = view => {
|
|
3155
|
+
view.input.lastTouch = Date.now();
|
|
3156
|
+
setSelectionOrigin(view, "pointer");
|
|
3157
|
+
};
|
|
3148
3158
|
handlers.contextmenu = view => forceDOMFlush(view);
|
|
3149
3159
|
function inOrNearComposition(view, event) {
|
|
3150
3160
|
if (view.composing)
|
|
@@ -3396,8 +3406,6 @@ editHandlers.drop = (view, _event) => {
|
|
|
3396
3406
|
if (!eventPos)
|
|
3397
3407
|
return;
|
|
3398
3408
|
let $mouse = view.state.doc.resolve(eventPos.pos);
|
|
3399
|
-
if (!$mouse)
|
|
3400
|
-
return;
|
|
3401
3409
|
let slice = dragging && dragging.slice;
|
|
3402
3410
|
if (slice) {
|
|
3403
3411
|
view.someProp("transformPasted", f => { slice = f(slice); });
|
|
@@ -3442,6 +3450,7 @@ editHandlers.drop = (view, _event) => {
|
|
|
3442
3450
|
view.dispatch(tr.setMeta("uiEvent", "drop"));
|
|
3443
3451
|
};
|
|
3444
3452
|
handlers.focus = view => {
|
|
3453
|
+
view.input.lastFocus = Date.now();
|
|
3445
3454
|
if (!view.focused) {
|
|
3446
3455
|
view.domObserver.stop();
|
|
3447
3456
|
view.dom.classList.add("ProseMirror-focused");
|
|
@@ -3956,23 +3965,26 @@ function mapChildren(oldChildren, newLocal, mapping, node, offset, oldOffset, op
|
|
|
3956
3965
|
let children = oldChildren.slice();
|
|
3957
3966
|
// Mark the children that are directly touched by changes, and
|
|
3958
3967
|
// move those that are after the changes.
|
|
3959
|
-
let
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3968
|
+
for (let i = 0; i < mapping.maps.length; i++) {
|
|
3969
|
+
let moved = 0;
|
|
3970
|
+
mapping.maps[i].forEach((oldStart, oldEnd, newStart, newEnd) => {
|
|
3971
|
+
let dSize = (newEnd - newStart) - (oldEnd - oldStart);
|
|
3972
|
+
for (let i = 0; i < children.length; i += 3) {
|
|
3973
|
+
let end = children[i + 1];
|
|
3974
|
+
if (end < 0 || oldStart > end + oldOffset - moved)
|
|
3975
|
+
continue;
|
|
3976
|
+
let start = children[i] + oldOffset - moved;
|
|
3977
|
+
if (oldEnd >= start) {
|
|
3978
|
+
children[i + 1] = oldStart <= start ? -2 : -1;
|
|
3979
|
+
}
|
|
3980
|
+
else if (newStart >= offset && dSize) {
|
|
3981
|
+
children[i] += dSize;
|
|
3982
|
+
children[i + 1] += dSize;
|
|
3983
|
+
}
|
|
3971
3984
|
}
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
mapping.maps[i].forEach(shift);
|
|
3985
|
+
moved += dSize;
|
|
3986
|
+
});
|
|
3987
|
+
}
|
|
3976
3988
|
// Find the child nodes that still correspond to a single node,
|
|
3977
3989
|
// recursively call mapInner on them and update their positions.
|
|
3978
3990
|
let mustRebuild = false;
|
|
@@ -4300,17 +4312,18 @@ class DOMObserver {
|
|
|
4300
4312
|
}
|
|
4301
4313
|
}
|
|
4302
4314
|
flush() {
|
|
4303
|
-
|
|
4315
|
+
let { view } = this;
|
|
4316
|
+
if (!view.docView || this.flushingSoon > -1)
|
|
4304
4317
|
return;
|
|
4305
4318
|
let mutations = this.observer ? this.observer.takeRecords() : [];
|
|
4306
4319
|
if (this.queue.length) {
|
|
4307
4320
|
mutations = this.queue.concat(mutations);
|
|
4308
4321
|
this.queue.length = 0;
|
|
4309
4322
|
}
|
|
4310
|
-
let sel =
|
|
4311
|
-
let newSel = !this.suppressingSelectionUpdates && !this.currentSelection.eq(sel) && hasFocusAndSelection(
|
|
4323
|
+
let sel = view.domSelection();
|
|
4324
|
+
let newSel = !this.suppressingSelectionUpdates && !this.currentSelection.eq(sel) && hasFocusAndSelection(view) && !this.ignoreSelectionChange(sel);
|
|
4312
4325
|
let from = -1, to = -1, typeOver = false, added = [];
|
|
4313
|
-
if (
|
|
4326
|
+
if (view.editable) {
|
|
4314
4327
|
for (let i = 0; i < mutations.length; i++) {
|
|
4315
4328
|
let result = this.registerMutation(mutations[i], added);
|
|
4316
4329
|
if (result) {
|
|
@@ -4331,16 +4344,29 @@ class DOMObserver {
|
|
|
4331
4344
|
a.remove();
|
|
4332
4345
|
}
|
|
4333
4346
|
}
|
|
4334
|
-
|
|
4347
|
+
let readSel = null;
|
|
4348
|
+
// If it looks like the browser has reset the selection to the
|
|
4349
|
+
// start of the document after focus, restore the selection from
|
|
4350
|
+
// the state
|
|
4351
|
+
if (from < 0 && newSel && view.input.lastFocus > Date.now() - 200 &&
|
|
4352
|
+
view.input.lastTouch < Date.now() - 300 &&
|
|
4353
|
+
selectionCollapsed(sel) && (readSel = selectionFromDOM(view)) &&
|
|
4354
|
+
readSel.eq(Selection.near(view.state.doc.resolve(0), 1))) {
|
|
4355
|
+
view.input.lastFocus = 0;
|
|
4356
|
+
selectionToDOM(view);
|
|
4357
|
+
this.currentSelection.set(sel);
|
|
4358
|
+
view.scrollToSelection();
|
|
4359
|
+
}
|
|
4360
|
+
else if (from > -1 || newSel) {
|
|
4335
4361
|
if (from > -1) {
|
|
4336
|
-
|
|
4337
|
-
checkCSS(
|
|
4362
|
+
view.docView.markDirty(from, to);
|
|
4363
|
+
checkCSS(view);
|
|
4338
4364
|
}
|
|
4339
4365
|
this.handleDOMChange(from, to, typeOver, added);
|
|
4340
|
-
if (
|
|
4341
|
-
|
|
4366
|
+
if (view.docView && view.docView.dirty)
|
|
4367
|
+
view.updateState(view.state);
|
|
4342
4368
|
else if (!this.currentSelection.eq(sel))
|
|
4343
|
-
selectionToDOM(
|
|
4369
|
+
selectionToDOM(view);
|
|
4344
4370
|
this.currentSelection.set(sel);
|
|
4345
4371
|
}
|
|
4346
4372
|
}
|
|
@@ -4397,13 +4423,19 @@ class DOMObserver {
|
|
|
4397
4423
|
}
|
|
4398
4424
|
}
|
|
4399
4425
|
}
|
|
4400
|
-
let cssChecked =
|
|
4426
|
+
let cssChecked = new WeakMap();
|
|
4427
|
+
let cssCheckWarned = false;
|
|
4401
4428
|
function checkCSS(view) {
|
|
4402
|
-
if (cssChecked)
|
|
4429
|
+
if (cssChecked.has(view))
|
|
4403
4430
|
return;
|
|
4404
|
-
cssChecked
|
|
4405
|
-
if (getComputedStyle(view.dom).whiteSpace
|
|
4431
|
+
cssChecked.set(view, null);
|
|
4432
|
+
if (['normal', 'nowrap', 'pre-line'].indexOf(getComputedStyle(view.dom).whiteSpace) !== -1) {
|
|
4433
|
+
view.requiresGeckoHackNode = gecko;
|
|
4434
|
+
if (cssCheckWarned)
|
|
4435
|
+
return;
|
|
4406
4436
|
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.");
|
|
4437
|
+
cssCheckWarned = true;
|
|
4438
|
+
}
|
|
4407
4439
|
}
|
|
4408
4440
|
|
|
4409
4441
|
// Note that all referencing and parsing is done with the
|
|
@@ -4810,6 +4842,12 @@ class EditorView {
|
|
|
4810
4842
|
this.prevDirectPlugins = [];
|
|
4811
4843
|
this.pluginViews = [];
|
|
4812
4844
|
/**
|
|
4845
|
+
Holds `true` when a hack node is needed in Firefox to prevent the
|
|
4846
|
+
[space is eaten issue](https://github.com/ProseMirror/prosemirror/issues/651)
|
|
4847
|
+
@internal
|
|
4848
|
+
*/
|
|
4849
|
+
this.requiresGeckoHackNode = false;
|
|
4850
|
+
/**
|
|
4813
4851
|
When editor content is being dragged, this object contains
|
|
4814
4852
|
information about the dragged slice and whether it is being
|
|
4815
4853
|
copied or moved. At any other time, it is null.
|
|
@@ -4960,21 +4998,27 @@ class EditorView {
|
|
|
4960
4998
|
this.dom.scrollTop = 0;
|
|
4961
4999
|
}
|
|
4962
5000
|
else if (scroll == "to selection") {
|
|
4963
|
-
|
|
4964
|
-
if (this.someProp("handleScrollToSelection", f => f(this))) ;
|
|
4965
|
-
else if (state.selection instanceof NodeSelection) {
|
|
4966
|
-
let target = this.docView.domAfterPos(state.selection.from);
|
|
4967
|
-
if (target.nodeType == 1)
|
|
4968
|
-
scrollRectIntoView(this, target.getBoundingClientRect(), startDOM);
|
|
4969
|
-
}
|
|
4970
|
-
else {
|
|
4971
|
-
scrollRectIntoView(this, this.coordsAtPos(state.selection.head, 1), startDOM);
|
|
4972
|
-
}
|
|
5001
|
+
this.scrollToSelection();
|
|
4973
5002
|
}
|
|
4974
5003
|
else if (oldScrollPos) {
|
|
4975
5004
|
resetScrollPos(oldScrollPos);
|
|
4976
5005
|
}
|
|
4977
5006
|
}
|
|
5007
|
+
/**
|
|
5008
|
+
@internal
|
|
5009
|
+
*/
|
|
5010
|
+
scrollToSelection() {
|
|
5011
|
+
let startDOM = this.domSelection().focusNode;
|
|
5012
|
+
if (this.someProp("handleScrollToSelection", f => f(this))) ;
|
|
5013
|
+
else if (this.state.selection instanceof NodeSelection) {
|
|
5014
|
+
let target = this.docView.domAfterPos(this.state.selection.from);
|
|
5015
|
+
if (target.nodeType == 1)
|
|
5016
|
+
scrollRectIntoView(this, target.getBoundingClientRect(), startDOM);
|
|
5017
|
+
}
|
|
5018
|
+
else {
|
|
5019
|
+
scrollRectIntoView(this, this.coordsAtPos(this.state.selection.head, 1), startDOM);
|
|
5020
|
+
}
|
|
5021
|
+
}
|
|
4978
5022
|
destroyPluginViews() {
|
|
4979
5023
|
let view;
|
|
4980
5024
|
while (view = this.pluginViews.pop())
|