vue-files-preview-inno
Version:
A tool for previewing files such as doc, excel, pdf, image, markdown, txt, audio, and video and so on.
874 lines (871 loc) • 30.3 kB
JavaScript
import { EditorView as x, ViewPlugin as Z, getPanel as R, Decoration as d, showPanel as ee, runScopeHandlers as me } from "../../view/dist/index.mjs";
import { StateField as te, StateEffect as A, Prec as pe, EditorSelection as g, Facet as ne, combineConfig as re, codePointAt as ge, codePointSize as xe, fromCodePoint as Se, CharCategory as p, EditorState as ye, RangeSetBuilder as Me, findClusterBreak as ie } from "../../state/dist/index.mjs";
import h from "../../../crelt/index.mjs";
const J = typeof String.prototype.normalize == "function" ? (t) => t.normalize("NFKD") : (t) => t;
class v {
/**
Create a text cursor. The query is the search string, `from` to
`to` provides the region to search.
When `normalize` is given, it will be called, on both the query
string and the content it is matched against, before comparing.
You can, for example, create a case-insensitive search by
passing `s => s.toLowerCase()`.
Text is always normalized with
[`.normalize("NFKD")`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize)
(when supported).
*/
constructor(e, n, r = 0, i = e.length, s, l) {
this.test = l, this.value = { from: 0, to: 0 }, this.done = !1, this.matches = [], this.buffer = "", this.bufferPos = 0, this.iter = e.iterRange(r, i), this.bufferStart = r, this.normalize = s ? (o) => s(J(o)) : J, this.query = this.normalize(n);
}
peek() {
if (this.bufferPos == this.buffer.length) {
if (this.bufferStart += this.buffer.length, this.iter.next(), this.iter.done)
return -1;
this.bufferPos = 0, this.buffer = this.iter.value;
}
return ge(this.buffer, this.bufferPos);
}
/**
Look for the next match. Updates the iterator's
[`value`](https://codemirror.net/6/docs/ref/#search.SearchCursor.value) and
[`done`](https://codemirror.net/6/docs/ref/#search.SearchCursor.done) properties. Should be called
at least once before using the cursor.
*/
next() {
for (; this.matches.length; )
this.matches.pop();
return this.nextOverlapping();
}
/**
The `next` method will ignore matches that partially overlap a
previous match. This method behaves like `next`, but includes
such matches.
*/
nextOverlapping() {
for (; ; ) {
let e = this.peek();
if (e < 0)
return this.done = !0, this;
let n = Se(e), r = this.bufferStart + this.bufferPos;
this.bufferPos += xe(e);
let i = this.normalize(n);
if (i.length)
for (let s = 0, l = r; ; s++) {
let o = i.charCodeAt(s), c = this.match(o, l, this.bufferPos + this.bufferStart);
if (s == i.length - 1) {
if (c)
return this.value = c, this;
break;
}
l == r && s < n.length && n.charCodeAt(s) == o && l++;
}
}
}
match(e, n, r) {
let i = null;
for (let s = 0; s < this.matches.length; s += 2) {
let l = this.matches[s], o = !1;
this.query.charCodeAt(l) == e && (l == this.query.length - 1 ? i = { from: this.matches[s + 1], to: r } : (this.matches[s]++, o = !0)), o || (this.matches.splice(s, 2), s -= 2);
}
return this.query.charCodeAt(0) == e && (this.query.length == 1 ? i = { from: n, to: r } : this.matches.push(1, n)), i && this.test && !this.test(i.from, i.to, this.buffer, this.bufferStart) && (i = null), i;
}
}
typeof Symbol < "u" && (v.prototype[Symbol.iterator] = function() {
return this;
});
const se = { from: -1, to: -1, match: /* @__PURE__ */ /.*/.exec("") }, N = "gm" + (/x/.unicode == null ? "" : "u");
class le {
/**
Create a cursor that will search the given range in the given
document. `query` should be the raw pattern (as you'd pass it to
`new RegExp`).
*/
constructor(e, n, r, i = 0, s = e.length) {
if (this.text = e, this.to = s, this.curLine = "", this.done = !1, this.value = se, /\\[sWDnr]|\n|\r|\[\^/.test(n))
return new oe(e, n, r, i, s);
this.re = new RegExp(n, N + (r != null && r.ignoreCase ? "i" : "")), this.test = r == null ? void 0 : r.test, this.iter = e.iter();
let l = e.lineAt(i);
this.curLineStart = l.from, this.matchPos = P(e, i), this.getLine(this.curLineStart);
}
getLine(e) {
this.iter.next(e), this.iter.lineBreak ? this.curLine = "" : (this.curLine = this.iter.value, this.curLineStart + this.curLine.length > this.to && (this.curLine = this.curLine.slice(0, this.to - this.curLineStart)), this.iter.next());
}
nextLine() {
this.curLineStart = this.curLineStart + this.curLine.length + 1, this.curLineStart > this.to ? this.curLine = "" : this.getLine(0);
}
/**
Move to the next match, if there is one.
*/
next() {
for (let e = this.matchPos - this.curLineStart; ; ) {
this.re.lastIndex = e;
let n = this.matchPos <= this.to && this.re.exec(this.curLine);
if (n) {
let r = this.curLineStart + n.index, i = r + n[0].length;
if (this.matchPos = P(this.text, i + (r == i ? 1 : 0)), r == this.curLineStart + this.curLine.length && this.nextLine(), (r < i || r > this.value.to) && (!this.test || this.test(r, i, n)))
return this.value = { from: r, to: i, match: n }, this;
e = this.matchPos - this.curLineStart;
} else if (this.curLineStart + this.curLine.length < this.to)
this.nextLine(), e = 0;
else
return this.done = !0, this;
}
}
}
const Q = /* @__PURE__ */ new WeakMap();
class b {
constructor(e, n) {
this.from = e, this.text = n;
}
get to() {
return this.from + this.text.length;
}
static get(e, n, r) {
let i = Q.get(e);
if (!i || i.from >= r || i.to <= n) {
let o = new b(n, e.sliceString(n, r));
return Q.set(e, o), o;
}
if (i.from == n && i.to == r)
return i;
let { text: s, from: l } = i;
return l > n && (s = e.sliceString(n, l) + s, l = n), i.to < r && (s += e.sliceString(i.to, r)), Q.set(e, new b(l, s)), new b(n, s.slice(n - l, r - l));
}
}
class oe {
constructor(e, n, r, i, s) {
this.text = e, this.to = s, this.done = !1, this.value = se, this.matchPos = P(e, i), this.re = new RegExp(n, N + (r != null && r.ignoreCase ? "i" : "")), this.test = r == null ? void 0 : r.test, this.flat = b.get(e, i, this.chunkEnd(
i + 5e3
/* Chunk.Base */
));
}
chunkEnd(e) {
return e >= this.to ? this.to : this.text.lineAt(e).to;
}
next() {
for (; ; ) {
let e = this.re.lastIndex = this.matchPos - this.flat.from, n = this.re.exec(this.flat.text);
if (n && !n[0] && n.index == e && (this.re.lastIndex = e + 1, n = this.re.exec(this.flat.text)), n) {
let r = this.flat.from + n.index, i = r + n[0].length;
if ((this.flat.to >= this.to || n.index + n[0].length <= this.flat.text.length - 10) && (!this.test || this.test(r, i, n)))
return this.value = { from: r, to: i, match: n }, this.matchPos = P(this.text, i + (r == i ? 1 : 0)), this;
}
if (this.flat.to == this.to)
return this.done = !0, this;
this.flat = b.get(this.text, this.flat.from, this.chunkEnd(this.flat.from + this.flat.text.length * 2));
}
}
}
typeof Symbol < "u" && (le.prototype[Symbol.iterator] = oe.prototype[Symbol.iterator] = function() {
return this;
});
function be(t) {
try {
return new RegExp(t, N), !0;
} catch {
return !1;
}
}
function P(t, e) {
if (e >= t.length)
return e;
let n = t.lineAt(e), r;
for (; e < n.to && (r = n.text.charCodeAt(e - n.from)) >= 56320 && r < 57344; )
e++;
return e;
}
function _(t) {
let e = String(t.state.doc.lineAt(t.state.selection.main.head).number), n = h("input", { class: "cm-textfield", name: "line", value: e }), r = h("form", {
class: "cm-gotoLine",
onkeydown: (s) => {
s.keyCode == 27 ? (s.preventDefault(), t.dispatch({ effects: L.of(!1) }), t.focus()) : s.keyCode == 13 && (s.preventDefault(), i());
},
onsubmit: (s) => {
s.preventDefault(), i();
}
}, h("label", t.state.phrase("Go to line"), ": ", n), " ", h("button", { class: "cm-button", type: "submit" }, t.state.phrase("go")), h("button", {
name: "close",
onclick: () => {
t.dispatch({ effects: L.of(!1) }), t.focus();
},
"aria-label": t.state.phrase("close"),
type: "button"
}, ["×"]));
function i() {
let s = /^([+-])?(\d+)?(:\d+)?(%)?$/.exec(n.value);
if (!s)
return;
let { state: l } = t, o = l.doc.lineAt(l.selection.main.head), [, c, a, u, m] = s, E = u ? +u.slice(1) : 0, k = a ? +a : o.number;
if (a && m) {
let O = k / 100;
c && (O = O * (c == "-" ? -1 : 1) + o.number / l.doc.lines), k = Math.round(l.doc.lines * O);
} else a && c && (k = k * (c == "-" ? -1 : 1) + o.number);
let G = l.doc.line(Math.max(1, Math.min(l.doc.lines, k))), j = g.cursor(G.from + Math.max(0, Math.min(E, G.length)));
t.dispatch({
effects: [L.of(!1), x.scrollIntoView(j.from, { y: "center" })],
selection: j
}), t.focus();
}
return { dom: r };
}
const L = /* @__PURE__ */ A.define(), U = /* @__PURE__ */ te.define({
create() {
return !0;
},
update(t, e) {
for (let n of e.effects)
n.is(L) && (t = n.value);
return t;
},
provide: (t) => ee.from(t, (e) => e ? _ : null)
}), ve = (t) => {
let e = R(t, _);
if (!e) {
let n = [L.of(!0)];
t.state.field(U, !1) == null && n.push(A.appendConfig.of([U, Ce])), t.dispatch({ effects: n }), e = R(t, _);
}
return e && e.dom.querySelector("input").select(), !0;
}, Ce = /* @__PURE__ */ x.baseTheme({
".cm-panel.cm-gotoLine": {
padding: "2px 6px 4px",
position: "relative",
"& label": { fontSize: "80%" },
"& [name=close]": {
position: "absolute",
top: "0",
bottom: "0",
right: "4px",
backgroundColor: "inherit",
border: "none",
font: "inherit",
padding: "0"
}
}
}), ke = {
highlightWordAroundCursor: !1,
minSelectionLength: 1,
maxMatches: 100,
wholeWords: !1
}, Le = /* @__PURE__ */ ne.define({
combine(t) {
return re(t, ke, {
highlightWordAroundCursor: (e, n) => e || n,
minSelectionLength: Math.min,
maxMatches: Math.min
});
}
});
function Ue(t) {
return [Fe, Ee];
}
const We = /* @__PURE__ */ d.mark({ class: "cm-selectionMatch" }), Ae = /* @__PURE__ */ d.mark({ class: "cm-selectionMatch cm-selectionMatch-main" });
function X(t, e, n, r) {
return (n == 0 || t(e.sliceDoc(n - 1, n)) != p.Word) && (r == e.doc.length || t(e.sliceDoc(r, r + 1)) != p.Word);
}
function De(t, e, n, r) {
return t(e.sliceDoc(n, n + 1)) == p.Word && t(e.sliceDoc(r - 1, r)) == p.Word;
}
const Ee = /* @__PURE__ */ Z.fromClass(class {
constructor(t) {
this.decorations = this.getDeco(t);
}
update(t) {
(t.selectionSet || t.docChanged || t.viewportChanged) && (this.decorations = this.getDeco(t.view));
}
getDeco(t) {
let e = t.state.facet(Le), { state: n } = t, r = n.selection;
if (r.ranges.length > 1)
return d.none;
let i = r.main, s, l = null;
if (i.empty) {
if (!e.highlightWordAroundCursor)
return d.none;
let c = n.wordAt(i.head);
if (!c)
return d.none;
l = n.charCategorizer(i.head), s = n.sliceDoc(c.from, c.to);
} else {
let c = i.to - i.from;
if (c < e.minSelectionLength || c > 200)
return d.none;
if (e.wholeWords) {
if (s = n.sliceDoc(i.from, i.to), l = n.charCategorizer(i.head), !(X(l, n, i.from, i.to) && De(l, n, i.from, i.to)))
return d.none;
} else if (s = n.sliceDoc(i.from, i.to), !s)
return d.none;
}
let o = [];
for (let c of t.visibleRanges) {
let a = new v(n.doc, s, c.from, c.to);
for (; !a.next().done; ) {
let { from: u, to: m } = a.value;
if ((!l || X(l, n, u, m)) && (i.empty && u <= i.from && m >= i.to ? o.push(Ae.range(u, m)) : (u >= i.to || m <= i.from) && o.push(We.range(u, m)), o.length > e.maxMatches))
return d.none;
}
}
return d.set(o);
}
}, {
decorations: (t) => t.decorations
}), Fe = /* @__PURE__ */ x.baseTheme({
".cm-selectionMatch": { backgroundColor: "#99ff7780" },
".cm-searchMatch .cm-selectionMatch": { backgroundColor: "transparent" }
}), qe = ({ state: t, dispatch: e }) => {
let { selection: n } = t, r = g.create(n.ranges.map((i) => t.wordAt(i.head) || g.cursor(i.head)), n.mainIndex);
return r.eq(n) ? !1 : (e(t.update({ selection: r })), !0);
};
function Re(t, e) {
let { main: n, ranges: r } = t.selection, i = t.wordAt(n.head), s = i && i.from == n.from && i.to == n.to;
for (let l = !1, o = new v(t.doc, e, r[r.length - 1].to); ; )
if (o.next(), o.done) {
if (l)
return null;
o = new v(t.doc, e, 0, Math.max(0, r[r.length - 1].from - 1)), l = !0;
} else {
if (l && r.some((c) => c.from == o.value.from))
continue;
if (s) {
let c = t.wordAt(o.value.from);
if (!c || c.from != o.value.from || c.to != o.value.to)
continue;
}
return o.value;
}
}
const Pe = ({ state: t, dispatch: e }) => {
let { ranges: n } = t.selection;
if (n.some((s) => s.from === s.to))
return qe({ state: t, dispatch: e });
let r = t.sliceDoc(n[0].from, n[0].to);
if (t.selection.ranges.some((s) => t.sliceDoc(s.from, s.to) != r))
return !1;
let i = Re(t, r);
return i ? (e(t.update({
selection: t.selection.addRange(g.range(i.from, i.to), !1),
effects: x.scrollIntoView(i.to)
})), !0) : !1;
}, C = /* @__PURE__ */ ne.define({
combine(t) {
return re(t, {
top: !1,
caseSensitive: !1,
literal: !1,
regexp: !1,
wholeWord: !1,
createPanel: (e) => new Ve(e),
scrollToMatch: (e) => x.scrollIntoView(e)
});
}
});
class ce {
/**
Create a query object.
*/
constructor(e) {
this.search = e.search, this.caseSensitive = !!e.caseSensitive, this.literal = !!e.literal, this.regexp = !!e.regexp, this.replace = e.replace || "", this.valid = !!this.search && (!this.regexp || be(this.search)), this.unquoted = this.unquote(this.search), this.wholeWord = !!e.wholeWord;
}
/**
@internal
*/
unquote(e) {
return this.literal ? e : e.replace(/\\([nrt\\])/g, (n, r) => r == "n" ? `
` : r == "r" ? "\r" : r == "t" ? " " : "\\");
}
/**
Compare this query to another query.
*/
eq(e) {
return this.search == e.search && this.replace == e.replace && this.caseSensitive == e.caseSensitive && this.regexp == e.regexp && this.wholeWord == e.wholeWord;
}
/**
@internal
*/
create() {
return this.regexp ? new we(this) : new Te(this);
}
/**
Get a search cursor for this query, searching through the given
range in the given state.
*/
getCursor(e, n = 0, r) {
let i = e.doc ? e : ye.create({ doc: e });
return r == null && (r = i.doc.length), this.regexp ? M(this, i, n, r) : y(this, i, n, r);
}
}
class ae {
constructor(e) {
this.spec = e;
}
}
function y(t, e, n, r) {
return new v(e.doc, t.unquoted, n, r, t.caseSensitive ? void 0 : (i) => i.toLowerCase(), t.wholeWord ? Ie(e.doc, e.charCategorizer(e.selection.main.head)) : void 0);
}
function Ie(t, e) {
return (n, r, i, s) => ((s > n || s + i.length < r) && (s = Math.max(0, n - 2), i = t.sliceString(s, Math.min(t.length, r + 2))), (e(I(i, n - s)) != p.Word || e(T(i, n - s)) != p.Word) && (e(T(i, r - s)) != p.Word || e(I(i, r - s)) != p.Word));
}
class Te extends ae {
constructor(e) {
super(e);
}
nextMatch(e, n, r) {
let i = y(this.spec, e, r, e.doc.length).nextOverlapping();
if (i.done) {
let s = Math.min(e.doc.length, n + this.spec.unquoted.length);
i = y(this.spec, e, 0, s).nextOverlapping();
}
return i.done || i.value.from == n && i.value.to == r ? null : i.value;
}
// Searching in reverse is, rather than implementing an inverted search
// cursor, done by scanning chunk after chunk forward.
prevMatchInRange(e, n, r) {
for (let i = r; ; ) {
let s = Math.max(n, i - 1e4 - this.spec.unquoted.length), l = y(this.spec, e, s, i), o = null;
for (; !l.nextOverlapping().done; )
o = l.value;
if (o)
return o;
if (s == n)
return null;
i -= 1e4;
}
}
prevMatch(e, n, r) {
let i = this.prevMatchInRange(e, 0, n);
return i || (i = this.prevMatchInRange(e, Math.max(0, r - this.spec.unquoted.length), e.doc.length)), i && (i.from != n || i.to != r) ? i : null;
}
getReplacement(e) {
return this.spec.unquote(this.spec.replace);
}
matchAll(e, n) {
let r = y(this.spec, e, 0, e.doc.length), i = [];
for (; !r.next().done; ) {
if (i.length >= n)
return null;
i.push(r.value);
}
return i;
}
highlight(e, n, r, i) {
let s = y(this.spec, e, Math.max(0, n - this.spec.unquoted.length), Math.min(r + this.spec.unquoted.length, e.doc.length));
for (; !s.next().done; )
i(s.value.from, s.value.to);
}
}
function M(t, e, n, r) {
return new le(e.doc, t.search, {
ignoreCase: !t.caseSensitive,
test: t.wholeWord ? $e(e.charCategorizer(e.selection.main.head)) : void 0
}, n, r);
}
function I(t, e) {
return t.slice(ie(t, e, !1), e);
}
function T(t, e) {
return t.slice(e, ie(t, e));
}
function $e(t) {
return (e, n, r) => !r[0].length || (t(I(r.input, r.index)) != p.Word || t(T(r.input, r.index)) != p.Word) && (t(T(r.input, r.index + r[0].length)) != p.Word || t(I(r.input, r.index + r[0].length)) != p.Word);
}
class we extends ae {
nextMatch(e, n, r) {
let i = M(this.spec, e, r, e.doc.length).next();
return i.done && (i = M(this.spec, e, 0, n).next()), i.done ? null : i.value;
}
prevMatchInRange(e, n, r) {
for (let i = 1; ; i++) {
let s = Math.max(
n,
r - i * 1e4
/* FindPrev.ChunkSize */
), l = M(this.spec, e, s, r), o = null;
for (; !l.next().done; )
o = l.value;
if (o && (s == n || o.from > s + 10))
return o;
if (s == n)
return null;
}
}
prevMatch(e, n, r) {
return this.prevMatchInRange(e, 0, n) || this.prevMatchInRange(e, r, e.doc.length);
}
getReplacement(e) {
return this.spec.unquote(this.spec.replace).replace(/\$([$&]|\d+)/g, (n, r) => {
if (r == "&")
return e.match[0];
if (r == "$")
return "$";
for (let i = r.length; i > 0; i--) {
let s = +r.slice(0, i);
if (s > 0 && s < e.match.length)
return e.match[s] + r.slice(i);
}
return n;
});
}
matchAll(e, n) {
let r = M(this.spec, e, 0, e.doc.length), i = [];
for (; !r.next().done; ) {
if (i.length >= n)
return null;
i.push(r.value);
}
return i;
}
highlight(e, n, r, i) {
let s = M(this.spec, e, Math.max(
0,
n - 250
/* RegExp.HighlightMargin */
), Math.min(r + 250, e.doc.length));
for (; !s.next().done; )
i(s.value.from, s.value.to);
}
}
const W = /* @__PURE__ */ A.define(), V = /* @__PURE__ */ A.define(), S = /* @__PURE__ */ te.define({
create(t) {
return new z(B(t).create(), null);
},
update(t, e) {
for (let n of e.effects)
n.is(W) ? t = new z(n.value.create(), t.panel) : n.is(V) && (t = new z(t.query, n.value ? H : null));
return t;
},
provide: (t) => ee.from(t, (e) => e.panel)
});
class z {
constructor(e, n) {
this.query = e, this.panel = n;
}
}
const Oe = /* @__PURE__ */ d.mark({ class: "cm-searchMatch" }), Qe = /* @__PURE__ */ d.mark({ class: "cm-searchMatch cm-searchMatch-selected" }), ze = /* @__PURE__ */ Z.fromClass(class {
constructor(t) {
this.view = t, this.decorations = this.highlight(t.state.field(S));
}
update(t) {
let e = t.state.field(S);
(e != t.startState.field(S) || t.docChanged || t.selectionSet || t.viewportChanged) && (this.decorations = this.highlight(e));
}
highlight({ query: t, panel: e }) {
if (!e || !t.spec.valid)
return d.none;
let { view: n } = this, r = new Me();
for (let i = 0, s = n.visibleRanges, l = s.length; i < l; i++) {
let { from: o, to: c } = s[i];
for (; i < l - 1 && c > s[i + 1].from - 2 * 250; )
c = s[++i].to;
t.highlight(n.state, o, c, (a, u) => {
let m = n.state.selection.ranges.some((E) => E.from == a && E.to == u);
r.add(a, u, m ? Qe : Oe);
});
}
return r.finish();
}
}, {
decorations: (t) => t.decorations
});
function D(t) {
return (e) => {
let n = e.state.field(S, !1);
return n && n.query.spec.valid ? t(e, n) : fe(e);
};
}
const $ = /* @__PURE__ */ D((t, { query: e }) => {
let { to: n } = t.state.selection.main, r = e.nextMatch(t.state, n, n);
if (!r)
return !1;
let i = g.single(r.from, r.to), s = t.state.facet(C);
return t.dispatch({
selection: i,
effects: [K(t, r), s.scrollToMatch(i.main, t)],
userEvent: "select.search"
}), ue(t), !0;
}), w = /* @__PURE__ */ D((t, { query: e }) => {
let { state: n } = t, { from: r } = n.selection.main, i = e.prevMatch(n, r, r);
if (!i)
return !1;
let s = g.single(i.from, i.to), l = t.state.facet(C);
return t.dispatch({
selection: s,
effects: [K(t, i), l.scrollToMatch(s.main, t)],
userEvent: "select.search"
}), ue(t), !0;
}), _e = /* @__PURE__ */ D((t, { query: e }) => {
let n = e.matchAll(t.state, 1e3);
return !n || !n.length ? !1 : (t.dispatch({
selection: g.create(n.map((r) => g.range(r.from, r.to))),
userEvent: "select.search.matches"
}), !0);
}), Be = ({ state: t, dispatch: e }) => {
let n = t.selection;
if (n.ranges.length > 1 || n.main.empty)
return !1;
let { from: r, to: i } = n.main, s = [], l = 0;
for (let o = new v(t.doc, t.sliceDoc(r, i)); !o.next().done; ) {
if (s.length > 1e3)
return !1;
o.value.from == r && (l = s.length), s.push(g.range(o.value.from, o.value.to));
}
return e(t.update({
selection: g.create(s, l),
userEvent: "select.search.matches"
})), !0;
}, Y = /* @__PURE__ */ D((t, { query: e }) => {
let { state: n } = t, { from: r, to: i } = n.selection.main;
if (n.readOnly)
return !1;
let s = e.nextMatch(n, r, r);
if (!s)
return !1;
let l = s, o = [], c, a, u = [];
l.from == r && l.to == i && (a = n.toText(e.getReplacement(l)), o.push({ from: l.from, to: l.to, insert: a }), l = e.nextMatch(n, l.from, l.to), u.push(x.announce.of(n.phrase("replaced match on line $", n.doc.lineAt(r).number) + ".")));
let m = t.state.changes(o);
return l && (c = g.single(l.from, l.to).map(m), u.push(K(t, l)), u.push(n.facet(C).scrollToMatch(c.main, t))), t.dispatch({
changes: m,
selection: c,
effects: u,
userEvent: "input.replace"
}), !0;
}), Ne = /* @__PURE__ */ D((t, { query: e }) => {
if (t.state.readOnly)
return !1;
let n = e.matchAll(t.state, 1e9).map((i) => {
let { from: s, to: l } = i;
return { from: s, to: l, insert: e.getReplacement(i) };
});
if (!n.length)
return !1;
let r = t.state.phrase("replaced $ matches", n.length) + ".";
return t.dispatch({
changes: n,
effects: x.announce.of(r),
userEvent: "input.replace.all"
}), !0;
});
function H(t) {
return t.state.facet(C).createPanel(t);
}
function B(t, e) {
var n, r, i, s, l;
let o = t.selection.main, c = o.empty || o.to > o.from + 100 ? "" : t.sliceDoc(o.from, o.to);
if (e && !c)
return e;
let a = t.facet(C);
return new ce({
search: ((n = e == null ? void 0 : e.literal) !== null && n !== void 0 ? n : a.literal) ? c : c.replace(/\n/g, "\\n"),
caseSensitive: (r = e == null ? void 0 : e.caseSensitive) !== null && r !== void 0 ? r : a.caseSensitive,
literal: (i = e == null ? void 0 : e.literal) !== null && i !== void 0 ? i : a.literal,
regexp: (s = e == null ? void 0 : e.regexp) !== null && s !== void 0 ? s : a.regexp,
wholeWord: (l = e == null ? void 0 : e.wholeWord) !== null && l !== void 0 ? l : a.wholeWord
});
}
function he(t) {
let e = R(t, H);
return e && e.dom.querySelector("[main-field]");
}
function ue(t) {
let e = he(t);
e && e == t.root.activeElement && e.select();
}
const fe = (t) => {
let e = t.state.field(S, !1);
if (e && e.panel) {
let n = he(t);
if (n && n != t.root.activeElement) {
let r = B(t.state, e.query.spec);
r.valid && t.dispatch({ effects: W.of(r) }), n.focus(), n.select();
}
} else
t.dispatch({ effects: [
V.of(!0),
e ? W.of(B(t.state, e.query.spec)) : A.appendConfig.of(Ke)
] });
return !0;
}, de = (t) => {
let e = t.state.field(S, !1);
if (!e || !e.panel)
return !1;
let n = R(t, H);
return n && n.dom.contains(t.root.activeElement) && t.focus(), t.dispatch({ effects: V.of(!1) }), !0;
}, Xe = [
{ key: "Mod-f", run: fe, scope: "editor search-panel" },
{ key: "F3", run: $, shift: w, scope: "editor search-panel", preventDefault: !0 },
{ key: "Mod-g", run: $, shift: w, scope: "editor search-panel", preventDefault: !0 },
{ key: "Escape", run: de, scope: "editor search-panel" },
{ key: "Mod-Shift-l", run: Be },
{ key: "Mod-Alt-g", run: ve },
{ key: "Mod-d", run: Pe, preventDefault: !0 }
];
class Ve {
constructor(e) {
this.view = e;
let n = this.query = e.state.field(S).query.spec;
this.commit = this.commit.bind(this), this.searchField = h("input", {
value: n.search,
placeholder: f(e, "Find"),
"aria-label": f(e, "Find"),
class: "cm-textfield",
name: "search",
form: "",
"main-field": "true",
onchange: this.commit,
onkeyup: this.commit
}), this.replaceField = h("input", {
value: n.replace,
placeholder: f(e, "Replace"),
"aria-label": f(e, "Replace"),
class: "cm-textfield",
name: "replace",
form: "",
onchange: this.commit,
onkeyup: this.commit
}), this.caseField = h("input", {
type: "checkbox",
name: "case",
form: "",
checked: n.caseSensitive,
onchange: this.commit
}), this.reField = h("input", {
type: "checkbox",
name: "re",
form: "",
checked: n.regexp,
onchange: this.commit
}), this.wordField = h("input", {
type: "checkbox",
name: "word",
form: "",
checked: n.wholeWord,
onchange: this.commit
});
function r(i, s, l) {
return h("button", { class: "cm-button", name: i, onclick: s, type: "button" }, l);
}
this.dom = h("div", { onkeydown: (i) => this.keydown(i), class: "cm-search" }, [
this.searchField,
r("next", () => $(e), [f(e, "next")]),
r("prev", () => w(e), [f(e, "previous")]),
r("select", () => _e(e), [f(e, "all")]),
h("label", null, [this.caseField, f(e, "match case")]),
h("label", null, [this.reField, f(e, "regexp")]),
h("label", null, [this.wordField, f(e, "by word")]),
...e.state.readOnly ? [] : [
h("br"),
this.replaceField,
r("replace", () => Y(e), [f(e, "replace")]),
r("replaceAll", () => Ne(e), [f(e, "replace all")])
],
h("button", {
name: "close",
onclick: () => de(e),
"aria-label": f(e, "close"),
type: "button"
}, ["×"])
]);
}
commit() {
let e = new ce({
search: this.searchField.value,
caseSensitive: this.caseField.checked,
regexp: this.reField.checked,
wholeWord: this.wordField.checked,
replace: this.replaceField.value
});
e.eq(this.query) || (this.query = e, this.view.dispatch({ effects: W.of(e) }));
}
keydown(e) {
me(this.view, e, "search-panel") ? e.preventDefault() : e.keyCode == 13 && e.target == this.searchField ? (e.preventDefault(), (e.shiftKey ? w : $)(this.view)) : e.keyCode == 13 && e.target == this.replaceField && (e.preventDefault(), Y(this.view));
}
update(e) {
for (let n of e.transactions)
for (let r of n.effects)
r.is(W) && !r.value.eq(this.query) && this.setQuery(r.value);
}
setQuery(e) {
this.query = e, this.searchField.value = e.search, this.replaceField.value = e.replace, this.caseField.checked = e.caseSensitive, this.reField.checked = e.regexp, this.wordField.checked = e.wholeWord;
}
mount() {
this.searchField.select();
}
get pos() {
return 80;
}
get top() {
return this.view.state.facet(C).top;
}
}
function f(t, e) {
return t.state.phrase(e);
}
const F = 30, q = /[\s\.,:;?!]/;
function K(t, { from: e, to: n }) {
let r = t.state.doc.lineAt(e), i = t.state.doc.lineAt(n).to, s = Math.max(r.from, e - F), l = Math.min(i, n + F), o = t.state.sliceDoc(s, l);
if (s != r.from) {
for (let c = 0; c < F; c++)
if (!q.test(o[c + 1]) && q.test(o[c])) {
o = o.slice(c);
break;
}
}
if (l != i) {
for (let c = o.length - 1; c > o.length - F; c--)
if (!q.test(o[c - 1]) && q.test(o[c])) {
o = o.slice(0, c);
break;
}
}
return x.announce.of(`${t.state.phrase("current match")}. ${o} ${t.state.phrase("on line")} ${r.number}.`);
}
const He = /* @__PURE__ */ x.baseTheme({
".cm-panel.cm-search": {
padding: "2px 6px 4px",
position: "relative",
"& [name=close]": {
position: "absolute",
top: "0",
right: "4px",
backgroundColor: "inherit",
border: "none",
font: "inherit",
padding: 0,
margin: 0
},
"& input, & button, & label": {
margin: ".2em .6em .2em 0"
},
"& input[type=checkbox]": {
marginRight: ".2em"
},
"& label": {
fontSize: "80%",
whiteSpace: "pre"
}
},
"&light .cm-searchMatch": { backgroundColor: "#ffff0054" },
"&dark .cm-searchMatch": { backgroundColor: "#00ffff8a" },
"&light .cm-searchMatch-selected": { backgroundColor: "#ff6a0054" },
"&dark .cm-searchMatch-selected": { backgroundColor: "#ff00ff8a" }
}), Ke = [
S,
/* @__PURE__ */ pe.low(ze),
He
];
export {
le as RegExpCursor,
v as SearchCursor,
ce as SearchQuery,
de as closeSearchPanel,
$ as findNext,
w as findPrevious,
ve as gotoLine,
Ue as highlightSelectionMatches,
fe as openSearchPanel,
Ne as replaceAll,
Y as replaceNext,
Xe as searchKeymap,
_e as selectMatches,
Pe as selectNextOccurrence,
Be as selectSelectionMatches,
W as setSearchQuery
};
//# sourceMappingURL=index.mjs.map