@codemirror/view 6.28.4 → 6.28.6
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 +14 -0
- package/dist/index.cjs +58 -36
- package/dist/index.js +58 -36
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## 6.28.6 (2024-07-19)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Fix an issue where the editor got confused about the position of inserted text when using Chrome's `EditContext` and canceling transactions for typed text.
|
|
6
|
+
|
|
7
|
+
## 6.28.5 (2024-07-17)
|
|
8
|
+
|
|
9
|
+
### Bug fixes
|
|
10
|
+
|
|
11
|
+
Fix a bug that broke drag scrolling along one axis when the innermost scrollable element around the editor was only scrollable along the other axis.
|
|
12
|
+
|
|
13
|
+
Work around a memory leak in Chrome's EditContext implementation.
|
|
14
|
+
|
|
1
15
|
## 6.28.4 (2024-07-03)
|
|
2
16
|
|
|
3
17
|
### Bug fixes
|
package/dist/index.cjs
CHANGED
|
@@ -210,15 +210,17 @@ function scrollRectIntoView(dom, rect, side, x, y, xMargin, yMargin, ltr) {
|
|
|
210
210
|
}
|
|
211
211
|
}
|
|
212
212
|
}
|
|
213
|
-
function
|
|
214
|
-
let doc = dom.ownerDocument;
|
|
213
|
+
function scrollableParents(dom) {
|
|
214
|
+
let doc = dom.ownerDocument, x, y;
|
|
215
215
|
for (let cur = dom.parentNode; cur;) {
|
|
216
|
-
if (cur == doc.body) {
|
|
216
|
+
if (cur == doc.body || (x && y)) {
|
|
217
217
|
break;
|
|
218
218
|
}
|
|
219
219
|
else if (cur.nodeType == 1) {
|
|
220
|
-
if (cur.scrollHeight > cur.clientHeight
|
|
221
|
-
|
|
220
|
+
if (!y && cur.scrollHeight > cur.clientHeight)
|
|
221
|
+
y = cur;
|
|
222
|
+
if (!x && cur.scrollWidth > cur.clientWidth)
|
|
223
|
+
x = cur;
|
|
222
224
|
cur = cur.assignedSlot || cur.parentNode;
|
|
223
225
|
}
|
|
224
226
|
else if (cur.nodeType == 11) {
|
|
@@ -228,7 +230,7 @@ function scrollableParent(dom) {
|
|
|
228
230
|
break;
|
|
229
231
|
}
|
|
230
232
|
}
|
|
231
|
-
return
|
|
233
|
+
return { x, y };
|
|
232
234
|
}
|
|
233
235
|
class DOMSelectionState {
|
|
234
236
|
constructor() {
|
|
@@ -3984,7 +3986,7 @@ class MouseSelection {
|
|
|
3984
3986
|
this.scrollSpeed = { x: 0, y: 0 };
|
|
3985
3987
|
this.scrolling = -1;
|
|
3986
3988
|
this.lastEvent = startEvent;
|
|
3987
|
-
this.
|
|
3989
|
+
this.scrollParents = scrollableParents(view.contentDOM);
|
|
3988
3990
|
this.atoms = view.state.facet(atomicRanges).map(f => f(view));
|
|
3989
3991
|
let doc = view.contentDOM.ownerDocument;
|
|
3990
3992
|
doc.addEventListener("mousemove", this.move = this.move.bind(this));
|
|
@@ -4000,24 +4002,26 @@ class MouseSelection {
|
|
|
4000
4002
|
this.select(event);
|
|
4001
4003
|
}
|
|
4002
4004
|
move(event) {
|
|
4003
|
-
var _a;
|
|
4004
4005
|
if (event.buttons == 0)
|
|
4005
4006
|
return this.destroy();
|
|
4006
4007
|
if (this.dragging || this.dragging == null && dist(this.startEvent, event) < 10)
|
|
4007
4008
|
return;
|
|
4008
4009
|
this.select(this.lastEvent = event);
|
|
4009
4010
|
let sx = 0, sy = 0;
|
|
4010
|
-
let
|
|
4011
|
-
|
|
4011
|
+
let left = 0, top = 0, right = this.view.win.innerWidth, bottom = this.view.win.innerHeight;
|
|
4012
|
+
if (this.scrollParents.x)
|
|
4013
|
+
({ left, right } = this.scrollParents.x.getBoundingClientRect());
|
|
4014
|
+
if (this.scrollParents.y)
|
|
4015
|
+
({ top, bottom } = this.scrollParents.y.getBoundingClientRect());
|
|
4012
4016
|
let margins = getScrollMargins(this.view);
|
|
4013
|
-
if (event.clientX - margins.left <=
|
|
4014
|
-
sx = -dragScrollSpeed(
|
|
4015
|
-
else if (event.clientX + margins.right >=
|
|
4016
|
-
sx = dragScrollSpeed(event.clientX -
|
|
4017
|
-
if (event.clientY - margins.top <=
|
|
4018
|
-
sy = -dragScrollSpeed(
|
|
4019
|
-
else if (event.clientY + margins.bottom >=
|
|
4020
|
-
sy = dragScrollSpeed(event.clientY -
|
|
4017
|
+
if (event.clientX - margins.left <= left + dragScrollMargin)
|
|
4018
|
+
sx = -dragScrollSpeed(left - event.clientX);
|
|
4019
|
+
else if (event.clientX + margins.right >= right - dragScrollMargin)
|
|
4020
|
+
sx = dragScrollSpeed(event.clientX - right);
|
|
4021
|
+
if (event.clientY - margins.top <= top + dragScrollMargin)
|
|
4022
|
+
sy = -dragScrollSpeed(top - event.clientY);
|
|
4023
|
+
else if (event.clientY + margins.bottom >= bottom - dragScrollMargin)
|
|
4024
|
+
sy = dragScrollSpeed(event.clientY - bottom);
|
|
4021
4025
|
this.setScrollSpeed(sx, sy);
|
|
4022
4026
|
}
|
|
4023
4027
|
up(event) {
|
|
@@ -4046,13 +4050,17 @@ class MouseSelection {
|
|
|
4046
4050
|
}
|
|
4047
4051
|
}
|
|
4048
4052
|
scroll() {
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
this.
|
|
4053
|
+
let { x, y } = this.scrollSpeed;
|
|
4054
|
+
if (x && this.scrollParents.x) {
|
|
4055
|
+
this.scrollParents.x.scrollLeft += x;
|
|
4056
|
+
x = 0;
|
|
4052
4057
|
}
|
|
4053
|
-
|
|
4054
|
-
this.
|
|
4058
|
+
if (y && this.scrollParents.y) {
|
|
4059
|
+
this.scrollParents.y.scrollTop += y;
|
|
4060
|
+
y = 0;
|
|
4055
4061
|
}
|
|
4062
|
+
if (x || y)
|
|
4063
|
+
this.view.win.scrollBy(x, y);
|
|
4056
4064
|
if (this.dragging === false)
|
|
4057
4065
|
this.select(this.lastEvent);
|
|
4058
4066
|
}
|
|
@@ -7030,6 +7038,10 @@ class DOMObserver {
|
|
|
7030
7038
|
clearTimeout(this.resizeTimeout);
|
|
7031
7039
|
this.win.cancelAnimationFrame(this.delayedFlush);
|
|
7032
7040
|
this.win.cancelAnimationFrame(this.flushingAndroidKey);
|
|
7041
|
+
if (this.editContext) {
|
|
7042
|
+
this.view.contentDOM.editContext = null;
|
|
7043
|
+
this.editContext.destroy();
|
|
7044
|
+
}
|
|
7033
7045
|
}
|
|
7034
7046
|
}
|
|
7035
7047
|
function findChild(cView, dom, dir) {
|
|
@@ -7089,13 +7101,14 @@ class EditContextManager {
|
|
|
7089
7101
|
// that sometimes breaks series of multiple edits made for a single
|
|
7090
7102
|
// user action on some Android keyboards)
|
|
7091
7103
|
this.pendingContextChange = null;
|
|
7104
|
+
this.handlers = Object.create(null);
|
|
7092
7105
|
this.resetRange(view.state);
|
|
7093
7106
|
let context = this.editContext = new window.EditContext({
|
|
7094
7107
|
text: view.state.doc.sliceString(this.from, this.to),
|
|
7095
7108
|
selectionStart: this.toContextPos(Math.max(this.from, Math.min(this.to, view.state.selection.main.anchor))),
|
|
7096
7109
|
selectionEnd: this.toContextPos(view.state.selection.main.head)
|
|
7097
7110
|
});
|
|
7098
|
-
|
|
7111
|
+
this.handlers.textupdate = e => {
|
|
7099
7112
|
let { anchor } = view.state.selection.main;
|
|
7100
7113
|
let change = { from: this.toEditorPos(e.updateRangeStart),
|
|
7101
7114
|
to: this.toEditorPos(e.updateRangeEnd),
|
|
@@ -7113,10 +7126,12 @@ class EditContextManager {
|
|
|
7113
7126
|
applyDOMChangeInner(view, change, state.EditorSelection.single(this.toEditorPos(e.selectionStart), this.toEditorPos(e.selectionEnd)));
|
|
7114
7127
|
// If the transaction didn't flush our change, revert it so
|
|
7115
7128
|
// that the context is in sync with the editor state again.
|
|
7116
|
-
if (this.pendingContextChange)
|
|
7129
|
+
if (this.pendingContextChange) {
|
|
7117
7130
|
this.revertPending(view.state);
|
|
7118
|
-
|
|
7119
|
-
|
|
7131
|
+
this.setSelection(view.state);
|
|
7132
|
+
}
|
|
7133
|
+
};
|
|
7134
|
+
this.handlers.characterboundsupdate = e => {
|
|
7120
7135
|
let rects = [], prev = null;
|
|
7121
7136
|
for (let i = this.toEditorPos(e.rangeStart), end = this.toEditorPos(e.rangeEnd); i < end; i++) {
|
|
7122
7137
|
let rect = view.coordsForChar(i);
|
|
@@ -7125,8 +7140,8 @@ class EditContextManager {
|
|
|
7125
7140
|
rects.push(prev);
|
|
7126
7141
|
}
|
|
7127
7142
|
context.updateCharacterBounds(e.rangeStart, rects);
|
|
7128
|
-
}
|
|
7129
|
-
|
|
7143
|
+
};
|
|
7144
|
+
this.handlers.textformatupdate = e => {
|
|
7130
7145
|
let deco = [];
|
|
7131
7146
|
for (let format of e.getTextFormats()) {
|
|
7132
7147
|
let lineStyle = format.underlineStyle, thickness = format.underlineThickness;
|
|
@@ -7137,17 +7152,19 @@ class EditContextManager {
|
|
|
7137
7152
|
}
|
|
7138
7153
|
}
|
|
7139
7154
|
view.dispatch({ effects: setEditContextFormatting.of(Decoration.set(deco)) });
|
|
7140
|
-
}
|
|
7141
|
-
|
|
7155
|
+
};
|
|
7156
|
+
this.handlers.compositionstart = () => {
|
|
7142
7157
|
if (view.inputState.composing < 0) {
|
|
7143
7158
|
view.inputState.composing = 0;
|
|
7144
7159
|
view.inputState.compositionFirstChange = true;
|
|
7145
7160
|
}
|
|
7146
|
-
}
|
|
7147
|
-
|
|
7161
|
+
};
|
|
7162
|
+
this.handlers.compositionend = () => {
|
|
7148
7163
|
view.inputState.composing = -1;
|
|
7149
7164
|
view.inputState.compositionFirstChange = null;
|
|
7150
|
-
}
|
|
7165
|
+
};
|
|
7166
|
+
for (let event in this.handlers)
|
|
7167
|
+
context.addEventListener(event, this.handlers[event]);
|
|
7151
7168
|
this.measureReq = { read: view => {
|
|
7152
7169
|
this.editContext.updateControlBounds(view.contentDOM.getBoundingClientRect());
|
|
7153
7170
|
let sel = getSelection(view.root);
|
|
@@ -7194,13 +7211,14 @@ class EditContextManager {
|
|
|
7194
7211
|
return !abort;
|
|
7195
7212
|
}
|
|
7196
7213
|
update(update) {
|
|
7214
|
+
let reverted = this.pendingContextChange;
|
|
7197
7215
|
if (!this.applyEdits(update) || !this.rangeIsValid(update.state)) {
|
|
7198
7216
|
this.pendingContextChange = null;
|
|
7199
7217
|
this.resetRange(update.state);
|
|
7200
7218
|
this.editContext.updateText(0, this.editContext.text.length, update.state.doc.sliceString(this.from, this.to));
|
|
7201
7219
|
this.setSelection(update.state);
|
|
7202
7220
|
}
|
|
7203
|
-
else if (update.docChanged || update.selectionSet) {
|
|
7221
|
+
else if (update.docChanged || update.selectionSet || reverted) {
|
|
7204
7222
|
this.setSelection(update.state);
|
|
7205
7223
|
}
|
|
7206
7224
|
if (update.geometryChanged || update.docChanged || update.selectionSet)
|
|
@@ -7214,7 +7232,7 @@ class EditContextManager {
|
|
|
7214
7232
|
revertPending(state) {
|
|
7215
7233
|
let pending = this.pendingContextChange;
|
|
7216
7234
|
this.pendingContextChange = null;
|
|
7217
|
-
this.editContext.updateText(this.toContextPos(pending.from), this.toContextPos(pending.
|
|
7235
|
+
this.editContext.updateText(this.toContextPos(pending.from), this.toContextPos(pending.from + pending.insert.length), state.doc.sliceString(pending.from, pending.to));
|
|
7218
7236
|
}
|
|
7219
7237
|
setSelection(state) {
|
|
7220
7238
|
let { main } = state.selection;
|
|
@@ -7231,6 +7249,10 @@ class EditContextManager {
|
|
|
7231
7249
|
}
|
|
7232
7250
|
toEditorPos(contextPos) { return contextPos + this.from; }
|
|
7233
7251
|
toContextPos(editorPos) { return editorPos - this.from; }
|
|
7252
|
+
destroy() {
|
|
7253
|
+
for (let event in this.handlers)
|
|
7254
|
+
this.editContext.removeEventListener(event, this.handlers[event]);
|
|
7255
|
+
}
|
|
7234
7256
|
}
|
|
7235
7257
|
|
|
7236
7258
|
// The editor's update state machine looks something like this:
|
package/dist/index.js
CHANGED
|
@@ -208,15 +208,17 @@ function scrollRectIntoView(dom, rect, side, x, y, xMargin, yMargin, ltr) {
|
|
|
208
208
|
}
|
|
209
209
|
}
|
|
210
210
|
}
|
|
211
|
-
function
|
|
212
|
-
let doc = dom.ownerDocument;
|
|
211
|
+
function scrollableParents(dom) {
|
|
212
|
+
let doc = dom.ownerDocument, x, y;
|
|
213
213
|
for (let cur = dom.parentNode; cur;) {
|
|
214
|
-
if (cur == doc.body) {
|
|
214
|
+
if (cur == doc.body || (x && y)) {
|
|
215
215
|
break;
|
|
216
216
|
}
|
|
217
217
|
else if (cur.nodeType == 1) {
|
|
218
|
-
if (cur.scrollHeight > cur.clientHeight
|
|
219
|
-
|
|
218
|
+
if (!y && cur.scrollHeight > cur.clientHeight)
|
|
219
|
+
y = cur;
|
|
220
|
+
if (!x && cur.scrollWidth > cur.clientWidth)
|
|
221
|
+
x = cur;
|
|
220
222
|
cur = cur.assignedSlot || cur.parentNode;
|
|
221
223
|
}
|
|
222
224
|
else if (cur.nodeType == 11) {
|
|
@@ -226,7 +228,7 @@ function scrollableParent(dom) {
|
|
|
226
228
|
break;
|
|
227
229
|
}
|
|
228
230
|
}
|
|
229
|
-
return
|
|
231
|
+
return { x, y };
|
|
230
232
|
}
|
|
231
233
|
class DOMSelectionState {
|
|
232
234
|
constructor() {
|
|
@@ -3980,7 +3982,7 @@ class MouseSelection {
|
|
|
3980
3982
|
this.scrollSpeed = { x: 0, y: 0 };
|
|
3981
3983
|
this.scrolling = -1;
|
|
3982
3984
|
this.lastEvent = startEvent;
|
|
3983
|
-
this.
|
|
3985
|
+
this.scrollParents = scrollableParents(view.contentDOM);
|
|
3984
3986
|
this.atoms = view.state.facet(atomicRanges).map(f => f(view));
|
|
3985
3987
|
let doc = view.contentDOM.ownerDocument;
|
|
3986
3988
|
doc.addEventListener("mousemove", this.move = this.move.bind(this));
|
|
@@ -3996,24 +3998,26 @@ class MouseSelection {
|
|
|
3996
3998
|
this.select(event);
|
|
3997
3999
|
}
|
|
3998
4000
|
move(event) {
|
|
3999
|
-
var _a;
|
|
4000
4001
|
if (event.buttons == 0)
|
|
4001
4002
|
return this.destroy();
|
|
4002
4003
|
if (this.dragging || this.dragging == null && dist(this.startEvent, event) < 10)
|
|
4003
4004
|
return;
|
|
4004
4005
|
this.select(this.lastEvent = event);
|
|
4005
4006
|
let sx = 0, sy = 0;
|
|
4006
|
-
let
|
|
4007
|
-
|
|
4007
|
+
let left = 0, top = 0, right = this.view.win.innerWidth, bottom = this.view.win.innerHeight;
|
|
4008
|
+
if (this.scrollParents.x)
|
|
4009
|
+
({ left, right } = this.scrollParents.x.getBoundingClientRect());
|
|
4010
|
+
if (this.scrollParents.y)
|
|
4011
|
+
({ top, bottom } = this.scrollParents.y.getBoundingClientRect());
|
|
4008
4012
|
let margins = getScrollMargins(this.view);
|
|
4009
|
-
if (event.clientX - margins.left <=
|
|
4010
|
-
sx = -dragScrollSpeed(
|
|
4011
|
-
else if (event.clientX + margins.right >=
|
|
4012
|
-
sx = dragScrollSpeed(event.clientX -
|
|
4013
|
-
if (event.clientY - margins.top <=
|
|
4014
|
-
sy = -dragScrollSpeed(
|
|
4015
|
-
else if (event.clientY + margins.bottom >=
|
|
4016
|
-
sy = dragScrollSpeed(event.clientY -
|
|
4013
|
+
if (event.clientX - margins.left <= left + dragScrollMargin)
|
|
4014
|
+
sx = -dragScrollSpeed(left - event.clientX);
|
|
4015
|
+
else if (event.clientX + margins.right >= right - dragScrollMargin)
|
|
4016
|
+
sx = dragScrollSpeed(event.clientX - right);
|
|
4017
|
+
if (event.clientY - margins.top <= top + dragScrollMargin)
|
|
4018
|
+
sy = -dragScrollSpeed(top - event.clientY);
|
|
4019
|
+
else if (event.clientY + margins.bottom >= bottom - dragScrollMargin)
|
|
4020
|
+
sy = dragScrollSpeed(event.clientY - bottom);
|
|
4017
4021
|
this.setScrollSpeed(sx, sy);
|
|
4018
4022
|
}
|
|
4019
4023
|
up(event) {
|
|
@@ -4042,13 +4046,17 @@ class MouseSelection {
|
|
|
4042
4046
|
}
|
|
4043
4047
|
}
|
|
4044
4048
|
scroll() {
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
this.
|
|
4049
|
+
let { x, y } = this.scrollSpeed;
|
|
4050
|
+
if (x && this.scrollParents.x) {
|
|
4051
|
+
this.scrollParents.x.scrollLeft += x;
|
|
4052
|
+
x = 0;
|
|
4048
4053
|
}
|
|
4049
|
-
|
|
4050
|
-
this.
|
|
4054
|
+
if (y && this.scrollParents.y) {
|
|
4055
|
+
this.scrollParents.y.scrollTop += y;
|
|
4056
|
+
y = 0;
|
|
4051
4057
|
}
|
|
4058
|
+
if (x || y)
|
|
4059
|
+
this.view.win.scrollBy(x, y);
|
|
4052
4060
|
if (this.dragging === false)
|
|
4053
4061
|
this.select(this.lastEvent);
|
|
4054
4062
|
}
|
|
@@ -7025,6 +7033,10 @@ class DOMObserver {
|
|
|
7025
7033
|
clearTimeout(this.resizeTimeout);
|
|
7026
7034
|
this.win.cancelAnimationFrame(this.delayedFlush);
|
|
7027
7035
|
this.win.cancelAnimationFrame(this.flushingAndroidKey);
|
|
7036
|
+
if (this.editContext) {
|
|
7037
|
+
this.view.contentDOM.editContext = null;
|
|
7038
|
+
this.editContext.destroy();
|
|
7039
|
+
}
|
|
7028
7040
|
}
|
|
7029
7041
|
}
|
|
7030
7042
|
function findChild(cView, dom, dir) {
|
|
@@ -7084,13 +7096,14 @@ class EditContextManager {
|
|
|
7084
7096
|
// that sometimes breaks series of multiple edits made for a single
|
|
7085
7097
|
// user action on some Android keyboards)
|
|
7086
7098
|
this.pendingContextChange = null;
|
|
7099
|
+
this.handlers = Object.create(null);
|
|
7087
7100
|
this.resetRange(view.state);
|
|
7088
7101
|
let context = this.editContext = new window.EditContext({
|
|
7089
7102
|
text: view.state.doc.sliceString(this.from, this.to),
|
|
7090
7103
|
selectionStart: this.toContextPos(Math.max(this.from, Math.min(this.to, view.state.selection.main.anchor))),
|
|
7091
7104
|
selectionEnd: this.toContextPos(view.state.selection.main.head)
|
|
7092
7105
|
});
|
|
7093
|
-
|
|
7106
|
+
this.handlers.textupdate = e => {
|
|
7094
7107
|
let { anchor } = view.state.selection.main;
|
|
7095
7108
|
let change = { from: this.toEditorPos(e.updateRangeStart),
|
|
7096
7109
|
to: this.toEditorPos(e.updateRangeEnd),
|
|
@@ -7108,10 +7121,12 @@ class EditContextManager {
|
|
|
7108
7121
|
applyDOMChangeInner(view, change, EditorSelection.single(this.toEditorPos(e.selectionStart), this.toEditorPos(e.selectionEnd)));
|
|
7109
7122
|
// If the transaction didn't flush our change, revert it so
|
|
7110
7123
|
// that the context is in sync with the editor state again.
|
|
7111
|
-
if (this.pendingContextChange)
|
|
7124
|
+
if (this.pendingContextChange) {
|
|
7112
7125
|
this.revertPending(view.state);
|
|
7113
|
-
|
|
7114
|
-
|
|
7126
|
+
this.setSelection(view.state);
|
|
7127
|
+
}
|
|
7128
|
+
};
|
|
7129
|
+
this.handlers.characterboundsupdate = e => {
|
|
7115
7130
|
let rects = [], prev = null;
|
|
7116
7131
|
for (let i = this.toEditorPos(e.rangeStart), end = this.toEditorPos(e.rangeEnd); i < end; i++) {
|
|
7117
7132
|
let rect = view.coordsForChar(i);
|
|
@@ -7120,8 +7135,8 @@ class EditContextManager {
|
|
|
7120
7135
|
rects.push(prev);
|
|
7121
7136
|
}
|
|
7122
7137
|
context.updateCharacterBounds(e.rangeStart, rects);
|
|
7123
|
-
}
|
|
7124
|
-
|
|
7138
|
+
};
|
|
7139
|
+
this.handlers.textformatupdate = e => {
|
|
7125
7140
|
let deco = [];
|
|
7126
7141
|
for (let format of e.getTextFormats()) {
|
|
7127
7142
|
let lineStyle = format.underlineStyle, thickness = format.underlineThickness;
|
|
@@ -7132,17 +7147,19 @@ class EditContextManager {
|
|
|
7132
7147
|
}
|
|
7133
7148
|
}
|
|
7134
7149
|
view.dispatch({ effects: setEditContextFormatting.of(Decoration.set(deco)) });
|
|
7135
|
-
}
|
|
7136
|
-
|
|
7150
|
+
};
|
|
7151
|
+
this.handlers.compositionstart = () => {
|
|
7137
7152
|
if (view.inputState.composing < 0) {
|
|
7138
7153
|
view.inputState.composing = 0;
|
|
7139
7154
|
view.inputState.compositionFirstChange = true;
|
|
7140
7155
|
}
|
|
7141
|
-
}
|
|
7142
|
-
|
|
7156
|
+
};
|
|
7157
|
+
this.handlers.compositionend = () => {
|
|
7143
7158
|
view.inputState.composing = -1;
|
|
7144
7159
|
view.inputState.compositionFirstChange = null;
|
|
7145
|
-
}
|
|
7160
|
+
};
|
|
7161
|
+
for (let event in this.handlers)
|
|
7162
|
+
context.addEventListener(event, this.handlers[event]);
|
|
7146
7163
|
this.measureReq = { read: view => {
|
|
7147
7164
|
this.editContext.updateControlBounds(view.contentDOM.getBoundingClientRect());
|
|
7148
7165
|
let sel = getSelection(view.root);
|
|
@@ -7189,13 +7206,14 @@ class EditContextManager {
|
|
|
7189
7206
|
return !abort;
|
|
7190
7207
|
}
|
|
7191
7208
|
update(update) {
|
|
7209
|
+
let reverted = this.pendingContextChange;
|
|
7192
7210
|
if (!this.applyEdits(update) || !this.rangeIsValid(update.state)) {
|
|
7193
7211
|
this.pendingContextChange = null;
|
|
7194
7212
|
this.resetRange(update.state);
|
|
7195
7213
|
this.editContext.updateText(0, this.editContext.text.length, update.state.doc.sliceString(this.from, this.to));
|
|
7196
7214
|
this.setSelection(update.state);
|
|
7197
7215
|
}
|
|
7198
|
-
else if (update.docChanged || update.selectionSet) {
|
|
7216
|
+
else if (update.docChanged || update.selectionSet || reverted) {
|
|
7199
7217
|
this.setSelection(update.state);
|
|
7200
7218
|
}
|
|
7201
7219
|
if (update.geometryChanged || update.docChanged || update.selectionSet)
|
|
@@ -7209,7 +7227,7 @@ class EditContextManager {
|
|
|
7209
7227
|
revertPending(state) {
|
|
7210
7228
|
let pending = this.pendingContextChange;
|
|
7211
7229
|
this.pendingContextChange = null;
|
|
7212
|
-
this.editContext.updateText(this.toContextPos(pending.from), this.toContextPos(pending.
|
|
7230
|
+
this.editContext.updateText(this.toContextPos(pending.from), this.toContextPos(pending.from + pending.insert.length), state.doc.sliceString(pending.from, pending.to));
|
|
7213
7231
|
}
|
|
7214
7232
|
setSelection(state) {
|
|
7215
7233
|
let { main } = state.selection;
|
|
@@ -7226,6 +7244,10 @@ class EditContextManager {
|
|
|
7226
7244
|
}
|
|
7227
7245
|
toEditorPos(contextPos) { return contextPos + this.from; }
|
|
7228
7246
|
toContextPos(editorPos) { return editorPos - this.from; }
|
|
7247
|
+
destroy() {
|
|
7248
|
+
for (let event in this.handlers)
|
|
7249
|
+
this.editContext.removeEventListener(event, this.handlers[event]);
|
|
7250
|
+
}
|
|
7229
7251
|
}
|
|
7230
7252
|
|
|
7231
7253
|
// The editor's update state machine looks something like this:
|