@codemirror/autocomplete 0.19.11 → 0.19.14
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 +26 -14
- package/dist/index.js +27 -15
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
## 0.19.14 (2022-03-10)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Make the ARIA attributes added to the editor during autocompletion spec-compliant.
|
|
6
|
+
|
|
7
|
+
## 0.19.13 (2022-02-18)
|
|
8
|
+
|
|
9
|
+
### Bug fixes
|
|
10
|
+
|
|
11
|
+
Fix an issue where the completion tooltip stayed open if it was explicitly opened and the user backspaced past its start.
|
|
12
|
+
|
|
13
|
+
Stop snippet filling when a change happens across one of the snippet fields' boundaries.
|
|
14
|
+
|
|
15
|
+
## 0.19.12 (2022-01-11)
|
|
16
|
+
|
|
17
|
+
### Bug fixes
|
|
18
|
+
|
|
19
|
+
Fix completion navigation with PageUp/Down when the completion tooltip isn't part of the view DOM.
|
|
20
|
+
|
|
1
21
|
## 0.19.11 (2022-01-11)
|
|
2
22
|
|
|
3
23
|
### Bug fixes
|
package/dist/index.cjs
CHANGED
|
@@ -514,6 +514,7 @@ class CompletionTooltip {
|
|
|
514
514
|
const ul = document.createElement("ul");
|
|
515
515
|
ul.id = id;
|
|
516
516
|
ul.setAttribute("role", "listbox");
|
|
517
|
+
ul.setAttribute("aria-expanded", "true");
|
|
517
518
|
for (let i = range.from; i < range.to; i++) {
|
|
518
519
|
let { completion, match } = options[i];
|
|
519
520
|
const li = ul.appendChild(document.createElement("li"));
|
|
@@ -574,7 +575,6 @@ function sortOptions(active, state) {
|
|
|
574
575
|
}
|
|
575
576
|
}
|
|
576
577
|
}
|
|
577
|
-
options.sort(cmpOption);
|
|
578
578
|
let result = [], prev = null;
|
|
579
579
|
for (let opt of options.sort(cmpOption)) {
|
|
580
580
|
if (result.length == MaxOptions)
|
|
@@ -607,10 +607,11 @@ class CompletionDialog {
|
|
|
607
607
|
let selected = 0;
|
|
608
608
|
if (prev && prev.selected) {
|
|
609
609
|
let selectedValue = prev.options[prev.selected].completion;
|
|
610
|
-
for (let i = 0; i < options.length
|
|
611
|
-
if (options[i].completion == selectedValue)
|
|
610
|
+
for (let i = 0; i < options.length; i++)
|
|
611
|
+
if (options[i].completion == selectedValue) {
|
|
612
612
|
selected = i;
|
|
613
|
-
|
|
613
|
+
break;
|
|
614
|
+
}
|
|
614
615
|
}
|
|
615
616
|
return new CompletionDialog(options, makeAttrs(id, selected), {
|
|
616
617
|
pos: active.reduce((a, b) => b.hasResult() ? Math.min(a, b.from) : a, 1e8),
|
|
@@ -671,13 +672,12 @@ function sameResults(a, b) {
|
|
|
671
672
|
}
|
|
672
673
|
}
|
|
673
674
|
const baseAttrs = {
|
|
674
|
-
"aria-autocomplete": "list"
|
|
675
|
-
"aria-expanded": "false"
|
|
675
|
+
"aria-autocomplete": "list"
|
|
676
676
|
};
|
|
677
677
|
function makeAttrs(id, selected) {
|
|
678
678
|
return {
|
|
679
679
|
"aria-autocomplete": "list",
|
|
680
|
-
"aria-
|
|
680
|
+
"aria-haspopup": "listbox",
|
|
681
681
|
"aria-activedescendant": id + "-" + selected,
|
|
682
682
|
"aria-controls": id
|
|
683
683
|
};
|
|
@@ -741,7 +741,9 @@ class ActiveResult extends ActiveSource {
|
|
|
741
741
|
handleUserEvent(tr, type, conf) {
|
|
742
742
|
let from = tr.changes.mapPos(this.from), to = tr.changes.mapPos(this.to, 1);
|
|
743
743
|
let pos = cur(tr.state);
|
|
744
|
-
if ((this.explicitPos
|
|
744
|
+
if ((this.explicitPos < 0 ? pos <= from : pos < this.from) ||
|
|
745
|
+
pos > to ||
|
|
746
|
+
type == "delete" && cur(tr.startState) == this.from)
|
|
745
747
|
return new ActiveSource(this.source, type == "input" && conf.activateOnTyping ? 1 /* Pending */ : 0 /* Inactive */);
|
|
746
748
|
let explicitPos = this.explicitPos < 0 ? -1 : tr.changes.mapPos(this.explicitPos);
|
|
747
749
|
if (this.span && (from == to || this.span.test(tr.state.sliceDoc(from, to))))
|
|
@@ -781,9 +783,10 @@ function moveCompletionSelection(forward, by = "option") {
|
|
|
781
783
|
let cState = view.state.field(completionState, false);
|
|
782
784
|
if (!cState || !cState.open || Date.now() - cState.open.timestamp < CompletionInteractMargin)
|
|
783
785
|
return false;
|
|
784
|
-
let step = 1, tooltip;
|
|
785
|
-
if (by == "page" && (tooltip = view.
|
|
786
|
-
step = Math.max(2, Math.floor(tooltip.offsetHeight /
|
|
786
|
+
let step = 1, tooltip$1;
|
|
787
|
+
if (by == "page" && (tooltip$1 = tooltip.getTooltip(view, cState.open.tooltip)))
|
|
788
|
+
step = Math.max(2, Math.floor(tooltip$1.dom.offsetHeight /
|
|
789
|
+
tooltip$1.dom.querySelector("li").offsetHeight) - 1);
|
|
787
790
|
let selected = cState.open.selected + step * (forward ? 1 : -1), { length } = cState.open.options;
|
|
788
791
|
if (selected < 0)
|
|
789
792
|
selected = by == "page" ? 0 : length - 1;
|
|
@@ -856,7 +859,7 @@ const completionPlugin = view.ViewPlugin.fromClass(class {
|
|
|
856
859
|
for (let i = 0; i < this.running.length; i++) {
|
|
857
860
|
let query = this.running[i];
|
|
858
861
|
if (doesReset ||
|
|
859
|
-
query.updates.length + update.transactions.length > MaxUpdateCount &&
|
|
862
|
+
query.updates.length + update.transactions.length > MaxUpdateCount && Date.now() - query.time > MinAbortTime) {
|
|
860
863
|
for (let handler of query.context.abortListeners) {
|
|
861
864
|
try {
|
|
862
865
|
handler();
|
|
@@ -1092,7 +1095,9 @@ class FieldRange {
|
|
|
1092
1095
|
this.to = to;
|
|
1093
1096
|
}
|
|
1094
1097
|
map(changes) {
|
|
1095
|
-
|
|
1098
|
+
let from = changes.mapPos(this.from, -1, state.MapMode.TrackDel);
|
|
1099
|
+
let to = changes.mapPos(this.to, 1, state.MapMode.TrackDel);
|
|
1100
|
+
return from == null || to == null ? null : new FieldRange(this.field, from, to);
|
|
1096
1101
|
}
|
|
1097
1102
|
}
|
|
1098
1103
|
class Snippet {
|
|
@@ -1161,7 +1166,14 @@ class ActiveSnippet {
|
|
|
1161
1166
|
this.deco = view.Decoration.set(ranges.map(r => (r.from == r.to ? fieldMarker : fieldRange).range(r.from, r.to)));
|
|
1162
1167
|
}
|
|
1163
1168
|
map(changes) {
|
|
1164
|
-
|
|
1169
|
+
let ranges = [];
|
|
1170
|
+
for (let r of this.ranges) {
|
|
1171
|
+
let mapped = r.map(changes);
|
|
1172
|
+
if (!mapped)
|
|
1173
|
+
return null;
|
|
1174
|
+
ranges.push(mapped);
|
|
1175
|
+
}
|
|
1176
|
+
return new ActiveSnippet(ranges, this.active);
|
|
1165
1177
|
}
|
|
1166
1178
|
selectionInsideField(sel) {
|
|
1167
1179
|
return sel.ranges.every(range => this.ranges.some(r => r.field == this.active && r.from <= range.from && r.to >= range.to));
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Annotation, Facet, combineConfig, StateEffect, StateField, Prec, EditorSelection, Text } from '@codemirror/state';
|
|
1
|
+
import { Annotation, Facet, combineConfig, StateEffect, StateField, Prec, EditorSelection, Text, MapMode } from '@codemirror/state';
|
|
2
2
|
import { Direction, logException, EditorView, ViewPlugin, Decoration, WidgetType, keymap } from '@codemirror/view';
|
|
3
|
-
import { showTooltip } from '@codemirror/tooltip';
|
|
3
|
+
import { showTooltip, getTooltip } from '@codemirror/tooltip';
|
|
4
4
|
import { syntaxTree, indentUnit } from '@codemirror/language';
|
|
5
5
|
import { codePointAt, codePointSize, fromCodePoint } from '@codemirror/text';
|
|
6
6
|
|
|
@@ -510,6 +510,7 @@ class CompletionTooltip {
|
|
|
510
510
|
const ul = document.createElement("ul");
|
|
511
511
|
ul.id = id;
|
|
512
512
|
ul.setAttribute("role", "listbox");
|
|
513
|
+
ul.setAttribute("aria-expanded", "true");
|
|
513
514
|
for (let i = range.from; i < range.to; i++) {
|
|
514
515
|
let { completion, match } = options[i];
|
|
515
516
|
const li = ul.appendChild(document.createElement("li"));
|
|
@@ -570,7 +571,6 @@ function sortOptions(active, state) {
|
|
|
570
571
|
}
|
|
571
572
|
}
|
|
572
573
|
}
|
|
573
|
-
options.sort(cmpOption);
|
|
574
574
|
let result = [], prev = null;
|
|
575
575
|
for (let opt of options.sort(cmpOption)) {
|
|
576
576
|
if (result.length == MaxOptions)
|
|
@@ -603,10 +603,11 @@ class CompletionDialog {
|
|
|
603
603
|
let selected = 0;
|
|
604
604
|
if (prev && prev.selected) {
|
|
605
605
|
let selectedValue = prev.options[prev.selected].completion;
|
|
606
|
-
for (let i = 0; i < options.length
|
|
607
|
-
if (options[i].completion == selectedValue)
|
|
606
|
+
for (let i = 0; i < options.length; i++)
|
|
607
|
+
if (options[i].completion == selectedValue) {
|
|
608
608
|
selected = i;
|
|
609
|
-
|
|
609
|
+
break;
|
|
610
|
+
}
|
|
610
611
|
}
|
|
611
612
|
return new CompletionDialog(options, makeAttrs(id, selected), {
|
|
612
613
|
pos: active.reduce((a, b) => b.hasResult() ? Math.min(a, b.from) : a, 1e8),
|
|
@@ -667,13 +668,12 @@ function sameResults(a, b) {
|
|
|
667
668
|
}
|
|
668
669
|
}
|
|
669
670
|
const baseAttrs = {
|
|
670
|
-
"aria-autocomplete": "list"
|
|
671
|
-
"aria-expanded": "false"
|
|
671
|
+
"aria-autocomplete": "list"
|
|
672
672
|
};
|
|
673
673
|
function makeAttrs(id, selected) {
|
|
674
674
|
return {
|
|
675
675
|
"aria-autocomplete": "list",
|
|
676
|
-
"aria-
|
|
676
|
+
"aria-haspopup": "listbox",
|
|
677
677
|
"aria-activedescendant": id + "-" + selected,
|
|
678
678
|
"aria-controls": id
|
|
679
679
|
};
|
|
@@ -737,7 +737,9 @@ class ActiveResult extends ActiveSource {
|
|
|
737
737
|
handleUserEvent(tr, type, conf) {
|
|
738
738
|
let from = tr.changes.mapPos(this.from), to = tr.changes.mapPos(this.to, 1);
|
|
739
739
|
let pos = cur(tr.state);
|
|
740
|
-
if ((this.explicitPos
|
|
740
|
+
if ((this.explicitPos < 0 ? pos <= from : pos < this.from) ||
|
|
741
|
+
pos > to ||
|
|
742
|
+
type == "delete" && cur(tr.startState) == this.from)
|
|
741
743
|
return new ActiveSource(this.source, type == "input" && conf.activateOnTyping ? 1 /* Pending */ : 0 /* Inactive */);
|
|
742
744
|
let explicitPos = this.explicitPos < 0 ? -1 : tr.changes.mapPos(this.explicitPos);
|
|
743
745
|
if (this.span && (from == to || this.span.test(tr.state.sliceDoc(from, to))))
|
|
@@ -778,8 +780,9 @@ function moveCompletionSelection(forward, by = "option") {
|
|
|
778
780
|
if (!cState || !cState.open || Date.now() - cState.open.timestamp < CompletionInteractMargin)
|
|
779
781
|
return false;
|
|
780
782
|
let step = 1, tooltip;
|
|
781
|
-
if (by == "page" && (tooltip = view.
|
|
782
|
-
step = Math.max(2, Math.floor(tooltip.offsetHeight /
|
|
783
|
+
if (by == "page" && (tooltip = getTooltip(view, cState.open.tooltip)))
|
|
784
|
+
step = Math.max(2, Math.floor(tooltip.dom.offsetHeight /
|
|
785
|
+
tooltip.dom.querySelector("li").offsetHeight) - 1);
|
|
783
786
|
let selected = cState.open.selected + step * (forward ? 1 : -1), { length } = cState.open.options;
|
|
784
787
|
if (selected < 0)
|
|
785
788
|
selected = by == "page" ? 0 : length - 1;
|
|
@@ -852,7 +855,7 @@ const completionPlugin = /*@__PURE__*/ViewPlugin.fromClass(class {
|
|
|
852
855
|
for (let i = 0; i < this.running.length; i++) {
|
|
853
856
|
let query = this.running[i];
|
|
854
857
|
if (doesReset ||
|
|
855
|
-
query.updates.length + update.transactions.length > MaxUpdateCount &&
|
|
858
|
+
query.updates.length + update.transactions.length > MaxUpdateCount && Date.now() - query.time > MinAbortTime) {
|
|
856
859
|
for (let handler of query.context.abortListeners) {
|
|
857
860
|
try {
|
|
858
861
|
handler();
|
|
@@ -1088,7 +1091,9 @@ class FieldRange {
|
|
|
1088
1091
|
this.to = to;
|
|
1089
1092
|
}
|
|
1090
1093
|
map(changes) {
|
|
1091
|
-
|
|
1094
|
+
let from = changes.mapPos(this.from, -1, MapMode.TrackDel);
|
|
1095
|
+
let to = changes.mapPos(this.to, 1, MapMode.TrackDel);
|
|
1096
|
+
return from == null || to == null ? null : new FieldRange(this.field, from, to);
|
|
1092
1097
|
}
|
|
1093
1098
|
}
|
|
1094
1099
|
class Snippet {
|
|
@@ -1157,7 +1162,14 @@ class ActiveSnippet {
|
|
|
1157
1162
|
this.deco = Decoration.set(ranges.map(r => (r.from == r.to ? fieldMarker : fieldRange).range(r.from, r.to)));
|
|
1158
1163
|
}
|
|
1159
1164
|
map(changes) {
|
|
1160
|
-
|
|
1165
|
+
let ranges = [];
|
|
1166
|
+
for (let r of this.ranges) {
|
|
1167
|
+
let mapped = r.map(changes);
|
|
1168
|
+
if (!mapped)
|
|
1169
|
+
return null;
|
|
1170
|
+
ranges.push(mapped);
|
|
1171
|
+
}
|
|
1172
|
+
return new ActiveSnippet(ranges, this.active);
|
|
1161
1173
|
}
|
|
1162
1174
|
selectionInsideField(sel) {
|
|
1163
1175
|
return sel.ranges.every(range => this.ranges.some(r => r.field == this.active && r.from <= range.from && r.to >= range.to));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codemirror/autocomplete",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.14",
|
|
4
4
|
"description": "Autocompletion for the CodeMirror code editor",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "cm-runtests",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"@codemirror/language": "^0.19.0",
|
|
30
30
|
"@codemirror/state": "^0.19.4",
|
|
31
31
|
"@codemirror/text": "^0.19.2",
|
|
32
|
-
"@codemirror/tooltip": "^0.19.
|
|
32
|
+
"@codemirror/tooltip": "^0.19.12",
|
|
33
33
|
"@codemirror/view": "^0.19.0",
|
|
34
34
|
"@lezer/common": "^0.15.0"
|
|
35
35
|
},
|