prosemirror-view 1.33.0 → 1.33.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/dist/index.cjs +56 -27
- package/dist/index.d.cts +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +66 -36
- package/package.json +1 -1
- package/src/#index.ts# +803 -0
- package/src/decoration.ts +0 -1
- package/src/dom.ts +36 -0
- package/src/domchange.ts +10 -11
- package/src/domcoords.ts +5 -0
- package/src/index.ts +3 -2
- package/src/viewdesc.ts +9 -19
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
## 1.33.2 (2024-03-21)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Improve Android backspace detection when the native effect is to delete an entire block element.
|
|
6
|
+
|
|
7
|
+
Fix a bug where reconfiguring node views caused the editor to lose focus.
|
|
8
|
+
|
|
9
|
+
Fix an issue where some commands didn't properly scroll the cursor into view on Mobile Safari.
|
|
10
|
+
|
|
11
|
+
Fix a bug where starting a composition with stored marks or after a noninclusive mark, with an IME that keeps the cursor at the start of the composed text (like many Chinese IMEs) disrupted composition on Chrome.
|
|
12
|
+
|
|
13
|
+
Fix a memory leak where a (single) destroyed editor could be kept alive through a reused `Range` object.
|
|
14
|
+
|
|
15
|
+
## 1.33.1 (2024-02-15)
|
|
16
|
+
|
|
17
|
+
### Bug fixes
|
|
18
|
+
|
|
19
|
+
Fix a type error in the published type declarations in 1.33.0.
|
|
20
|
+
|
|
1
21
|
## 1.33.0 (2024-02-15)
|
|
2
22
|
|
|
3
23
|
### New features
|
package/dist/index.cjs
CHANGED
|
@@ -38,6 +38,9 @@ var textRange = function textRange(node, from, to) {
|
|
|
38
38
|
range.setStart(node, from || 0);
|
|
39
39
|
return range;
|
|
40
40
|
};
|
|
41
|
+
var clearReusedRange = function clearReusedRange() {
|
|
42
|
+
reusedRange = null;
|
|
43
|
+
};
|
|
41
44
|
var isEquivalentPosition = function isEquivalentPosition(node, off, targetNode, targetOff) {
|
|
42
45
|
return targetNode && (scanFor(node, off, targetNode, targetOff, -1) || scanFor(node, off, targetNode, targetOff, 1));
|
|
43
46
|
};
|
|
@@ -62,6 +65,36 @@ function scanFor(node, off, targetNode, targetOff, dir) {
|
|
|
62
65
|
function nodeSize(node) {
|
|
63
66
|
return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length;
|
|
64
67
|
}
|
|
68
|
+
function textNodeBefore$1(node, offset) {
|
|
69
|
+
for (;;) {
|
|
70
|
+
if (node.nodeType == 3 && offset) return node;
|
|
71
|
+
if (node.nodeType == 1 && offset > 0) {
|
|
72
|
+
if (node.contentEditable != "false") return null;
|
|
73
|
+
node = node.childNodes[offset - 1];
|
|
74
|
+
offset = nodeSize(node);
|
|
75
|
+
} else if (node.parentNode && !hasBlockDesc(node)) {
|
|
76
|
+
offset = domIndex(node);
|
|
77
|
+
node = node.parentNode;
|
|
78
|
+
} else {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function textNodeAfter$1(node, offset) {
|
|
84
|
+
for (;;) {
|
|
85
|
+
if (node.nodeType == 3 && offset < node.nodeValue.length) return node;
|
|
86
|
+
if (node.nodeType == 1 && offset < node.childNodes.length) {
|
|
87
|
+
if (node.contentEditable != "false") return null;
|
|
88
|
+
node = node.childNodes[offset];
|
|
89
|
+
offset = 0;
|
|
90
|
+
} else if (node.parentNode && !hasBlockDesc(node)) {
|
|
91
|
+
offset = domIndex(node) + 1;
|
|
92
|
+
node = node.parentNode;
|
|
93
|
+
} else {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
65
98
|
function isOnEdge(node, offset, parent) {
|
|
66
99
|
for (var atStart = offset == 0, atEnd = offset == nodeSize(node); atStart || atEnd;) {
|
|
67
100
|
if (node == parent) return true;
|
|
@@ -131,6 +164,13 @@ var android = /Android \d/.test(agent);
|
|
|
131
164
|
var webkit = !!doc && "webkitFontSmoothing" in doc.documentElement.style;
|
|
132
165
|
var webkit_version = webkit ? +(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent) || [0, 0])[1] : 0;
|
|
133
166
|
function windowRect(doc) {
|
|
167
|
+
var vp = doc.defaultView && doc.defaultView.visualViewport;
|
|
168
|
+
if (vp) return {
|
|
169
|
+
left: 0,
|
|
170
|
+
right: vp.width,
|
|
171
|
+
top: 0,
|
|
172
|
+
bottom: vp.height
|
|
173
|
+
};
|
|
134
174
|
return {
|
|
135
175
|
left: 0,
|
|
136
176
|
right: doc.documentElement.clientWidth,
|
|
@@ -1269,7 +1309,13 @@ var NodeViewDesc = function (_ViewDesc4) {
|
|
|
1269
1309
|
to = _view$state$selection.to;
|
|
1270
1310
|
if (!(view.state.selection instanceof prosemirrorState.TextSelection) || from < pos || to > pos + this.node.content.size) return null;
|
|
1271
1311
|
var sel = view.domSelectionRange();
|
|
1272
|
-
var
|
|
1312
|
+
var textBefore = textNodeBefore$1(sel.focusNode, sel.focusOffset);
|
|
1313
|
+
var textAfter = textNodeAfter$1(sel.focusNode, sel.focusOffset);
|
|
1314
|
+
var textNode = textBefore || textAfter;
|
|
1315
|
+
if (textBefore && textAfter && textBefore != textAfter) {
|
|
1316
|
+
var descAfter = textAfter.pmViewDesc;
|
|
1317
|
+
if (!descAfter || descAfter instanceof TextViewDesc && descAfter.node.text != textAfter.nodeValue) textNode = textAfter;
|
|
1318
|
+
}
|
|
1273
1319
|
if (!textNode || !this.dom.contains(textNode.parentNode)) return null;
|
|
1274
1320
|
if (this.node.inlineContent) {
|
|
1275
1321
|
var text = textNode.nodeValue;
|
|
@@ -1998,21 +2044,6 @@ function iosHacks(dom) {
|
|
|
1998
2044
|
dom.style.cssText = oldCSS;
|
|
1999
2045
|
}
|
|
2000
2046
|
}
|
|
2001
|
-
function nearbyTextNode(node, offset) {
|
|
2002
|
-
for (;;) {
|
|
2003
|
-
if (node.nodeType == 3) return node;
|
|
2004
|
-
if (node.nodeType == 1 && offset > 0) {
|
|
2005
|
-
if (node.childNodes.length > offset && node.childNodes[offset].nodeType == 3) return node.childNodes[offset];
|
|
2006
|
-
node = node.childNodes[offset - 1];
|
|
2007
|
-
offset = nodeSize(node);
|
|
2008
|
-
} else if (node.nodeType == 1 && offset < node.childNodes.length) {
|
|
2009
|
-
node = node.childNodes[offset];
|
|
2010
|
-
offset = 0;
|
|
2011
|
-
} else {
|
|
2012
|
-
return null;
|
|
2013
|
-
}
|
|
2014
|
-
}
|
|
2015
|
-
}
|
|
2016
2047
|
function findTextInFragment(frag, text, from, to) {
|
|
2017
2048
|
for (var i = 0, pos = 0; i < frag.childCount && pos <= to;) {
|
|
2018
2049
|
var child = frag.child(i++),
|
|
@@ -4474,13 +4505,6 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
|
|
|
4474
4505
|
return;
|
|
4475
4506
|
}
|
|
4476
4507
|
}
|
|
4477
|
-
if (chrome && view.cursorWrapper && parse.sel && parse.sel.anchor == view.cursorWrapper.deco.from && parse.sel.head == parse.sel.anchor) {
|
|
4478
|
-
var size = change.endB - change.start;
|
|
4479
|
-
parse.sel = {
|
|
4480
|
-
anchor: parse.sel.anchor + size,
|
|
4481
|
-
head: parse.sel.anchor + size
|
|
4482
|
-
};
|
|
4483
|
-
}
|
|
4484
4508
|
view.input.domChangeCount++;
|
|
4485
4509
|
if (view.state.selection.from < view.state.selection.to && change.start == change.endB && view.state.selection instanceof prosemirrorState.TextSelection) {
|
|
4486
4510
|
if (change.start > view.state.selection.from && change.start <= view.state.selection.from + 2 && view.state.selection.from >= parse.from) {
|
|
@@ -4508,7 +4532,7 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
|
|
|
4508
4532
|
view.input.lastIOSEnter = 0;
|
|
4509
4533
|
return;
|
|
4510
4534
|
}
|
|
4511
|
-
if (view.state.selection.anchor > change.start &&
|
|
4535
|
+
if (view.state.selection.anchor > change.start && looksLikeBackspace(doc, change.start, change.endA, $from, $to) && view.someProp("handleKeyDown", function (f) {
|
|
4512
4536
|
return f(view, keyEvent(8, "Backspace"));
|
|
4513
4537
|
})) {
|
|
4514
4538
|
if (android && chrome) view.domObserver.suppressSelectionUpdates();
|
|
@@ -4593,9 +4617,13 @@ function isMarkChange(cur, prev) {
|
|
|
4593
4617
|
type: type
|
|
4594
4618
|
};
|
|
4595
4619
|
}
|
|
4596
|
-
function
|
|
4597
|
-
if (
|
|
4620
|
+
function looksLikeBackspace(old, start, end, $newStart, $newEnd) {
|
|
4621
|
+
if (end - start <= $newEnd.pos - $newStart.pos || skipClosingAndOpening($newStart, true, false) < $newEnd.pos) return false;
|
|
4598
4622
|
var $start = old.resolve(start);
|
|
4623
|
+
if (!$newStart.parent.isTextblock) {
|
|
4624
|
+
var after = $start.nodeAfter;
|
|
4625
|
+
return after != null && end == start + after.nodeSize;
|
|
4626
|
+
}
|
|
4599
4627
|
if ($start.parentOffset < $start.parent.content.size || !$start.parent.isTextblock) return false;
|
|
4600
4628
|
var $next = old.resolve(skipClosingAndOpening($start, true, true));
|
|
4601
4629
|
if (!$next.parent.isTextblock || $next.pos > end || skipClosingAndOpening($next, true, false) < end) return false;
|
|
@@ -4771,7 +4799,7 @@ var EditorView = function () {
|
|
|
4771
4799
|
if (updateDoc) {
|
|
4772
4800
|
var chromeKludge = chrome ? this.trackWrites = this.domSelectionRange().focusNode : null;
|
|
4773
4801
|
if (redraw || !this.docView.update(state.doc, outerDeco, innerDeco, this)) {
|
|
4774
|
-
this.docView.updateOuterDeco(
|
|
4802
|
+
this.docView.updateOuterDeco(outerDeco);
|
|
4775
4803
|
this.docView.destroy();
|
|
4776
4804
|
this.docView = docViewDesc(state.doc, outerDeco, innerDeco, this.dom, this);
|
|
4777
4805
|
}
|
|
@@ -4978,6 +5006,7 @@ var EditorView = function () {
|
|
|
4978
5006
|
}
|
|
4979
5007
|
this.docView.destroy();
|
|
4980
5008
|
this.docView = null;
|
|
5009
|
+
clearReusedRange();
|
|
4981
5010
|
}
|
|
4982
5011
|
}, {
|
|
4983
5012
|
key: "isDestroyed",
|
package/dist/index.d.cts
CHANGED
|
@@ -210,11 +210,21 @@ declare class DecorationSet implements DecorationSource {
|
|
|
210
210
|
*/
|
|
211
211
|
remove(decorations: Decoration[]): DecorationSet;
|
|
212
212
|
private removeInner;
|
|
213
|
+
forChild(offset: number, node: Node): DecorationSet | DecorationGroup;
|
|
213
214
|
/**
|
|
214
215
|
The empty set of decorations.
|
|
215
216
|
*/
|
|
216
217
|
static empty: DecorationSet;
|
|
217
218
|
}
|
|
219
|
+
declare class DecorationGroup implements DecorationSource {
|
|
220
|
+
readonly members: readonly DecorationSet[];
|
|
221
|
+
constructor(members: readonly DecorationSet[]);
|
|
222
|
+
map(mapping: Mapping, doc: Node): DecorationSource;
|
|
223
|
+
forChild(offset: number, child: Node): DecorationSource | DecorationSet;
|
|
224
|
+
eq(other: DecorationGroup): boolean;
|
|
225
|
+
locals(node: Node): readonly any[];
|
|
226
|
+
static from(members: readonly DecorationSource[]): DecorationSource;
|
|
227
|
+
}
|
|
218
228
|
|
|
219
229
|
declare global {
|
|
220
230
|
interface Node {
|
package/dist/index.d.ts
CHANGED
|
@@ -210,11 +210,21 @@ declare class DecorationSet implements DecorationSource {
|
|
|
210
210
|
*/
|
|
211
211
|
remove(decorations: Decoration[]): DecorationSet;
|
|
212
212
|
private removeInner;
|
|
213
|
+
forChild(offset: number, node: Node): DecorationSet | DecorationGroup;
|
|
213
214
|
/**
|
|
214
215
|
The empty set of decorations.
|
|
215
216
|
*/
|
|
216
217
|
static empty: DecorationSet;
|
|
217
218
|
}
|
|
219
|
+
declare class DecorationGroup implements DecorationSource {
|
|
220
|
+
readonly members: readonly DecorationSet[];
|
|
221
|
+
constructor(members: readonly DecorationSet[]);
|
|
222
|
+
map(mapping: Mapping, doc: Node): DecorationSource;
|
|
223
|
+
forChild(offset: number, child: Node): DecorationSource | DecorationSet;
|
|
224
|
+
eq(other: DecorationGroup): boolean;
|
|
225
|
+
locals(node: Node): readonly any[];
|
|
226
|
+
static from(members: readonly DecorationSource[]): DecorationSource;
|
|
227
|
+
}
|
|
218
228
|
|
|
219
229
|
declare global {
|
|
220
230
|
interface Node {
|
package/dist/index.js
CHANGED
|
@@ -23,6 +23,9 @@ const textRange = function (node, from, to) {
|
|
|
23
23
|
range.setStart(node, from || 0);
|
|
24
24
|
return range;
|
|
25
25
|
};
|
|
26
|
+
const clearReusedRange = function () {
|
|
27
|
+
reusedRange = null;
|
|
28
|
+
};
|
|
26
29
|
// Scans forward and backward through DOM positions equivalent to the
|
|
27
30
|
// given one to see if the two are in the same place (i.e. after a
|
|
28
31
|
// text node vs at the end of that text node)
|
|
@@ -57,6 +60,44 @@ function scanFor(node, off, targetNode, targetOff, dir) {
|
|
|
57
60
|
function nodeSize(node) {
|
|
58
61
|
return node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length;
|
|
59
62
|
}
|
|
63
|
+
function textNodeBefore$1(node, offset) {
|
|
64
|
+
for (;;) {
|
|
65
|
+
if (node.nodeType == 3 && offset)
|
|
66
|
+
return node;
|
|
67
|
+
if (node.nodeType == 1 && offset > 0) {
|
|
68
|
+
if (node.contentEditable != "false")
|
|
69
|
+
return null;
|
|
70
|
+
node = node.childNodes[offset - 1];
|
|
71
|
+
offset = nodeSize(node);
|
|
72
|
+
}
|
|
73
|
+
else if (node.parentNode && !hasBlockDesc(node)) {
|
|
74
|
+
offset = domIndex(node);
|
|
75
|
+
node = node.parentNode;
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function textNodeAfter$1(node, offset) {
|
|
83
|
+
for (;;) {
|
|
84
|
+
if (node.nodeType == 3 && offset < node.nodeValue.length)
|
|
85
|
+
return node;
|
|
86
|
+
if (node.nodeType == 1 && offset < node.childNodes.length) {
|
|
87
|
+
if (node.contentEditable != "false")
|
|
88
|
+
return null;
|
|
89
|
+
node = node.childNodes[offset];
|
|
90
|
+
offset = 0;
|
|
91
|
+
}
|
|
92
|
+
else if (node.parentNode && !hasBlockDesc(node)) {
|
|
93
|
+
offset = domIndex(node) + 1;
|
|
94
|
+
node = node.parentNode;
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
60
101
|
function isOnEdge(node, offset, parent) {
|
|
61
102
|
for (let atStart = offset == 0, atEnd = offset == nodeSize(node); atStart || atEnd;) {
|
|
62
103
|
if (node == parent)
|
|
@@ -133,6 +174,12 @@ const webkit = !!doc && "webkitFontSmoothing" in doc.documentElement.style;
|
|
|
133
174
|
const webkit_version = webkit ? +(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent) || [0, 0])[1] : 0;
|
|
134
175
|
|
|
135
176
|
function windowRect(doc) {
|
|
177
|
+
let vp = doc.defaultView && doc.defaultView.visualViewport;
|
|
178
|
+
if (vp)
|
|
179
|
+
return {
|
|
180
|
+
left: 0, right: vp.width,
|
|
181
|
+
top: 0, bottom: vp.height
|
|
182
|
+
};
|
|
136
183
|
return { left: 0, right: doc.documentElement.clientWidth,
|
|
137
184
|
top: 0, bottom: doc.documentElement.clientHeight };
|
|
138
185
|
}
|
|
@@ -1331,7 +1378,14 @@ class NodeViewDesc extends ViewDesc {
|
|
|
1331
1378
|
if (!(view.state.selection instanceof TextSelection) || from < pos || to > pos + this.node.content.size)
|
|
1332
1379
|
return null;
|
|
1333
1380
|
let sel = view.domSelectionRange();
|
|
1334
|
-
let
|
|
1381
|
+
let textBefore = textNodeBefore$1(sel.focusNode, sel.focusOffset);
|
|
1382
|
+
let textAfter = textNodeAfter$1(sel.focusNode, sel.focusOffset);
|
|
1383
|
+
let textNode = textBefore || textAfter;
|
|
1384
|
+
if (textBefore && textAfter && textBefore != textAfter) {
|
|
1385
|
+
let descAfter = textAfter.pmViewDesc;
|
|
1386
|
+
if (!descAfter || descAfter instanceof TextViewDesc && descAfter.node.text != textAfter.nodeValue)
|
|
1387
|
+
textNode = textAfter;
|
|
1388
|
+
}
|
|
1335
1389
|
if (!textNode || !this.dom.contains(textNode.parentNode))
|
|
1336
1390
|
return null;
|
|
1337
1391
|
if (this.node.inlineContent) {
|
|
@@ -2042,25 +2096,6 @@ function iosHacks(dom) {
|
|
|
2042
2096
|
dom.style.cssText = oldCSS;
|
|
2043
2097
|
}
|
|
2044
2098
|
}
|
|
2045
|
-
function nearbyTextNode(node, offset) {
|
|
2046
|
-
for (;;) {
|
|
2047
|
-
if (node.nodeType == 3)
|
|
2048
|
-
return node;
|
|
2049
|
-
if (node.nodeType == 1 && offset > 0) {
|
|
2050
|
-
if (node.childNodes.length > offset && node.childNodes[offset].nodeType == 3)
|
|
2051
|
-
return node.childNodes[offset];
|
|
2052
|
-
node = node.childNodes[offset - 1];
|
|
2053
|
-
offset = nodeSize(node);
|
|
2054
|
-
}
|
|
2055
|
-
else if (node.nodeType == 1 && offset < node.childNodes.length) {
|
|
2056
|
-
node = node.childNodes[offset];
|
|
2057
|
-
offset = 0;
|
|
2058
|
-
}
|
|
2059
|
-
else {
|
|
2060
|
-
return null;
|
|
2061
|
-
}
|
|
2062
|
-
}
|
|
2063
|
-
}
|
|
2064
2099
|
// Find a piece of text in an inline fragment, overlapping from-to
|
|
2065
2100
|
function findTextInFragment(frag, text, from, to) {
|
|
2066
2101
|
for (let i = 0, pos = 0; i < frag.childCount && pos <= to;) {
|
|
@@ -4022,9 +4057,6 @@ class DecorationSet {
|
|
|
4022
4057
|
return this;
|
|
4023
4058
|
return local.length || children.length ? new DecorationSet(local, children) : empty;
|
|
4024
4059
|
}
|
|
4025
|
-
/**
|
|
4026
|
-
@internal
|
|
4027
|
-
*/
|
|
4028
4060
|
forChild(offset, node) {
|
|
4029
4061
|
if (this == empty)
|
|
4030
4062
|
return this;
|
|
@@ -4825,13 +4857,6 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
|
|
|
4825
4857
|
return;
|
|
4826
4858
|
}
|
|
4827
4859
|
}
|
|
4828
|
-
// Chrome sometimes leaves the cursor before the inserted text when
|
|
4829
|
-
// composing after a cursor wrapper. This moves it forward.
|
|
4830
|
-
if (chrome && view.cursorWrapper && parse.sel && parse.sel.anchor == view.cursorWrapper.deco.from &&
|
|
4831
|
-
parse.sel.head == parse.sel.anchor) {
|
|
4832
|
-
let size = change.endB - change.start;
|
|
4833
|
-
parse.sel = { anchor: parse.sel.anchor + size, head: parse.sel.anchor + size };
|
|
4834
|
-
}
|
|
4835
4860
|
view.input.domChangeCount++;
|
|
4836
4861
|
// Handle the case where overwriting a selection by typing matches
|
|
4837
4862
|
// the start or end of the selected content, creating a change
|
|
@@ -4877,7 +4902,7 @@ function readDOMChange(view, from, to, typeOver, addedNodes) {
|
|
|
4877
4902
|
}
|
|
4878
4903
|
// Same for backspace
|
|
4879
4904
|
if (view.state.selection.anchor > change.start &&
|
|
4880
|
-
|
|
4905
|
+
looksLikeBackspace(doc, change.start, change.endA, $from, $to) &&
|
|
4881
4906
|
view.someProp("handleKeyDown", f => f(view, keyEvent(8, "Backspace")))) {
|
|
4882
4907
|
if (android && chrome)
|
|
4883
4908
|
view.domObserver.suppressSelectionUpdates(); // #820
|
|
@@ -4989,14 +5014,18 @@ function isMarkChange(cur, prev) {
|
|
|
4989
5014
|
if (Fragment.from(updated).eq(cur))
|
|
4990
5015
|
return { mark, type };
|
|
4991
5016
|
}
|
|
4992
|
-
function
|
|
4993
|
-
if (
|
|
4994
|
-
|
|
4995
|
-
end - start <= $newEnd.pos - $newStart.pos ||
|
|
5017
|
+
function looksLikeBackspace(old, start, end, $newStart, $newEnd) {
|
|
5018
|
+
if ( // The content must have shrunk
|
|
5019
|
+
end - start <= $newEnd.pos - $newStart.pos ||
|
|
4996
5020
|
// newEnd must point directly at or after the end of the block that newStart points into
|
|
4997
5021
|
skipClosingAndOpening($newStart, true, false) < $newEnd.pos)
|
|
4998
5022
|
return false;
|
|
4999
5023
|
let $start = old.resolve(start);
|
|
5024
|
+
// Handle the case where, rather than joining blocks, the change just removed an entire block
|
|
5025
|
+
if (!$newStart.parent.isTextblock) {
|
|
5026
|
+
let after = $start.nodeAfter;
|
|
5027
|
+
return after != null && end == start + after.nodeSize;
|
|
5028
|
+
}
|
|
5000
5029
|
// Start must be at the end of a block
|
|
5001
5030
|
if ($start.parentOffset < $start.parent.content.size || !$start.parent.isTextblock)
|
|
5002
5031
|
return false;
|
|
@@ -5248,7 +5277,7 @@ class EditorView {
|
|
|
5248
5277
|
// did write to the node.
|
|
5249
5278
|
let chromeKludge = chrome ? (this.trackWrites = this.domSelectionRange().focusNode) : null;
|
|
5250
5279
|
if (redraw || !this.docView.update(state.doc, outerDeco, innerDeco, this)) {
|
|
5251
|
-
this.docView.updateOuterDeco(
|
|
5280
|
+
this.docView.updateOuterDeco(outerDeco);
|
|
5252
5281
|
this.docView.destroy();
|
|
5253
5282
|
this.docView = docViewDesc(state.doc, outerDeco, innerDeco, this.dom, this);
|
|
5254
5283
|
}
|
|
@@ -5525,6 +5554,7 @@ class EditorView {
|
|
|
5525
5554
|
}
|
|
5526
5555
|
this.docView.destroy();
|
|
5527
5556
|
this.docView = null;
|
|
5557
|
+
clearReusedRange();
|
|
5528
5558
|
}
|
|
5529
5559
|
/**
|
|
5530
5560
|
This is true when the view has been
|