@codemirror/view 6.28.4 → 6.28.5
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 +8 -0
- package/dist/index.cjs +52 -33
- package/dist/index.js +52 -33
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
## 6.28.5 (2024-07-17)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
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.
|
|
6
|
+
|
|
7
|
+
Work around a memory leak in Chrome's EditContext implementation.
|
|
8
|
+
|
|
1
9
|
## 6.28.4 (2024-07-03)
|
|
2
10
|
|
|
3
11
|
### 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),
|
|
@@ -7115,8 +7128,8 @@ class EditContextManager {
|
|
|
7115
7128
|
// that the context is in sync with the editor state again.
|
|
7116
7129
|
if (this.pendingContextChange)
|
|
7117
7130
|
this.revertPending(view.state);
|
|
7118
|
-
}
|
|
7119
|
-
|
|
7131
|
+
};
|
|
7132
|
+
this.handlers.characterboundsupdate = e => {
|
|
7120
7133
|
let rects = [], prev = null;
|
|
7121
7134
|
for (let i = this.toEditorPos(e.rangeStart), end = this.toEditorPos(e.rangeEnd); i < end; i++) {
|
|
7122
7135
|
let rect = view.coordsForChar(i);
|
|
@@ -7125,8 +7138,8 @@ class EditContextManager {
|
|
|
7125
7138
|
rects.push(prev);
|
|
7126
7139
|
}
|
|
7127
7140
|
context.updateCharacterBounds(e.rangeStart, rects);
|
|
7128
|
-
}
|
|
7129
|
-
|
|
7141
|
+
};
|
|
7142
|
+
this.handlers.textformatupdate = e => {
|
|
7130
7143
|
let deco = [];
|
|
7131
7144
|
for (let format of e.getTextFormats()) {
|
|
7132
7145
|
let lineStyle = format.underlineStyle, thickness = format.underlineThickness;
|
|
@@ -7137,17 +7150,19 @@ class EditContextManager {
|
|
|
7137
7150
|
}
|
|
7138
7151
|
}
|
|
7139
7152
|
view.dispatch({ effects: setEditContextFormatting.of(Decoration.set(deco)) });
|
|
7140
|
-
}
|
|
7141
|
-
|
|
7153
|
+
};
|
|
7154
|
+
this.handlers.compositionstart = () => {
|
|
7142
7155
|
if (view.inputState.composing < 0) {
|
|
7143
7156
|
view.inputState.composing = 0;
|
|
7144
7157
|
view.inputState.compositionFirstChange = true;
|
|
7145
7158
|
}
|
|
7146
|
-
}
|
|
7147
|
-
|
|
7159
|
+
};
|
|
7160
|
+
this.handlers.compositionend = () => {
|
|
7148
7161
|
view.inputState.composing = -1;
|
|
7149
7162
|
view.inputState.compositionFirstChange = null;
|
|
7150
|
-
}
|
|
7163
|
+
};
|
|
7164
|
+
for (let event in this.handlers)
|
|
7165
|
+
context.addEventListener(event, this.handlers[event]);
|
|
7151
7166
|
this.measureReq = { read: view => {
|
|
7152
7167
|
this.editContext.updateControlBounds(view.contentDOM.getBoundingClientRect());
|
|
7153
7168
|
let sel = getSelection(view.root);
|
|
@@ -7231,6 +7246,10 @@ class EditContextManager {
|
|
|
7231
7246
|
}
|
|
7232
7247
|
toEditorPos(contextPos) { return contextPos + this.from; }
|
|
7233
7248
|
toContextPos(editorPos) { return editorPos - this.from; }
|
|
7249
|
+
destroy() {
|
|
7250
|
+
for (let event in this.handlers)
|
|
7251
|
+
this.editContext.removeEventListener(event, this.handlers[event]);
|
|
7252
|
+
}
|
|
7234
7253
|
}
|
|
7235
7254
|
|
|
7236
7255
|
// 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),
|
|
@@ -7110,8 +7123,8 @@ class EditContextManager {
|
|
|
7110
7123
|
// that the context is in sync with the editor state again.
|
|
7111
7124
|
if (this.pendingContextChange)
|
|
7112
7125
|
this.revertPending(view.state);
|
|
7113
|
-
}
|
|
7114
|
-
|
|
7126
|
+
};
|
|
7127
|
+
this.handlers.characterboundsupdate = e => {
|
|
7115
7128
|
let rects = [], prev = null;
|
|
7116
7129
|
for (let i = this.toEditorPos(e.rangeStart), end = this.toEditorPos(e.rangeEnd); i < end; i++) {
|
|
7117
7130
|
let rect = view.coordsForChar(i);
|
|
@@ -7120,8 +7133,8 @@ class EditContextManager {
|
|
|
7120
7133
|
rects.push(prev);
|
|
7121
7134
|
}
|
|
7122
7135
|
context.updateCharacterBounds(e.rangeStart, rects);
|
|
7123
|
-
}
|
|
7124
|
-
|
|
7136
|
+
};
|
|
7137
|
+
this.handlers.textformatupdate = e => {
|
|
7125
7138
|
let deco = [];
|
|
7126
7139
|
for (let format of e.getTextFormats()) {
|
|
7127
7140
|
let lineStyle = format.underlineStyle, thickness = format.underlineThickness;
|
|
@@ -7132,17 +7145,19 @@ class EditContextManager {
|
|
|
7132
7145
|
}
|
|
7133
7146
|
}
|
|
7134
7147
|
view.dispatch({ effects: setEditContextFormatting.of(Decoration.set(deco)) });
|
|
7135
|
-
}
|
|
7136
|
-
|
|
7148
|
+
};
|
|
7149
|
+
this.handlers.compositionstart = () => {
|
|
7137
7150
|
if (view.inputState.composing < 0) {
|
|
7138
7151
|
view.inputState.composing = 0;
|
|
7139
7152
|
view.inputState.compositionFirstChange = true;
|
|
7140
7153
|
}
|
|
7141
|
-
}
|
|
7142
|
-
|
|
7154
|
+
};
|
|
7155
|
+
this.handlers.compositionend = () => {
|
|
7143
7156
|
view.inputState.composing = -1;
|
|
7144
7157
|
view.inputState.compositionFirstChange = null;
|
|
7145
|
-
}
|
|
7158
|
+
};
|
|
7159
|
+
for (let event in this.handlers)
|
|
7160
|
+
context.addEventListener(event, this.handlers[event]);
|
|
7146
7161
|
this.measureReq = { read: view => {
|
|
7147
7162
|
this.editContext.updateControlBounds(view.contentDOM.getBoundingClientRect());
|
|
7148
7163
|
let sel = getSelection(view.root);
|
|
@@ -7226,6 +7241,10 @@ class EditContextManager {
|
|
|
7226
7241
|
}
|
|
7227
7242
|
toEditorPos(contextPos) { return contextPos + this.from; }
|
|
7228
7243
|
toContextPos(editorPos) { return editorPos - this.from; }
|
|
7244
|
+
destroy() {
|
|
7245
|
+
for (let event in this.handlers)
|
|
7246
|
+
this.editContext.removeEventListener(event, this.handlers[event]);
|
|
7247
|
+
}
|
|
7229
7248
|
}
|
|
7230
7249
|
|
|
7231
7250
|
// The editor's update state machine looks something like this:
|