prosemirror-view 1.30.2 → 1.31.0
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 +150 -36
- package/dist/index.js +120 -33
- package/package.json +1 -1
- package/src/browser.ts +1 -0
- package/src/capturekeys.ts +36 -9
- package/src/dom.ts +13 -0
- package/src/domchange.ts +7 -1
- package/src/domcoords.ts +18 -13
- package/src/input.ts +2 -0
- package/src/viewdesc.ts +31 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
## 1.31.0 (2023-04-26)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Fix an issue where, when the browser failed to return a cursor for a set of coordinates (as in a shadow root in Chrome) the library's own algorithm worked poorly for coordinates between lines in a textblock.
|
|
6
|
+
|
|
7
|
+
Improve performance of changing a parent node (by type or attributes) without modifying its children by reusing the DOM of the child nodes.
|
|
8
|
+
|
|
9
|
+
Fix an issue where, in right-to-left context, the left and right arrow keys could get stuck on a selectable leaf node because the editor was moving the selection in the wrong direction.
|
|
10
|
+
|
|
11
|
+
Fix a regression in `coordsAtPos` when querying the position of a line wrap.
|
|
12
|
+
|
|
13
|
+
### New features
|
|
14
|
+
|
|
15
|
+
Attach a `"composition"` meta field to transactions generated from DOM changes.
|
|
16
|
+
|
|
1
17
|
## 1.30.2 (2023-03-13)
|
|
2
18
|
|
|
3
19
|
### Bug fixes
|
package/dist/index.cjs
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
|
|
4
4
|
|
|
5
|
+
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
|
|
6
|
+
|
|
7
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
8
|
+
|
|
9
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
|
10
|
+
|
|
5
11
|
function _get() { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get; } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(arguments.length < 3 ? target : receiver); } return desc.value; }; } return _get.apply(this, arguments); }
|
|
6
12
|
|
|
7
13
|
function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; }
|
|
@@ -129,6 +135,26 @@ function deepActiveElement(doc) {
|
|
|
129
135
|
return elt;
|
|
130
136
|
}
|
|
131
137
|
|
|
138
|
+
function caretFromPoint(doc, x, y) {
|
|
139
|
+
if (doc.caretPositionFromPoint) {
|
|
140
|
+
try {
|
|
141
|
+
var pos = doc.caretPositionFromPoint(x, y);
|
|
142
|
+
if (pos) return {
|
|
143
|
+
node: pos.offsetNode,
|
|
144
|
+
offset: pos.offset
|
|
145
|
+
};
|
|
146
|
+
} catch (_) {}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (doc.caretRangeFromPoint) {
|
|
150
|
+
var range = doc.caretRangeFromPoint(x, y);
|
|
151
|
+
if (range) return {
|
|
152
|
+
node: range.startContainer,
|
|
153
|
+
offset: range.startOffset
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
132
158
|
var nav = typeof navigator != "undefined" ? navigator : null;
|
|
133
159
|
var doc = typeof document != "undefined" ? document : null;
|
|
134
160
|
var agent = nav && nav.userAgent || "";
|
|
@@ -147,6 +173,7 @@ var chrome_version = _chrome ? +_chrome[1] : 0;
|
|
|
147
173
|
var safari = !ie && !!nav && /Apple Computer/.test(nav.vendor);
|
|
148
174
|
var ios = safari && (/Mobile\/\w+/.test(agent) || !!nav && nav.maxTouchPoints > 2);
|
|
149
175
|
var mac = ios || (nav ? /Mac/.test(nav.platform) : false);
|
|
176
|
+
var windows = nav ? /Win/.test(nav.platform) : false;
|
|
150
177
|
var android = /Android \d/.test(agent);
|
|
151
178
|
var webkit = !!doc && "webkitFontSmoothing" in doc.documentElement.style;
|
|
152
179
|
var webkit_version = webkit ? +(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent) || [0, 0])[1] : 0;
|
|
@@ -303,6 +330,7 @@ function findOffsetInNode(node, coords) {
|
|
|
303
330
|
offset = 0;
|
|
304
331
|
var rowBot = coords.top,
|
|
305
332
|
rowTop = coords.top;
|
|
333
|
+
var firstBelow, coordsBelow;
|
|
306
334
|
|
|
307
335
|
for (var child = node.firstChild, childIndex = 0; child; child = child.nextSibling, childIndex++) {
|
|
308
336
|
var rects = void 0;
|
|
@@ -326,12 +354,24 @@ function findOffsetInNode(node, coords) {
|
|
|
326
354
|
if (child.nodeType == 1 && dx) offset = childIndex + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0);
|
|
327
355
|
continue;
|
|
328
356
|
}
|
|
357
|
+
} else if (rect.top > coords.top && !firstBelow && rect.left <= coords.left && rect.right >= coords.left) {
|
|
358
|
+
firstBelow = child;
|
|
359
|
+
coordsBelow = {
|
|
360
|
+
left: Math.max(rect.left, Math.min(rect.right, coords.left)),
|
|
361
|
+
top: rect.top
|
|
362
|
+
};
|
|
329
363
|
}
|
|
330
364
|
|
|
331
365
|
if (!closest && (coords.left >= rect.right && coords.top >= rect.top || coords.left >= rect.left && coords.top >= rect.bottom)) offset = childIndex + 1;
|
|
332
366
|
}
|
|
333
367
|
}
|
|
334
368
|
|
|
369
|
+
if (!closest && firstBelow) {
|
|
370
|
+
closest = firstBelow;
|
|
371
|
+
coordsClosest = coordsBelow;
|
|
372
|
+
dxClosest = 0;
|
|
373
|
+
}
|
|
374
|
+
|
|
335
375
|
if (closest && closest.nodeType == 3) return findOffsetInText(closest, coordsClosest);
|
|
336
376
|
if (!closest || dxClosest && closest.nodeType == 1) return {
|
|
337
377
|
node: node,
|
|
@@ -440,25 +480,11 @@ function _posAtCoords(view, coords) {
|
|
|
440
480
|
var doc = view.dom.ownerDocument,
|
|
441
481
|
node,
|
|
442
482
|
offset = 0;
|
|
483
|
+
var caret = caretFromPoint(doc, coords.left, coords.top);
|
|
443
484
|
|
|
444
|
-
if (
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
if (_pos) {
|
|
449
|
-
node = _pos.offsetNode;
|
|
450
|
-
offset = _pos.offset;
|
|
451
|
-
}
|
|
452
|
-
} catch (_) {}
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
if (!node && doc.caretRangeFromPoint) {
|
|
456
|
-
var range = doc.caretRangeFromPoint(coords.left, coords.top);
|
|
457
|
-
|
|
458
|
-
if (range) {
|
|
459
|
-
node = range.startContainer;
|
|
460
|
-
offset = range.startOffset;
|
|
461
|
-
}
|
|
485
|
+
if (caret) {
|
|
486
|
+
node = caret.node;
|
|
487
|
+
offset = caret.offset;
|
|
462
488
|
}
|
|
463
489
|
|
|
464
490
|
var elt = (view.root.elementFromPoint ? view.root : doc).elementFromPoint(coords.left, coords.top);
|
|
@@ -502,9 +528,19 @@ function _posAtCoords(view, coords) {
|
|
|
502
528
|
};
|
|
503
529
|
}
|
|
504
530
|
|
|
531
|
+
function nonZero(rect) {
|
|
532
|
+
return rect.top < rect.bottom || rect.left < rect.right;
|
|
533
|
+
}
|
|
534
|
+
|
|
505
535
|
function singleRect(target, bias) {
|
|
506
536
|
var rects = target.getClientRects();
|
|
507
|
-
|
|
537
|
+
|
|
538
|
+
if (rects.length) {
|
|
539
|
+
var first = rects[bias < 0 ? 0 : rects.length - 1];
|
|
540
|
+
if (nonZero(first)) return first;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
return Array.prototype.find.call(rects, nonZero) || target.getBoundingClientRect();
|
|
508
544
|
}
|
|
509
545
|
|
|
510
546
|
var BIDI = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;
|
|
@@ -548,7 +584,7 @@ function _coordsAtPos(view, pos, side) {
|
|
|
548
584
|
to++;
|
|
549
585
|
}
|
|
550
586
|
|
|
551
|
-
return flattenV(singleRect(textRange(node, from, to),
|
|
587
|
+
return flattenV(singleRect(textRange(node, from, to), takeSide), takeSide < 0);
|
|
552
588
|
}
|
|
553
589
|
}
|
|
554
590
|
|
|
@@ -1425,7 +1461,6 @@ var NodeViewDesc = function (_ViewDesc4) {
|
|
|
1425
1461
|
_this4.outerDeco = outerDeco;
|
|
1426
1462
|
_this4.innerDeco = innerDeco;
|
|
1427
1463
|
_this4.nodeDOM = nodeDOM;
|
|
1428
|
-
if (contentDOM) _this4.updateChildren(view, pos);
|
|
1429
1464
|
return _this4;
|
|
1430
1465
|
}
|
|
1431
1466
|
|
|
@@ -1496,7 +1531,7 @@ var NodeViewDesc = function (_ViewDesc4) {
|
|
|
1496
1531
|
}, function (child, outerDeco, innerDeco, i) {
|
|
1497
1532
|
updater.syncToMarks(child.marks, inline, view);
|
|
1498
1533
|
var compIndex;
|
|
1499
|
-
if (updater.findNodeMatch(child, outerDeco, innerDeco, i)) ;else if (compositionInChild && view.state.selection.from > off && view.state.selection.to < off + child.nodeSize && (compIndex = updater.findIndexWithChild(composition.node)) > -1 && updater.updateNodeAt(child, outerDeco, innerDeco, compIndex, view)) ;else if (updater.updateNextNode(child, outerDeco, innerDeco, view, i)) ;else {
|
|
1534
|
+
if (updater.findNodeMatch(child, outerDeco, innerDeco, i)) ;else if (compositionInChild && view.state.selection.from > off && view.state.selection.to < off + child.nodeSize && (compIndex = updater.findIndexWithChild(composition.node)) > -1 && updater.updateNodeAt(child, outerDeco, innerDeco, compIndex, view)) ;else if (updater.updateNextNode(child, outerDeco, innerDeco, view, i, off)) ;else {
|
|
1500
1535
|
updater.addNode(child, outerDeco, innerDeco, view, off);
|
|
1501
1536
|
}
|
|
1502
1537
|
off += child.nodeSize;
|
|
@@ -1650,7 +1685,9 @@ var NodeViewDesc = function (_ViewDesc4) {
|
|
|
1650
1685
|
|
|
1651
1686
|
function docViewDesc(doc, outerDeco, innerDeco, dom, view) {
|
|
1652
1687
|
applyOuterDeco(dom, outerDeco, doc);
|
|
1653
|
-
|
|
1688
|
+
var docView = new NodeViewDesc(undefined, doc, outerDeco, innerDeco, dom, dom, dom, view, 0);
|
|
1689
|
+
if (docView.contentDOM) docView.updateChildren(view, 0);
|
|
1690
|
+
return docView;
|
|
1654
1691
|
}
|
|
1655
1692
|
|
|
1656
1693
|
var TextViewDesc = function (_NodeViewDesc) {
|
|
@@ -2134,7 +2171,7 @@ var ViewTreeUpdater = function () {
|
|
|
2134
2171
|
}
|
|
2135
2172
|
}, {
|
|
2136
2173
|
key: "updateNextNode",
|
|
2137
|
-
value: function updateNextNode(node, outerDeco, innerDeco, view, index) {
|
|
2174
|
+
value: function updateNextNode(node, outerDeco, innerDeco, view, index, pos) {
|
|
2138
2175
|
for (var i = this.index; i < this.top.children.length; i++) {
|
|
2139
2176
|
var next = this.top.children[i];
|
|
2140
2177
|
|
|
@@ -2142,7 +2179,8 @@ var ViewTreeUpdater = function () {
|
|
|
2142
2179
|
var _preMatch = this.preMatch.matched.get(next);
|
|
2143
2180
|
|
|
2144
2181
|
if (_preMatch != null && _preMatch != index) return false;
|
|
2145
|
-
var nextDOM = next.dom
|
|
2182
|
+
var nextDOM = next.dom,
|
|
2183
|
+
updated = void 0;
|
|
2146
2184
|
var locked = this.isLocked(nextDOM) && !(node.isText && next.node && next.node.isText && next.nodeDOM.nodeValue == node.text && next.dirty != NODE_DIRTY && sameOuterDeco(outerDeco, next.outerDeco));
|
|
2147
2185
|
|
|
2148
2186
|
if (!locked && next.update(node, outerDeco, innerDeco, view)) {
|
|
@@ -2150,6 +2188,11 @@ var ViewTreeUpdater = function () {
|
|
|
2150
2188
|
if (next.dom != nextDOM) this.changed = true;
|
|
2151
2189
|
this.index++;
|
|
2152
2190
|
return true;
|
|
2191
|
+
} else if (!locked && (updated = this.recreateWrapper(next, node, outerDeco, innerDeco, view, pos))) {
|
|
2192
|
+
this.top.children[this.index] = updated;
|
|
2193
|
+
this.changed = true;
|
|
2194
|
+
this.index++;
|
|
2195
|
+
return true;
|
|
2153
2196
|
}
|
|
2154
2197
|
|
|
2155
2198
|
break;
|
|
@@ -2158,10 +2201,40 @@ var ViewTreeUpdater = function () {
|
|
|
2158
2201
|
|
|
2159
2202
|
return false;
|
|
2160
2203
|
}
|
|
2204
|
+
}, {
|
|
2205
|
+
key: "recreateWrapper",
|
|
2206
|
+
value: function recreateWrapper(next, node, outerDeco, innerDeco, view, pos) {
|
|
2207
|
+
if (next.dirty || node.isAtom || !next.children.length || !next.node.content.eq(node.content)) return null;
|
|
2208
|
+
var wrapper = NodeViewDesc.create(this.top, node, outerDeco, innerDeco, view, pos);
|
|
2209
|
+
if (!wrapper.contentDOM) return null;
|
|
2210
|
+
wrapper.children = next.children;
|
|
2211
|
+
next.children = [];
|
|
2212
|
+
|
|
2213
|
+
var _iterator = _createForOfIteratorHelper(wrapper.children),
|
|
2214
|
+
_step;
|
|
2215
|
+
|
|
2216
|
+
try {
|
|
2217
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
2218
|
+
var ch = _step.value;
|
|
2219
|
+
ch.parent = wrapper;
|
|
2220
|
+
}
|
|
2221
|
+
} catch (err) {
|
|
2222
|
+
_iterator.e(err);
|
|
2223
|
+
} finally {
|
|
2224
|
+
_iterator.f();
|
|
2225
|
+
}
|
|
2226
|
+
|
|
2227
|
+
wrapper.dirty = CONTENT_DIRTY;
|
|
2228
|
+
wrapper.updateChildren(view, pos + 1);
|
|
2229
|
+
wrapper.dirty = NOT_DIRTY;
|
|
2230
|
+
return wrapper;
|
|
2231
|
+
}
|
|
2161
2232
|
}, {
|
|
2162
2233
|
key: "addNode",
|
|
2163
2234
|
value: function addNode(node, outerDeco, innerDeco, view, pos) {
|
|
2164
|
-
|
|
2235
|
+
var desc = NodeViewDesc.create(this.top, node, outerDeco, innerDeco, view, pos);
|
|
2236
|
+
if (desc.contentDOM) desc.updateChildren(view, pos + 1);
|
|
2237
|
+
this.top.children.splice(this.index++, 0, desc);
|
|
2165
2238
|
this.changed = true;
|
|
2166
2239
|
}
|
|
2167
2240
|
}, {
|
|
@@ -2665,7 +2738,7 @@ function selectHorizontally(view, dir, mods) {
|
|
|
2665
2738
|
if (sel instanceof prosemirrorState.TextSelection) {
|
|
2666
2739
|
if (!sel.empty || mods.indexOf("s") > -1) {
|
|
2667
2740
|
return false;
|
|
2668
|
-
} else if (view.endOfTextblock(dir > 0 ? "
|
|
2741
|
+
} else if (view.endOfTextblock(dir > 0 ? "forward" : "backward")) {
|
|
2669
2742
|
var next = moveSelectionBlock(view.state, dir);
|
|
2670
2743
|
if (next && next instanceof prosemirrorState.NodeSelection) return apply(view, next);
|
|
2671
2744
|
return false;
|
|
@@ -2704,7 +2777,11 @@ function isIgnorable(dom) {
|
|
|
2704
2777
|
return desc && desc.size == 0 && (dom.nextSibling || dom.nodeName != "BR");
|
|
2705
2778
|
}
|
|
2706
2779
|
|
|
2707
|
-
function
|
|
2780
|
+
function skipIgnoredNodes(view, dir) {
|
|
2781
|
+
return dir < 0 ? skipIgnoredNodesBefore(view) : skipIgnoredNodesAfter(view);
|
|
2782
|
+
}
|
|
2783
|
+
|
|
2784
|
+
function skipIgnoredNodesBefore(view) {
|
|
2708
2785
|
var sel = view.domSelectionRange();
|
|
2709
2786
|
var node = sel.focusNode,
|
|
2710
2787
|
offset = sel.focusOffset;
|
|
@@ -2754,7 +2831,7 @@ function skipIgnoredNodesLeft(view) {
|
|
|
2754
2831
|
if (force) setSelFocus(view, node, offset);else if (moveNode) setSelFocus(view, moveNode, moveOffset);
|
|
2755
2832
|
}
|
|
2756
2833
|
|
|
2757
|
-
function
|
|
2834
|
+
function skipIgnoredNodesAfter(view) {
|
|
2758
2835
|
var sel = view.domSelectionRange();
|
|
2759
2836
|
var node = sel.focusNode,
|
|
2760
2837
|
offset = sel.focusOffset;
|
|
@@ -2822,6 +2899,31 @@ function setSelFocus(view, node, offset) {
|
|
|
2822
2899
|
}, 50);
|
|
2823
2900
|
}
|
|
2824
2901
|
|
|
2902
|
+
function findDirection(view, pos) {
|
|
2903
|
+
var $pos = view.state.doc.resolve(pos);
|
|
2904
|
+
|
|
2905
|
+
if (!(chrome || windows) && $pos.parent.inlineContent) {
|
|
2906
|
+
var coords = view.coordsAtPos(pos);
|
|
2907
|
+
|
|
2908
|
+
if (pos > $pos.start()) {
|
|
2909
|
+
var before = view.coordsAtPos(pos - 1);
|
|
2910
|
+
var mid = (before.top + before.bottom) / 2;
|
|
2911
|
+
if (mid > coords.top && mid < coords.bottom && Math.abs(before.left - coords.left) > 1) return before.left < coords.left ? "ltr" : "rtl";
|
|
2912
|
+
}
|
|
2913
|
+
|
|
2914
|
+
if (pos < $pos.end()) {
|
|
2915
|
+
var after = view.coordsAtPos(pos + 1);
|
|
2916
|
+
|
|
2917
|
+
var _mid = (after.top + after.bottom) / 2;
|
|
2918
|
+
|
|
2919
|
+
if (_mid > coords.top && _mid < coords.bottom && Math.abs(after.left - coords.left) > 1) return after.left > coords.left ? "ltr" : "rtl";
|
|
2920
|
+
}
|
|
2921
|
+
}
|
|
2922
|
+
|
|
2923
|
+
var computed = getComputedStyle(view.dom).direction;
|
|
2924
|
+
return computed == "rtl" ? "rtl" : "ltr";
|
|
2925
|
+
}
|
|
2926
|
+
|
|
2825
2927
|
function selectVertically(view, dir, mods) {
|
|
2826
2928
|
var sel = view.state.selection;
|
|
2827
2929
|
if (sel instanceof prosemirrorState.TextSelection && !sel.empty || mods.indexOf("s") > -1) return false;
|
|
@@ -2902,19 +3004,22 @@ function captureKeyDown(view, event) {
|
|
|
2902
3004
|
mods = getMods(event);
|
|
2903
3005
|
|
|
2904
3006
|
if (code == 8 || mac && code == 72 && mods == "c") {
|
|
2905
|
-
return stopNativeHorizontalDelete(view, -1) ||
|
|
3007
|
+
return stopNativeHorizontalDelete(view, -1) || skipIgnoredNodes(view, -1);
|
|
2906
3008
|
} else if (code == 46 || mac && code == 68 && mods == "c") {
|
|
2907
|
-
return stopNativeHorizontalDelete(view, 1) ||
|
|
3009
|
+
return stopNativeHorizontalDelete(view, 1) || skipIgnoredNodes(view, 1);
|
|
2908
3010
|
} else if (code == 13 || code == 27) {
|
|
2909
3011
|
return true;
|
|
2910
3012
|
} else if (code == 37 || mac && code == 66 && mods == "c") {
|
|
2911
|
-
|
|
3013
|
+
var dir = code == 37 ? findDirection(view, view.state.selection.from) == "ltr" ? -1 : 1 : -1;
|
|
3014
|
+
return selectHorizontally(view, dir, mods) || skipIgnoredNodes(view, dir);
|
|
2912
3015
|
} else if (code == 39 || mac && code == 70 && mods == "c") {
|
|
2913
|
-
|
|
3016
|
+
var _dir = code == 39 ? findDirection(view, view.state.selection.from) == "ltr" ? 1 : -1 : 1;
|
|
3017
|
+
|
|
3018
|
+
return selectHorizontally(view, _dir, mods) || skipIgnoredNodes(view, _dir);
|
|
2914
3019
|
} else if (code == 38 || mac && code == 80 && mods == "c") {
|
|
2915
|
-
return selectVertically(view, -1, mods) ||
|
|
3020
|
+
return selectVertically(view, -1, mods) || skipIgnoredNodes(view, -1);
|
|
2916
3021
|
} else if (code == 40 || mac && code == 78 && mods == "c") {
|
|
2917
|
-
return safariDownArrowBug(view) || selectVertically(view, 1, mods) ||
|
|
3022
|
+
return safariDownArrowBug(view) || selectVertically(view, 1, mods) || skipIgnoredNodesAfter(view);
|
|
2918
3023
|
} else if (mods == (mac ? "m" : "c") && (code == 66 || code == 73 || code == 89 || code == 90)) {
|
|
2919
3024
|
return true;
|
|
2920
3025
|
}
|
|
@@ -3241,6 +3346,7 @@ var InputState = _createClass(function InputState() {
|
|
|
3241
3346
|
this.composingTimeout = -1;
|
|
3242
3347
|
this.compositionNodes = [];
|
|
3243
3348
|
this.compositionEndedAt = -2e8;
|
|
3349
|
+
this.compositionID = 1;
|
|
3244
3350
|
this.domChangeCount = 0;
|
|
3245
3351
|
this.eventHandlers = Object.create(null);
|
|
3246
3352
|
this.hideSelectionGuard = null;
|
|
@@ -3704,6 +3810,7 @@ editHandlers.compositionend = function (view, event) {
|
|
|
3704
3810
|
if (view.composing) {
|
|
3705
3811
|
view.input.composing = false;
|
|
3706
3812
|
view.input.compositionEndedAt = event.timeStamp;
|
|
3813
|
+
view.input.compositionID++;
|
|
3707
3814
|
scheduleComposeEnd(view, 20);
|
|
3708
3815
|
}
|
|
3709
3816
|
};
|
|
@@ -5185,6 +5292,7 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
|
|
|
5185
5292
|
var _tr = view.state.tr.setSelection(newSel);
|
|
5186
5293
|
|
|
5187
5294
|
if (origin == "pointer") _tr.setMeta("pointer", true);else if (origin == "key") _tr.scrollIntoView();
|
|
5295
|
+
if (view.composing) _tr.setMeta("composition", view.input.compositionID);
|
|
5188
5296
|
view.dispatch(_tr);
|
|
5189
5297
|
}
|
|
5190
5298
|
|
|
@@ -5232,7 +5340,12 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
|
|
|
5232
5340
|
if (parse.sel) {
|
|
5233
5341
|
var _sel = resolveSelection(view, view.state.doc, parse.sel);
|
|
5234
5342
|
|
|
5235
|
-
if (_sel && !_sel.eq(view.state.selection))
|
|
5343
|
+
if (_sel && !_sel.eq(view.state.selection)) {
|
|
5344
|
+
var _tr2 = view.state.tr.setSelection(_sel);
|
|
5345
|
+
|
|
5346
|
+
if (view.composing) _tr2.setMeta("composition", view.input.compositionID);
|
|
5347
|
+
view.dispatch(_tr2);
|
|
5348
|
+
}
|
|
5236
5349
|
}
|
|
5237
5350
|
|
|
5238
5351
|
return;
|
|
@@ -5334,6 +5447,7 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
|
|
|
5334
5447
|
}
|
|
5335
5448
|
|
|
5336
5449
|
if (storedMarks) tr.ensureMarks(storedMarks);
|
|
5450
|
+
if (view.composing) tr.setMeta("composition", view.input.compositionID);
|
|
5337
5451
|
view.dispatch(tr.scrollIntoView());
|
|
5338
5452
|
}
|
|
5339
5453
|
|
package/dist/index.js
CHANGED
|
@@ -94,6 +94,21 @@ function deepActiveElement(doc) {
|
|
|
94
94
|
elt = elt.shadowRoot.activeElement;
|
|
95
95
|
return elt;
|
|
96
96
|
}
|
|
97
|
+
function caretFromPoint(doc, x, y) {
|
|
98
|
+
if (doc.caretPositionFromPoint) {
|
|
99
|
+
try { // Firefox throws for this call in hard-to-predict circumstances (#994)
|
|
100
|
+
let pos = doc.caretPositionFromPoint(x, y);
|
|
101
|
+
if (pos)
|
|
102
|
+
return { node: pos.offsetNode, offset: pos.offset };
|
|
103
|
+
}
|
|
104
|
+
catch (_) { }
|
|
105
|
+
}
|
|
106
|
+
if (doc.caretRangeFromPoint) {
|
|
107
|
+
let range = doc.caretRangeFromPoint(x, y);
|
|
108
|
+
if (range)
|
|
109
|
+
return { node: range.startContainer, offset: range.startOffset };
|
|
110
|
+
}
|
|
111
|
+
}
|
|
97
112
|
|
|
98
113
|
const nav = typeof navigator != "undefined" ? navigator : null;
|
|
99
114
|
const doc = typeof document != "undefined" ? document : null;
|
|
@@ -112,6 +127,7 @@ const safari = !ie && !!nav && /Apple Computer/.test(nav.vendor);
|
|
|
112
127
|
// Is true for both iOS and iPadOS for convenience
|
|
113
128
|
const ios = safari && (/Mobile\/\w+/.test(agent) || !!nav && nav.maxTouchPoints > 2);
|
|
114
129
|
const mac = ios || (nav ? /Mac/.test(nav.platform) : false);
|
|
130
|
+
const windows = nav ? /Win/.test(nav.platform) : false;
|
|
115
131
|
const android = /Android \d/.test(agent);
|
|
116
132
|
const webkit = !!doc && "webkitFontSmoothing" in doc.documentElement.style;
|
|
117
133
|
const webkit_version = webkit ? +(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent) || [0, 0])[1] : 0;
|
|
@@ -237,6 +253,7 @@ function focusPreventScroll(dom) {
|
|
|
237
253
|
function findOffsetInNode(node, coords) {
|
|
238
254
|
let closest, dxClosest = 2e8, coordsClosest, offset = 0;
|
|
239
255
|
let rowBot = coords.top, rowTop = coords.top;
|
|
256
|
+
let firstBelow, coordsBelow;
|
|
240
257
|
for (let child = node.firstChild, childIndex = 0; child; child = child.nextSibling, childIndex++) {
|
|
241
258
|
let rects;
|
|
242
259
|
if (child.nodeType == 1)
|
|
@@ -264,11 +281,20 @@ function findOffsetInNode(node, coords) {
|
|
|
264
281
|
continue;
|
|
265
282
|
}
|
|
266
283
|
}
|
|
284
|
+
else if (rect.top > coords.top && !firstBelow && rect.left <= coords.left && rect.right >= coords.left) {
|
|
285
|
+
firstBelow = child;
|
|
286
|
+
coordsBelow = { left: Math.max(rect.left, Math.min(rect.right, coords.left)), top: rect.top };
|
|
287
|
+
}
|
|
267
288
|
if (!closest && (coords.left >= rect.right && coords.top >= rect.top ||
|
|
268
289
|
coords.left >= rect.left && coords.top >= rect.bottom))
|
|
269
290
|
offset = childIndex + 1;
|
|
270
291
|
}
|
|
271
292
|
}
|
|
293
|
+
if (!closest && firstBelow) {
|
|
294
|
+
closest = firstBelow;
|
|
295
|
+
coordsClosest = coordsBelow;
|
|
296
|
+
dxClosest = 0;
|
|
297
|
+
}
|
|
272
298
|
if (closest && closest.nodeType == 3)
|
|
273
299
|
return findOffsetInText(closest, coordsClosest);
|
|
274
300
|
if (!closest || (dxClosest && closest.nodeType == 1))
|
|
@@ -363,19 +389,9 @@ function elementFromPoint(element, coords, box) {
|
|
|
363
389
|
// Given an x,y position on the editor, get the position in the document.
|
|
364
390
|
function posAtCoords(view, coords) {
|
|
365
391
|
let doc = view.dom.ownerDocument, node, offset = 0;
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
if (pos)
|
|
370
|
-
({ offsetNode: node, offset } = pos);
|
|
371
|
-
}
|
|
372
|
-
catch (_) { }
|
|
373
|
-
}
|
|
374
|
-
if (!node && doc.caretRangeFromPoint) {
|
|
375
|
-
let range = doc.caretRangeFromPoint(coords.left, coords.top);
|
|
376
|
-
if (range)
|
|
377
|
-
({ startContainer: node, startOffset: offset } = range);
|
|
378
|
-
}
|
|
392
|
+
let caret = caretFromPoint(doc, coords.left, coords.top);
|
|
393
|
+
if (caret)
|
|
394
|
+
({ node, offset } = caret);
|
|
379
395
|
let elt = (view.root.elementFromPoint ? view.root : doc)
|
|
380
396
|
.elementFromPoint(coords.left, coords.top);
|
|
381
397
|
let pos;
|
|
@@ -424,9 +440,17 @@ function posAtCoords(view, coords) {
|
|
|
424
440
|
let desc = view.docView.nearestDesc(elt, true);
|
|
425
441
|
return { pos, inside: desc ? desc.posAtStart - desc.border : -1 };
|
|
426
442
|
}
|
|
443
|
+
function nonZero(rect) {
|
|
444
|
+
return rect.top < rect.bottom || rect.left < rect.right;
|
|
445
|
+
}
|
|
427
446
|
function singleRect(target, bias) {
|
|
428
447
|
let rects = target.getClientRects();
|
|
429
|
-
|
|
448
|
+
if (rects.length) {
|
|
449
|
+
let first = rects[bias < 0 ? 0 : rects.length - 1];
|
|
450
|
+
if (nonZero(first))
|
|
451
|
+
return first;
|
|
452
|
+
}
|
|
453
|
+
return Array.prototype.find.call(rects, nonZero) || target.getBoundingClientRect();
|
|
430
454
|
}
|
|
431
455
|
const BIDI = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;
|
|
432
456
|
// Given a position in the document model, get a bounding box of the
|
|
@@ -468,7 +492,7 @@ function coordsAtPos(view, pos, side) {
|
|
|
468
492
|
else {
|
|
469
493
|
to++;
|
|
470
494
|
}
|
|
471
|
-
return flattenV(singleRect(textRange(node, from, to),
|
|
495
|
+
return flattenV(singleRect(textRange(node, from, to), takeSide), takeSide < 0);
|
|
472
496
|
}
|
|
473
497
|
}
|
|
474
498
|
let $dom = view.state.doc.resolve(pos - (atom || 0));
|
|
@@ -1159,8 +1183,6 @@ class NodeViewDesc extends ViewDesc {
|
|
|
1159
1183
|
this.outerDeco = outerDeco;
|
|
1160
1184
|
this.innerDeco = innerDeco;
|
|
1161
1185
|
this.nodeDOM = nodeDOM;
|
|
1162
|
-
if (contentDOM)
|
|
1163
|
-
this.updateChildren(view, pos);
|
|
1164
1186
|
}
|
|
1165
1187
|
// By default, a node is rendered using the `toDOM` method from the
|
|
1166
1188
|
// node type spec. But client code can use the `nodeViews` spec to
|
|
@@ -1273,7 +1295,7 @@ class NodeViewDesc extends ViewDesc {
|
|
|
1273
1295
|
view.state.selection.to < off + child.nodeSize &&
|
|
1274
1296
|
(compIndex = updater.findIndexWithChild(composition.node)) > -1 &&
|
|
1275
1297
|
updater.updateNodeAt(child, outerDeco, innerDeco, compIndex, view)) ;
|
|
1276
|
-
else if (updater.updateNextNode(child, outerDeco, innerDeco, view, i)) ;
|
|
1298
|
+
else if (updater.updateNextNode(child, outerDeco, innerDeco, view, i, off)) ;
|
|
1277
1299
|
else {
|
|
1278
1300
|
// Add it as a new view
|
|
1279
1301
|
updater.addNode(child, outerDeco, innerDeco, view, off);
|
|
@@ -1387,7 +1409,10 @@ class NodeViewDesc extends ViewDesc {
|
|
|
1387
1409
|
// and used by the view class.
|
|
1388
1410
|
function docViewDesc(doc, outerDeco, innerDeco, dom, view) {
|
|
1389
1411
|
applyOuterDeco(dom, outerDeco, doc);
|
|
1390
|
-
|
|
1412
|
+
let docView = new NodeViewDesc(undefined, doc, outerDeco, innerDeco, dom, dom, dom, view, 0);
|
|
1413
|
+
if (docView.contentDOM)
|
|
1414
|
+
docView.updateChildren(view, 0);
|
|
1415
|
+
return docView;
|
|
1391
1416
|
}
|
|
1392
1417
|
class TextViewDesc extends NodeViewDesc {
|
|
1393
1418
|
constructor(parent, node, outerDeco, innerDeco, dom, nodeDOM, view) {
|
|
@@ -1760,14 +1785,14 @@ class ViewTreeUpdater {
|
|
|
1760
1785
|
}
|
|
1761
1786
|
// Try to update the next node, if any, to the given data. Checks
|
|
1762
1787
|
// pre-matches to avoid overwriting nodes that could still be used.
|
|
1763
|
-
updateNextNode(node, outerDeco, innerDeco, view, index) {
|
|
1788
|
+
updateNextNode(node, outerDeco, innerDeco, view, index, pos) {
|
|
1764
1789
|
for (let i = this.index; i < this.top.children.length; i++) {
|
|
1765
1790
|
let next = this.top.children[i];
|
|
1766
1791
|
if (next instanceof NodeViewDesc) {
|
|
1767
1792
|
let preMatch = this.preMatch.matched.get(next);
|
|
1768
1793
|
if (preMatch != null && preMatch != index)
|
|
1769
1794
|
return false;
|
|
1770
|
-
let nextDOM = next.dom;
|
|
1795
|
+
let nextDOM = next.dom, updated;
|
|
1771
1796
|
// Can't update if nextDOM is or contains this.lock, except if
|
|
1772
1797
|
// it's a text node whose content already matches the new text
|
|
1773
1798
|
// and whose decorations match the new ones.
|
|
@@ -1781,14 +1806,41 @@ class ViewTreeUpdater {
|
|
|
1781
1806
|
this.index++;
|
|
1782
1807
|
return true;
|
|
1783
1808
|
}
|
|
1809
|
+
else if (!locked && (updated = this.recreateWrapper(next, node, outerDeco, innerDeco, view, pos))) {
|
|
1810
|
+
this.top.children[this.index] = updated;
|
|
1811
|
+
this.changed = true;
|
|
1812
|
+
this.index++;
|
|
1813
|
+
return true;
|
|
1814
|
+
}
|
|
1784
1815
|
break;
|
|
1785
1816
|
}
|
|
1786
1817
|
}
|
|
1787
1818
|
return false;
|
|
1788
1819
|
}
|
|
1820
|
+
// When a node with content is replaced by a different node with
|
|
1821
|
+
// identical content, move over its children.
|
|
1822
|
+
recreateWrapper(next, node, outerDeco, innerDeco, view, pos) {
|
|
1823
|
+
if (next.dirty || node.isAtom || !next.children.length ||
|
|
1824
|
+
!next.node.content.eq(node.content))
|
|
1825
|
+
return null;
|
|
1826
|
+
let wrapper = NodeViewDesc.create(this.top, node, outerDeco, innerDeco, view, pos);
|
|
1827
|
+
if (!wrapper.contentDOM)
|
|
1828
|
+
return null;
|
|
1829
|
+
wrapper.children = next.children;
|
|
1830
|
+
next.children = [];
|
|
1831
|
+
for (let ch of wrapper.children)
|
|
1832
|
+
ch.parent = wrapper;
|
|
1833
|
+
wrapper.dirty = CONTENT_DIRTY;
|
|
1834
|
+
wrapper.updateChildren(view, pos + 1);
|
|
1835
|
+
wrapper.dirty = NOT_DIRTY;
|
|
1836
|
+
return wrapper;
|
|
1837
|
+
}
|
|
1789
1838
|
// Insert the node as a newly created node desc.
|
|
1790
1839
|
addNode(node, outerDeco, innerDeco, view, pos) {
|
|
1791
|
-
|
|
1840
|
+
let desc = NodeViewDesc.create(this.top, node, outerDeco, innerDeco, view, pos);
|
|
1841
|
+
if (desc.contentDOM)
|
|
1842
|
+
desc.updateChildren(view, pos + 1);
|
|
1843
|
+
this.top.children.splice(this.index++, 0, desc);
|
|
1792
1844
|
this.changed = true;
|
|
1793
1845
|
}
|
|
1794
1846
|
placeWidget(widget, view, pos) {
|
|
@@ -2260,7 +2312,7 @@ function selectHorizontally(view, dir, mods) {
|
|
|
2260
2312
|
if (!sel.empty || mods.indexOf("s") > -1) {
|
|
2261
2313
|
return false;
|
|
2262
2314
|
}
|
|
2263
|
-
else if (view.endOfTextblock(dir > 0 ? "
|
|
2315
|
+
else if (view.endOfTextblock(dir > 0 ? "forward" : "backward")) {
|
|
2264
2316
|
let next = moveSelectionBlock(view.state, dir);
|
|
2265
2317
|
if (next && (next instanceof NodeSelection))
|
|
2266
2318
|
return apply(view, next);
|
|
@@ -2304,9 +2356,12 @@ function isIgnorable(dom) {
|
|
|
2304
2356
|
let desc = dom.pmViewDesc;
|
|
2305
2357
|
return desc && desc.size == 0 && (dom.nextSibling || dom.nodeName != "BR");
|
|
2306
2358
|
}
|
|
2359
|
+
function skipIgnoredNodes(view, dir) {
|
|
2360
|
+
return dir < 0 ? skipIgnoredNodesBefore(view) : skipIgnoredNodesAfter(view);
|
|
2361
|
+
}
|
|
2307
2362
|
// Make sure the cursor isn't directly after one or more ignored
|
|
2308
2363
|
// nodes, which will confuse the browser's cursor motion logic.
|
|
2309
|
-
function
|
|
2364
|
+
function skipIgnoredNodesBefore(view) {
|
|
2310
2365
|
let sel = view.domSelectionRange();
|
|
2311
2366
|
let node = sel.focusNode, offset = sel.focusOffset;
|
|
2312
2367
|
if (!node)
|
|
@@ -2365,7 +2420,7 @@ function skipIgnoredNodesLeft(view) {
|
|
|
2365
2420
|
}
|
|
2366
2421
|
// Make sure the cursor isn't directly before one or more ignored
|
|
2367
2422
|
// nodes.
|
|
2368
|
-
function
|
|
2423
|
+
function skipIgnoredNodesAfter(view) {
|
|
2369
2424
|
let sel = view.domSelectionRange();
|
|
2370
2425
|
let node = sel.focusNode, offset = sel.focusOffset;
|
|
2371
2426
|
if (!node)
|
|
@@ -2434,6 +2489,26 @@ function setSelFocus(view, node, offset) {
|
|
|
2434
2489
|
selectionToDOM(view);
|
|
2435
2490
|
}, 50);
|
|
2436
2491
|
}
|
|
2492
|
+
function findDirection(view, pos) {
|
|
2493
|
+
let $pos = view.state.doc.resolve(pos);
|
|
2494
|
+
if (!(chrome || windows) && $pos.parent.inlineContent) {
|
|
2495
|
+
let coords = view.coordsAtPos(pos);
|
|
2496
|
+
if (pos > $pos.start()) {
|
|
2497
|
+
let before = view.coordsAtPos(pos - 1);
|
|
2498
|
+
let mid = (before.top + before.bottom) / 2;
|
|
2499
|
+
if (mid > coords.top && mid < coords.bottom && Math.abs(before.left - coords.left) > 1)
|
|
2500
|
+
return before.left < coords.left ? "ltr" : "rtl";
|
|
2501
|
+
}
|
|
2502
|
+
if (pos < $pos.end()) {
|
|
2503
|
+
let after = view.coordsAtPos(pos + 1);
|
|
2504
|
+
let mid = (after.top + after.bottom) / 2;
|
|
2505
|
+
if (mid > coords.top && mid < coords.bottom && Math.abs(after.left - coords.left) > 1)
|
|
2506
|
+
return after.left > coords.left ? "ltr" : "rtl";
|
|
2507
|
+
}
|
|
2508
|
+
}
|
|
2509
|
+
let computed = getComputedStyle(view.dom).direction;
|
|
2510
|
+
return computed == "rtl" ? "rtl" : "ltr";
|
|
2511
|
+
}
|
|
2437
2512
|
// Check whether vertical selection motion would involve node
|
|
2438
2513
|
// selections. If so, apply it (if not, the result is left to the
|
|
2439
2514
|
// browser)
|
|
@@ -2521,25 +2596,27 @@ function getMods(event) {
|
|
|
2521
2596
|
function captureKeyDown(view, event) {
|
|
2522
2597
|
let code = event.keyCode, mods = getMods(event);
|
|
2523
2598
|
if (code == 8 || (mac && code == 72 && mods == "c")) { // Backspace, Ctrl-h on Mac
|
|
2524
|
-
return stopNativeHorizontalDelete(view, -1) ||
|
|
2599
|
+
return stopNativeHorizontalDelete(view, -1) || skipIgnoredNodes(view, -1);
|
|
2525
2600
|
}
|
|
2526
2601
|
else if (code == 46 || (mac && code == 68 && mods == "c")) { // Delete, Ctrl-d on Mac
|
|
2527
|
-
return stopNativeHorizontalDelete(view, 1) ||
|
|
2602
|
+
return stopNativeHorizontalDelete(view, 1) || skipIgnoredNodes(view, 1);
|
|
2528
2603
|
}
|
|
2529
2604
|
else if (code == 13 || code == 27) { // Enter, Esc
|
|
2530
2605
|
return true;
|
|
2531
2606
|
}
|
|
2532
2607
|
else if (code == 37 || (mac && code == 66 && mods == "c")) { // Left arrow, Ctrl-b on Mac
|
|
2533
|
-
|
|
2608
|
+
let dir = code == 37 ? (findDirection(view, view.state.selection.from) == "ltr" ? -1 : 1) : -1;
|
|
2609
|
+
return selectHorizontally(view, dir, mods) || skipIgnoredNodes(view, dir);
|
|
2534
2610
|
}
|
|
2535
2611
|
else if (code == 39 || (mac && code == 70 && mods == "c")) { // Right arrow, Ctrl-f on Mac
|
|
2536
|
-
|
|
2612
|
+
let dir = code == 39 ? (findDirection(view, view.state.selection.from) == "ltr" ? 1 : -1) : 1;
|
|
2613
|
+
return selectHorizontally(view, dir, mods) || skipIgnoredNodes(view, dir);
|
|
2537
2614
|
}
|
|
2538
2615
|
else if (code == 38 || (mac && code == 80 && mods == "c")) { // Up arrow, Ctrl-p on Mac
|
|
2539
|
-
return selectVertically(view, -1, mods) ||
|
|
2616
|
+
return selectVertically(view, -1, mods) || skipIgnoredNodes(view, -1);
|
|
2540
2617
|
}
|
|
2541
2618
|
else if (code == 40 || (mac && code == 78 && mods == "c")) { // Down arrow, Ctrl-n on Mac
|
|
2542
|
-
return safariDownArrowBug(view) || selectVertically(view, 1, mods) ||
|
|
2619
|
+
return safariDownArrowBug(view) || selectVertically(view, 1, mods) || skipIgnoredNodesAfter(view);
|
|
2543
2620
|
}
|
|
2544
2621
|
else if (mods == (mac ? "m" : "c") &&
|
|
2545
2622
|
(code == 66 || code == 73 || code == 89 || code == 90)) { // Mod-[biyz]
|
|
@@ -2818,6 +2895,7 @@ class InputState {
|
|
|
2818
2895
|
this.composingTimeout = -1;
|
|
2819
2896
|
this.compositionNodes = [];
|
|
2820
2897
|
this.compositionEndedAt = -2e8;
|
|
2898
|
+
this.compositionID = 1;
|
|
2821
2899
|
this.domChangeCount = 0;
|
|
2822
2900
|
this.eventHandlers = Object.create(null);
|
|
2823
2901
|
this.hideSelectionGuard = null;
|
|
@@ -3247,6 +3325,7 @@ editHandlers.compositionend = (view, event) => {
|
|
|
3247
3325
|
if (view.composing) {
|
|
3248
3326
|
view.input.composing = false;
|
|
3249
3327
|
view.input.compositionEndedAt = event.timeStamp;
|
|
3328
|
+
view.input.compositionID++;
|
|
3250
3329
|
scheduleComposeEnd(view, 20);
|
|
3251
3330
|
}
|
|
3252
3331
|
};
|
|
@@ -4590,6 +4669,8 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
|
|
|
4590
4669
|
tr.setMeta("pointer", true);
|
|
4591
4670
|
else if (origin == "key")
|
|
4592
4671
|
tr.scrollIntoView();
|
|
4672
|
+
if (view.composing)
|
|
4673
|
+
tr.setMeta("composition", view.input.compositionID);
|
|
4593
4674
|
view.dispatch(tr);
|
|
4594
4675
|
}
|
|
4595
4676
|
return;
|
|
@@ -4628,8 +4709,12 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
|
|
|
4628
4709
|
else {
|
|
4629
4710
|
if (parse.sel) {
|
|
4630
4711
|
let sel = resolveSelection(view, view.state.doc, parse.sel);
|
|
4631
|
-
if (sel && !sel.eq(view.state.selection))
|
|
4632
|
-
view.
|
|
4712
|
+
if (sel && !sel.eq(view.state.selection)) {
|
|
4713
|
+
let tr = view.state.tr.setSelection(sel);
|
|
4714
|
+
if (view.composing)
|
|
4715
|
+
tr.setMeta("composition", view.input.compositionID);
|
|
4716
|
+
view.dispatch(tr);
|
|
4717
|
+
}
|
|
4633
4718
|
}
|
|
4634
4719
|
return;
|
|
4635
4720
|
}
|
|
@@ -4760,6 +4845,8 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
|
|
|
4760
4845
|
}
|
|
4761
4846
|
if (storedMarks)
|
|
4762
4847
|
tr.ensureMarks(storedMarks);
|
|
4848
|
+
if (view.composing)
|
|
4849
|
+
tr.setMeta("composition", view.input.compositionID);
|
|
4763
4850
|
view.dispatch(tr.scrollIntoView());
|
|
4764
4851
|
}
|
|
4765
4852
|
function resolveSelection(view, doc, parsedSel) {
|
package/package.json
CHANGED
package/src/browser.ts
CHANGED
|
@@ -18,6 +18,7 @@ export const safari = !ie && !!nav && /Apple Computer/.test(nav.vendor)
|
|
|
18
18
|
// Is true for both iOS and iPadOS for convenience
|
|
19
19
|
export const ios = safari && (/Mobile\/\w+/.test(agent) || !!nav && nav.maxTouchPoints > 2)
|
|
20
20
|
export const mac = ios || (nav ? /Mac/.test(nav.platform) : false)
|
|
21
|
+
export const windows = nav ? /Win/.test(nav.platform) : false
|
|
21
22
|
export const android = /Android \d/.test(agent)
|
|
22
23
|
export const webkit = !!doc && "webkitFontSmoothing" in doc.documentElement.style
|
|
23
24
|
export const webkit_version = webkit ? +(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent) || [0, 0])[1] : 0
|
package/src/capturekeys.ts
CHANGED
|
@@ -21,7 +21,7 @@ function selectHorizontally(view: EditorView, dir: number, mods: string) {
|
|
|
21
21
|
if (sel instanceof TextSelection) {
|
|
22
22
|
if (!sel.empty || mods.indexOf("s") > -1) {
|
|
23
23
|
return false
|
|
24
|
-
} else if (view.endOfTextblock(dir > 0 ? "
|
|
24
|
+
} else if (view.endOfTextblock(dir > 0 ? "forward" : "backward")) {
|
|
25
25
|
let next = moveSelectionBlock(view.state, dir)
|
|
26
26
|
if (next && (next instanceof NodeSelection)) return apply(view, next)
|
|
27
27
|
return false
|
|
@@ -59,9 +59,13 @@ function isIgnorable(dom: Node) {
|
|
|
59
59
|
return desc && desc.size == 0 && (dom.nextSibling || dom.nodeName != "BR")
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
function skipIgnoredNodes(view: EditorView, dir: number) {
|
|
63
|
+
return dir < 0 ? skipIgnoredNodesBefore(view) : skipIgnoredNodesAfter(view)
|
|
64
|
+
}
|
|
65
|
+
|
|
62
66
|
// Make sure the cursor isn't directly after one or more ignored
|
|
63
67
|
// nodes, which will confuse the browser's cursor motion logic.
|
|
64
|
-
function
|
|
68
|
+
function skipIgnoredNodesBefore(view: EditorView) {
|
|
65
69
|
let sel = view.domSelectionRange()
|
|
66
70
|
let node = sel.focusNode!, offset = sel.focusOffset
|
|
67
71
|
if (!node) return
|
|
@@ -109,7 +113,7 @@ function skipIgnoredNodesLeft(view: EditorView) {
|
|
|
109
113
|
|
|
110
114
|
// Make sure the cursor isn't directly before one or more ignored
|
|
111
115
|
// nodes.
|
|
112
|
-
function
|
|
116
|
+
function skipIgnoredNodesAfter(view: EditorView) {
|
|
113
117
|
let sel = view.domSelectionRange()
|
|
114
118
|
let node = sel.focusNode!, offset = sel.focusOffset
|
|
115
119
|
if (!node) return
|
|
@@ -171,6 +175,27 @@ function setSelFocus(view: EditorView, node: Node, offset: number) {
|
|
|
171
175
|
}, 50)
|
|
172
176
|
}
|
|
173
177
|
|
|
178
|
+
function findDirection(view: EditorView, pos: number): "rtl" | "ltr" {
|
|
179
|
+
let $pos = view.state.doc.resolve(pos)
|
|
180
|
+
if (!(browser.chrome || browser.windows) && $pos.parent.inlineContent) {
|
|
181
|
+
let coords = view.coordsAtPos(pos)
|
|
182
|
+
if (pos > $pos.start()) {
|
|
183
|
+
let before = view.coordsAtPos(pos - 1)
|
|
184
|
+
let mid = (before.top + before.bottom) / 2
|
|
185
|
+
if (mid > coords.top && mid < coords.bottom && Math.abs(before.left - coords.left) > 1)
|
|
186
|
+
return before.left < coords.left ? "ltr" : "rtl"
|
|
187
|
+
}
|
|
188
|
+
if (pos < $pos.end()) {
|
|
189
|
+
let after = view.coordsAtPos(pos + 1)
|
|
190
|
+
let mid = (after.top + after.bottom) / 2
|
|
191
|
+
if (mid > coords.top && mid < coords.bottom && Math.abs(after.left - coords.left) > 1)
|
|
192
|
+
return after.left > coords.left ? "ltr" : "rtl"
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
let computed = getComputedStyle(view.dom).direction
|
|
196
|
+
return computed == "rtl" ? "rtl" : "ltr"
|
|
197
|
+
}
|
|
198
|
+
|
|
174
199
|
// Check whether vertical selection motion would involve node
|
|
175
200
|
// selections. If so, apply it (if not, the result is left to the
|
|
176
201
|
// browser)
|
|
@@ -252,19 +277,21 @@ function getMods(event: KeyboardEvent) {
|
|
|
252
277
|
export function captureKeyDown(view: EditorView, event: KeyboardEvent) {
|
|
253
278
|
let code = event.keyCode, mods = getMods(event)
|
|
254
279
|
if (code == 8 || (browser.mac && code == 72 && mods == "c")) { // Backspace, Ctrl-h on Mac
|
|
255
|
-
return stopNativeHorizontalDelete(view, -1) ||
|
|
280
|
+
return stopNativeHorizontalDelete(view, -1) || skipIgnoredNodes(view, -1)
|
|
256
281
|
} else if (code == 46 || (browser.mac && code == 68 && mods == "c")) { // Delete, Ctrl-d on Mac
|
|
257
|
-
return stopNativeHorizontalDelete(view, 1) ||
|
|
282
|
+
return stopNativeHorizontalDelete(view, 1) || skipIgnoredNodes(view, 1)
|
|
258
283
|
} else if (code == 13 || code == 27) { // Enter, Esc
|
|
259
284
|
return true
|
|
260
285
|
} else if (code == 37 || (browser.mac && code == 66 && mods == "c")) { // Left arrow, Ctrl-b on Mac
|
|
261
|
-
|
|
286
|
+
let dir = code == 37 ? (findDirection(view, view.state.selection.from) == "ltr" ? -1 : 1) : -1
|
|
287
|
+
return selectHorizontally(view, dir, mods) || skipIgnoredNodes(view, dir)
|
|
262
288
|
} else if (code == 39 || (browser.mac && code == 70 && mods == "c")) { // Right arrow, Ctrl-f on Mac
|
|
263
|
-
|
|
289
|
+
let dir = code == 39 ? (findDirection(view, view.state.selection.from) == "ltr" ? 1 : -1) : 1
|
|
290
|
+
return selectHorizontally(view, dir, mods) || skipIgnoredNodes(view, dir)
|
|
264
291
|
} else if (code == 38 || (browser.mac && code == 80 && mods == "c")) { // Up arrow, Ctrl-p on Mac
|
|
265
|
-
return selectVertically(view, -1, mods) ||
|
|
292
|
+
return selectVertically(view, -1, mods) || skipIgnoredNodes(view, -1)
|
|
266
293
|
} else if (code == 40 || (browser.mac && code == 78 && mods == "c")) { // Down arrow, Ctrl-n on Mac
|
|
267
|
-
return safariDownArrowBug(view) || selectVertically(view, 1, mods) ||
|
|
294
|
+
return safariDownArrowBug(view) || selectVertically(view, 1, mods) || skipIgnoredNodesAfter(view)
|
|
268
295
|
} else if (mods == (browser.mac ? "m" : "c") &&
|
|
269
296
|
(code == 66 || code == 73 || code == 89 || code == 90)) { // Mod-[biyz]
|
|
270
297
|
return true
|
package/src/dom.ts
CHANGED
|
@@ -100,3 +100,16 @@ export function deepActiveElement(doc: Document) {
|
|
|
100
100
|
while (elt && elt.shadowRoot) elt = elt.shadowRoot.activeElement
|
|
101
101
|
return elt
|
|
102
102
|
}
|
|
103
|
+
|
|
104
|
+
export function caretFromPoint(doc: Document, x: number, y: number): {node: Node, offset: number} | undefined {
|
|
105
|
+
if ((doc as any).caretPositionFromPoint) {
|
|
106
|
+
try { // Firefox throws for this call in hard-to-predict circumstances (#994)
|
|
107
|
+
let pos = (doc as any).caretPositionFromPoint(x, y)
|
|
108
|
+
if (pos) return {node: pos.offsetNode, offset: pos.offset}
|
|
109
|
+
} catch (_) {}
|
|
110
|
+
}
|
|
111
|
+
if (doc.caretRangeFromPoint) {
|
|
112
|
+
let range = doc.caretRangeFromPoint(x, y)
|
|
113
|
+
if (range) return {node: range.startContainer, offset: range.startOffset}
|
|
114
|
+
}
|
|
115
|
+
}
|
package/src/domchange.ts
CHANGED
|
@@ -90,6 +90,7 @@ export function readDOMChange(view: EditorView, from: number, to: number, typeOv
|
|
|
90
90
|
let tr = view.state.tr.setSelection(newSel)
|
|
91
91
|
if (origin == "pointer") tr.setMeta("pointer", true)
|
|
92
92
|
else if (origin == "key") tr.scrollIntoView()
|
|
93
|
+
if (view.composing) tr.setMeta("composition", view.input.compositionID)
|
|
93
94
|
view.dispatch(tr)
|
|
94
95
|
}
|
|
95
96
|
return
|
|
@@ -130,7 +131,11 @@ export function readDOMChange(view: EditorView, from: number, to: number, typeOv
|
|
|
130
131
|
} else {
|
|
131
132
|
if (parse.sel) {
|
|
132
133
|
let sel = resolveSelection(view, view.state.doc, parse.sel)
|
|
133
|
-
if (sel && !sel.eq(view.state.selection))
|
|
134
|
+
if (sel && !sel.eq(view.state.selection)) {
|
|
135
|
+
let tr = view.state.tr.setSelection(sel)
|
|
136
|
+
if (view.composing) tr.setMeta("composition", view.input.compositionID)
|
|
137
|
+
view.dispatch(tr)
|
|
138
|
+
}
|
|
134
139
|
}
|
|
135
140
|
return
|
|
136
141
|
}
|
|
@@ -263,6 +268,7 @@ export function readDOMChange(view: EditorView, from: number, to: number, typeOv
|
|
|
263
268
|
tr.setSelection(sel)
|
|
264
269
|
}
|
|
265
270
|
if (storedMarks) tr.ensureMarks(storedMarks)
|
|
271
|
+
if (view.composing) tr.setMeta("composition", view.input.compositionID)
|
|
266
272
|
view.dispatch(tr.scrollIntoView())
|
|
267
273
|
}
|
|
268
274
|
|
package/src/domcoords.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {EditorState} from "prosemirror-state"
|
|
2
|
-
import {nodeSize, textRange, parentNode} from "./dom"
|
|
2
|
+
import {nodeSize, textRange, parentNode, caretFromPoint} from "./dom"
|
|
3
3
|
import * as browser from "./browser"
|
|
4
4
|
import {EditorView} from "./index"
|
|
5
5
|
|
|
@@ -133,6 +133,7 @@ export function focusPreventScroll(dom: HTMLElement) {
|
|
|
133
133
|
function findOffsetInNode(node: HTMLElement, coords: {top: number, left: number}): {node: Node, offset: number} {
|
|
134
134
|
let closest, dxClosest = 2e8, coordsClosest: {left: number, top: number} | undefined, offset = 0
|
|
135
135
|
let rowBot = coords.top, rowTop = coords.top
|
|
136
|
+
let firstBelow: Node | undefined, coordsBelow: {left: number, top: number} | undefined
|
|
136
137
|
for (let child = node.firstChild, childIndex = 0; child; child = child.nextSibling, childIndex++) {
|
|
137
138
|
let rects
|
|
138
139
|
if (child.nodeType == 1) rects = (child as HTMLElement).getClientRects()
|
|
@@ -157,12 +158,16 @@ function findOffsetInNode(node: HTMLElement, coords: {top: number, left: number}
|
|
|
157
158
|
offset = childIndex + (coords.left >= (rect.left + rect.right) / 2 ? 1 : 0)
|
|
158
159
|
continue
|
|
159
160
|
}
|
|
161
|
+
} else if (rect.top > coords.top && !firstBelow && rect.left <= coords.left && rect.right >= coords.left) {
|
|
162
|
+
firstBelow = child
|
|
163
|
+
coordsBelow = {left: Math.max(rect.left, Math.min(rect.right, coords.left)), top: rect.top}
|
|
160
164
|
}
|
|
161
165
|
if (!closest && (coords.left >= rect.right && coords.top >= rect.top ||
|
|
162
166
|
coords.left >= rect.left && coords.top >= rect.bottom))
|
|
163
167
|
offset = childIndex + 1
|
|
164
168
|
}
|
|
165
169
|
}
|
|
170
|
+
if (!closest && firstBelow) { closest = firstBelow; coordsClosest = coordsBelow; dxClosest = 0 }
|
|
166
171
|
if (closest && closest.nodeType == 3) return findOffsetInText(closest as Text, coordsClosest!)
|
|
167
172
|
if (!closest || (dxClosest && closest.nodeType == 1)) return {node, offset}
|
|
168
173
|
return findOffsetInNode(closest as HTMLElement, coordsClosest!)
|
|
@@ -255,16 +260,8 @@ function elementFromPoint(element: HTMLElement, coords: {top: number, left: numb
|
|
|
255
260
|
// Given an x,y position on the editor, get the position in the document.
|
|
256
261
|
export function posAtCoords(view: EditorView, coords: {top: number, left: number}) {
|
|
257
262
|
let doc = view.dom.ownerDocument, node: Node | undefined, offset = 0
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
let pos = (doc as any).caretPositionFromPoint(coords.left, coords.top)
|
|
261
|
-
if (pos) ({offsetNode: node, offset} = pos)
|
|
262
|
-
} catch (_) {}
|
|
263
|
-
}
|
|
264
|
-
if (!node && doc.caretRangeFromPoint) {
|
|
265
|
-
let range = doc.caretRangeFromPoint(coords.left, coords.top)
|
|
266
|
-
if (range) ({startContainer: node, startOffset: offset} = range)
|
|
267
|
-
}
|
|
263
|
+
let caret = caretFromPoint(doc, coords.left, coords.top)
|
|
264
|
+
if (caret) ({node, offset} = caret)
|
|
268
265
|
|
|
269
266
|
let elt = ((view.root as any).elementFromPoint ? view.root : doc)
|
|
270
267
|
.elementFromPoint(coords.left, coords.top) as HTMLElement
|
|
@@ -312,9 +309,17 @@ export function posAtCoords(view: EditorView, coords: {top: number, left: number
|
|
|
312
309
|
return {pos, inside: desc ? desc.posAtStart - desc.border : -1}
|
|
313
310
|
}
|
|
314
311
|
|
|
312
|
+
function nonZero(rect: DOMRect) {
|
|
313
|
+
return rect.top < rect.bottom || rect.left < rect.right
|
|
314
|
+
}
|
|
315
|
+
|
|
315
316
|
function singleRect(target: HTMLElement | Range, bias: number): DOMRect {
|
|
316
317
|
let rects = target.getClientRects()
|
|
317
|
-
|
|
318
|
+
if (rects.length) {
|
|
319
|
+
let first = rects[bias < 0 ? 0 : rects.length - 1]
|
|
320
|
+
if (nonZero(first)) return first
|
|
321
|
+
}
|
|
322
|
+
return Array.prototype.find.call(rects, nonZero) || target.getBoundingClientRect()
|
|
318
323
|
}
|
|
319
324
|
|
|
320
325
|
const BIDI = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/
|
|
@@ -348,7 +353,7 @@ export function coordsAtPos(view: EditorView, pos: number, side: number): Rect {
|
|
|
348
353
|
else if (side >= 0 && offset == node.nodeValue!.length) { from--; takeSide = 1 }
|
|
349
354
|
else if (side < 0) { from-- }
|
|
350
355
|
else { to ++ }
|
|
351
|
-
return flattenV(singleRect(textRange(node as Text, from, to),
|
|
356
|
+
return flattenV(singleRect(textRange(node as Text, from, to), takeSide), takeSide < 0)
|
|
352
357
|
}
|
|
353
358
|
}
|
|
354
359
|
|
package/src/input.ts
CHANGED
|
@@ -33,6 +33,7 @@ export class InputState {
|
|
|
33
33
|
composingTimeout = -1
|
|
34
34
|
compositionNodes: ViewDesc[] = []
|
|
35
35
|
compositionEndedAt = -2e8
|
|
36
|
+
compositionID = 1
|
|
36
37
|
domChangeCount = 0
|
|
37
38
|
eventHandlers: {[event: string]: (event: Event) => void} = Object.create(null)
|
|
38
39
|
hideSelectionGuard: (() => void) | null = null
|
|
@@ -486,6 +487,7 @@ editHandlers.compositionend = (view, event) => {
|
|
|
486
487
|
if (view.composing) {
|
|
487
488
|
view.input.composing = false
|
|
488
489
|
view.input.compositionEndedAt = event.timeStamp
|
|
490
|
+
view.input.compositionID++
|
|
489
491
|
scheduleComposeEnd(view, 20)
|
|
490
492
|
}
|
|
491
493
|
}
|
package/src/viewdesc.ts
CHANGED
|
@@ -619,7 +619,6 @@ export class NodeViewDesc extends ViewDesc {
|
|
|
619
619
|
pos: number
|
|
620
620
|
) {
|
|
621
621
|
super(parent, [], dom, contentDOM)
|
|
622
|
-
if (contentDOM) this.updateChildren(view, pos)
|
|
623
622
|
}
|
|
624
623
|
|
|
625
624
|
// By default, a node is rendered using the `toDOM` method from the
|
|
@@ -733,7 +732,7 @@ export class NodeViewDesc extends ViewDesc {
|
|
|
733
732
|
(compIndex = updater.findIndexWithChild(composition!.node)) > -1 &&
|
|
734
733
|
updater.updateNodeAt(child, outerDeco, innerDeco, compIndex, view)) {
|
|
735
734
|
// Updated the specific node that holds the composition
|
|
736
|
-
} else if (updater.updateNextNode(child, outerDeco, innerDeco, view, i)) {
|
|
735
|
+
} else if (updater.updateNextNode(child, outerDeco, innerDeco, view, i, off)) {
|
|
737
736
|
// Could update an existing node to reflect this node
|
|
738
737
|
} else {
|
|
739
738
|
// Add it as a new view
|
|
@@ -846,7 +845,9 @@ export class NodeViewDesc extends ViewDesc {
|
|
|
846
845
|
export function docViewDesc(doc: Node, outerDeco: readonly Decoration[], innerDeco: DecorationSource,
|
|
847
846
|
dom: HTMLElement, view: EditorView): NodeViewDesc {
|
|
848
847
|
applyOuterDeco(dom, outerDeco, doc)
|
|
849
|
-
|
|
848
|
+
let docView = new NodeViewDesc(undefined, doc, outerDeco, innerDeco, dom, dom, dom, view, 0)
|
|
849
|
+
if (docView.contentDOM) docView.updateChildren(view, 0)
|
|
850
|
+
return docView
|
|
850
851
|
}
|
|
851
852
|
|
|
852
853
|
class TextViewDesc extends NodeViewDesc {
|
|
@@ -1222,13 +1223,13 @@ class ViewTreeUpdater {
|
|
|
1222
1223
|
// Try to update the next node, if any, to the given data. Checks
|
|
1223
1224
|
// pre-matches to avoid overwriting nodes that could still be used.
|
|
1224
1225
|
updateNextNode(node: Node, outerDeco: readonly Decoration[], innerDeco: DecorationSource,
|
|
1225
|
-
view: EditorView, index: number): boolean {
|
|
1226
|
+
view: EditorView, index: number, pos: number): boolean {
|
|
1226
1227
|
for (let i = this.index; i < this.top.children.length; i++) {
|
|
1227
1228
|
let next = this.top.children[i]
|
|
1228
1229
|
if (next instanceof NodeViewDesc) {
|
|
1229
1230
|
let preMatch = this.preMatch.matched.get(next)
|
|
1230
1231
|
if (preMatch != null && preMatch != index) return false
|
|
1231
|
-
let nextDOM = next.dom
|
|
1232
|
+
let nextDOM = next.dom, updated
|
|
1232
1233
|
|
|
1233
1234
|
// Can't update if nextDOM is or contains this.lock, except if
|
|
1234
1235
|
// it's a text node whose content already matches the new text
|
|
@@ -1241,6 +1242,11 @@ class ViewTreeUpdater {
|
|
|
1241
1242
|
if (next.dom != nextDOM) this.changed = true
|
|
1242
1243
|
this.index++
|
|
1243
1244
|
return true
|
|
1245
|
+
} else if (!locked && (updated = this.recreateWrapper(next, node, outerDeco, innerDeco, view, pos))) {
|
|
1246
|
+
this.top.children[this.index] = updated
|
|
1247
|
+
this.changed = true
|
|
1248
|
+
this.index++
|
|
1249
|
+
return true
|
|
1244
1250
|
}
|
|
1245
1251
|
break
|
|
1246
1252
|
}
|
|
@@ -1248,9 +1254,28 @@ class ViewTreeUpdater {
|
|
|
1248
1254
|
return false
|
|
1249
1255
|
}
|
|
1250
1256
|
|
|
1257
|
+
// When a node with content is replaced by a different node with
|
|
1258
|
+
// identical content, move over its children.
|
|
1259
|
+
recreateWrapper(next: NodeViewDesc, node: Node, outerDeco: readonly Decoration[], innerDeco: DecorationSource,
|
|
1260
|
+
view: EditorView, pos: number) {
|
|
1261
|
+
if (next.dirty || node.isAtom || !next.children.length ||
|
|
1262
|
+
!next.node.content.eq(node.content)) return null
|
|
1263
|
+
let wrapper = NodeViewDesc.create(this.top, node, outerDeco, innerDeco, view, pos)
|
|
1264
|
+
if (!wrapper.contentDOM) return null
|
|
1265
|
+
wrapper.children = next.children
|
|
1266
|
+
next.children = []
|
|
1267
|
+
for (let ch of wrapper.children) ch.parent = wrapper
|
|
1268
|
+
wrapper.dirty = CONTENT_DIRTY
|
|
1269
|
+
wrapper.updateChildren(view, pos + 1)
|
|
1270
|
+
wrapper.dirty = NOT_DIRTY
|
|
1271
|
+
return wrapper
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1251
1274
|
// Insert the node as a newly created node desc.
|
|
1252
1275
|
addNode(node: Node, outerDeco: readonly Decoration[], innerDeco: DecorationSource, view: EditorView, pos: number) {
|
|
1253
|
-
|
|
1276
|
+
let desc = NodeViewDesc.create(this.top, node, outerDeco, innerDeco, view, pos)
|
|
1277
|
+
if (desc.contentDOM) desc.updateChildren(view, pos + 1)
|
|
1278
|
+
this.top.children.splice(this.index++, 0, desc)
|
|
1254
1279
|
this.changed = true
|
|
1255
1280
|
}
|
|
1256
1281
|
|