prosemirror-view 1.42.6 → 1.42.7
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 +16 -0
- package/dist/index.cjs +158 -116
- package/dist/index.js +77 -37
- package/package.json +1 -1
- package/src/capturekeys.ts +11 -9
- package/src/decoration.ts +37 -13
- package/src/domchange.ts +4 -3
- package/src/domobserver.ts +9 -6
- package/src/viewdesc.ts +6 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
## 1.42.7 (2026-10-22)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Fix an issue where some kinds of changes inside inline nodes with content were inappropriately treated as backspace events.
|
|
6
|
+
|
|
7
|
+
Fix some selection issues in a shadow root on Safari by working around the relevant browser bugs.
|
|
8
|
+
|
|
9
|
+
Improve cursor motion across non-text in blocks that don't have the same text direction as the editor as a whole.
|
|
10
|
+
|
|
11
|
+
Fix an issue where decoration sets with lots of node decorations inside a single parent would require quadratic time to update.
|
|
12
|
+
|
|
13
|
+
Fix a regression in `posAtDOM` (and DOM selection reading) when the position is outside the nearest node's content DOM, but not directly in its outer element.
|
|
14
|
+
|
|
15
|
+
Avoid a selection read in DOM flushing when the editor doesn't have focus.
|
|
16
|
+
|
|
1
17
|
## 1.42.6 (2026-09-25)
|
|
2
18
|
|
|
3
19
|
### Bug fixes
|
package/dist/index.cjs
CHANGED
|
@@ -754,6 +754,7 @@ var ViewDesc = function () {
|
|
|
754
754
|
}, {
|
|
755
755
|
key: "localPosFromDOM",
|
|
756
756
|
value: function localPosFromDOM(dom, offset, bias) {
|
|
757
|
+
var _this = this;
|
|
757
758
|
if (this.contentDOM && contains(this.contentDOM, dom)) {
|
|
758
759
|
if (bias < 0) {
|
|
759
760
|
var domBefore, desc;
|
|
@@ -781,7 +782,14 @@ var ViewDesc = function () {
|
|
|
781
782
|
if (dom == this.dom && this.contentDOM) {
|
|
782
783
|
atEnd = offset > domIndex(this.contentDOM);
|
|
783
784
|
} else if (this.contentDOM && this.contentDOM != this.dom && this.dom.contains(this.contentDOM)) {
|
|
784
|
-
|
|
785
|
+
var rel = dom.compareDocumentPosition(this.contentDOM);
|
|
786
|
+
if (rel & 16) {
|
|
787
|
+
atEnd = offset > Array.from(dom.childNodes).findIndex(function (n) {
|
|
788
|
+
return n.contains(_this.contentDOM);
|
|
789
|
+
});
|
|
790
|
+
} else {
|
|
791
|
+
atEnd = !(rel & 4);
|
|
792
|
+
}
|
|
785
793
|
} else if (this.dom.firstChild) {
|
|
786
794
|
if (offset == 0) for (var search = dom;; search = search.parentNode) {
|
|
787
795
|
if (search == this.dom) {
|
|
@@ -1102,7 +1110,7 @@ var WidgetViewDesc = function (_ViewDesc) {
|
|
|
1102
1110
|
_inherits(WidgetViewDesc, _ViewDesc);
|
|
1103
1111
|
var _super = _createSuper(WidgetViewDesc);
|
|
1104
1112
|
function WidgetViewDesc(parent, widget, view, pos) {
|
|
1105
|
-
var
|
|
1113
|
+
var _this2;
|
|
1106
1114
|
_classCallCheck(this, WidgetViewDesc);
|
|
1107
1115
|
var self,
|
|
1108
1116
|
dom = widget.type.toDOM;
|
|
@@ -1116,11 +1124,11 @@ var WidgetViewDesc = function (_ViewDesc) {
|
|
|
1116
1124
|
if (!elt.hasAttribute("contenteditable")) elt.contentEditable = "false";
|
|
1117
1125
|
elt.classList.add("ProseMirror-widget");
|
|
1118
1126
|
}
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
self = _assertThisInitialized(
|
|
1123
|
-
return
|
|
1127
|
+
_this2 = _super.call(this, parent, [], dom, null);
|
|
1128
|
+
_this2.widget = widget;
|
|
1129
|
+
_this2.widget = widget;
|
|
1130
|
+
self = _assertThisInitialized(_this2);
|
|
1131
|
+
return _this2;
|
|
1124
1132
|
}
|
|
1125
1133
|
_createClass(WidgetViewDesc, [{
|
|
1126
1134
|
key: "matchesWidget",
|
|
@@ -1173,12 +1181,12 @@ var CompositionViewDesc = function (_ViewDesc2) {
|
|
|
1173
1181
|
_inherits(CompositionViewDesc, _ViewDesc2);
|
|
1174
1182
|
var _super2 = _createSuper(CompositionViewDesc);
|
|
1175
1183
|
function CompositionViewDesc(parent, dom, textDOM, text) {
|
|
1176
|
-
var
|
|
1184
|
+
var _this3;
|
|
1177
1185
|
_classCallCheck(this, CompositionViewDesc);
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
return
|
|
1186
|
+
_this3 = _super2.call(this, parent, [], dom, null);
|
|
1187
|
+
_this3.textDOM = textDOM;
|
|
1188
|
+
_this3.text = text;
|
|
1189
|
+
return _this3;
|
|
1182
1190
|
}
|
|
1183
1191
|
_createClass(CompositionViewDesc, [{
|
|
1184
1192
|
key: "size",
|
|
@@ -1211,12 +1219,12 @@ var MarkViewDesc = function (_ViewDesc3) {
|
|
|
1211
1219
|
_inherits(MarkViewDesc, _ViewDesc3);
|
|
1212
1220
|
var _super3 = _createSuper(MarkViewDesc);
|
|
1213
1221
|
function MarkViewDesc(parent, mark, dom, contentDOM, spec) {
|
|
1214
|
-
var
|
|
1222
|
+
var _this4;
|
|
1215
1223
|
_classCallCheck(this, MarkViewDesc);
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
return
|
|
1224
|
+
_this4 = _super3.call(this, parent, [], dom, contentDOM);
|
|
1225
|
+
_this4.mark = mark;
|
|
1226
|
+
_this4.spec = spec;
|
|
1227
|
+
return _this4;
|
|
1220
1228
|
}
|
|
1221
1229
|
_createClass(MarkViewDesc, [{
|
|
1222
1230
|
key: "parseRule",
|
|
@@ -1282,19 +1290,19 @@ var NodeViewDesc = function (_ViewDesc4) {
|
|
|
1282
1290
|
_inherits(NodeViewDesc, _ViewDesc4);
|
|
1283
1291
|
var _super4 = _createSuper(NodeViewDesc);
|
|
1284
1292
|
function NodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM) {
|
|
1285
|
-
var
|
|
1293
|
+
var _this5;
|
|
1286
1294
|
_classCallCheck(this, NodeViewDesc);
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
return
|
|
1295
|
+
_this5 = _super4.call(this, parent, [], dom, contentDOM);
|
|
1296
|
+
_this5.node = node;
|
|
1297
|
+
_this5.outerDeco = outerDeco;
|
|
1298
|
+
_this5.innerDeco = innerDeco;
|
|
1299
|
+
_this5.nodeDOM = nodeDOM;
|
|
1300
|
+
return _this5;
|
|
1293
1301
|
}
|
|
1294
1302
|
_createClass(NodeViewDesc, [{
|
|
1295
1303
|
key: "parseRule",
|
|
1296
1304
|
value: function parseRule(addedNodes) {
|
|
1297
|
-
var
|
|
1305
|
+
var _this6 = this;
|
|
1298
1306
|
if (this.node.type.spec.reparseInView) return null;
|
|
1299
1307
|
var rule = {
|
|
1300
1308
|
node: this.node.type.name,
|
|
@@ -1303,7 +1311,7 @@ var NodeViewDesc = function (_ViewDesc4) {
|
|
|
1303
1311
|
if (this.node.type.whitespace == "pre") rule.preserveWhitespace = "full";
|
|
1304
1312
|
if (!this.contentDOM) {
|
|
1305
1313
|
rule.getContent = function () {
|
|
1306
|
-
return
|
|
1314
|
+
return _this6.node.content;
|
|
1307
1315
|
};
|
|
1308
1316
|
} else if (!this.contentLost) {
|
|
1309
1317
|
rule.contentElement = this.contentDOM;
|
|
@@ -1317,7 +1325,7 @@ var NodeViewDesc = function (_ViewDesc4) {
|
|
|
1317
1325
|
}
|
|
1318
1326
|
if (!rule.contentElement) {
|
|
1319
1327
|
var found = addedNodes && addedNodes.find(function (n) {
|
|
1320
|
-
return isElt(n) && addedNodes.indexOf(n.parentNode) < 0 &&
|
|
1328
|
+
return isElt(n) && addedNodes.indexOf(n.parentNode) < 0 && _this6.dom.contains(n);
|
|
1321
1329
|
});
|
|
1322
1330
|
if (found) rule.contentElement = found;else rule.getContent = function () {
|
|
1323
1331
|
return prosemirrorModel.Fragment.empty;
|
|
@@ -1344,7 +1352,7 @@ var NodeViewDesc = function (_ViewDesc4) {
|
|
|
1344
1352
|
}, {
|
|
1345
1353
|
key: "updateChildren",
|
|
1346
1354
|
value: function updateChildren(view, pos) {
|
|
1347
|
-
var
|
|
1355
|
+
var _this7 = this;
|
|
1348
1356
|
var inline = this.node.inlineContent,
|
|
1349
1357
|
off = pos;
|
|
1350
1358
|
var composition = view.composing ? this.localCompositionInfo(view, pos) : null;
|
|
@@ -1354,7 +1362,7 @@ var NodeViewDesc = function (_ViewDesc4) {
|
|
|
1354
1362
|
var addBuffers = this.node.inlineContent,
|
|
1355
1363
|
atBufferPos = addBuffers && this.node.isBlock;
|
|
1356
1364
|
iterDeco(this.node, this.innerDeco, function (widget, i, insideNode) {
|
|
1357
|
-
if (widget.spec.marks) updater.syncToMarks(widget.spec.marks, inline, view, i);else if (widget.type.side >= 0 && !insideNode) updater.syncToMarks(i ==
|
|
1365
|
+
if (widget.spec.marks) updater.syncToMarks(widget.spec.marks, inline, view, i);else if (widget.type.side >= 0 && !insideNode) updater.syncToMarks(i == _this7.node.childCount ? prosemirrorModel.Mark.none : _this7.node.child(i).marks, inline, view, i);
|
|
1358
1366
|
updater.placeWidget(widget, view, off);
|
|
1359
1367
|
}, function (child, outerDeco, innerDeco, i) {
|
|
1360
1368
|
updater.syncToMarks(child.marks, inline, view, i);
|
|
@@ -1620,11 +1628,11 @@ var CustomNodeViewDesc = function (_NodeViewDesc2) {
|
|
|
1620
1628
|
_inherits(CustomNodeViewDesc, _NodeViewDesc2);
|
|
1621
1629
|
var _super7 = _createSuper(CustomNodeViewDesc);
|
|
1622
1630
|
function CustomNodeViewDesc(parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM, spec) {
|
|
1623
|
-
var
|
|
1631
|
+
var _this8;
|
|
1624
1632
|
_classCallCheck(this, CustomNodeViewDesc);
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
return
|
|
1633
|
+
_this8 = _super7.call(this, parent, node, outerDeco, innerDeco, dom, contentDOM, nodeDOM);
|
|
1634
|
+
_this8.spec = spec;
|
|
1635
|
+
return _this8;
|
|
1628
1636
|
}
|
|
1629
1637
|
_createClass(CustomNodeViewDesc, [{
|
|
1630
1638
|
key: "update",
|
|
@@ -2391,7 +2399,7 @@ function selectHorizontally(view, dir, mods) {
|
|
|
2391
2399
|
var next = moveSelectionBlock(view.state, dir);
|
|
2392
2400
|
if (next && next instanceof prosemirrorState.NodeSelection) return apply(view, next);
|
|
2393
2401
|
return false;
|
|
2394
|
-
} else if (!
|
|
2402
|
+
} else if (!mac || mods.indexOf("m") < 0) {
|
|
2395
2403
|
var _$head = sel.$head,
|
|
2396
2404
|
_node = _$head.textOffset ? null : dir < 0 ? _$head.nodeBefore : _$head.nodeAfter,
|
|
2397
2405
|
desc;
|
|
@@ -2542,15 +2550,13 @@ function setSelFocus(view, node, offset) {
|
|
|
2542
2550
|
offset = before.nodeValue.length;
|
|
2543
2551
|
}
|
|
2544
2552
|
}
|
|
2545
|
-
var sel = view.domSelection()
|
|
2553
|
+
var sel = view.domSelection(),
|
|
2554
|
+
range = view.domSelectionRange();
|
|
2546
2555
|
if (!sel) return;
|
|
2547
|
-
if (selectionCollapsed(
|
|
2548
|
-
|
|
2549
|
-
range.setEnd(node, offset);
|
|
2550
|
-
range.setStart(node, offset);
|
|
2551
|
-
sel.removeAllRanges();
|
|
2552
|
-
sel.addRange(range);
|
|
2556
|
+
if (selectionCollapsed(range)) {
|
|
2557
|
+
sel.collapse(node, offset);
|
|
2553
2558
|
} else if (sel.extend) {
|
|
2559
|
+
sel.collapse(range.anchorNode, range.anchorOffset);
|
|
2554
2560
|
sel.extend(node, offset);
|
|
2555
2561
|
}
|
|
2556
2562
|
view.domObserver.setCurSelection();
|
|
@@ -2574,7 +2580,12 @@ function findDirection(view, pos) {
|
|
|
2574
2580
|
if (_mid > coords.top && _mid < coords.bottom && Math.abs(after.left - coords.left) > 1) return after.left > coords.left ? "ltr" : "rtl";
|
|
2575
2581
|
}
|
|
2576
2582
|
}
|
|
2577
|
-
var
|
|
2583
|
+
var block = view.dom;
|
|
2584
|
+
for (var d = $pos.depth; d > 0; d--) if ($pos.node(d).isBlock) {
|
|
2585
|
+
block = view.nodeDOM($pos.before(d)) || block;
|
|
2586
|
+
break;
|
|
2587
|
+
}
|
|
2588
|
+
var computed = getComputedStyle(block).direction;
|
|
2578
2589
|
return computed == "rtl" ? "rtl" : "ltr";
|
|
2579
2590
|
}
|
|
2580
2591
|
function selectVertically(view, dir, mods) {
|
|
@@ -3245,16 +3256,16 @@ var LeftMouseDown = function (_MouseDown) {
|
|
|
3245
3256
|
_inherits(LeftMouseDown, _MouseDown);
|
|
3246
3257
|
var _super8 = _createSuper(LeftMouseDown);
|
|
3247
3258
|
function LeftMouseDown(view, pos, event, flushed) {
|
|
3248
|
-
var
|
|
3259
|
+
var _this9;
|
|
3249
3260
|
_classCallCheck(this, LeftMouseDown);
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3261
|
+
_this9 = _super8.call(this, view);
|
|
3262
|
+
_this9.pos = pos;
|
|
3263
|
+
_this9.event = event;
|
|
3264
|
+
_this9.flushed = flushed;
|
|
3265
|
+
_this9.delayedSelectionSync = false;
|
|
3266
|
+
_this9.startDoc = view.state.doc;
|
|
3267
|
+
_this9.selectNode = !!event[selectNodeModifier];
|
|
3268
|
+
_this9.allowDefault = event.shiftKey;
|
|
3258
3269
|
var targetNode, targetPos;
|
|
3259
3270
|
if (pos.inside > -1) {
|
|
3260
3271
|
targetNode = view.state.doc.nodeAt(pos.inside);
|
|
@@ -3266,29 +3277,29 @@ var LeftMouseDown = function (_MouseDown) {
|
|
|
3266
3277
|
}
|
|
3267
3278
|
var target = flushed ? null : event.target;
|
|
3268
3279
|
var targetDesc = target ? view.docView.nearestDesc(target, true) : null;
|
|
3269
|
-
|
|
3280
|
+
_this9.target = targetDesc && isElt(targetDesc.nodeDOM) ? targetDesc.nodeDOM : null;
|
|
3270
3281
|
var selection = view.state.selection;
|
|
3271
|
-
if (event.button == 0 && (targetNode.type.spec.draggable && targetNode.type.spec.selectable !== false || selection instanceof prosemirrorState.NodeSelection && selection.from <= targetPos && selection.to > targetPos))
|
|
3282
|
+
if (event.button == 0 && (targetNode.type.spec.draggable && targetNode.type.spec.selectable !== false || selection instanceof prosemirrorState.NodeSelection && selection.from <= targetPos && selection.to > targetPos)) _this9.mightDrag = {
|
|
3272
3283
|
node: targetNode,
|
|
3273
3284
|
pos: targetPos,
|
|
3274
|
-
addAttr: !!(
|
|
3275
|
-
setUneditable: !!(
|
|
3285
|
+
addAttr: !!(_this9.target && !_this9.target.draggable),
|
|
3286
|
+
setUneditable: !!(_this9.target && gecko && !_this9.target.hasAttribute("contentEditable"))
|
|
3276
3287
|
};
|
|
3277
|
-
if (
|
|
3278
|
-
|
|
3279
|
-
if (
|
|
3280
|
-
if (
|
|
3281
|
-
if (
|
|
3288
|
+
if (_this9.target && _this9.mightDrag && (_this9.mightDrag.addAttr || _this9.mightDrag.setUneditable)) {
|
|
3289
|
+
_this9.view.domObserver.stop();
|
|
3290
|
+
if (_this9.mightDrag.addAttr) _this9.target.draggable = true;
|
|
3291
|
+
if (_this9.mightDrag.setUneditable) setTimeout(function () {
|
|
3292
|
+
if (_this9.view.input.mouseDown == _assertThisInitialized(_this9)) _this9.target.setAttribute("contentEditable", "false");
|
|
3282
3293
|
}, 20);
|
|
3283
|
-
|
|
3294
|
+
_this9.view.domObserver.start();
|
|
3284
3295
|
}
|
|
3285
3296
|
setSelectionOrigin(view, "pointer");
|
|
3286
|
-
return
|
|
3297
|
+
return _this9;
|
|
3287
3298
|
}
|
|
3288
3299
|
_createClass(LeftMouseDown, [{
|
|
3289
3300
|
key: "done",
|
|
3290
3301
|
value: function done() {
|
|
3291
|
-
var
|
|
3302
|
+
var _this10 = this;
|
|
3292
3303
|
_get(_getPrototypeOf(LeftMouseDown.prototype), "done", this).call(this);
|
|
3293
3304
|
if (this.mightDrag && this.target) {
|
|
3294
3305
|
this.view.domObserver.stop();
|
|
@@ -3297,7 +3308,7 @@ var LeftMouseDown = function (_MouseDown) {
|
|
|
3297
3308
|
this.view.domObserver.start();
|
|
3298
3309
|
}
|
|
3299
3310
|
if (this.delayedSelectionSync) setTimeout(function () {
|
|
3300
|
-
if (!
|
|
3311
|
+
if (!_this10.view.isDestroyed) selectionToDOM(_this10.view);
|
|
3301
3312
|
});
|
|
3302
3313
|
}
|
|
3303
3314
|
}, {
|
|
@@ -3345,12 +3356,12 @@ var TripleClickDrag = function (_MouseDown2) {
|
|
|
3345
3356
|
_inherits(TripleClickDrag, _MouseDown2);
|
|
3346
3357
|
var _super9 = _createSuper(TripleClickDrag);
|
|
3347
3358
|
function TripleClickDrag(view, startSelection) {
|
|
3348
|
-
var
|
|
3359
|
+
var _this11;
|
|
3349
3360
|
_classCallCheck(this, TripleClickDrag);
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
return
|
|
3361
|
+
_this11 = _super9.call(this, view);
|
|
3362
|
+
_this11.startSelection = startSelection;
|
|
3363
|
+
_this11.startDoc = view.state.doc;
|
|
3364
|
+
return _this11;
|
|
3354
3365
|
}
|
|
3355
3366
|
_createClass(TripleClickDrag, [{
|
|
3356
3367
|
key: "move",
|
|
@@ -3720,6 +3731,27 @@ function compareObjs(a, b) {
|
|
|
3720
3731
|
for (var _p in b) if (!(_p in a)) return false;
|
|
3721
3732
|
return true;
|
|
3722
3733
|
}
|
|
3734
|
+
var FragmentCursor = function () {
|
|
3735
|
+
function FragmentCursor(frag) {
|
|
3736
|
+
_classCallCheck(this, FragmentCursor);
|
|
3737
|
+
this.frag = frag;
|
|
3738
|
+
this.index = 0;
|
|
3739
|
+
this.off = 0;
|
|
3740
|
+
}
|
|
3741
|
+
_createClass(FragmentCursor, [{
|
|
3742
|
+
key: "nodeAt",
|
|
3743
|
+
value: function nodeAt(off) {
|
|
3744
|
+
while (this.off <= off && this.index < this.frag.childCount) {
|
|
3745
|
+
var next = this.frag.child(this.index);
|
|
3746
|
+
if (this.off == off) return next;
|
|
3747
|
+
this.off += next.nodeSize;
|
|
3748
|
+
this.index++;
|
|
3749
|
+
}
|
|
3750
|
+
return null;
|
|
3751
|
+
}
|
|
3752
|
+
}]);
|
|
3753
|
+
return FragmentCursor;
|
|
3754
|
+
}();
|
|
3723
3755
|
var WidgetType = function () {
|
|
3724
3756
|
function WidgetType(toDOM, spec) {
|
|
3725
3757
|
_classCallCheck(this, WidgetType);
|
|
@@ -3804,12 +3836,9 @@ var NodeType = function () {
|
|
|
3804
3836
|
}
|
|
3805
3837
|
}, {
|
|
3806
3838
|
key: "valid",
|
|
3807
|
-
value: function valid(node, span) {
|
|
3808
|
-
var
|
|
3809
|
-
|
|
3810
|
-
offset = _node$content$findInd.offset,
|
|
3811
|
-
child;
|
|
3812
|
-
return offset == span.from && !(child = node.child(index)).isText && offset + child.nodeSize == span.to;
|
|
3839
|
+
value: function valid(node, span, cursor) {
|
|
3840
|
+
var found = cursor.nodeAt(span.from);
|
|
3841
|
+
return !!found && !found.isText && span.from + found.nodeSize == span.to;
|
|
3813
3842
|
}
|
|
3814
3843
|
}, {
|
|
3815
3844
|
key: "eq",
|
|
@@ -3917,9 +3946,12 @@ var DecorationSet = function () {
|
|
|
3917
3946
|
key: "mapInner",
|
|
3918
3947
|
value: function mapInner(mapping, node, offset, oldOffset, options) {
|
|
3919
3948
|
var newLocal;
|
|
3920
|
-
|
|
3921
|
-
var
|
|
3922
|
-
|
|
3949
|
+
if (this.local.length) {
|
|
3950
|
+
var cur = new FragmentCursor(node.content);
|
|
3951
|
+
for (var i = 0; i < this.local.length; i++) {
|
|
3952
|
+
var mapped = this.local[i].map(mapping, offset, oldOffset);
|
|
3953
|
+
if (mapped && mapped.type.valid(node, mapped, cur)) (newLocal || (newLocal = [])).push(mapped);else if (options.onRemove) options.onRemove(this.local[i].spec);
|
|
3954
|
+
}
|
|
3923
3955
|
}
|
|
3924
3956
|
if (this.children.length) return mapChildren(this.children, newLocal || [], mapping, node, offset, oldOffset, options);else return newLocal ? new DecorationSet(newLocal.sort(byPos), none) : empty;
|
|
3925
3957
|
}
|
|
@@ -3933,20 +3965,23 @@ var DecorationSet = function () {
|
|
|
3933
3965
|
}, {
|
|
3934
3966
|
key: "addInner",
|
|
3935
3967
|
value: function addInner(doc, decorations, offset) {
|
|
3936
|
-
var
|
|
3968
|
+
var _this12 = this;
|
|
3937
3969
|
var children,
|
|
3938
3970
|
childIndex = 0;
|
|
3939
3971
|
doc.forEach(function (childNode, childOffset) {
|
|
3940
3972
|
var baseOffset = childOffset + offset,
|
|
3941
3973
|
found;
|
|
3942
3974
|
if (!(found = takeSpansForNode(decorations, childNode, baseOffset))) return;
|
|
3943
|
-
if (!children) children =
|
|
3975
|
+
if (!children) children = _this12.children.slice();
|
|
3944
3976
|
while (childIndex < children.length && children[childIndex] < childOffset) childIndex += 3;
|
|
3945
3977
|
if (children[childIndex] == childOffset) children[childIndex + 2] = children[childIndex + 2].addInner(childNode, found, baseOffset + 1);else children.splice(childIndex, 0, childOffset, childOffset + childNode.nodeSize, buildTree(found, childNode, baseOffset + 1, noSpec));
|
|
3946
3978
|
childIndex += 3;
|
|
3947
3979
|
});
|
|
3948
3980
|
var local = moveSpans(childIndex ? withoutNulls(decorations) : decorations, -offset);
|
|
3949
|
-
|
|
3981
|
+
if (local.length) {
|
|
3982
|
+
var cur = new FragmentCursor(doc.content);
|
|
3983
|
+
for (var i = 0; i < local.length; i++) if (!local[i].type.valid(doc, local[i], cur)) local.splice(i--, 1);
|
|
3984
|
+
}
|
|
3950
3985
|
return new DecorationSet(local.length ? this.local.concat(local).sort(byPos) : this.local, children || this.children);
|
|
3951
3986
|
}
|
|
3952
3987
|
}, {
|
|
@@ -4172,9 +4207,9 @@ function mapChildren(oldChildren, newLocal, mapping, node, offset, oldOffset, op
|
|
|
4172
4207
|
}
|
|
4173
4208
|
var to = mapping.map(oldChildren[_i11 + 1] + oldOffset, -1),
|
|
4174
4209
|
toLocal = to - offset;
|
|
4175
|
-
var _node$content$
|
|
4176
|
-
index = _node$content$
|
|
4177
|
-
childOffset = _node$content$
|
|
4210
|
+
var _node$content$findInd = node.content.findIndex(fromLocal),
|
|
4211
|
+
index = _node$content$findInd.index,
|
|
4212
|
+
childOffset = _node$content$findInd.offset;
|
|
4178
4213
|
var childNode = node.maybeChild(index);
|
|
4179
4214
|
if (childNode && childOffset == fromLocal && childOffset + childNode.nodeSize == toLocal) {
|
|
4180
4215
|
var mapped = children[_i11 + 2].mapInner(mapping, childNode, from + 1, oldChildren[_i11] + oldOffset + 1, options);
|
|
@@ -4255,9 +4290,12 @@ function buildTree(spans, node, offset, options) {
|
|
|
4255
4290
|
}
|
|
4256
4291
|
});
|
|
4257
4292
|
var locals = moveSpans(hasNulls ? withoutNulls(spans) : spans, -offset).sort(byPos);
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
locals.
|
|
4293
|
+
if (locals.length) {
|
|
4294
|
+
var cur = new FragmentCursor(node.content);
|
|
4295
|
+
for (var i = 0; i < locals.length; i++) if (!locals[i].type.valid(node, locals[i], cur)) {
|
|
4296
|
+
if (options.onRemove) options.onRemove(locals[i].spec);
|
|
4297
|
+
locals.splice(i--, 1);
|
|
4298
|
+
}
|
|
4261
4299
|
}
|
|
4262
4300
|
return locals.length || children.length ? new DecorationSet(locals, children) : empty;
|
|
4263
4301
|
}
|
|
@@ -4342,7 +4380,7 @@ var SelectionState = function () {
|
|
|
4342
4380
|
}();
|
|
4343
4381
|
var DOMObserver = function () {
|
|
4344
4382
|
function DOMObserver(view, handleDOMChange) {
|
|
4345
|
-
var
|
|
4383
|
+
var _this13 = this;
|
|
4346
4384
|
_classCallCheck(this, DOMObserver);
|
|
4347
4385
|
this.view = view;
|
|
4348
4386
|
this.handleDOMChange = handleDOMChange;
|
|
@@ -4354,28 +4392,28 @@ var DOMObserver = function () {
|
|
|
4354
4392
|
this.suppressingSelectionUpdates = false;
|
|
4355
4393
|
this.lastChangedTextNode = null;
|
|
4356
4394
|
this.observer = window.MutationObserver && new window.MutationObserver(function (mutations) {
|
|
4357
|
-
for (var i = 0; i < mutations.length; i++)
|
|
4395
|
+
for (var i = 0; i < mutations.length; i++) _this13.queue.push(mutations[i]);
|
|
4358
4396
|
if (ie && ie_version <= 11 && mutations.some(function (m) {
|
|
4359
4397
|
return m.type == "childList" && m.removedNodes.length || m.type == "characterData" && m.oldValue.length > m.target.nodeValue.length;
|
|
4360
4398
|
})) {
|
|
4361
|
-
|
|
4399
|
+
_this13.flushSoon();
|
|
4362
4400
|
} else if (safari && view.composing && mutations.some(function (m) {
|
|
4363
4401
|
return m.type == "childList" && m.target.nodeName == "TR";
|
|
4364
4402
|
})) {
|
|
4365
4403
|
view.input.badSafariComposition = true;
|
|
4366
|
-
|
|
4404
|
+
_this13.flushSoon();
|
|
4367
4405
|
} else {
|
|
4368
|
-
|
|
4406
|
+
_this13.flush();
|
|
4369
4407
|
}
|
|
4370
4408
|
});
|
|
4371
4409
|
if (useCharData) {
|
|
4372
4410
|
this.onCharData = function (e) {
|
|
4373
|
-
|
|
4411
|
+
_this13.queue.push({
|
|
4374
4412
|
target: e.target,
|
|
4375
4413
|
type: "characterData",
|
|
4376
4414
|
oldValue: e.prevValue
|
|
4377
4415
|
});
|
|
4378
|
-
|
|
4416
|
+
_this13.flushSoon();
|
|
4379
4417
|
};
|
|
4380
4418
|
}
|
|
4381
4419
|
this.onSelectionChange = this.onSelectionChange.bind(this);
|
|
@@ -4383,10 +4421,10 @@ var DOMObserver = function () {
|
|
|
4383
4421
|
_createClass(DOMObserver, [{
|
|
4384
4422
|
key: "flushSoon",
|
|
4385
4423
|
value: function flushSoon() {
|
|
4386
|
-
var
|
|
4424
|
+
var _this14 = this;
|
|
4387
4425
|
if (this.flushingSoon < 0) this.flushingSoon = window.setTimeout(function () {
|
|
4388
|
-
|
|
4389
|
-
|
|
4426
|
+
_this14.flushingSoon = -1;
|
|
4427
|
+
_this14.flush();
|
|
4390
4428
|
}, 20);
|
|
4391
4429
|
}
|
|
4392
4430
|
}, {
|
|
@@ -4411,13 +4449,13 @@ var DOMObserver = function () {
|
|
|
4411
4449
|
}, {
|
|
4412
4450
|
key: "stop",
|
|
4413
4451
|
value: function stop() {
|
|
4414
|
-
var
|
|
4452
|
+
var _this15 = this;
|
|
4415
4453
|
if (this.observer) {
|
|
4416
4454
|
var take = this.observer.takeRecords();
|
|
4417
4455
|
if (take.length) {
|
|
4418
4456
|
for (var i = 0; i < take.length; i++) this.queue.push(take[i]);
|
|
4419
4457
|
window.setTimeout(function () {
|
|
4420
|
-
return
|
|
4458
|
+
return _this15.flush();
|
|
4421
4459
|
}, 20);
|
|
4422
4460
|
}
|
|
4423
4461
|
this.observer.disconnect();
|
|
@@ -4438,10 +4476,10 @@ var DOMObserver = function () {
|
|
|
4438
4476
|
}, {
|
|
4439
4477
|
key: "suppressSelectionUpdates",
|
|
4440
4478
|
value: function suppressSelectionUpdates() {
|
|
4441
|
-
var
|
|
4479
|
+
var _this16 = this;
|
|
4442
4480
|
this.suppressingSelectionUpdates = true;
|
|
4443
4481
|
setTimeout(function () {
|
|
4444
|
-
return
|
|
4482
|
+
return _this16.suppressingSelectionUpdates = false;
|
|
4445
4483
|
}, 50);
|
|
4446
4484
|
}
|
|
4447
4485
|
}, {
|
|
@@ -4506,8 +4544,12 @@ var DOMObserver = function () {
|
|
|
4506
4544
|
if (!view.docView || this.flushingSoon > -1) return;
|
|
4507
4545
|
var mutations = this.pendingRecords();
|
|
4508
4546
|
if (mutations.length) this.queue = [];
|
|
4509
|
-
var
|
|
4510
|
-
|
|
4547
|
+
var selRange,
|
|
4548
|
+
newSel = false;
|
|
4549
|
+
if (!this.suppressingSelectionUpdates && hasFocusAndSelection(view)) {
|
|
4550
|
+
selRange = view.domSelectionRange();
|
|
4551
|
+
newSel = !this.currentSelection.eq(selRange) && !this.ignoreSelectionChange(selRange);
|
|
4552
|
+
}
|
|
4511
4553
|
var from = -1,
|
|
4512
4554
|
to = -1,
|
|
4513
4555
|
typeOver = false,
|
|
@@ -4575,10 +4617,10 @@ var DOMObserver = function () {
|
|
|
4575
4617
|
}
|
|
4576
4618
|
}
|
|
4577
4619
|
var readSel = null;
|
|
4578
|
-
if (from < 0 && newSel && view.input.lastFocus > Date.now() - 200 && Math.max(view.input.lastTouch, view.input.lastClick.time) < Date.now() - 300 && selectionCollapsed(
|
|
4620
|
+
if (from < 0 && newSel && view.input.lastFocus > Date.now() - 200 && Math.max(view.input.lastTouch, view.input.lastClick.time) < Date.now() - 300 && selectionCollapsed(selRange) && (readSel = selectionFromDOM(view)) && readSel.eq(prosemirrorState.Selection.near(view.state.doc.resolve(0), 1))) {
|
|
4579
4621
|
view.input.lastFocus = 0;
|
|
4580
4622
|
selectionToDOM(view);
|
|
4581
|
-
this.currentSelection.set(
|
|
4623
|
+
this.currentSelection.set(selRange);
|
|
4582
4624
|
view.scrollToSelection();
|
|
4583
4625
|
} else if (from > -1 || newSel) {
|
|
4584
4626
|
if (from > -1) {
|
|
@@ -4590,8 +4632,8 @@ var DOMObserver = function () {
|
|
|
4590
4632
|
fixUpBadSafariComposition(view, added);
|
|
4591
4633
|
}
|
|
4592
4634
|
this.handleDOMChange(from, to, typeOver, added);
|
|
4593
|
-
if (view.docView && view.docView.dirty) view.updateState(view.state);else if (!this.currentSelection.eq(
|
|
4594
|
-
this.currentSelection.set(
|
|
4635
|
+
if (view.docView && view.docView.dirty) view.updateState(view.state);else if (selRange && !this.currentSelection.eq(selRange)) selectionToDOM(view);
|
|
4636
|
+
if (selRange) this.currentSelection.set(selRange);
|
|
4595
4637
|
}
|
|
4596
4638
|
}
|
|
4597
4639
|
}, {
|
|
@@ -4911,7 +4953,7 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
|
|
|
4911
4953
|
view.input.lastIOSEnter = 0;
|
|
4912
4954
|
return;
|
|
4913
4955
|
}
|
|
4914
|
-
if (view.state.selection.anchor > change.start &&
|
|
4956
|
+
if (view.state.selection.anchor > change.start && (inlineChange ? change.endA > change.start && change.endB == change.start : looksLikeBlockJoin(doc, change.start, change.endA, $from, $to)) && view.someProp("handleKeyDown", function (f) {
|
|
4915
4957
|
return f(view, keyEvent(8, "Backspace"));
|
|
4916
4958
|
})) {
|
|
4917
4959
|
if (android && chrome) view.domObserver.suppressSelectionUpdates();
|
|
@@ -5006,10 +5048,10 @@ function isMarkChange(cur, prev) {
|
|
|
5006
5048
|
type: type
|
|
5007
5049
|
};
|
|
5008
5050
|
}
|
|
5009
|
-
function
|
|
5051
|
+
function looksLikeBlockJoin(old, start, end, $newStart, $newEnd) {
|
|
5010
5052
|
if (end - start <= $newEnd.pos - $newStart.pos || skipClosingAndOpening($newStart, true, false) < $newEnd.pos) return false;
|
|
5011
5053
|
var $start = old.resolve(start);
|
|
5012
|
-
if (!$newStart.parent.
|
|
5054
|
+
if (!$newStart.parent.inlineContent) {
|
|
5013
5055
|
var after = $start.nodeAfter;
|
|
5014
5056
|
return after != null && end == start + after.nodeSize;
|
|
5015
5057
|
}
|
|
@@ -5076,7 +5118,7 @@ var __parseFromClipboard = parseFromClipboard;
|
|
|
5076
5118
|
var __endComposition = endComposition;
|
|
5077
5119
|
var EditorView = function () {
|
|
5078
5120
|
function EditorView(place, props) {
|
|
5079
|
-
var
|
|
5121
|
+
var _this17 = this;
|
|
5080
5122
|
_classCallCheck(this, EditorView);
|
|
5081
5123
|
this._root = null;
|
|
5082
5124
|
this.focused = false;
|
|
@@ -5104,7 +5146,7 @@ var EditorView = function () {
|
|
|
5104
5146
|
this.nodeViews = buildNodeViews(this);
|
|
5105
5147
|
this.docView = docViewDesc(this.state.doc, computeDocDeco(this), viewDecorations(this), this.dom, this);
|
|
5106
5148
|
this.domObserver = new DOMObserver(this, function (from, to, typeOver, added) {
|
|
5107
|
-
return readDOMChange(
|
|
5149
|
+
return readDOMChange(_this17, from, to, typeOver, added);
|
|
5108
5150
|
});
|
|
5109
5151
|
this.domObserver.start();
|
|
5110
5152
|
initInput(this);
|
|
@@ -5218,10 +5260,10 @@ var EditorView = function () {
|
|
|
5218
5260
|
}, {
|
|
5219
5261
|
key: "scrollToSelection",
|
|
5220
5262
|
value: function scrollToSelection() {
|
|
5221
|
-
var
|
|
5263
|
+
var _this18 = this;
|
|
5222
5264
|
var startDOM = this.domSelectionRange().focusNode;
|
|
5223
5265
|
if (!startDOM || !contains(this.dom, startDOM)) ;else if (this.someProp("handleScrollToSelection", function (f) {
|
|
5224
|
-
return f(
|
|
5266
|
+
return f(_this18);
|
|
5225
5267
|
})) ;else if (this.state.selection instanceof prosemirrorState.NodeSelection) {
|
|
5226
5268
|
var target = this.docView.domAfterPos(this.state.selection.from);
|
|
5227
5269
|
if (isElt(target)) scrollRectIntoView(this, target.getBoundingClientRect(), startDOM);
|
|
@@ -5312,7 +5354,7 @@ var EditorView = function () {
|
|
|
5312
5354
|
}, {
|
|
5313
5355
|
key: "root",
|
|
5314
5356
|
get: function get() {
|
|
5315
|
-
var
|
|
5357
|
+
var _this19 = this;
|
|
5316
5358
|
var cached = this._root;
|
|
5317
5359
|
if (cached == null) {
|
|
5318
5360
|
var _loop5 = function _loop5(search) {
|
|
@@ -5321,7 +5363,7 @@ var EditorView = function () {
|
|
|
5321
5363
|
return search.ownerDocument.getSelection();
|
|
5322
5364
|
};
|
|
5323
5365
|
return {
|
|
5324
|
-
v:
|
|
5366
|
+
v: _this19._root = search
|
|
5325
5367
|
};
|
|
5326
5368
|
}
|
|
5327
5369
|
},
|
package/dist/index.js
CHANGED
|
@@ -850,7 +850,13 @@ class ViewDesc {
|
|
|
850
850
|
atEnd = offset > domIndex(this.contentDOM);
|
|
851
851
|
}
|
|
852
852
|
else if (this.contentDOM && this.contentDOM != this.dom && this.dom.contains(this.contentDOM)) {
|
|
853
|
-
|
|
853
|
+
let rel = dom.compareDocumentPosition(this.contentDOM);
|
|
854
|
+
if (rel & 16) { // this.contentDOM is inside dom
|
|
855
|
+
atEnd = offset > Array.from(dom.childNodes).findIndex(n => n.contains(this.contentDOM));
|
|
856
|
+
}
|
|
857
|
+
else { // Check if after or before
|
|
858
|
+
atEnd = !(rel & 4);
|
|
859
|
+
}
|
|
854
860
|
}
|
|
855
861
|
else if (this.dom.firstChild) {
|
|
856
862
|
if (offset == 0)
|
|
@@ -2483,7 +2489,7 @@ function selectHorizontally(view, dir, mods) {
|
|
|
2483
2489
|
return apply(view, next);
|
|
2484
2490
|
return false;
|
|
2485
2491
|
}
|
|
2486
|
-
else if (!
|
|
2492
|
+
else if (!mac || mods.indexOf("m") < 0) {
|
|
2487
2493
|
let $head = sel.$head, node = $head.textOffset ? null : dir < 0 ? $head.nodeBefore : $head.nodeAfter, desc;
|
|
2488
2494
|
if (!node || node.isText)
|
|
2489
2495
|
return false;
|
|
@@ -2672,17 +2678,14 @@ function setSelFocus(view, node, offset) {
|
|
|
2672
2678
|
offset = before.nodeValue.length;
|
|
2673
2679
|
}
|
|
2674
2680
|
}
|
|
2675
|
-
let sel = view.domSelection();
|
|
2681
|
+
let sel = view.domSelection(), range = view.domSelectionRange();
|
|
2676
2682
|
if (!sel)
|
|
2677
2683
|
return;
|
|
2678
|
-
if (selectionCollapsed(
|
|
2679
|
-
|
|
2680
|
-
range.setEnd(node, offset);
|
|
2681
|
-
range.setStart(node, offset);
|
|
2682
|
-
sel.removeAllRanges();
|
|
2683
|
-
sel.addRange(range);
|
|
2684
|
+
if (selectionCollapsed(range)) {
|
|
2685
|
+
sel.collapse(node, offset);
|
|
2684
2686
|
}
|
|
2685
2687
|
else if (sel.extend) {
|
|
2688
|
+
sel.collapse(range.anchorNode, range.anchorOffset);
|
|
2686
2689
|
sel.extend(node, offset);
|
|
2687
2690
|
}
|
|
2688
2691
|
view.domObserver.setCurSelection();
|
|
@@ -2710,7 +2713,13 @@ function findDirection(view, pos) {
|
|
|
2710
2713
|
return after.left > coords.left ? "ltr" : "rtl";
|
|
2711
2714
|
}
|
|
2712
2715
|
}
|
|
2713
|
-
let
|
|
2716
|
+
let block = view.dom;
|
|
2717
|
+
for (let d = $pos.depth; d > 0; d--)
|
|
2718
|
+
if ($pos.node(d).isBlock) {
|
|
2719
|
+
block = view.nodeDOM($pos.before(d)) || block;
|
|
2720
|
+
break;
|
|
2721
|
+
}
|
|
2722
|
+
let computed = getComputedStyle(block).direction;
|
|
2714
2723
|
return computed == "rtl" ? "rtl" : "ltr";
|
|
2715
2724
|
}
|
|
2716
2725
|
// Check whether vertical selection motion would involve node
|
|
@@ -3983,6 +3992,23 @@ function compareObjs(a, b) {
|
|
|
3983
3992
|
return false;
|
|
3984
3993
|
return true;
|
|
3985
3994
|
}
|
|
3995
|
+
class FragmentCursor {
|
|
3996
|
+
constructor(frag) {
|
|
3997
|
+
this.frag = frag;
|
|
3998
|
+
this.index = 0;
|
|
3999
|
+
this.off = 0;
|
|
4000
|
+
}
|
|
4001
|
+
nodeAt(off) {
|
|
4002
|
+
while (this.off <= off && this.index < this.frag.childCount) {
|
|
4003
|
+
let next = this.frag.child(this.index);
|
|
4004
|
+
if (this.off == off)
|
|
4005
|
+
return next;
|
|
4006
|
+
this.off += next.nodeSize;
|
|
4007
|
+
this.index++;
|
|
4008
|
+
}
|
|
4009
|
+
return null;
|
|
4010
|
+
}
|
|
4011
|
+
}
|
|
3986
4012
|
class WidgetType {
|
|
3987
4013
|
constructor(toDOM, spec) {
|
|
3988
4014
|
this.toDOM = toDOM;
|
|
@@ -4038,9 +4064,9 @@ class NodeType {
|
|
|
4038
4064
|
return null;
|
|
4039
4065
|
return new Decoration(from.pos - offset, to.pos - offset, this);
|
|
4040
4066
|
}
|
|
4041
|
-
valid(node, span) {
|
|
4042
|
-
let
|
|
4043
|
-
return
|
|
4067
|
+
valid(node, span, cursor) {
|
|
4068
|
+
let found = cursor.nodeAt(span.from);
|
|
4069
|
+
return !!found && !found.isText && span.from + found.nodeSize == span.to;
|
|
4044
4070
|
}
|
|
4045
4071
|
eq(other) {
|
|
4046
4072
|
return this == other ||
|
|
@@ -4197,12 +4223,15 @@ class DecorationSet {
|
|
|
4197
4223
|
*/
|
|
4198
4224
|
mapInner(mapping, node, offset, oldOffset, options) {
|
|
4199
4225
|
let newLocal;
|
|
4200
|
-
|
|
4201
|
-
let
|
|
4202
|
-
|
|
4203
|
-
|
|
4204
|
-
|
|
4205
|
-
|
|
4226
|
+
if (this.local.length) {
|
|
4227
|
+
let cur = new FragmentCursor(node.content);
|
|
4228
|
+
for (let i = 0; i < this.local.length; i++) {
|
|
4229
|
+
let mapped = this.local[i].map(mapping, offset, oldOffset);
|
|
4230
|
+
if (mapped && mapped.type.valid(node, mapped, cur))
|
|
4231
|
+
(newLocal || (newLocal = [])).push(mapped);
|
|
4232
|
+
else if (options.onRemove)
|
|
4233
|
+
options.onRemove(this.local[i].spec);
|
|
4234
|
+
}
|
|
4206
4235
|
}
|
|
4207
4236
|
if (this.children.length)
|
|
4208
4237
|
return mapChildren(this.children, newLocal || [], mapping, node, offset, oldOffset, options);
|
|
@@ -4239,9 +4268,12 @@ class DecorationSet {
|
|
|
4239
4268
|
childIndex += 3;
|
|
4240
4269
|
});
|
|
4241
4270
|
let local = moveSpans(childIndex ? withoutNulls(decorations) : decorations, -offset);
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4271
|
+
if (local.length) {
|
|
4272
|
+
let cur = new FragmentCursor(doc.content);
|
|
4273
|
+
for (let i = 0; i < local.length; i++)
|
|
4274
|
+
if (!local[i].type.valid(doc, local[i], cur))
|
|
4275
|
+
local.splice(i--, 1);
|
|
4276
|
+
}
|
|
4245
4277
|
return new DecorationSet(local.length ? this.local.concat(local).sort(byPos) : this.local, children || this.children);
|
|
4246
4278
|
}
|
|
4247
4279
|
/**
|
|
@@ -4584,12 +4616,15 @@ function buildTree(spans, node, offset, options) {
|
|
|
4584
4616
|
}
|
|
4585
4617
|
});
|
|
4586
4618
|
let locals = moveSpans(hasNulls ? withoutNulls(spans) : spans, -offset).sort(byPos);
|
|
4587
|
-
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
|
|
4619
|
+
if (locals.length) {
|
|
4620
|
+
let cur = new FragmentCursor(node.content);
|
|
4621
|
+
for (let i = 0; i < locals.length; i++)
|
|
4622
|
+
if (!locals[i].type.valid(node, locals[i], cur)) {
|
|
4623
|
+
if (options.onRemove)
|
|
4624
|
+
options.onRemove(locals[i].spec);
|
|
4625
|
+
locals.splice(i--, 1);
|
|
4626
|
+
}
|
|
4627
|
+
}
|
|
4593
4628
|
return locals.length || children.length ? new DecorationSet(locals, children) : empty;
|
|
4594
4629
|
}
|
|
4595
4630
|
// Used to sort decorations so that ones with a low start position
|
|
@@ -4822,8 +4857,11 @@ class DOMObserver {
|
|
|
4822
4857
|
let mutations = this.pendingRecords();
|
|
4823
4858
|
if (mutations.length)
|
|
4824
4859
|
this.queue = [];
|
|
4825
|
-
let
|
|
4826
|
-
|
|
4860
|
+
let selRange, newSel = false;
|
|
4861
|
+
if (!this.suppressingSelectionUpdates && hasFocusAndSelection(view)) {
|
|
4862
|
+
selRange = view.domSelectionRange();
|
|
4863
|
+
newSel = !this.currentSelection.eq(selRange) && !this.ignoreSelectionChange(selRange);
|
|
4864
|
+
}
|
|
4827
4865
|
let from = -1, to = -1, typeOver = false, added = [];
|
|
4828
4866
|
if (view.editable) {
|
|
4829
4867
|
for (let i = 0; i < mutations.length; i++) {
|
|
@@ -4878,11 +4916,11 @@ class DOMObserver {
|
|
|
4878
4916
|
// the state
|
|
4879
4917
|
if (from < 0 && newSel && view.input.lastFocus > Date.now() - 200 &&
|
|
4880
4918
|
Math.max(view.input.lastTouch, view.input.lastClick.time) < Date.now() - 300 &&
|
|
4881
|
-
selectionCollapsed(
|
|
4919
|
+
selectionCollapsed(selRange) && (readSel = selectionFromDOM(view)) &&
|
|
4882
4920
|
readSel.eq(Selection.near(view.state.doc.resolve(0), 1))) {
|
|
4883
4921
|
view.input.lastFocus = 0;
|
|
4884
4922
|
selectionToDOM(view);
|
|
4885
|
-
this.currentSelection.set(
|
|
4923
|
+
this.currentSelection.set(selRange);
|
|
4886
4924
|
view.scrollToSelection();
|
|
4887
4925
|
}
|
|
4888
4926
|
else if (from > -1 || newSel) {
|
|
@@ -4897,9 +4935,10 @@ class DOMObserver {
|
|
|
4897
4935
|
this.handleDOMChange(from, to, typeOver, added);
|
|
4898
4936
|
if (view.docView && view.docView.dirty)
|
|
4899
4937
|
view.updateState(view.state);
|
|
4900
|
-
else if (!this.currentSelection.eq(
|
|
4938
|
+
else if (selRange && !this.currentSelection.eq(selRange))
|
|
4901
4939
|
selectionToDOM(view);
|
|
4902
|
-
|
|
4940
|
+
if (selRange)
|
|
4941
|
+
this.currentSelection.set(selRange);
|
|
4903
4942
|
}
|
|
4904
4943
|
}
|
|
4905
4944
|
registerMutation(mut, added) {
|
|
@@ -5231,7 +5270,8 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
|
|
|
5231
5270
|
}
|
|
5232
5271
|
// Same for backspace
|
|
5233
5272
|
if (view.state.selection.anchor > change.start &&
|
|
5234
|
-
|
|
5273
|
+
(inlineChange ? change.endA > change.start && change.endB == change.start
|
|
5274
|
+
: looksLikeBlockJoin(doc, change.start, change.endA, $from, $to)) &&
|
|
5235
5275
|
view.someProp("handleKeyDown", f => f(view, keyEvent(8, "Backspace")))) {
|
|
5236
5276
|
if (android && chrome)
|
|
5237
5277
|
view.domObserver.suppressSelectionUpdates(); // #820
|
|
@@ -5352,7 +5392,7 @@ function isMarkChange(cur, prev) {
|
|
|
5352
5392
|
if (Fragment.from(updated).eq(cur))
|
|
5353
5393
|
return { mark, type };
|
|
5354
5394
|
}
|
|
5355
|
-
function
|
|
5395
|
+
function looksLikeBlockJoin(old, start, end, $newStart, $newEnd) {
|
|
5356
5396
|
if ( // The content must have shrunk
|
|
5357
5397
|
end - start <= $newEnd.pos - $newStart.pos ||
|
|
5358
5398
|
// newEnd must point directly at or after the end of the block that newStart points into
|
|
@@ -5360,7 +5400,7 @@ function looksLikeBackspace(old, start, end, $newStart, $newEnd) {
|
|
|
5360
5400
|
return false;
|
|
5361
5401
|
let $start = old.resolve(start);
|
|
5362
5402
|
// Handle the case where, rather than joining blocks, the change just removed an entire block
|
|
5363
|
-
if (!$newStart.parent.
|
|
5403
|
+
if (!$newStart.parent.inlineContent) {
|
|
5364
5404
|
let after = $start.nodeAfter;
|
|
5365
5405
|
return after != null && end == start + after.nodeSize;
|
|
5366
5406
|
}
|
package/package.json
CHANGED
package/src/capturekeys.ts
CHANGED
|
@@ -30,7 +30,7 @@ function selectHorizontally(view: EditorView, dir: number, mods: string) {
|
|
|
30
30
|
let next = moveSelectionBlock(view.state, dir)
|
|
31
31
|
if (next && (next instanceof NodeSelection)) return apply(view, next)
|
|
32
32
|
return false
|
|
33
|
-
} else if (!
|
|
33
|
+
} else if (!browser.mac || mods.indexOf("m") < 0) {
|
|
34
34
|
let $head = sel.$head, node = $head.textOffset ? null : dir < 0 ? $head.nodeBefore : $head.nodeAfter, desc
|
|
35
35
|
if (!node || node.isText) return false
|
|
36
36
|
let nodePos = dir < 0 ? $head.pos - node.nodeSize : $head.pos
|
|
@@ -198,15 +198,12 @@ function setSelFocus(view: EditorView, node: Node, offset: number) {
|
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
200
|
|
|
201
|
-
let sel = view.domSelection()
|
|
201
|
+
let sel = view.domSelection(), range = view.domSelectionRange()
|
|
202
202
|
if (!sel) return
|
|
203
|
-
if (selectionCollapsed(
|
|
204
|
-
|
|
205
|
-
range.setEnd(node, offset)
|
|
206
|
-
range.setStart(node, offset)
|
|
207
|
-
sel.removeAllRanges()
|
|
208
|
-
sel.addRange(range)
|
|
203
|
+
if (selectionCollapsed(range)) {
|
|
204
|
+
sel.collapse(node, offset)
|
|
209
205
|
} else if (sel.extend) {
|
|
206
|
+
sel.collapse(range.anchorNode, range.anchorOffset)
|
|
210
207
|
sel.extend(node, offset)
|
|
211
208
|
}
|
|
212
209
|
view.domObserver.setCurSelection()
|
|
@@ -234,7 +231,12 @@ function findDirection(view: EditorView, pos: number): "rtl" | "ltr" {
|
|
|
234
231
|
return after.left > coords.left ? "ltr" : "rtl"
|
|
235
232
|
}
|
|
236
233
|
}
|
|
237
|
-
let
|
|
234
|
+
let block: Element = view.dom
|
|
235
|
+
for (let d = $pos.depth; d > 0; d--) if ($pos.node(d).isBlock) {
|
|
236
|
+
block = view.nodeDOM($pos.before(d)) as Element || block
|
|
237
|
+
break
|
|
238
|
+
}
|
|
239
|
+
let computed = getComputedStyle(block).direction
|
|
238
240
|
return computed == "rtl" ? "rtl" : "ltr"
|
|
239
241
|
}
|
|
240
242
|
|
package/src/decoration.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {Node, Mark} from "prosemirror-model"
|
|
1
|
+
import {Node, Mark, Fragment} from "prosemirror-model"
|
|
2
2
|
import {Mappable, Mapping} from "prosemirror-transform"
|
|
3
3
|
import {EditorView} from "./index"
|
|
4
4
|
import {DOMNode} from "./dom"
|
|
@@ -10,10 +10,25 @@ function compareObjs(a: {[prop: string]: any}, b: {[prop: string]: any}) {
|
|
|
10
10
|
return true
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
class FragmentCursor {
|
|
14
|
+
index = 0
|
|
15
|
+
off = 0
|
|
16
|
+
constructor(readonly frag: Fragment) {}
|
|
17
|
+
nodeAt(off: number) {
|
|
18
|
+
while (this.off <= off && this.index < this.frag.childCount) {
|
|
19
|
+
let next = this.frag.child(this.index)
|
|
20
|
+
if (this.off == off) return next
|
|
21
|
+
this.off += next.nodeSize
|
|
22
|
+
this.index++
|
|
23
|
+
}
|
|
24
|
+
return null
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
13
28
|
export interface DecorationType {
|
|
14
29
|
spec: any
|
|
15
30
|
map(mapping: Mappable, span: Decoration, offset: number, oldOffset: number): Decoration | null
|
|
16
|
-
valid(node: Node, span: Decoration): boolean
|
|
31
|
+
valid(node: Node, span: Decoration, cur: FragmentCursor): boolean
|
|
17
32
|
eq(other: DecorationType): boolean
|
|
18
33
|
destroy(dom: DOMNode): void
|
|
19
34
|
}
|
|
@@ -88,9 +103,9 @@ export class NodeType implements DecorationType {
|
|
|
88
103
|
return new Decoration(from.pos - offset, to.pos - offset, this)
|
|
89
104
|
}
|
|
90
105
|
|
|
91
|
-
valid(node: Node, span: Decoration): boolean {
|
|
92
|
-
let
|
|
93
|
-
return
|
|
106
|
+
valid(node: Node, span: Decoration, cursor: FragmentCursor): boolean {
|
|
107
|
+
let found = cursor.nodeAt(span.from)
|
|
108
|
+
return !!found && !found.isText && span.from + found.nodeSize == span.to
|
|
94
109
|
}
|
|
95
110
|
|
|
96
111
|
eq(other: DecorationType): boolean {
|
|
@@ -346,10 +361,13 @@ export class DecorationSet implements DecorationSource {
|
|
|
346
361
|
onRemove?: (decorationSpec: any) => void
|
|
347
362
|
}) {
|
|
348
363
|
let newLocal: Decoration[] | undefined
|
|
349
|
-
|
|
350
|
-
let
|
|
351
|
-
|
|
352
|
-
|
|
364
|
+
if (this.local.length) {
|
|
365
|
+
let cur = new FragmentCursor(node.content)
|
|
366
|
+
for (let i = 0; i < this.local.length; i++) {
|
|
367
|
+
let mapped = this.local[i].map(mapping, offset, oldOffset)
|
|
368
|
+
if (mapped && mapped.type.valid(node, mapped, cur)) (newLocal || (newLocal = [])).push(mapped)
|
|
369
|
+
else if (options.onRemove) options.onRemove(this.local[i].spec)
|
|
370
|
+
}
|
|
353
371
|
}
|
|
354
372
|
|
|
355
373
|
if (this.children.length)
|
|
@@ -384,7 +402,10 @@ export class DecorationSet implements DecorationSource {
|
|
|
384
402
|
})
|
|
385
403
|
|
|
386
404
|
let local = moveSpans(childIndex ? withoutNulls(decorations) : decorations, -offset)
|
|
387
|
-
|
|
405
|
+
if (local.length) {
|
|
406
|
+
let cur = new FragmentCursor(doc.content)
|
|
407
|
+
for (let i = 0; i < local.length; i++) if (!local[i].type.valid(doc, local[i], cur)) local.splice(i--, 1)
|
|
408
|
+
}
|
|
388
409
|
|
|
389
410
|
return new DecorationSet(local.length ? this.local.concat(local).sort(byPos) : this.local,
|
|
390
411
|
children || this.children)
|
|
@@ -727,9 +748,12 @@ function buildTree(
|
|
|
727
748
|
}
|
|
728
749
|
})
|
|
729
750
|
let locals = moveSpans(hasNulls ? withoutNulls(spans) : spans, -offset).sort(byPos)
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
locals.
|
|
751
|
+
if (locals.length) {
|
|
752
|
+
let cur = new FragmentCursor(node.content)
|
|
753
|
+
for (let i = 0; i < locals.length; i++) if (!locals[i].type.valid(node, locals[i], cur)) {
|
|
754
|
+
if (options.onRemove) options.onRemove(locals[i].spec)
|
|
755
|
+
locals.splice(i--, 1)
|
|
756
|
+
}
|
|
733
757
|
}
|
|
734
758
|
return locals.length || children.length ? new DecorationSet(locals, children) : empty
|
|
735
759
|
}
|
package/src/domchange.ts
CHANGED
|
@@ -187,7 +187,8 @@ export function readDOMChange(view: EditorView, from: number, to: number, typeOv
|
|
|
187
187
|
}
|
|
188
188
|
// Same for backspace
|
|
189
189
|
if (view.state.selection.anchor > change.start &&
|
|
190
|
-
|
|
190
|
+
(inlineChange ? change.endA > change.start && change.endB == change.start
|
|
191
|
+
: looksLikeBlockJoin(doc, change.start, change.endA, $from, $to)) &&
|
|
191
192
|
view.someProp("handleKeyDown", f => f(view, keyEvent(8, "Backspace")))) {
|
|
192
193
|
if (browser.android && browser.chrome) view.domObserver.suppressSelectionUpdates() // #820
|
|
193
194
|
return
|
|
@@ -303,7 +304,7 @@ function isMarkChange(cur: Fragment, prev: Fragment) {
|
|
|
303
304
|
if (Fragment.from(updated).eq(cur)) return {mark, type}
|
|
304
305
|
}
|
|
305
306
|
|
|
306
|
-
function
|
|
307
|
+
function looksLikeBlockJoin(old: Node, start: number, end: number, $newStart: ResolvedPos, $newEnd: ResolvedPos) {
|
|
307
308
|
if (// The content must have shrunk
|
|
308
309
|
end - start <= $newEnd.pos - $newStart.pos ||
|
|
309
310
|
// newEnd must point directly at or after the end of the block that newStart points into
|
|
@@ -313,7 +314,7 @@ function looksLikeBackspace(old: Node, start: number, end: number, $newStart: Re
|
|
|
313
314
|
let $start = old.resolve(start)
|
|
314
315
|
|
|
315
316
|
// Handle the case where, rather than joining blocks, the change just removed an entire block
|
|
316
|
-
if (!$newStart.parent.
|
|
317
|
+
if (!$newStart.parent.inlineContent) {
|
|
317
318
|
let after = $start.nodeAfter
|
|
318
319
|
return after != null && end == start + after.nodeSize
|
|
319
320
|
}
|
package/src/domobserver.ts
CHANGED
|
@@ -177,8 +177,11 @@ export class DOMObserver {
|
|
|
177
177
|
let mutations = this.pendingRecords()
|
|
178
178
|
if (mutations.length) this.queue = []
|
|
179
179
|
|
|
180
|
-
let
|
|
181
|
-
|
|
180
|
+
let selRange: DOMSelectionRange | undefined, newSel = false
|
|
181
|
+
if (!this.suppressingSelectionUpdates && hasFocusAndSelection(view)) {
|
|
182
|
+
selRange = view.domSelectionRange()
|
|
183
|
+
newSel = !this.currentSelection.eq(selRange) && !this.ignoreSelectionChange(selRange)
|
|
184
|
+
}
|
|
182
185
|
|
|
183
186
|
let from = -1, to = -1, typeOver = false, added: Node[] = []
|
|
184
187
|
if (view.editable) {
|
|
@@ -230,11 +233,11 @@ export class DOMObserver {
|
|
|
230
233
|
// the state
|
|
231
234
|
if (from < 0 && newSel && view.input.lastFocus > Date.now() - 200 &&
|
|
232
235
|
Math.max(view.input.lastTouch, view.input.lastClick.time) < Date.now() - 300 &&
|
|
233
|
-
selectionCollapsed(
|
|
236
|
+
selectionCollapsed(selRange!) && (readSel = selectionFromDOM(view)) &&
|
|
234
237
|
readSel.eq(Selection.near(view.state.doc.resolve(0), 1))) {
|
|
235
238
|
view.input.lastFocus = 0
|
|
236
239
|
selectionToDOM(view)
|
|
237
|
-
this.currentSelection.set(
|
|
240
|
+
this.currentSelection.set(selRange!)
|
|
238
241
|
view.scrollToSelection()
|
|
239
242
|
} else if (from > -1 || newSel) {
|
|
240
243
|
if (from > -1) {
|
|
@@ -247,8 +250,8 @@ export class DOMObserver {
|
|
|
247
250
|
}
|
|
248
251
|
this.handleDOMChange(from, to, typeOver, added)
|
|
249
252
|
if (view.docView && view.docView.dirty) view.updateState(view.state)
|
|
250
|
-
else if (!this.currentSelection.eq(
|
|
251
|
-
this.currentSelection.set(
|
|
253
|
+
else if (selRange && !this.currentSelection.eq(selRange)) selectionToDOM(view)
|
|
254
|
+
if (selRange) this.currentSelection.set(selRange)
|
|
252
255
|
}
|
|
253
256
|
}
|
|
254
257
|
|
package/src/viewdesc.ts
CHANGED
|
@@ -248,7 +248,12 @@ export class ViewDesc {
|
|
|
248
248
|
if (dom == this.dom && this.contentDOM) {
|
|
249
249
|
atEnd = offset > domIndex(this.contentDOM)
|
|
250
250
|
} else if (this.contentDOM && this.contentDOM != this.dom && this.dom.contains(this.contentDOM)) {
|
|
251
|
-
|
|
251
|
+
let rel = dom.compareDocumentPosition(this.contentDOM)
|
|
252
|
+
if (rel & 16) { // this.contentDOM is inside dom
|
|
253
|
+
atEnd = offset > Array.from(dom.childNodes).findIndex(n => n.contains(this.contentDOM))
|
|
254
|
+
} else { // Check if after or before
|
|
255
|
+
atEnd = !(rel & 4)
|
|
256
|
+
}
|
|
252
257
|
} else if (this.dom.firstChild) {
|
|
253
258
|
if (offset == 0) for (let search = dom;; search = search.parentNode!) {
|
|
254
259
|
if (search == this.dom) { atEnd = false; break }
|