@codemirror/view 6.43.10 → 6.43.12
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 +34 -14
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +34 -14
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
## 6.43.12 (2026-09-15)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Make `visualLineSide` use bidi information when looking for the start or end of line with no wrap points.
|
|
6
|
+
|
|
7
|
+
Fix a bug in updating the DOM for marks around an active composition that could sometimes try to use the same DOM node twice.
|
|
8
|
+
|
|
9
|
+
Work around an issue on Firefox where a composition might be started outside of a line container.
|
|
10
|
+
|
|
11
|
+
Make sure repeated screen reader announcement messages don't get swallowed by VoiceOver.
|
|
12
|
+
|
|
13
|
+
## 6.43.11 (2026-09-03)
|
|
14
|
+
|
|
15
|
+
### Bug fixes
|
|
16
|
+
|
|
17
|
+
Speed up handling of Enter/Backspace on iOS in cases where the browser's native behavior is to do nothing.
|
|
18
|
+
|
|
19
|
+
Fix the patch that avoids a crash in `posAtCoords` for non-rendered elements.
|
|
20
|
+
|
|
1
21
|
## 6.43.10 (2026-08-31)
|
|
2
22
|
|
|
3
23
|
### Bug fixes
|
package/dist/index.cjs
CHANGED
|
@@ -2323,12 +2323,13 @@ class TileBuilder {
|
|
|
2323
2323
|
head = last;
|
|
2324
2324
|
}
|
|
2325
2325
|
else {
|
|
2326
|
+
let { dom } = mark;
|
|
2326
2327
|
if (this.cache.reused.get(mark)) {
|
|
2327
2328
|
let tile = Tile.get(mark.dom);
|
|
2328
2329
|
if (tile)
|
|
2329
|
-
|
|
2330
|
+
dom = freeNode(mark.dom);
|
|
2330
2331
|
}
|
|
2331
|
-
let nw = MarkTile.of(mark.mark,
|
|
2332
|
+
let nw = MarkTile.of(mark.mark, dom);
|
|
2332
2333
|
head.append(nw);
|
|
2333
2334
|
head = nw;
|
|
2334
2335
|
}
|
|
@@ -2828,12 +2829,14 @@ class TileUpdate {
|
|
|
2828
2829
|
else if (tile === null || tile === void 0 ? void 0 : tile.isLine())
|
|
2829
2830
|
line = tile;
|
|
2830
2831
|
else if (tile instanceof BlockWrapperTile) ; // Ignore
|
|
2831
|
-
else if (parent.nodeName == "DIV" && !line
|
|
2832
|
+
else if (parent.nodeName == "DIV" && !line)
|
|
2832
2833
|
line = new LineTile(parent, lineBaseAttrs);
|
|
2833
2834
|
else if (!line)
|
|
2834
2835
|
marks.push(MarkTile.of(new MarkDecoration({ tagName: parent.nodeName.toLowerCase(), attributes: getAttrs(parent) }), parent));
|
|
2835
2836
|
}
|
|
2836
|
-
|
|
2837
|
+
if (!line)
|
|
2838
|
+
return null;
|
|
2839
|
+
return { line, marks };
|
|
2837
2840
|
}
|
|
2838
2841
|
}
|
|
2839
2842
|
function hasContent(tile, requireText) {
|
|
@@ -3664,18 +3667,21 @@ function blockAt(view, pos, side) {
|
|
|
3664
3667
|
return line;
|
|
3665
3668
|
}
|
|
3666
3669
|
function moveToLineBoundary(view, start, forward, includeWrap) {
|
|
3667
|
-
let
|
|
3668
|
-
let coords = !includeWrap ||
|
|
3669
|
-
: view.coordsAtPos(start.assoc < 0 && start.head >
|
|
3670
|
+
let block = blockAt(view, start.head, start.assoc || -1);
|
|
3671
|
+
let coords = !includeWrap || block.type != exports.BlockType.Text || !(view.lineWrapping || block.widgetLineBreaks) ? null
|
|
3672
|
+
: view.coordsAtPos(start.assoc < 0 && start.head > block.from ? start.head - 1 : start.head);
|
|
3670
3673
|
if (coords) {
|
|
3671
3674
|
let editorRect = view.dom.getBoundingClientRect();
|
|
3672
|
-
let direction = view.textDirectionAt(
|
|
3675
|
+
let direction = view.textDirectionAt(block.from);
|
|
3673
3676
|
let pos = view.posAtCoords({ x: forward == (direction == exports.Direction.LTR) ? editorRect.right - 1 : editorRect.left + 1,
|
|
3674
3677
|
y: (coords.top + coords.bottom) / 2 });
|
|
3675
3678
|
if (pos != null)
|
|
3676
3679
|
return state.EditorSelection.cursor(pos, forward ? -1 : 1);
|
|
3677
3680
|
}
|
|
3678
|
-
|
|
3681
|
+
let line = view.state.doc.lineAt(start.head);
|
|
3682
|
+
if (forward ? line.to == block.to : line.from == block.from)
|
|
3683
|
+
return view.visualLineSide(line, forward);
|
|
3684
|
+
return state.EditorSelection.cursor(forward ? block.to : block.from, forward ? -1 : 1);
|
|
3679
3685
|
}
|
|
3680
3686
|
function moveByChar(view, start, forward, by) {
|
|
3681
3687
|
let line = view.state.doc.lineAt(start.head), spans = view.bidiSpans(line);
|
|
@@ -3947,7 +3953,7 @@ class InlineCoordsScan {
|
|
|
3947
3953
|
// on the y axis, move this.y into it, and retry the scan.
|
|
3948
3954
|
if (!closestRect) {
|
|
3949
3955
|
if (!below && !above)
|
|
3950
|
-
return { i:
|
|
3956
|
+
return { i: 0, after: false };
|
|
3951
3957
|
let side = above && (!below || (this.y - above.bottom < below.top - this.y)) ? above : below;
|
|
3952
3958
|
this.y = (side.top + side.bottom) / 2;
|
|
3953
3959
|
return this.scan(positions, getRects, true);
|
|
@@ -4629,7 +4635,7 @@ class InputState {
|
|
|
4629
4635
|
iosVirtualKeyboardOpen(this.view.win))
|
|
4630
4636
|
mods.shiftKey = false;
|
|
4631
4637
|
this.pendingIOSKey = { key: event.key, keyCode: event.keyCode, mods };
|
|
4632
|
-
setTimeout(() => this.flushIOSKey(),
|
|
4638
|
+
setTimeout(() => this.flushIOSKey(), 50);
|
|
4633
4639
|
return true;
|
|
4634
4640
|
}
|
|
4635
4641
|
if (event.keyCode != 229)
|
|
@@ -4638,7 +4644,7 @@ class InputState {
|
|
|
4638
4644
|
}
|
|
4639
4645
|
flushIOSKey(change) {
|
|
4640
4646
|
let key = this.pendingIOSKey;
|
|
4641
|
-
if (!key)
|
|
4647
|
+
if (!key || this.view.observer.pendingRecords().length)
|
|
4642
4648
|
return false;
|
|
4643
4649
|
// This looks like an autocorrection before Enter
|
|
4644
4650
|
if (key.key == "Enter" && change && change.from < change.to && /^\S+$/.test(change.insert.toString()))
|
|
@@ -5263,6 +5269,13 @@ observers.compositionstart = observers.compositionupdate = view => {
|
|
|
5263
5269
|
if (view.inputState.compositionFirstChange == null)
|
|
5264
5270
|
view.inputState.compositionFirstChange = true;
|
|
5265
5271
|
if (view.inputState.composing < 0) {
|
|
5272
|
+
let { main } = view.state.selection;
|
|
5273
|
+
if (!main.empty && view.lineBlockAt(main.from).from != view.lineBlockAt(main.to).from) {
|
|
5274
|
+
view.dispatch({
|
|
5275
|
+
changes: view.state.selection.ranges.filter(r => !r.empty).map(r => ({ from: r.from, to: r.to })),
|
|
5276
|
+
userEvent: "input"
|
|
5277
|
+
});
|
|
5278
|
+
}
|
|
5266
5279
|
// FIXME possibly set a timeout to clear it again on Android
|
|
5267
5280
|
view.inputState.composing = 0;
|
|
5268
5281
|
}
|
|
@@ -7896,6 +7909,7 @@ class EditorView {
|
|
|
7896
7909
|
@internal
|
|
7897
7910
|
*/
|
|
7898
7911
|
this.measureRequests = [];
|
|
7912
|
+
this.clearAnnouncement = -1;
|
|
7899
7913
|
this.contentDOM = document.createElement("div");
|
|
7900
7914
|
this.scrollDOM = document.createElement("div");
|
|
7901
7915
|
this.scrollDOM.tabIndex = -1;
|
|
@@ -8301,9 +8315,14 @@ class EditorView {
|
|
|
8301
8315
|
for (let tr of trs)
|
|
8302
8316
|
for (let effect of tr.effects)
|
|
8303
8317
|
if (effect.is(EditorView.announce)) {
|
|
8304
|
-
if (first)
|
|
8318
|
+
if (first) {
|
|
8305
8319
|
this.announceDOM.textContent = "";
|
|
8306
|
-
|
|
8320
|
+
this.win.clearTimeout(this.clearAnnouncement);
|
|
8321
|
+
this.clearAnnouncement = this.win.setTimeout(() => {
|
|
8322
|
+
this.announceDOM.textContent = "\u00a0";
|
|
8323
|
+
}, 200);
|
|
8324
|
+
first = false;
|
|
8325
|
+
}
|
|
8307
8326
|
let div = this.announceDOM.appendChild(document.createElement("div"));
|
|
8308
8327
|
div.textContent = effect.value;
|
|
8309
8328
|
}
|
|
@@ -8653,6 +8672,7 @@ class EditorView {
|
|
|
8653
8672
|
this.docView.destroy();
|
|
8654
8673
|
this.dom.remove();
|
|
8655
8674
|
this.observer.destroy();
|
|
8675
|
+
this.win.clearTimeout(this.clearAnnouncement);
|
|
8656
8676
|
if (this.measureScheduled > -1)
|
|
8657
8677
|
this.win.cancelAnimationFrame(this.measureScheduled);
|
|
8658
8678
|
this.destroyed = true;
|
package/dist/index.d.cts
CHANGED
|
@@ -813,6 +813,7 @@ declare class EditorView {
|
|
|
813
813
|
private styleModules;
|
|
814
814
|
private bidiCache;
|
|
815
815
|
private destroyed;
|
|
816
|
+
private clearAnnouncement;
|
|
816
817
|
/**
|
|
817
818
|
Construct a new view. You'll want to either provide a `parent`
|
|
818
819
|
option, or put `view.dom` into your document after creating a
|
package/dist/index.d.ts
CHANGED
|
@@ -813,6 +813,7 @@ declare class EditorView {
|
|
|
813
813
|
private styleModules;
|
|
814
814
|
private bidiCache;
|
|
815
815
|
private destroyed;
|
|
816
|
+
private clearAnnouncement;
|
|
816
817
|
/**
|
|
817
818
|
Construct a new view. You'll want to either provide a `parent`
|
|
818
819
|
option, or put `view.dom` into your document after creating a
|
package/dist/index.js
CHANGED
|
@@ -2319,12 +2319,13 @@ class TileBuilder {
|
|
|
2319
2319
|
head = last;
|
|
2320
2320
|
}
|
|
2321
2321
|
else {
|
|
2322
|
+
let { dom } = mark;
|
|
2322
2323
|
if (this.cache.reused.get(mark)) {
|
|
2323
2324
|
let tile = Tile.get(mark.dom);
|
|
2324
2325
|
if (tile)
|
|
2325
|
-
|
|
2326
|
+
dom = freeNode(mark.dom);
|
|
2326
2327
|
}
|
|
2327
|
-
let nw = MarkTile.of(mark.mark,
|
|
2328
|
+
let nw = MarkTile.of(mark.mark, dom);
|
|
2328
2329
|
head.append(nw);
|
|
2329
2330
|
head = nw;
|
|
2330
2331
|
}
|
|
@@ -2824,12 +2825,14 @@ class TileUpdate {
|
|
|
2824
2825
|
else if (tile === null || tile === void 0 ? void 0 : tile.isLine())
|
|
2825
2826
|
line = tile;
|
|
2826
2827
|
else if (tile instanceof BlockWrapperTile) ; // Ignore
|
|
2827
|
-
else if (parent.nodeName == "DIV" && !line
|
|
2828
|
+
else if (parent.nodeName == "DIV" && !line)
|
|
2828
2829
|
line = new LineTile(parent, lineBaseAttrs);
|
|
2829
2830
|
else if (!line)
|
|
2830
2831
|
marks.push(MarkTile.of(new MarkDecoration({ tagName: parent.nodeName.toLowerCase(), attributes: getAttrs(parent) }), parent));
|
|
2831
2832
|
}
|
|
2832
|
-
|
|
2833
|
+
if (!line)
|
|
2834
|
+
return null;
|
|
2835
|
+
return { line, marks };
|
|
2833
2836
|
}
|
|
2834
2837
|
}
|
|
2835
2838
|
function hasContent(tile, requireText) {
|
|
@@ -3660,18 +3663,21 @@ function blockAt(view, pos, side) {
|
|
|
3660
3663
|
return line;
|
|
3661
3664
|
}
|
|
3662
3665
|
function moveToLineBoundary(view, start, forward, includeWrap) {
|
|
3663
|
-
let
|
|
3664
|
-
let coords = !includeWrap ||
|
|
3665
|
-
: view.coordsAtPos(start.assoc < 0 && start.head >
|
|
3666
|
+
let block = blockAt(view, start.head, start.assoc || -1);
|
|
3667
|
+
let coords = !includeWrap || block.type != BlockType.Text || !(view.lineWrapping || block.widgetLineBreaks) ? null
|
|
3668
|
+
: view.coordsAtPos(start.assoc < 0 && start.head > block.from ? start.head - 1 : start.head);
|
|
3666
3669
|
if (coords) {
|
|
3667
3670
|
let editorRect = view.dom.getBoundingClientRect();
|
|
3668
|
-
let direction = view.textDirectionAt(
|
|
3671
|
+
let direction = view.textDirectionAt(block.from);
|
|
3669
3672
|
let pos = view.posAtCoords({ x: forward == (direction == Direction.LTR) ? editorRect.right - 1 : editorRect.left + 1,
|
|
3670
3673
|
y: (coords.top + coords.bottom) / 2 });
|
|
3671
3674
|
if (pos != null)
|
|
3672
3675
|
return EditorSelection.cursor(pos, forward ? -1 : 1);
|
|
3673
3676
|
}
|
|
3674
|
-
|
|
3677
|
+
let line = view.state.doc.lineAt(start.head);
|
|
3678
|
+
if (forward ? line.to == block.to : line.from == block.from)
|
|
3679
|
+
return view.visualLineSide(line, forward);
|
|
3680
|
+
return EditorSelection.cursor(forward ? block.to : block.from, forward ? -1 : 1);
|
|
3675
3681
|
}
|
|
3676
3682
|
function moveByChar(view, start, forward, by) {
|
|
3677
3683
|
let line = view.state.doc.lineAt(start.head), spans = view.bidiSpans(line);
|
|
@@ -3943,7 +3949,7 @@ class InlineCoordsScan {
|
|
|
3943
3949
|
// on the y axis, move this.y into it, and retry the scan.
|
|
3944
3950
|
if (!closestRect) {
|
|
3945
3951
|
if (!below && !above)
|
|
3946
|
-
return { i:
|
|
3952
|
+
return { i: 0, after: false };
|
|
3947
3953
|
let side = above && (!below || (this.y - above.bottom < below.top - this.y)) ? above : below;
|
|
3948
3954
|
this.y = (side.top + side.bottom) / 2;
|
|
3949
3955
|
return this.scan(positions, getRects, true);
|
|
@@ -4625,7 +4631,7 @@ class InputState {
|
|
|
4625
4631
|
iosVirtualKeyboardOpen(this.view.win))
|
|
4626
4632
|
mods.shiftKey = false;
|
|
4627
4633
|
this.pendingIOSKey = { key: event.key, keyCode: event.keyCode, mods };
|
|
4628
|
-
setTimeout(() => this.flushIOSKey(),
|
|
4634
|
+
setTimeout(() => this.flushIOSKey(), 50);
|
|
4629
4635
|
return true;
|
|
4630
4636
|
}
|
|
4631
4637
|
if (event.keyCode != 229)
|
|
@@ -4634,7 +4640,7 @@ class InputState {
|
|
|
4634
4640
|
}
|
|
4635
4641
|
flushIOSKey(change) {
|
|
4636
4642
|
let key = this.pendingIOSKey;
|
|
4637
|
-
if (!key)
|
|
4643
|
+
if (!key || this.view.observer.pendingRecords().length)
|
|
4638
4644
|
return false;
|
|
4639
4645
|
// This looks like an autocorrection before Enter
|
|
4640
4646
|
if (key.key == "Enter" && change && change.from < change.to && /^\S+$/.test(change.insert.toString()))
|
|
@@ -5259,6 +5265,13 @@ observers.compositionstart = observers.compositionupdate = view => {
|
|
|
5259
5265
|
if (view.inputState.compositionFirstChange == null)
|
|
5260
5266
|
view.inputState.compositionFirstChange = true;
|
|
5261
5267
|
if (view.inputState.composing < 0) {
|
|
5268
|
+
let { main } = view.state.selection;
|
|
5269
|
+
if (!main.empty && view.lineBlockAt(main.from).from != view.lineBlockAt(main.to).from) {
|
|
5270
|
+
view.dispatch({
|
|
5271
|
+
changes: view.state.selection.ranges.filter(r => !r.empty).map(r => ({ from: r.from, to: r.to })),
|
|
5272
|
+
userEvent: "input"
|
|
5273
|
+
});
|
|
5274
|
+
}
|
|
5262
5275
|
// FIXME possibly set a timeout to clear it again on Android
|
|
5263
5276
|
view.inputState.composing = 0;
|
|
5264
5277
|
}
|
|
@@ -7891,6 +7904,7 @@ class EditorView {
|
|
|
7891
7904
|
@internal
|
|
7892
7905
|
*/
|
|
7893
7906
|
this.measureRequests = [];
|
|
7907
|
+
this.clearAnnouncement = -1;
|
|
7894
7908
|
this.contentDOM = document.createElement("div");
|
|
7895
7909
|
this.scrollDOM = document.createElement("div");
|
|
7896
7910
|
this.scrollDOM.tabIndex = -1;
|
|
@@ -8296,9 +8310,14 @@ class EditorView {
|
|
|
8296
8310
|
for (let tr of trs)
|
|
8297
8311
|
for (let effect of tr.effects)
|
|
8298
8312
|
if (effect.is(EditorView.announce)) {
|
|
8299
|
-
if (first)
|
|
8313
|
+
if (first) {
|
|
8300
8314
|
this.announceDOM.textContent = "";
|
|
8301
|
-
|
|
8315
|
+
this.win.clearTimeout(this.clearAnnouncement);
|
|
8316
|
+
this.clearAnnouncement = this.win.setTimeout(() => {
|
|
8317
|
+
this.announceDOM.textContent = "\u00a0";
|
|
8318
|
+
}, 200);
|
|
8319
|
+
first = false;
|
|
8320
|
+
}
|
|
8302
8321
|
let div = this.announceDOM.appendChild(document.createElement("div"));
|
|
8303
8322
|
div.textContent = effect.value;
|
|
8304
8323
|
}
|
|
@@ -8648,6 +8667,7 @@ class EditorView {
|
|
|
8648
8667
|
this.docView.destroy();
|
|
8649
8668
|
this.dom.remove();
|
|
8650
8669
|
this.observer.destroy();
|
|
8670
|
+
this.win.clearTimeout(this.clearAnnouncement);
|
|
8651
8671
|
if (this.measureScheduled > -1)
|
|
8652
8672
|
this.win.cancelAnimationFrame(this.measureScheduled);
|
|
8653
8673
|
this.destroyed = true;
|