1
0
Fork 0
mirror of https://github.com/DanielnetoDotCom/YouPHPTube synced 2025-10-05 02:39:46 +02:00

Update npm

This commit is contained in:
Daniel Neto 2024-04-03 15:54:35 -03:00
parent 8341712d58
commit 1bd85100b9
5320 changed files with 58396 additions and 344722 deletions

View file

@ -1,7 +1,5 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var state = require('@codemirror/state');
var view = require('@codemirror/view');
var language = require('@codemirror/language');
@ -175,7 +173,7 @@ function insertCompletionText(state$1, text, from, to) {
changes: { from: range.from + fromOff, to: to == main.from ? range.to : range.from + toOff, insert: text },
range: state.EditorSelection.cursor(range.from + fromOff + text.length)
};
})), { userEvent: "input.complete" });
})), { scrollIntoView: true, userEvent: "input.complete" });
}
const SourceCache = new WeakMap();
function asSource(source) {
@ -216,7 +214,7 @@ class FuzzyMatcher {
ret(score, matched) {
this.score = score;
this.matched = matched;
return true;
return this;
}
// Matches a given word (completion) against the pattern (input).
// Will return a boolean indicating whether there was a match and,
@ -227,25 +225,25 @@ class FuzzyMatcher {
// is. See `Penalty` above.
match(word) {
if (this.pattern.length == 0)
return this.ret(-100 /* NotFull */, []);
return this.ret(-100 /* Penalty.NotFull */, []);
if (word.length < this.pattern.length)
return false;
return null;
let { chars, folded, any, precise, byWord } = this;
// For single-character queries, only match when they occur right
// at the start
if (chars.length == 1) {
let first = state.codePointAt(word, 0), firstSize = state.codePointSize(first);
let score = firstSize == word.length ? 0 : -100 /* NotFull */;
let score = firstSize == word.length ? 0 : -100 /* Penalty.NotFull */;
if (first == chars[0]) ;
else if (first == folded[0])
score += -200 /* CaseFold */;
score += -200 /* Penalty.CaseFold */;
else
return false;
return null;
return this.ret(score, [0, firstSize]);
}
let direct = word.indexOf(this.pattern);
if (direct == 0)
return this.ret(word.length == this.pattern.length ? 0 : -100 /* NotFull */, [0, this.pattern.length]);
return this.ret(word.length == this.pattern.length ? 0 : -100 /* Penalty.NotFull */, [0, this.pattern.length]);
let len = chars.length, anyTo = 0;
if (direct < 0) {
for (let i = 0, e = Math.min(word.length, 200); i < e && anyTo < len;) {
@ -256,7 +254,7 @@ class FuzzyMatcher {
}
// No match, exit immediately
if (anyTo < len)
return false;
return null;
}
// This tracks the extent of the precise (non-folded, not
// necessarily adjacent) match
@ -269,7 +267,7 @@ class FuzzyMatcher {
let adjacentTo = 0, adjacentStart = -1, adjacentEnd = -1;
let hasLower = /[a-z]/.test(word), wordAdjacent = true;
// Go over the option's text, scanning for the various kinds of matches
for (let i = 0, e = Math.min(word.length, 200), prevType = 0 /* NonWord */; i < e && byWordTo < len;) {
for (let i = 0, e = Math.min(word.length, 200), prevType = 0 /* Tp.NonWord */; i < e && byWordTo < len;) {
let next = state.codePointAt(word, i);
if (direct < 0) {
if (preciseTo < len && next == chars[preciseTo])
@ -287,9 +285,9 @@ class FuzzyMatcher {
}
}
let ch, type = next < 0xff
? (next >= 48 && next <= 57 || next >= 97 && next <= 122 ? 2 /* Lower */ : next >= 65 && next <= 90 ? 1 /* Upper */ : 0 /* NonWord */)
: ((ch = state.fromCodePoint(next)) != ch.toLowerCase() ? 1 /* Upper */ : ch != ch.toUpperCase() ? 2 /* Lower */ : 0 /* NonWord */);
if (!i || type == 1 /* Upper */ && hasLower || prevType == 0 /* NonWord */ && type != 0 /* NonWord */) {
? (next >= 48 && next <= 57 || next >= 97 && next <= 122 ? 2 /* Tp.Lower */ : next >= 65 && next <= 90 ? 1 /* Tp.Upper */ : 0 /* Tp.NonWord */)
: ((ch = state.fromCodePoint(next)) != ch.toLowerCase() ? 1 /* Tp.Upper */ : ch != ch.toUpperCase() ? 2 /* Tp.Lower */ : 0 /* Tp.NonWord */);
if (!i || type == 1 /* Tp.Upper */ && hasLower || prevType == 0 /* Tp.NonWord */ && type != 0 /* Tp.NonWord */) {
if (chars[byWordTo] == next || (folded[byWordTo] == next && (byWordFolded = true)))
byWord[byWordTo++] = i;
else if (byWord.length)
@ -299,18 +297,18 @@ class FuzzyMatcher {
i += state.codePointSize(next);
}
if (byWordTo == len && byWord[0] == 0 && wordAdjacent)
return this.result(-100 /* ByWord */ + (byWordFolded ? -200 /* CaseFold */ : 0), byWord, word);
return this.result(-100 /* Penalty.ByWord */ + (byWordFolded ? -200 /* Penalty.CaseFold */ : 0), byWord, word);
if (adjacentTo == len && adjacentStart == 0)
return this.ret(-200 /* CaseFold */ - word.length + (adjacentEnd == word.length ? 0 : -100 /* NotFull */), [0, adjacentEnd]);
return this.ret(-200 /* Penalty.CaseFold */ - word.length + (adjacentEnd == word.length ? 0 : -100 /* Penalty.NotFull */), [0, adjacentEnd]);
if (direct > -1)
return this.ret(-700 /* NotStart */ - word.length, [direct, direct + this.pattern.length]);
return this.ret(-700 /* Penalty.NotStart */ - word.length, [direct, direct + this.pattern.length]);
if (adjacentTo == len)
return this.ret(-200 /* CaseFold */ + -700 /* NotStart */ - word.length, [adjacentStart, adjacentEnd]);
return this.ret(-200 /* Penalty.CaseFold */ + -700 /* Penalty.NotStart */ - word.length, [adjacentStart, adjacentEnd]);
if (byWordTo == len)
return this.result(-100 /* ByWord */ + (byWordFolded ? -200 /* CaseFold */ : 0) + -700 /* NotStart */ +
(wordAdjacent ? 0 : -1100 /* Gap */), byWord, word);
return chars.length == 2 ? false
: this.result((any[0] ? -700 /* NotStart */ : 0) + -200 /* CaseFold */ + -1100 /* Gap */, any, word);
return this.result(-100 /* Penalty.ByWord */ + (byWordFolded ? -200 /* Penalty.CaseFold */ : 0) + -700 /* Penalty.NotStart */ +
(wordAdjacent ? 0 : -1100 /* Penalty.Gap */), byWord, word);
return chars.length == 2 ? null
: this.result((any[0] ? -700 /* Penalty.NotStart */ : 0) + -200 /* Penalty.CaseFold */ + -1100 /* Penalty.Gap */, any, word);
}
result(score, positions, word) {
let result = [], i = 0;
@ -326,11 +324,31 @@ class FuzzyMatcher {
return this.ret(score - word.length, result);
}
}
class StrictMatcher {
constructor(pattern) {
this.pattern = pattern;
this.matched = [];
this.score = 0;
this.folded = pattern.toLowerCase();
}
match(word) {
if (word.length < this.pattern.length)
return null;
let start = word.slice(0, this.pattern.length);
let match = start == this.pattern ? 0 : start.toLowerCase() == this.folded ? -200 /* Penalty.CaseFold */ : null;
if (match == null)
return null;
this.matched = [0, start.length];
this.score = match + (word.length == this.pattern.length ? 0 : -100 /* Penalty.NotFull */);
return this;
}
}
const completionConfig = state.Facet.define({
combine(configs) {
return state.combineConfig(configs, {
activateOnTyping: true,
activateOnTypingDelay: 100,
selectOnOpen: true,
override: null,
closeOnBlur: true,
@ -342,22 +360,25 @@ const completionConfig = state.Facet.define({
icons: true,
addToOptions: [],
positionInfo: defaultPositionInfo,
filterStrict: false,
compareCompletions: (a, b) => a.label.localeCompare(b.label),
interactionDelay: 75
interactionDelay: 75,
updateSyncTime: 100
}, {
defaultKeymap: (a, b) => a && b,
closeOnBlur: (a, b) => a && b,
icons: (a, b) => a && b,
tooltipClass: (a, b) => c => joinClass(a(c), b(c)),
optionClass: (a, b) => c => joinClass(a(c), b(c)),
addToOptions: (a, b) => a.concat(b)
addToOptions: (a, b) => a.concat(b),
filterStrict: (a, b) => a || b,
});
}
});
function joinClass(a, b) {
return a ? b ? a + " " + b : a : b;
}
function defaultPositionInfo(view$1, list, option, info, space) {
function defaultPositionInfo(view$1, list, option, info, space, tooltip) {
let rtl = view$1.textDirection == view.Direction.RTL, left = rtl, narrow = false;
let side = "top", offset, maxWidth;
let spaceLeft = list.left - space.left, spaceRight = space.right - list.right;
@ -368,11 +389,11 @@ function defaultPositionInfo(view$1, list, option, info, space) {
left = true;
if (infoWidth <= (left ? spaceLeft : spaceRight)) {
offset = Math.max(space.top, Math.min(option.top, space.bottom - infoHeight)) - list.top;
maxWidth = Math.min(400 /* Width */, left ? spaceLeft : spaceRight);
maxWidth = Math.min(400 /* Info.Width */, left ? spaceLeft : spaceRight);
}
else {
narrow = true;
maxWidth = Math.min(400 /* Width */, (rtl ? list.right : space.right - list.left) - 30 /* Margin */);
maxWidth = Math.min(400 /* Info.Width */, (rtl ? list.right : space.right - list.left) - 30 /* Info.Margin */);
let spaceBelow = space.bottom - list.bottom;
if (spaceBelow >= infoHeight || spaceBelow > list.top) { // Below the completion
offset = option.bottom - list.top;
@ -382,8 +403,10 @@ function defaultPositionInfo(view$1, list, option, info, space) {
offset = list.bottom - option.top;
}
}
let scaleY = (list.bottom - list.top) / tooltip.offsetHeight;
let scaleX = (list.right - list.left) / tooltip.offsetWidth;
return {
style: `${side}: ${offset}px; max-width: ${maxWidth}px`,
style: `${side}: ${offset / scaleY}px; max-width: ${maxWidth / scaleX}px`,
class: "cm-completionInfo-" + (narrow ? (rtl ? "left-narrow" : "right-narrow") : left ? "left" : "right")
};
}
@ -403,7 +426,7 @@ function optionContent(config) {
position: 20
});
content.push({
render(completion, _s, match) {
render(completion, _s, _v, match) {
let labelElt = document.createElement("span");
labelElt.className = "cm-completionLabel";
let label = completion.displayLabel || completion.label, off = 0;
@ -471,6 +494,7 @@ class CompletionTooltip {
this.dom.className = "cm-tooltip-autocomplete";
this.updateTooltipClass(view.state);
this.dom.addEventListener("mousedown", (e) => {
let { options } = view.state.field(stateField).open;
for (let dom = e.target, match; dom && dom != this.dom; dom = dom.parentNode) {
if (dom.nodeName == "LI" && (match = /-(\d+)$/.exec(dom.id)) && +match[1] < options.length) {
this.applyCompletion(view, options[+match[1]]);
@ -485,22 +509,32 @@ class CompletionTooltip {
e.relatedTarget != view.contentDOM)
view.dispatch({ effects: closeCompletionEffect.of(null) });
});
this.list = this.dom.appendChild(this.createListBox(options, cState.id, this.range));
this.showOptions(options, cState.id);
}
mount() { this.updateSel(); }
showOptions(options, id) {
if (this.list)
this.list.remove();
this.list = this.dom.appendChild(this.createListBox(options, id, this.range));
this.list.addEventListener("scroll", () => {
if (this.info)
this.view.requestMeasure(this.placeInfoReq);
});
}
mount() { this.updateSel(); }
update(update) {
var _a, _b, _c;
var _a;
let cState = update.state.field(this.stateField);
let prevState = update.startState.field(this.stateField);
this.updateTooltipClass(update.state);
if (cState != prevState) {
let { options, selected, disabled } = cState.open;
if (!prevState.open || prevState.open.options != options) {
this.range = rangeAroundSelected(options.length, selected, update.state.facet(completionConfig).maxRenderedOptions);
this.showOptions(options, cState.id);
}
this.updateSel();
if (((_a = cState.open) === null || _a === void 0 ? void 0 : _a.disabled) != ((_b = prevState.open) === null || _b === void 0 ? void 0 : _b.disabled))
this.dom.classList.toggle("cm-tooltip-autocomplete-disabled", !!((_c = cState.open) === null || _c === void 0 ? void 0 : _c.disabled));
if (disabled != ((_a = prevState.open) === null || _a === void 0 ? void 0 : _a.disabled))
this.dom.classList.toggle("cm-tooltip-autocomplete-disabled", !!disabled);
}
}
updateTooltipClass(state) {
@ -524,12 +558,7 @@ class CompletionTooltip {
let cState = this.view.state.field(this.stateField), open = cState.open;
if (open.selected > -1 && open.selected < this.range.from || open.selected >= this.range.to) {
this.range = rangeAroundSelected(open.options.length, open.selected, this.view.state.facet(completionConfig).maxRenderedOptions);
this.list.remove();
this.list = this.dom.appendChild(this.createListBox(open.options, cState.id, this.range));
this.list.addEventListener("scroll", () => {
if (this.info)
this.view.requestMeasure(this.placeInfoReq);
});
this.showOptions(open.options, cState.id);
}
if (this.updateSelectedOption(open.selected)) {
this.destroyInfo();
@ -603,7 +632,7 @@ class CompletionTooltip {
if (selRect.top > Math.min(space.bottom, listRect.bottom) - 10 ||
selRect.bottom < Math.max(space.top, listRect.top) + 10)
return null;
return this.view.state.facet(completionConfig).positionInfo(this.view, listRect, selRect, infoRect, space);
return this.view.state.facet(completionConfig).positionInfo(this.view, listRect, selRect, infoRect, space, this.dom);
}
placeInfo(pos) {
if (this.info) {
@ -646,7 +675,7 @@ class CompletionTooltip {
if (cls)
li.className = cls;
for (let source of this.optionContent) {
let node = source(completion, this.view.state, match);
let node = source(completion, this.view.state, this.view, match);
if (node)
li.appendChild(node);
}
@ -669,18 +698,17 @@ class CompletionTooltip {
this.destroyInfo();
}
}
// We allocate a new function instance every time the completion
// changes to force redrawing/repositioning of the tooltip
function completionTooltip(stateField, applyCompletion) {
return (view) => new CompletionTooltip(view, stateField, applyCompletion);
}
function scrollIntoView(container, element) {
let parent = container.getBoundingClientRect();
let self = element.getBoundingClientRect();
let scaleY = parent.height / container.offsetHeight;
if (self.top < parent.top)
container.scrollTop -= parent.top - self.top;
container.scrollTop -= (parent.top - self.top) / scaleY;
else if (self.bottom > parent.bottom)
container.scrollTop += self.bottom - parent.bottom;
container.scrollTop += (self.bottom - parent.bottom) / scaleY;
}
// Used to pick a preferred option when two options with the same
@ -703,6 +731,7 @@ function sortOptions(active, state) {
sections.push(typeof section == "string" ? { name } : section);
}
};
let conf = state.facet(completionConfig);
for (let a of active)
if (a.hasResult()) {
let getMatch = a.result.getMatch;
@ -712,11 +741,12 @@ function sortOptions(active, state) {
}
}
else {
let matcher = new FuzzyMatcher(state.sliceDoc(a.from, a.to));
let pattern = state.sliceDoc(a.from, a.to), match;
let matcher = conf.filterStrict ? new StrictMatcher(pattern) : new FuzzyMatcher(pattern);
for (let option of a.result.options)
if (matcher.match(option.label)) {
let matched = !option.displayLabel ? matcher.matched : getMatch ? getMatch(option, matcher.matched) : [];
addOption(new Option(option, a.source, matched, matcher.score + (option.boost || 0)));
if (match = matcher.match(option.label)) {
let matched = !option.displayLabel ? match.matched : getMatch ? getMatch(option, match.matched) : [];
addOption(new Option(option, a.source, matched, match.score + (option.boost || 0)));
}
}
}
@ -734,7 +764,7 @@ function sortOptions(active, state) {
}
}
let result = [], prev = null;
let compare = state.facet(completionConfig).compareCompletions;
let compare = conf.compareCompletions;
for (let opt of options.sort((a, b) => (b.score - a.score) || compare(a.completion, b.completion))) {
let cur = opt.completion;
if (!prev || prev.label != cur.label || prev.detail != cur.detail ||
@ -763,7 +793,7 @@ class CompletionDialog {
static build(active, state, id, prev, conf) {
let options = sortOptions(active, state);
if (!options.length) {
return prev && active.some(a => a.state == 1 /* Pending */) ?
return prev && active.some(a => a.state == 1 /* State.Pending */) ?
new CompletionDialog(prev.options, prev.attrs, prev.tooltip, prev.timestamp, prev.selected, true) : null;
}
let selected = state.facet(completionConfig).selectOnOpen ? 0 : -1;
@ -777,7 +807,7 @@ class CompletionDialog {
}
return new CompletionDialog(options, makeAttrs(id, selected), {
pos: active.reduce((a, b) => b.hasResult() ? Math.min(a, b.from) : a, 1e8),
create: completionTooltip(completionState, applyCompletion),
create: createTooltip,
above: conf.aboveCursor,
}, prev ? prev.timestamp : Date.now(), selected, false);
}
@ -800,7 +830,7 @@ class CompletionState {
state.languageDataAt("autocomplete", cur(state)).map(asSource);
let active = sources.map(source => {
let value = this.active.find(s => s.source == source) ||
new ActiveSource(source, this.active.some(a => a.state != 0 /* Inactive */) ? 1 /* Pending */ : 0 /* Inactive */);
new ActiveSource(source, this.active.some(a => a.state != 0 /* State.Inactive */) ? 1 /* State.Pending */ : 0 /* State.Inactive */);
return value.update(tr, conf);
});
if (active.length == this.active.length && active.every((a, i) => a == this.active[i]))
@ -811,10 +841,10 @@ class CompletionState {
if (tr.selection || active.some(a => a.hasResult() && tr.changes.touchesRange(a.from, a.to)) ||
!sameResults(active, this.active))
open = CompletionDialog.build(active, state, this.id, open, conf);
else if (open && open.disabled && !active.some(a => a.state == 1 /* Pending */))
else if (open && open.disabled && !active.some(a => a.state == 1 /* State.Pending */))
open = null;
if (!open && active.every(a => a.state != 1 /* Pending */) && active.some(a => a.hasResult()))
active = active.map(a => a.hasResult() ? new ActiveSource(a.source, 0 /* Inactive */) : a);
if (!open && active.every(a => a.state != 1 /* State.Pending */) && active.some(a => a.hasResult()))
active = active.map(a => a.hasResult() ? new ActiveSource(a.source, 0 /* State.Inactive */) : a);
for (let effect of tr.effects)
if (effect.is(setSelectedEffect))
open = open && open.setSelected(effect.value, this.id);
@ -868,13 +898,13 @@ class ActiveSource {
value = value.handleUserEvent(tr, event, conf);
else if (tr.docChanged)
value = value.handleChange(tr);
else if (tr.selection && value.state != 0 /* Inactive */)
value = new ActiveSource(value.source, 0 /* Inactive */);
else if (tr.selection && value.state != 0 /* State.Inactive */)
value = new ActiveSource(value.source, 0 /* State.Inactive */);
for (let effect of tr.effects) {
if (effect.is(startCompletionEffect))
value = new ActiveSource(value.source, 1 /* Pending */, effect.value ? cur(tr.state) : -1);
value = new ActiveSource(value.source, 1 /* State.Pending */, effect.value ? cur(tr.state) : -1);
else if (effect.is(closeCompletionEffect))
value = new ActiveSource(value.source, 0 /* Inactive */);
value = new ActiveSource(value.source, 0 /* State.Inactive */);
else if (effect.is(setActiveEffect))
for (let active of effect.value)
if (active.source == value.source)
@ -883,10 +913,10 @@ class ActiveSource {
return value;
}
handleUserEvent(tr, type, conf) {
return type == "delete" || !conf.activateOnTyping ? this.map(tr.changes) : new ActiveSource(this.source, 1 /* Pending */);
return type == "delete" || !conf.activateOnTyping ? this.map(tr.changes) : new ActiveSource(this.source, 1 /* State.Pending */);
}
handleChange(tr) {
return tr.changes.touchesRange(cur(tr.startState)) ? new ActiveSource(this.source, 0 /* Inactive */) : this.map(tr.changes);
return tr.changes.touchesRange(cur(tr.startState)) ? new ActiveSource(this.source, 0 /* State.Inactive */) : this.map(tr.changes);
}
map(changes) {
return changes.empty || this.explicitPos < 0 ? this : new ActiveSource(this.source, this.state, changes.mapPos(this.explicitPos));
@ -894,7 +924,7 @@ class ActiveSource {
}
class ActiveResult extends ActiveSource {
constructor(source, explicitPos, result, from, to) {
super(source, 2 /* Result */, explicitPos);
super(source, 2 /* State.Result */, explicitPos);
this.result = result;
this.from = from;
this.to = to;
@ -902,26 +932,33 @@ class ActiveResult extends ActiveSource {
hasResult() { return true; }
handleUserEvent(tr, type, conf) {
var _a;
let result = this.result;
if (result.map && !tr.changes.empty)
result = result.map(result, tr.changes);
let from = tr.changes.mapPos(this.from), to = tr.changes.mapPos(this.to, 1);
let pos = cur(tr.state);
if ((this.explicitPos < 0 ? pos <= from : pos < this.from) ||
pos > to ||
pos > to || !result ||
type == "delete" && cur(tr.startState) == this.from)
return new ActiveSource(this.source, type == "input" && conf.activateOnTyping ? 1 /* Pending */ : 0 /* Inactive */);
let explicitPos = this.explicitPos < 0 ? -1 : tr.changes.mapPos(this.explicitPos), updated;
if (checkValid(this.result.validFor, tr.state, from, to))
return new ActiveResult(this.source, explicitPos, this.result, from, to);
if (this.result.update &&
(updated = this.result.update(this.result, from, to, new CompletionContext(tr.state, pos, explicitPos >= 0))))
return new ActiveResult(this.source, explicitPos, updated, updated.from, (_a = updated.to) !== null && _a !== void 0 ? _a : cur(tr.state));
return new ActiveSource(this.source, 1 /* Pending */, explicitPos);
return new ActiveSource(this.source, type == "input" && conf.activateOnTyping ? 1 /* State.Pending */ : 0 /* State.Inactive */);
let explicitPos = this.explicitPos < 0 ? -1 : tr.changes.mapPos(this.explicitPos);
if (checkValid(result.validFor, tr.state, from, to))
return new ActiveResult(this.source, explicitPos, result, from, to);
if (result.update &&
(result = result.update(result, from, to, new CompletionContext(tr.state, pos, explicitPos >= 0))))
return new ActiveResult(this.source, explicitPos, result, result.from, (_a = result.to) !== null && _a !== void 0 ? _a : cur(tr.state));
return new ActiveSource(this.source, 1 /* State.Pending */, explicitPos);
}
handleChange(tr) {
return tr.changes.touchesRange(this.from, this.to) ? new ActiveSource(this.source, 0 /* Inactive */) : this.map(tr.changes);
return tr.changes.touchesRange(this.from, this.to) ? new ActiveSource(this.source, 0 /* State.Inactive */) : this.map(tr.changes);
}
map(mapping) {
return mapping.empty ? this :
new ActiveResult(this.source, this.explicitPos < 0 ? -1 : mapping.mapPos(this.explicitPos), this.result, mapping.mapPos(this.from), mapping.mapPos(this.to, 1));
if (mapping.empty)
return this;
let result = this.result.map ? this.result.map(this.result, mapping) : this.result;
if (!result)
return new ActiveSource(this.source, 0 /* State.Inactive */);
return new ActiveResult(this.source, this.explicitPos < 0 ? -1 : mapping.mapPos(this.explicitPos), this.result, mapping.mapPos(this.from), mapping.mapPos(this.to, 1));
}
}
function checkValid(validFor, state, from, to) {
@ -953,6 +990,7 @@ function applyCompletion(view, option) {
apply(view, option.completion, result.from, result.to);
return true;
}
const createTooltip = completionTooltip(completionState, applyCompletion);
/**
Returns a command that moves the completion selection forward or
@ -1003,7 +1041,7 @@ Close the currently active completion.
*/
const closeCompletion = (view) => {
let cState = view.state.field(completionState, false);
if (!cState || !cState.active.some(a => a.state != 0 /* Inactive */))
if (!cState || !cState.active.some(a => a.state != 0 /* State.Inactive */))
return false;
view.dispatch({ effects: closeCompletionEffect.of(null) });
return true;
@ -1019,16 +1057,17 @@ class RunningQuery {
this.done = undefined;
}
}
const DebounceTime = 50, MaxUpdateCount = 50, MinAbortTime = 1000;
const MaxUpdateCount = 50, MinAbortTime = 1000;
const completionPlugin = view.ViewPlugin.fromClass(class {
constructor(view) {
this.view = view;
this.debounceUpdate = -1;
this.running = [];
this.debounceAccept = -1;
this.composing = 0 /* None */;
this.pendingStart = false;
this.composing = 0 /* CompositionState.None */;
for (let active of view.state.field(completionState).active)
if (active.state == 1 /* Pending */)
if (active.state == 1 /* State.Pending */)
this.startQuery(active);
}
update(update) {
@ -1059,21 +1098,25 @@ const completionPlugin = view.ViewPlugin.fromClass(class {
}
if (this.debounceUpdate > -1)
clearTimeout(this.debounceUpdate);
this.debounceUpdate = cState.active.some(a => a.state == 1 /* Pending */ && !this.running.some(q => q.active.source == a.source))
? setTimeout(() => this.startUpdate(), DebounceTime) : -1;
if (this.composing != 0 /* None */)
if (update.transactions.some(tr => tr.effects.some(e => e.is(startCompletionEffect))))
this.pendingStart = true;
let delay = this.pendingStart ? 50 : update.state.facet(completionConfig).activateOnTypingDelay;
this.debounceUpdate = cState.active.some(a => a.state == 1 /* State.Pending */ && !this.running.some(q => q.active.source == a.source))
? setTimeout(() => this.startUpdate(), delay) : -1;
if (this.composing != 0 /* CompositionState.None */)
for (let tr of update.transactions) {
if (getUserEvent(tr) == "input")
this.composing = 2 /* Changed */;
else if (this.composing == 2 /* Changed */ && tr.selection)
this.composing = 3 /* ChangedAndMoved */;
this.composing = 2 /* CompositionState.Changed */;
else if (this.composing == 2 /* CompositionState.Changed */ && tr.selection)
this.composing = 3 /* CompositionState.ChangedAndMoved */;
}
}
startUpdate() {
this.debounceUpdate = -1;
this.pendingStart = false;
let { state } = this.view, cState = state.field(completionState);
for (let active of cState.active) {
if (active.state == 1 /* Pending */ && !this.running.some(r => r.active.source == active.source))
if (active.state == 1 /* State.Pending */ && !this.running.some(r => r.active.source == active.source))
this.startQuery(active);
}
}
@ -1096,7 +1139,7 @@ const completionPlugin = view.ViewPlugin.fromClass(class {
if (this.running.every(q => q.done !== undefined))
this.accept();
else if (this.debounceAccept < 0)
this.debounceAccept = setTimeout(() => this.accept(), DebounceTime);
this.debounceAccept = setTimeout(() => this.accept(), this.view.state.facet(completionConfig).updateSyncTime);
}
// For each finished query in this.running, try to create a result
// or, if appropriate, restart the query.
@ -1124,14 +1167,14 @@ const completionPlugin = view.ViewPlugin.fromClass(class {
}
}
let current = this.view.state.field(completionState).active.find(a => a.source == query.active.source);
if (current && current.state == 1 /* Pending */) {
if (current && current.state == 1 /* State.Pending */) {
if (query.done == null) {
// Explicitly failed. Should clear the pending status if it
// hasn't been re-set in the meantime.
let active = new ActiveSource(query.active.source, 0 /* Inactive */);
let active = new ActiveSource(query.active.source, 0 /* State.Inactive */);
for (let tr of query.updates)
active = active.update(tr, conf);
if (active.state != 1 /* Pending */)
if (active.state != 1 /* State.Pending */)
updated.push(active);
}
else {
@ -1150,22 +1193,37 @@ const completionPlugin = view.ViewPlugin.fromClass(class {
if (state && state.tooltip && this.view.state.facet(completionConfig).closeOnBlur) {
let dialog = state.open && view.getTooltip(this.view, state.open.tooltip);
if (!dialog || !dialog.dom.contains(event.relatedTarget))
this.view.dispatch({ effects: closeCompletionEffect.of(null) });
setTimeout(() => this.view.dispatch({ effects: closeCompletionEffect.of(null) }), 10);
}
},
compositionstart() {
this.composing = 1 /* Started */;
this.composing = 1 /* CompositionState.Started */;
},
compositionend() {
if (this.composing == 3 /* ChangedAndMoved */) {
if (this.composing == 3 /* CompositionState.ChangedAndMoved */) {
// Safari fires compositionend events synchronously, possibly
// from inside an update, so dispatch asynchronously to avoid reentrancy
setTimeout(() => this.view.dispatch({ effects: startCompletionEffect.of(false) }), 20);
}
this.composing = 0 /* None */;
this.composing = 0 /* CompositionState.None */;
}
}
});
const windows = typeof navigator == "object" && /Win/.test(navigator.platform);
const commitCharacters = state.Prec.highest(view.EditorView.domEventHandlers({
keydown(event, view) {
let field = view.state.field(completionState, false);
if (!field || !field.open || field.open.disabled || field.open.selected < 0 ||
event.key.length > 1 || event.ctrlKey && !(windows && event.altKey) || event.metaKey)
return false;
let option = field.open.options[field.open.selected];
let result = field.active.find(a => a.source == option.source);
let commitChars = option.completion.commitCharacters || result.result.commitCharacters;
if (commitChars && commitChars.indexOf(event.key) > -1)
applyCompletion(view, option);
return false;
}
}));
const baseTheme = view.EditorView.baseTheme({
".cm-tooltip.cm-tooltip-autocomplete": {
@ -1222,13 +1280,13 @@ const baseTheme = view.EditorView.baseTheme({
position: "absolute",
padding: "3px 9px",
width: "max-content",
maxWidth: `${400 /* Width */}px`,
maxWidth: `${400 /* Info.Width */}px`,
boxSizing: "border-box"
},
".cm-completionInfo.cm-completionInfo-left": { right: "100%" },
".cm-completionInfo.cm-completionInfo-right": { left: "100%" },
".cm-completionInfo.cm-completionInfo-left-narrow": { right: `${30 /* Margin */}px` },
".cm-completionInfo.cm-completionInfo-right-narrow": { left: `${30 /* Margin */}px` },
".cm-completionInfo.cm-completionInfo-left-narrow": { right: `${30 /* Info.Margin */}px` },
".cm-completionInfo.cm-completionInfo-right-narrow": { left: `${30 /* Info.Margin */}px` },
"&light .cm-snippetField": { backgroundColor: "#00000022" },
"&dark .cm-snippetField": { backgroundColor: "#ffffff22" },
".cm-snippetFieldPosition": {
@ -1458,11 +1516,11 @@ function snippet(template) {
let spec = {
changes: { from, to, insert: state.Text.of(text) },
scrollIntoView: true,
annotations: completion ? pickedCompletion.of(completion) : undefined
annotations: completion ? [pickedCompletion.of(completion), state.Transaction.userEvent.of("input.complete")] : undefined
};
if (ranges.length)
spec.selection = fieldSelection(ranges, 0);
if (ranges.length > 1) {
if (ranges.some(r => r.field > 0)) {
let active = new ActiveSnippet(ranges, 0);
let effects = spec.effects = [setActive.of(active)];
if (editor.state.field(snippetState, false) === undefined)
@ -1479,7 +1537,8 @@ function moveField(dir) {
let next = active.active + dir, last = dir > 0 && !active.ranges.some(r => r.field == next + dir);
dispatch(state.update({
selection: fieldSelection(active.ranges, next),
effects: setActive.of(last ? null : new ActiveSnippet(active.ranges, next))
effects: setActive.of(last ? null : new ActiveSnippet(active.ranges, next)),
scrollIntoView: true
}));
return true;
};
@ -1551,14 +1610,16 @@ const snippetPointerHandler = view.EditorView.domEventHandlers({
return false;
view.dispatch({
selection: fieldSelection(active.ranges, match.field),
effects: setActive.of(active.ranges.some(r => r.field > match.field) ? new ActiveSnippet(active.ranges, match.field) : null)
effects: setActive.of(active.ranges.some(r => r.field > match.field)
? new ActiveSnippet(active.ranges, match.field) : null),
scrollIntoView: true
});
return true;
}
});
function wordRE(wordChars) {
let escaped = wordChars.replace(/[\\[.+*?(){|^$]/g, "\\$&");
let escaped = wordChars.replace(/[\]\-\\]/g, "\\$&");
try {
return new RegExp(`[\\p{Alphabetic}\\p{Number}_${escaped}]+`, "ug");
}
@ -1581,7 +1642,7 @@ function storeWords(doc, wordRE, result, seen, ignoreAt) {
if (!seen[m[0]] && pos + m.index != ignoreAt) {
result.push({ type: "text", label: m[0] });
seen[m[0]] = true;
if (result.length >= 2000 /* MaxList */)
if (result.length >= 2000 /* C.MaxList */)
return;
}
}
@ -1589,7 +1650,7 @@ function storeWords(doc, wordRE, result, seen, ignoreAt) {
}
}
function collectWords(doc, cache, wordRE, to, ignoreAt) {
let big = doc.length >= 1000 /* MinCacheLen */;
let big = doc.length >= 1000 /* C.MinCacheLen */;
let cached = big && cache.get(doc);
if (cached)
return cached;
@ -1597,7 +1658,7 @@ function collectWords(doc, cache, wordRE, to, ignoreAt) {
if (doc.children) {
let pos = 0;
for (let ch of doc.children) {
if (ch.length >= 1000 /* MinCacheLen */) {
if (ch.length >= 1000 /* C.MinCacheLen */) {
for (let c of collectWords(ch, cache, wordRE, to - pos, ignoreAt - pos)) {
if (!seen[c.label]) {
seen[c.label] = true;
@ -1614,7 +1675,7 @@ function collectWords(doc, cache, wordRE, to, ignoreAt) {
else {
storeWords(doc, wordRE, result, seen, ignoreAt);
}
if (big && result.length < 2000 /* MaxList */)
if (big && result.length < 2000 /* C.MaxList */)
cache.set(doc, result);
return result;
}
@ -1630,7 +1691,7 @@ const completeAnyWord = context => {
if (!token && !context.explicit)
return null;
let from = token ? token.from : context.pos;
let options = collectWords(context.state.doc, wordCache(wordChars), re, 50000 /* Range */, from);
let options = collectWords(context.state.doc, wordCache(wordChars), re, 50000 /* C.Range */, from);
return { from, options, validFor: mapRE(re, s => "^" + s) };
};
@ -1652,13 +1713,11 @@ closedBracket.endSide = -1;
const bracketState = state.StateField.define({
create() { return state.RangeSet.empty; },
update(value, tr) {
if (tr.selection) {
let lineStart = tr.state.doc.lineAt(tr.selection.main.head).from;
let prevLineStart = tr.startState.doc.lineAt(tr.startState.selection.main.head).from;
if (lineStart != tr.changes.mapPos(prevLineStart, -1))
value = state.RangeSet.empty;
}
value = value.map(tr.changes);
if (tr.selection) {
let line = tr.state.doc.lineAt(tr.selection.main.head);
value = value.update({ filter: from => from >= line.from && from <= line.to });
}
for (let effect of tr.effects)
if (effect.is(closeBracketEffect))
value = value.update({ add: [closedBracket.range(effect.value, effect.value + 1)] });
@ -1886,6 +1945,7 @@ Returns an extension that enables autocompletion.
*/
function autocompletion(config = {}) {
return [
commitCharacters,
completionState,
completionConfig.of(config),
completionPlugin,
@ -1922,8 +1982,8 @@ returns `null`.
*/
function completionStatus(state) {
let cState = state.field(completionState, false);
return cState && cState.active.some(a => a.state == 1 /* Pending */) ? "pending"
: cState && cState.active.some(a => a.state != 0 /* Inactive */) ? "active" : null;
return cState && cState.active.some(a => a.state == 1 /* State.Pending */) ? "pending"
: cState && cState.active.some(a => a.state != 0 /* State.Inactive */) ? "active" : null;
}
const completionArrayCache = new WeakMap;
/**