@xiaoso/dsh-tool-plus 0.1.16 → 0.1.17-beta.0
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/lib/{abort-DZ54CaKU.mjs → abort-BTblp0Rt.mjs} +2 -2
- package/lib/{alibaba-coding-plan-DODpkcqi.mjs → alibaba-coding-plan-t3R4YKCB.mjs} +3 -3
- package/lib/{alibaba-token-plan-C6lpKCda.mjs → alibaba-token-plan-CO4djG1y.mjs} +4 -4
- package/lib/{alibaba-token-plan-CHGyWOfX.mjs → alibaba-token-plan-CUjYJX0-.mjs} +1 -1
- package/lib/{anthropic-Dv_GGX6g.mjs → anthropic-nf7w6so1.mjs} +48 -21
- package/lib/{api-key-validation-MnMf_ihX.mjs → api-key-validation-C_tZ7Y9a.mjs} +2 -2
- package/lib/behavior-BwvTUtag.mjs +111 -0
- package/lib/{browser-render-BZXt548F.mjs → browser-render-BQaEVK_n.mjs} +4 -4
- package/lib/{reference-CtvM4zLU.mjs → bundled-references-CrQ4dQcT.mjs} +57 -4
- package/lib/cascade-BWjRTD1q.mjs +30265 -0
- package/lib/{cline-pass-BT9CBEOj.mjs → cline-pass-Bjm-O8GG.mjs} +2 -2
- package/lib/cloudflare-CKXRJ0l9.mjs +37 -0
- package/lib/{cloudflare-ai-gateway-DReN6ohJ.mjs → cloudflare-ai-gateway-BpnBSjwV.mjs} +8 -4
- package/lib/cloudflare-workers-ai-odj9XswL.mjs +32 -0
- package/lib/collapse-_nkb2dn7.mjs +1945 -0
- package/lib/{coreweave-C82HrLpb.mjs → coreweave-CGDZOD8-.mjs} +1 -1
- package/lib/{coreweave-C68UgRQO.mjs → coreweave-DwffcgW5.mjs} +4 -4
- package/lib/cursor-BgOuV7Qf.mjs +794 -0
- package/lib/{cursor-_gHHq-Dq.mjs → cursor-CF1iHHbv.mjs} +68 -19
- package/lib/{cursor-proto-Cr_WEMuv.mjs → cursor-proto-BuNTjX3L.mjs} +823 -23
- package/lib/{devin-QpfTSl9H.mjs → devin-7OEeEb80.mjs} +112 -31
- package/lib/{devin-proto-DYhp4Ty6.mjs → devin-proto-C-QreeAv.mjs} +71 -5
- package/lib/{dom-DG3sPESc.mjs → dom-BmbZv4v9.mjs} +598 -182
- package/lib/{error-O63pC8zg.mjs → error-8LVo7tug.mjs} +725 -104
- package/lib/factory-droid-ChhmsGWb.mjs +71 -0
- package/lib/{fs-promises-shim-B2YFWkcd.mjs → fs-promises-shim-CANAxFWh.mjs} +10 -1
- package/lib/{github-copilot-BMEcw8N1.mjs → github-copilot-QwevdT30.mjs} +4 -4
- package/lib/{github-copilot-headers-DnjGEbko.mjs → github-copilot-headers-CAUZ0rUD.mjs} +138 -26
- package/lib/{gitlab-duo-DnHqJjFY.mjs → gitlab-duo-DigV7k_o.mjs} +2 -2
- package/lib/{google-antigravity-B1mSckrK.mjs → google-antigravity-D-oe0r8A.mjs} +6 -7
- package/lib/{google-gemini-cli-DJwThCCn.mjs → google-gemini-cli-CQBHgGJT.mjs} +5 -6
- package/lib/{google-oauth-shared-BctLpVUN.mjs → google-oauth-shared-CvgVIUwJ.mjs} +2 -2
- package/lib/google-validation-CdvRj4ec.mjs +126 -0
- package/lib/id-EJwVLDHE.mjs +2548 -0
- package/lib/index.mjs +248 -258
- package/lib/{kilo-BEgEwMJQ.mjs → kilo-5r6OffCa.mjs} +2 -2
- package/lib/{kimi-T9NldEIJ.mjs → kimi-DOOtbXmm.mjs} +9 -10
- package/lib/{launch-BIWNyrBB.mjs → launch-DkAjib7h.mjs} +1 -1
- package/lib/{markit-Dvp2JPdT.mjs → markit-CCcyeAds.mjs} +359 -140
- package/lib/{models-DnXMYGcJ.mjs → models-DCpDT_im.mjs} +199203 -112275
- package/lib/{muse-code-CNvqqAp6.mjs → muse-code-CYf8zj_B.mjs} +5 -5
- package/lib/{openai-codex-D5-CyTxa.mjs → openai-codex-Cj-TvSFh.mjs} +13 -10
- package/lib/{perplexity-A2PEoGaC.mjs → perplexity-Dh_Qgsmx.mjs} +68 -25
- package/lib/{pkce-BYjmugmw.mjs → pkce-DO-jBJLV.mjs} +1 -1
- package/lib/pricing-DusBEhwm.mjs +593 -0
- package/lib/{readability-uGhqb4GC.mjs → readability-XHK0o3bv.mjs} +287 -27
- package/lib/{scrapers-C1ujjV8k.mjs → scrapers-B6PADOVm.mjs} +13 -13
- package/lib/slugify-ynYWBIA5.mjs +11 -0
- package/lib/snowflake-B_jap6lz.mjs +666 -0
- package/lib/snowflake-Cu1ZyOp6.mjs +151 -0
- package/lib/{src-AELUUb5U.mjs → src-BhinCSpi.mjs} +1172 -458
- package/lib/{stream-AVOoe5Hj.mjs → stream-D2ivg3GH.mjs} +3740 -5311
- package/lib/{turndown-D6fof1OX.mjs → turndown-Vya8SavL.mjs} +82 -30
- package/lib/types/tools/hashline/native/index.d.ts +2 -2
- package/lib/types/tools/hashline/native/policy.d.ts +19 -21
- package/lib/types/tools/omp/session/agent-storage.d.ts +3 -3
- package/lib/types/tools/shared/bun-named-shim.d.ts +5 -0
- package/lib/{types-BLrLohwK.mjs → types-tH1v9uRm.mjs} +2 -2
- package/lib/{utils-cZX3f_Ls.mjs → utils-C_Ncya1r.mjs} +1737 -509
- package/lib/utils-D2tK38xq.mjs +34006 -0
- package/lib/{utils-I4I8azHN.mjs → utils-DrDwmNtu.mjs} +8 -3
- package/lib/{xai-oauth-CbeldUSV.mjs → xai-oauth-DLLzX6my.mjs} +4 -4
- package/lib/{xiaomi-Dl3VSs04.mjs → xiaomi-CqK-KivK.mjs} +2 -2
- package/lib/{zai-FyjGSypr.mjs → zai-DoJ2xPIH.mjs} +2 -2
- package/lib/{zip-DRrycScC.mjs → zip-DG1mUV6X.mjs} +1 -1
- package/package.json +8 -8
- package/lib/amazon-bedrock-Dx0rr9dY.mjs +0 -996
- package/lib/anthropic-ClCw0PV_.mjs +0 -3624
- package/lib/anthropic-wire-lbGAFzYb.mjs +0 -927
- package/lib/azure-openai-responses-WE_bgFWp.mjs +0 -285
- package/lib/bundled-references-DY3EJxZV.mjs +0 -56
- package/lib/cloudflare-ai-gateway-CrMa97Ap.mjs +0 -44
- package/lib/collapse-CkMNRNr7.mjs +0 -2304
- package/lib/cursor-C6jaIJDg.mjs +0 -283
- package/lib/cursor-D-XZYDf_.mjs +0 -4544
- package/lib/deterministic-id-CUEIMSqR.mjs +0 -17
- package/lib/devin-ExGIghmx.mjs +0 -69
- package/lib/devin-u0ljw5P6.mjs +0 -628
- package/lib/effort-BdtQMN-_.mjs +0 -23
- package/lib/event-stream-BKEtb45Y.mjs +0 -167
- package/lib/gemini-headers-Co9cVvex.mjs +0 -54
- package/lib/google-auth-qAN-6DMW.mjs +0 -232
- package/lib/google-gemini-cli-B2Aw1S5w.mjs +0 -844
- package/lib/google-lTxuq28n.mjs +0 -38
- package/lib/google-shared-Y01j9xOr.mjs +0 -856
- package/lib/google-validation-BEkNs-Bx.mjs +0 -18
- package/lib/google-vertex-DcM-FRC5.mjs +0 -99
- package/lib/hosts-00rjRzUD.mjs +0 -203
- package/lib/id-AL5obQzR.mjs +0 -71
- package/lib/idle-iterator-D0ZXEcUq.mjs +0 -366
- package/lib/ollama-6R0oXZks.mjs +0 -574
- package/lib/openai-codex-responses-C8bnBWOe.mjs +0 -3232
- package/lib/openai-completions-DNr3mUsn.mjs +0 -1430
- package/lib/openai-configuration-update-xMYUjaK_.mjs +0 -150
- package/lib/openai-reasoning-fallback-Ju-5pSR8.mjs +0 -380
- package/lib/openai-responses-CjpafAEr.mjs +0 -861
- package/lib/protobuf-BMgDYu_U.mjs +0 -717
- package/lib/provider-response-SqKSkkUc.mjs +0 -22
- package/lib/proxy-DxvCQOCA.mjs +0 -230
- package/lib/request-debug-BwPOqN_j.mjs +0 -183
- package/lib/sanitize-text-BCf5KmCf.mjs +0 -33
- package/lib/sse-debug-B-tkLCPW.mjs +0 -11
- package/lib/stream-markup-healing-CN3RsqG9.mjs +0 -267
- package/lib/strict-tool-validation-CBTz1dAA.mjs +0 -105
- package/lib/taxonomy-DSIM99rS.mjs +0 -15392
- package/lib/thinking-ngMwf_1Y.mjs +0 -336
- package/lib/type-guards-CttAANEx.mjs +0 -11
- package/lib/utils-CE3DSebh.mjs +0 -11763
- package/lib/vision-guard-BCpXWUj3.mjs +0 -77
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import { installBunShim as __installBunShim } from "./bun-shim.mjs";
|
|
2
2
|
__installBunShim();
|
|
3
|
-
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/dom/parser.ts
|
|
4
|
+
/** Closing-tag patterns for raw-text elements, reused across parses (callers reset `lastIndex`). */
|
|
5
|
+
const RAW_TEXT_CLOSE = {
|
|
6
|
+
script: /<\/script\s*>/gi,
|
|
7
|
+
style: /<\/style\s*>/gi
|
|
7
8
|
};
|
|
9
|
+
const DOCTYPE_PATTERN = /<!doctype\b/iy;
|
|
10
|
+
const TAG_NAME_PATTERN = /[^\s/>]+/y;
|
|
11
|
+
const ATTRIBUTE_NAME_PATTERN = /[^\s=/>]+/y;
|
|
12
|
+
const UNQUOTED_VALUE_PATTERN = /[^\s>]+/y;
|
|
13
|
+
const SVG_NAMESPACE$1 = "http://www.w3.org/2000/svg";
|
|
14
|
+
const HTML_NAMESPACE$1 = "http://www.w3.org/1999/xhtml";
|
|
8
15
|
const VOID_ELEMENTS$1 = {
|
|
9
16
|
area: true,
|
|
10
17
|
base: true,
|
|
@@ -186,9 +193,11 @@ const NAMED_ENTITIES = {
|
|
|
186
193
|
yuml: "ÿ",
|
|
187
194
|
yen: "¥"
|
|
188
195
|
};
|
|
196
|
+
const ENTITY_PATTERN = /&(#(?:x[0-9a-f]+|\d+)|[a-z][a-z0-9]+);/gi;
|
|
189
197
|
/** Decode common named entities and all valid numeric character references. */
|
|
190
198
|
function decodeEntities(value) {
|
|
191
|
-
|
|
199
|
+
if (!value.includes("&")) return value;
|
|
200
|
+
return value.replace(ENTITY_PATTERN, (whole, entity) => {
|
|
192
201
|
if (entity[0] !== "#") return NAMED_ENTITIES[entity] ?? NAMED_ENTITIES[entity.toLowerCase()] ?? whole;
|
|
193
202
|
const hexadecimal = entity[1]?.toLowerCase() === "x";
|
|
194
203
|
const codePoint = Number.parseInt(entity.slice(hexadecimal ? 2 : 1), hexadecimal ? 16 : 10);
|
|
@@ -210,7 +219,8 @@ function findTagEnd(html, start) {
|
|
|
210
219
|
function parseStartTag(source) {
|
|
211
220
|
let index = 0;
|
|
212
221
|
while (/\s/.test(source[index] ?? "")) index++;
|
|
213
|
-
|
|
222
|
+
TAG_NAME_PATTERN.lastIndex = index;
|
|
223
|
+
const nameMatch = TAG_NAME_PATTERN.exec(source);
|
|
214
224
|
if (!nameMatch) return null;
|
|
215
225
|
const name = nameMatch[0].toLowerCase();
|
|
216
226
|
index += nameMatch[0].length;
|
|
@@ -222,7 +232,8 @@ function parseStartTag(source) {
|
|
|
222
232
|
selfClosing = true;
|
|
223
233
|
break;
|
|
224
234
|
}
|
|
225
|
-
|
|
235
|
+
ATTRIBUTE_NAME_PATTERN.lastIndex = index;
|
|
236
|
+
const attributeMatch = ATTRIBUTE_NAME_PATTERN.exec(source);
|
|
226
237
|
if (!attributeMatch) break;
|
|
227
238
|
const attributeName = attributeMatch[0];
|
|
228
239
|
index += attributeMatch[0].length;
|
|
@@ -243,7 +254,8 @@ function parseStartTag(source) {
|
|
|
243
254
|
index = end + 1;
|
|
244
255
|
}
|
|
245
256
|
} else {
|
|
246
|
-
|
|
257
|
+
UNQUOTED_VALUE_PATTERN.lastIndex = index;
|
|
258
|
+
value = UNQUOTED_VALUE_PATTERN.exec(source)?.[0] ?? "";
|
|
247
259
|
index += value.length;
|
|
248
260
|
}
|
|
249
261
|
}
|
|
@@ -264,7 +276,8 @@ function closeOptionalElements(stack, incoming) {
|
|
|
264
276
|
}
|
|
265
277
|
if (CLOSE_ON_OPEN[incoming]?.includes(current.localName)) stack.pop();
|
|
266
278
|
}
|
|
267
|
-
|
|
279
|
+
/** Parse markup, appending the resulting nodes to `root` (a document, fragment, or element). */
|
|
280
|
+
function parseInto(html, document, root) {
|
|
268
281
|
const stack = [];
|
|
269
282
|
const xmlLike = root instanceof Document && /^\s*(?:<\?xml[\s\S]*?\?>\s*)?<(?:feed|rss)\b/i.test(html);
|
|
270
283
|
let parent = root;
|
|
@@ -284,7 +297,7 @@ function parseInto(html, document, root, contextTag) {
|
|
|
284
297
|
index = end;
|
|
285
298
|
continue;
|
|
286
299
|
}
|
|
287
|
-
if (
|
|
300
|
+
if (html[index + 1] === "!" && isDoctypeAt(html, index)) {
|
|
288
301
|
const end = html.indexOf(">", index + 2);
|
|
289
302
|
index = end < 0 ? html.length : end + 1;
|
|
290
303
|
continue;
|
|
@@ -319,7 +332,7 @@ function parseInto(html, document, root, contextTag) {
|
|
|
319
332
|
}
|
|
320
333
|
closeOptionalElements(stack, parsed.name);
|
|
321
334
|
parent = stack[stack.length - 1] ?? root;
|
|
322
|
-
const namespace = parent instanceof Element && parent.namespaceURI ===
|
|
335
|
+
const namespace = parent !== root && parent instanceof Element && parent.namespaceURI === SVG_NAMESPACE$1 || parsed.name === "svg" ? SVG_NAMESPACE$1 : HTML_NAMESPACE$1;
|
|
323
336
|
const element = document.createElementNS(namespace, parsed.name);
|
|
324
337
|
for (let attributeIndex = parsed.attributes.length - 1; attributeIndex >= 0; attributeIndex--) {
|
|
325
338
|
const [name, value] = parsed.attributes[attributeIndex];
|
|
@@ -327,8 +340,8 @@ function parseInto(html, document, root, contextTag) {
|
|
|
327
340
|
}
|
|
328
341
|
parent.appendChild(element);
|
|
329
342
|
index = end + 1;
|
|
330
|
-
if (
|
|
331
|
-
const closePattern = new RegExp(`</${parsed.name}\\s*>`, "ig");
|
|
343
|
+
if (RAW_TEXT_CLOSE[parsed.name] && !parsed.selfClosing) {
|
|
344
|
+
const closePattern = Object.hasOwn(RAW_TEXT_CLOSE, parsed.name) ? RAW_TEXT_CLOSE[parsed.name] : new RegExp(`</${parsed.name}\\s*>`, "ig");
|
|
332
345
|
closePattern.lastIndex = index;
|
|
333
346
|
const match = closePattern.exec(html);
|
|
334
347
|
const rawEnd = match?.index ?? html.length;
|
|
@@ -336,16 +349,20 @@ function parseInto(html, document, root, contextTag) {
|
|
|
336
349
|
index = match ? closePattern.lastIndex : html.length;
|
|
337
350
|
continue;
|
|
338
351
|
}
|
|
339
|
-
if (!VOID_ELEMENTS$1[parsed.name]
|
|
352
|
+
if (!(xmlLike ? parsed.selfClosing : VOID_ELEMENTS$1[parsed.name] || namespace === SVG_NAMESPACE$1 && parsed.selfClosing)) {
|
|
340
353
|
stack.push(element);
|
|
341
354
|
parent = element;
|
|
342
355
|
}
|
|
343
356
|
}
|
|
344
357
|
}
|
|
345
|
-
|
|
346
|
-
|
|
358
|
+
function isDoctypeAt(html, index) {
|
|
359
|
+
DOCTYPE_PATTERN.lastIndex = index;
|
|
360
|
+
return DOCTYPE_PATTERN.test(html);
|
|
361
|
+
}
|
|
362
|
+
/** Parse markup into a document fragment. `_contextTag` is accepted for compatibility and ignored. */
|
|
363
|
+
function parseFragment(html, document, _contextTag) {
|
|
347
364
|
const fragment = document.createDocumentFragment();
|
|
348
|
-
parseInto(html, document, fragment
|
|
365
|
+
parseInto(html, document, fragment);
|
|
349
366
|
return fragment;
|
|
350
367
|
}
|
|
351
368
|
/** Parse markup directly into a document. */
|
|
@@ -355,7 +372,24 @@ function parseDocument(html) {
|
|
|
355
372
|
return document;
|
|
356
373
|
}
|
|
357
374
|
//#endregion
|
|
358
|
-
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.
|
|
375
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/dom/selector.ts
|
|
376
|
+
const SUPPORTED_PSEUDOS = {
|
|
377
|
+
not: true,
|
|
378
|
+
is: true,
|
|
379
|
+
where: true,
|
|
380
|
+
"first-child": true,
|
|
381
|
+
"last-child": true,
|
|
382
|
+
"only-child": true,
|
|
383
|
+
empty: true,
|
|
384
|
+
root: true,
|
|
385
|
+
"nth-child": true,
|
|
386
|
+
"first-of-type": true,
|
|
387
|
+
"last-of-type": true
|
|
388
|
+
};
|
|
389
|
+
const ATTRIBUTE_PATTERN = /^\s*([^\s~|^$*!=]+)\s*(?:(\^=|\$=|\*=|~=|\|=|=)\s*(?:(["'])(.*?)\3|([^\s]+))\s*([isIS])?)?\s*$/;
|
|
390
|
+
const IDENTIFIER_CHARACTER = /[a-zA-Z0-9_-]/;
|
|
391
|
+
const MAX_CACHED_SELECTORS = 512;
|
|
392
|
+
const compiledSelectors = /* @__PURE__ */ new Map();
|
|
359
393
|
function splitTopLevel(value, delimiter) {
|
|
360
394
|
const parts = [];
|
|
361
395
|
let start = 0;
|
|
@@ -381,7 +415,7 @@ function splitTopLevel(value, delimiter) {
|
|
|
381
415
|
parts.push(value.slice(start).trim());
|
|
382
416
|
return parts.filter(Boolean);
|
|
383
417
|
}
|
|
384
|
-
function
|
|
418
|
+
function splitComplex(selector) {
|
|
385
419
|
const simples = [];
|
|
386
420
|
const combinators = [];
|
|
387
421
|
let current = "";
|
|
@@ -444,7 +478,7 @@ function readIdentifier(source, start) {
|
|
|
444
478
|
index += 2;
|
|
445
479
|
continue;
|
|
446
480
|
}
|
|
447
|
-
if (
|
|
481
|
+
if (!IDENTIFIER_CHARACTER.test(character)) break;
|
|
448
482
|
value += character;
|
|
449
483
|
index++;
|
|
450
484
|
}
|
|
@@ -466,81 +500,89 @@ function findClosing(source, start, opener, closer) {
|
|
|
466
500
|
}
|
|
467
501
|
return source.length - 1;
|
|
468
502
|
}
|
|
469
|
-
function
|
|
470
|
-
const match =
|
|
471
|
-
if (!match) return
|
|
503
|
+
function compileAttribute(expression) {
|
|
504
|
+
const match = ATTRIBUTE_PATTERN.exec(expression);
|
|
505
|
+
if (!match) return null;
|
|
472
506
|
const [, name, operator, , quotedValue, bareValue, flag] = match;
|
|
473
|
-
const
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
}
|
|
482
|
-
switch (operator) {
|
|
483
|
-
case "=": return left === right;
|
|
484
|
-
case "^=": return left.startsWith(right);
|
|
485
|
-
case "$=": return left.endsWith(right);
|
|
486
|
-
case "*=": return left.includes(right);
|
|
487
|
-
case "~=": return left.split(/\s+/).includes(right);
|
|
488
|
-
case "|=": return left === right || left.startsWith(`${right}-`);
|
|
489
|
-
default: return false;
|
|
490
|
-
}
|
|
507
|
+
const ignoreCase = flag?.toLowerCase() === "i";
|
|
508
|
+
const value = (quotedValue ?? bareValue ?? "").replace(/\\(.)/g, "$1");
|
|
509
|
+
return {
|
|
510
|
+
name,
|
|
511
|
+
operator,
|
|
512
|
+
value: ignoreCase ? value.toLowerCase() : value,
|
|
513
|
+
ignoreCase
|
|
514
|
+
};
|
|
491
515
|
}
|
|
492
|
-
function
|
|
493
|
-
const index = (element.parentElement?.children ?? []).indexOf(element) + 1;
|
|
516
|
+
function compileNth(expression) {
|
|
494
517
|
const normalized = expression.trim().toLowerCase().replace(/\s+/g, "");
|
|
495
|
-
if (normalized === "odd") return
|
|
496
|
-
if (normalized
|
|
497
|
-
|
|
518
|
+
if (normalized === "odd" || normalized === "even") return { kind: normalized };
|
|
519
|
+
if (/^[+-]?\d+$/.test(normalized)) return {
|
|
520
|
+
kind: "index",
|
|
521
|
+
index: Number(normalized)
|
|
522
|
+
};
|
|
498
523
|
const match = /^([+-]?\d*)n([+-]\d+)?$/.exec(normalized);
|
|
499
|
-
if (!match) return
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
524
|
+
if (!match) return { kind: "invalid" };
|
|
525
|
+
return {
|
|
526
|
+
kind: "formula",
|
|
527
|
+
coefficient: match[1] === "" || match[1] === "+" ? 1 : match[1] === "-" ? -1 : Number(match[1]),
|
|
528
|
+
offset: Number(match[2] ?? 0)
|
|
529
|
+
};
|
|
503
530
|
}
|
|
504
|
-
function
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
default: return false;
|
|
522
|
-
}
|
|
531
|
+
function compilePseudo(name, argument) {
|
|
532
|
+
if (!SUPPORTED_PSEUDOS[name]) return null;
|
|
533
|
+
if (name === "not" || name === "is" || name === "where") return argument === void 0 ? null : {
|
|
534
|
+
name,
|
|
535
|
+
list: compileSelector(argument),
|
|
536
|
+
nth: null
|
|
537
|
+
};
|
|
538
|
+
if (name === "nth-child") return argument === void 0 ? null : {
|
|
539
|
+
name,
|
|
540
|
+
list: null,
|
|
541
|
+
nth: compileNth(argument)
|
|
542
|
+
};
|
|
543
|
+
return {
|
|
544
|
+
name,
|
|
545
|
+
list: null,
|
|
546
|
+
nth: null
|
|
547
|
+
};
|
|
523
548
|
}
|
|
524
|
-
function
|
|
549
|
+
function compileCompound(selector) {
|
|
550
|
+
const compound = {
|
|
551
|
+
tag: null,
|
|
552
|
+
ids: [],
|
|
553
|
+
classes: [],
|
|
554
|
+
attributes: [],
|
|
555
|
+
pseudos: [],
|
|
556
|
+
invalid: false,
|
|
557
|
+
bare: false
|
|
558
|
+
};
|
|
525
559
|
let index = 0;
|
|
526
560
|
if (selector[index] === "*") index++;
|
|
527
561
|
else if (/[a-zA-Z_]/.test(selector[index] ?? "")) {
|
|
528
562
|
const tag = readIdentifier(selector, index);
|
|
529
|
-
|
|
563
|
+
compound.tag = tag.value.toLowerCase();
|
|
530
564
|
index = tag.end;
|
|
531
565
|
}
|
|
532
566
|
while (index < selector.length) {
|
|
533
567
|
const marker = selector[index];
|
|
534
568
|
if (marker === "#" || marker === ".") {
|
|
535
569
|
const identifier = readIdentifier(selector, index + 1);
|
|
536
|
-
if (!identifier.value)
|
|
537
|
-
|
|
570
|
+
if (!identifier.value) {
|
|
571
|
+
compound.invalid = true;
|
|
572
|
+
break;
|
|
573
|
+
}
|
|
574
|
+
(marker === "#" ? compound.ids : compound.classes).push(identifier.value);
|
|
538
575
|
index = identifier.end;
|
|
539
576
|
continue;
|
|
540
577
|
}
|
|
541
578
|
if (marker === "[") {
|
|
542
579
|
const end = findClosing(selector, index, "[", "]");
|
|
543
|
-
|
|
580
|
+
const attribute = compileAttribute(selector.slice(index + 1, end));
|
|
581
|
+
if (!attribute) {
|
|
582
|
+
compound.invalid = true;
|
|
583
|
+
break;
|
|
584
|
+
}
|
|
585
|
+
compound.attributes.push(attribute);
|
|
544
586
|
index = end + 1;
|
|
545
587
|
continue;
|
|
546
588
|
}
|
|
@@ -553,19 +595,151 @@ function matchSimple(element, selector) {
|
|
|
553
595
|
argument = selector.slice(index + 1, end);
|
|
554
596
|
index = end + 1;
|
|
555
597
|
}
|
|
556
|
-
|
|
598
|
+
const pseudo = compilePseudo(identifier.value.toLowerCase(), argument);
|
|
599
|
+
if (!pseudo) {
|
|
600
|
+
compound.invalid = true;
|
|
601
|
+
break;
|
|
602
|
+
}
|
|
603
|
+
compound.pseudos.push(pseudo);
|
|
557
604
|
continue;
|
|
558
605
|
}
|
|
559
|
-
|
|
606
|
+
compound.invalid = true;
|
|
607
|
+
break;
|
|
608
|
+
}
|
|
609
|
+
compound.bare = !compound.invalid && compound.ids.length === 0 && compound.classes.length === 0 && compound.attributes.length === 0 && compound.pseudos.length === 0;
|
|
610
|
+
return compound;
|
|
611
|
+
}
|
|
612
|
+
function compileSelector(selector) {
|
|
613
|
+
const cached = compiledSelectors.get(selector);
|
|
614
|
+
if (cached) return cached;
|
|
615
|
+
const list = {
|
|
616
|
+
universal: false,
|
|
617
|
+
tags: null,
|
|
618
|
+
complexes: []
|
|
619
|
+
};
|
|
620
|
+
for (const part of splitTopLevel(selector, ",")) {
|
|
621
|
+
const { simples, combinators } = splitComplex(part);
|
|
622
|
+
if (!simples.length) continue;
|
|
623
|
+
const compounds = simples.map(compileCompound);
|
|
624
|
+
const only = compounds[0];
|
|
625
|
+
if (compounds.length === 1 && only.bare) {
|
|
626
|
+
if (only.tag === null) list.universal = true;
|
|
627
|
+
else (list.tags ??= /* @__PURE__ */ new Set()).add(only.tag);
|
|
628
|
+
continue;
|
|
629
|
+
}
|
|
630
|
+
list.complexes.push({
|
|
631
|
+
compounds,
|
|
632
|
+
combinators
|
|
633
|
+
});
|
|
560
634
|
}
|
|
635
|
+
if (compiledSelectors.size >= MAX_CACHED_SELECTORS) compiledSelectors.clear();
|
|
636
|
+
compiledSelectors.set(selector, list);
|
|
637
|
+
return list;
|
|
638
|
+
}
|
|
639
|
+
function isWhitespace(code) {
|
|
640
|
+
return code === 32 || code >= 9 && code <= 13 || code === 160 || code === 5760 || code >= 8192 && code <= 8202 || code === 8232 || code === 8233 || code === 8239 || code === 8287 || code === 12288 || code === 65279;
|
|
641
|
+
}
|
|
642
|
+
/** Whether a whitespace-separated class string contains a token, without splitting it. */
|
|
643
|
+
function hasClassToken(className, token) {
|
|
644
|
+
if (!token) return false;
|
|
645
|
+
for (let index = 0; index < token.length; index++) if (isWhitespace(token.charCodeAt(index))) return false;
|
|
646
|
+
let from = 0;
|
|
647
|
+
while (true) {
|
|
648
|
+
const found = className.indexOf(token, from);
|
|
649
|
+
if (found < 0) return false;
|
|
650
|
+
const end = found + token.length;
|
|
651
|
+
if ((found === 0 || isWhitespace(className.charCodeAt(found - 1))) && (end === className.length || isWhitespace(className.charCodeAt(end)))) return true;
|
|
652
|
+
from = found + 1;
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
function matchAttribute(element, test) {
|
|
656
|
+
const actual = element.getAttribute(test.name);
|
|
657
|
+
if (!test.operator) return actual !== null;
|
|
658
|
+
if (actual === null) return false;
|
|
659
|
+
const left = test.ignoreCase ? actual.toLowerCase() : actual;
|
|
660
|
+
const right = test.value;
|
|
661
|
+
switch (test.operator) {
|
|
662
|
+
case "=": return left === right;
|
|
663
|
+
case "^=": return left.startsWith(right);
|
|
664
|
+
case "$=": return left.endsWith(right);
|
|
665
|
+
case "*=": return left.includes(right);
|
|
666
|
+
case "~=": return left.split(/\s+/).includes(right);
|
|
667
|
+
case "|=": return left === right || left.startsWith(`${right}-`);
|
|
668
|
+
default: return false;
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
/** One-based position among element siblings, or 0 without a parent element. */
|
|
672
|
+
function elementIndex(element) {
|
|
673
|
+
const parent = element.parentElement;
|
|
674
|
+
if (!parent) return 0;
|
|
675
|
+
let index = 0;
|
|
676
|
+
for (const sibling of parent.childNodes) {
|
|
677
|
+
if (!(sibling instanceof Element)) continue;
|
|
678
|
+
index++;
|
|
679
|
+
if (sibling === element) return index;
|
|
680
|
+
}
|
|
681
|
+
return 0;
|
|
682
|
+
}
|
|
683
|
+
function matchNth(element, test) {
|
|
684
|
+
if (test.kind === "invalid") return false;
|
|
685
|
+
const index = elementIndex(element);
|
|
686
|
+
switch (test.kind) {
|
|
687
|
+
case "odd": return index % 2 === 1;
|
|
688
|
+
case "even": return index % 2 === 0;
|
|
689
|
+
case "index": return index === test.index;
|
|
690
|
+
case "formula": return test.coefficient === 0 ? index === test.offset : (index - test.offset) / test.coefficient >= 0 && Number.isInteger((index - test.offset) / test.coefficient);
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
function hasSingleElementChild(parent) {
|
|
694
|
+
let count = 0;
|
|
695
|
+
for (const child of parent.childNodes) if (child instanceof Element && ++count > 1) return false;
|
|
696
|
+
return count === 1;
|
|
697
|
+
}
|
|
698
|
+
function matchPseudo(element, pseudo) {
|
|
699
|
+
switch (pseudo.name) {
|
|
700
|
+
case "not": return !matchesList(element, pseudo.list);
|
|
701
|
+
case "is":
|
|
702
|
+
case "where": return matchesList(element, pseudo.list);
|
|
703
|
+
case "first-child": return element.parentElement?.firstElementChild === element;
|
|
704
|
+
case "last-child": return element.parentElement?.lastElementChild === element;
|
|
705
|
+
case "only-child": {
|
|
706
|
+
const parent = element.parentElement;
|
|
707
|
+
return parent !== null && hasSingleElementChild(parent);
|
|
708
|
+
}
|
|
709
|
+
case "empty": return !element.hasChildNodes() || element.childNodes.every((child) => child.nodeType === Node.COMMENT_NODE || child.textContent === "");
|
|
710
|
+
case "root": return element.ownerDocument?.documentElement === element;
|
|
711
|
+
case "nth-child": return matchNth(element, pseudo.nth);
|
|
712
|
+
case "first-of-type":
|
|
713
|
+
for (let sibling = element.previousElementSibling; sibling; sibling = sibling.previousElementSibling) if (sibling.tagName === element.tagName) return false;
|
|
714
|
+
return true;
|
|
715
|
+
case "last-of-type":
|
|
716
|
+
for (let sibling = element.nextElementSibling; sibling; sibling = sibling.nextElementSibling) if (sibling.tagName === element.tagName) return false;
|
|
717
|
+
return true;
|
|
718
|
+
default: return false;
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
function matchCompound(element, compound) {
|
|
722
|
+
if (compound.invalid) return false;
|
|
723
|
+
if (compound.tag !== null && element.localName !== compound.tag) return false;
|
|
724
|
+
if (compound.bare) return true;
|
|
725
|
+
for (const id of compound.ids) if (element.id !== id) return false;
|
|
726
|
+
if (compound.classes.length) {
|
|
727
|
+
const className = element.className;
|
|
728
|
+
for (const token of compound.classes) if (!hasClassToken(className, token)) return false;
|
|
729
|
+
}
|
|
730
|
+
for (const attribute of compound.attributes) if (!matchAttribute(element, attribute)) return false;
|
|
731
|
+
for (const pseudo of compound.pseudos) if (!matchPseudo(element, pseudo)) return false;
|
|
561
732
|
return true;
|
|
562
733
|
}
|
|
563
734
|
function matchComplexAt(element, complex, index) {
|
|
564
|
-
if (!
|
|
735
|
+
if (!matchCompound(element, complex.compounds[index])) return false;
|
|
565
736
|
if (index === 0) return true;
|
|
566
737
|
const combinator = complex.combinators[index - 1] ?? " ";
|
|
567
738
|
if (combinator === ">") return element.parentElement !== null && matchComplexAt(element.parentElement, complex, index - 1);
|
|
568
|
-
if (combinator === "+")
|
|
739
|
+
if (combinator === "+") {
|
|
740
|
+
const previous = element.previousElementSibling;
|
|
741
|
+
return previous !== null && matchComplexAt(previous, complex, index - 1);
|
|
742
|
+
}
|
|
569
743
|
if (combinator === "~") {
|
|
570
744
|
for (let sibling = element.previousElementSibling; sibling; sibling = sibling.previousElementSibling) if (matchComplexAt(sibling, complex, index - 1)) return true;
|
|
571
745
|
return false;
|
|
@@ -573,27 +747,52 @@ function matchComplexAt(element, complex, index) {
|
|
|
573
747
|
for (let ancestor = element.parentElement; ancestor; ancestor = ancestor.parentElement) if (matchComplexAt(ancestor, complex, index - 1)) return true;
|
|
574
748
|
return false;
|
|
575
749
|
}
|
|
750
|
+
function matchesList(element, list) {
|
|
751
|
+
if (list.universal) return true;
|
|
752
|
+
if (list.tags?.has(element.localName)) return true;
|
|
753
|
+
for (const complex of list.complexes) if (matchComplexAt(element, complex, complex.compounds.length - 1)) return true;
|
|
754
|
+
return false;
|
|
755
|
+
}
|
|
756
|
+
function collectMatches(nodes, list, result) {
|
|
757
|
+
for (let index = 0; index < nodes.length; index++) {
|
|
758
|
+
const node = nodes[index];
|
|
759
|
+
if (node instanceof Element && matchesList(node, list)) result.push(node);
|
|
760
|
+
if (node.hasChildNodes()) collectMatches(node.childNodes, list, result);
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
function findMatch(nodes, list) {
|
|
764
|
+
for (let index = 0; index < nodes.length; index++) {
|
|
765
|
+
const node = nodes[index];
|
|
766
|
+
if (node instanceof Element && matchesList(node, list)) return node;
|
|
767
|
+
if (node.hasChildNodes()) {
|
|
768
|
+
const found = findMatch(node.childNodes, list);
|
|
769
|
+
if (found) return found;
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
return null;
|
|
773
|
+
}
|
|
576
774
|
/** Whether an element matches a CSS selector list. */
|
|
577
775
|
function matchesSelector(element, selector) {
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
776
|
+
return matchesList(element, compileSelector(selector));
|
|
777
|
+
}
|
|
778
|
+
/** Nearest inclusive ancestor of an element matching a CSS selector list. */
|
|
779
|
+
function closestMatching(element, selector) {
|
|
780
|
+
const list = compileSelector(selector);
|
|
781
|
+
for (let current = element; current; current = current.parentElement) if (matchesList(current, list)) return current;
|
|
782
|
+
return null;
|
|
583
783
|
}
|
|
584
784
|
/** Query descendants of a node in document order. */
|
|
585
|
-
function querySelectorAllFrom(root, selector,
|
|
785
|
+
function querySelectorAllFrom(root, selector, _includeRoot) {
|
|
586
786
|
const result = [];
|
|
587
|
-
|
|
588
|
-
if (node instanceof Element && matchesSelector(node, selector)) result.push(node);
|
|
589
|
-
for (const child of node.childNodes) visit(child);
|
|
590
|
-
};
|
|
591
|
-
if (includeRoot) for (const child of root.childNodes) visit(child);
|
|
592
|
-
else for (const child of root.childNodes) visit(child);
|
|
787
|
+
if (root.hasChildNodes()) collectMatches(root.childNodes, compileSelector(selector), result);
|
|
593
788
|
return result;
|
|
594
789
|
}
|
|
790
|
+
/** First descendant of a node in document order matching a selector, stopping at the first match. */
|
|
791
|
+
function querySelectorFrom(root, selector) {
|
|
792
|
+
return root.hasChildNodes() ? findMatch(root.childNodes, compileSelector(selector)) : null;
|
|
793
|
+
}
|
|
595
794
|
//#endregion
|
|
596
|
-
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.
|
|
795
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/dom/core.ts
|
|
597
796
|
/** Behavior-compatible reimplementation of linkedom's used surface. */
|
|
598
797
|
/** DOM node type constants. */
|
|
599
798
|
let NodeType = /* @__PURE__ */ function(NodeType) {
|
|
@@ -649,26 +848,29 @@ var CustomEvent = class extends Event {
|
|
|
649
848
|
};
|
|
650
849
|
/** Minimal event-target implementation used by DOM nodes and window. */
|
|
651
850
|
var EventTarget = class {
|
|
652
|
-
|
|
851
|
+
/** Allocated on the first `addEventListener`; most nodes never get listeners. */
|
|
852
|
+
#listeners;
|
|
653
853
|
/** Register an event listener. */
|
|
654
854
|
addEventListener(type, listener) {
|
|
655
855
|
if (!listener) return;
|
|
656
|
-
|
|
856
|
+
const listenerMap = this.#listeners ??= /* @__PURE__ */ new Map();
|
|
857
|
+
let listeners = listenerMap.get(type);
|
|
657
858
|
if (!listeners) {
|
|
658
859
|
listeners = /* @__PURE__ */ new Set();
|
|
659
|
-
|
|
860
|
+
listenerMap.set(type, listeners);
|
|
660
861
|
}
|
|
661
862
|
listeners.add(listener);
|
|
662
863
|
}
|
|
663
864
|
/** Remove an event listener. */
|
|
664
865
|
removeEventListener(type, listener) {
|
|
665
|
-
if (listener) this.#listeners
|
|
866
|
+
if (listener) this.#listeners?.get(type)?.delete(listener);
|
|
666
867
|
}
|
|
667
868
|
/** Dispatch an event to listeners and optionally through node ancestors. */
|
|
668
869
|
dispatchEvent(event) {
|
|
669
870
|
if (!event.target) event.target = this;
|
|
670
871
|
event.currentTarget = this;
|
|
671
|
-
|
|
872
|
+
const listeners = this.#listeners?.get(event.type);
|
|
873
|
+
for (const listener of listeners ? Array.from(listeners) : []) {
|
|
672
874
|
if (typeof listener === "function") listener.call(this, event);
|
|
673
875
|
else listener.handleEvent(event);
|
|
674
876
|
if (event.propagationStopped) break;
|
|
@@ -677,6 +879,8 @@ var EventTarget = class {
|
|
|
677
879
|
return !event.defaultPrevented;
|
|
678
880
|
}
|
|
679
881
|
};
|
|
882
|
+
/** Index of a node in its parent's `childNodes`, or -1; bound to Node's private index hint. */
|
|
883
|
+
let indexInParent;
|
|
680
884
|
/** Base class for the implemented DOM tree. */
|
|
681
885
|
var Node = class Node extends EventTarget {
|
|
682
886
|
static ELEMENT_NODE = 1;
|
|
@@ -689,32 +893,108 @@ var Node = class Node extends EventTarget {
|
|
|
689
893
|
nodeName;
|
|
690
894
|
parentNode = null;
|
|
691
895
|
ownerDocument;
|
|
692
|
-
|
|
896
|
+
/** Allocated on first access or insertion, so leaf nodes (text, comments, attributes) usually never allocate. */
|
|
897
|
+
#childNodes;
|
|
898
|
+
/** Last known index in the parent's `childNodes`; always verified before use, so a stale value only costs a rescan. */
|
|
899
|
+
#index = 0;
|
|
900
|
+
static {
|
|
901
|
+
indexInParent = (node) => {
|
|
902
|
+
const siblings = node.#siblings();
|
|
903
|
+
return siblings ? node.#indexIn(siblings) : -1;
|
|
904
|
+
};
|
|
905
|
+
}
|
|
693
906
|
constructor(nodeType, nodeName, ownerDocument = null) {
|
|
694
907
|
super();
|
|
695
908
|
this.nodeType = nodeType;
|
|
696
909
|
this.nodeName = nodeName;
|
|
697
910
|
this.ownerDocument = ownerDocument;
|
|
698
911
|
}
|
|
912
|
+
/** Child nodes in tree order. */
|
|
913
|
+
get childNodes() {
|
|
914
|
+
this.#childNodes ??= [];
|
|
915
|
+
return this.#childNodes;
|
|
916
|
+
}
|
|
917
|
+
set childNodes(value) {
|
|
918
|
+
this.#childNodes = value;
|
|
919
|
+
}
|
|
920
|
+
/** Whether this node has any children (without allocating a child list). */
|
|
921
|
+
hasChildNodes() {
|
|
922
|
+
return this.#childNodes !== void 0 && this.#childNodes.length > 0;
|
|
923
|
+
}
|
|
699
924
|
/** First child node, if present. */
|
|
700
925
|
get firstChild() {
|
|
701
|
-
return this
|
|
926
|
+
return this.#childNodes?.[0] ?? null;
|
|
702
927
|
}
|
|
703
928
|
/** Last child node, if present. */
|
|
704
929
|
get lastChild() {
|
|
705
|
-
|
|
930
|
+
const children = this.#childNodes;
|
|
931
|
+
return children ? children[children.length - 1] ?? null : null;
|
|
706
932
|
}
|
|
707
933
|
/** Previous node with the same parent. */
|
|
708
934
|
get previousSibling() {
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
935
|
+
const siblings = this.#siblings();
|
|
936
|
+
if (!siblings) return null;
|
|
937
|
+
const index = this.#indexIn(siblings);
|
|
938
|
+
return index > 0 ? siblings[index - 1] : null;
|
|
712
939
|
}
|
|
713
940
|
/** Next node with the same parent. */
|
|
714
941
|
get nextSibling() {
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
942
|
+
const siblings = this.#siblings();
|
|
943
|
+
if (!siblings) return null;
|
|
944
|
+
const index = this.#indexIn(siblings);
|
|
945
|
+
return index >= 0 ? siblings[index + 1] ?? null : null;
|
|
946
|
+
}
|
|
947
|
+
/** The parent's child list, without allocating one. */
|
|
948
|
+
#siblings() {
|
|
949
|
+
const parent = this.parentNode;
|
|
950
|
+
return parent ? parent.#childNodes : void 0;
|
|
951
|
+
}
|
|
952
|
+
/** Locate this node in `siblings` via the index hint, re-indexing all siblings on a miss. */
|
|
953
|
+
#indexIn(siblings) {
|
|
954
|
+
const hint = this.#index;
|
|
955
|
+
if (siblings[hint] === this) return hint;
|
|
956
|
+
if (siblings[hint + 1] === this) return ++this.#index;
|
|
957
|
+
if (hint > 0 && siblings[hint - 1] === this) return --this.#index;
|
|
958
|
+
let found = -1;
|
|
959
|
+
for (let index = 0; index < siblings.length; index++) {
|
|
960
|
+
const sibling = siblings[index];
|
|
961
|
+
sibling.#index = index;
|
|
962
|
+
if (found < 0 && sibling === this) found = index;
|
|
963
|
+
}
|
|
964
|
+
if (found >= 0) this.#index = found;
|
|
965
|
+
return found;
|
|
966
|
+
}
|
|
967
|
+
/** Index of a child in this node's `childNodes`, or -1. */
|
|
968
|
+
#childIndex(child) {
|
|
969
|
+
const children = this.#childNodes;
|
|
970
|
+
if (!children) return -1;
|
|
971
|
+
return child?.parentNode === this ? child.#indexIn(children) : children.indexOf(child);
|
|
972
|
+
}
|
|
973
|
+
/** Move every child of a fragment into this node at `index` (append for null). */
|
|
974
|
+
#adoptChildren(fragment, index) {
|
|
975
|
+
const moved = fragment.#childNodes;
|
|
976
|
+
if (!moved?.length) return;
|
|
977
|
+
if (moved.some((nested) => nested.parentNode !== fragment || nested instanceof DocumentFragment)) {
|
|
978
|
+
const reference = index === null ? null : this.#childNodes?.[index] ?? null;
|
|
979
|
+
for (const nested of Array.from(moved)) if (reference === null) this.appendChild(nested);
|
|
980
|
+
else this.insertBefore(nested, reference);
|
|
981
|
+
return;
|
|
982
|
+
}
|
|
983
|
+
const document = this.documentForCreation();
|
|
984
|
+
const nodes = moved.slice();
|
|
985
|
+
moved.length = 0;
|
|
986
|
+
const children = this.#childNodes ??= [];
|
|
987
|
+
const tail = index === null ? [] : children.splice(index);
|
|
988
|
+
for (const node of nodes) {
|
|
989
|
+
node.parentNode = this;
|
|
990
|
+
node.setOwnerDocument(document);
|
|
991
|
+
node.#index = children.length;
|
|
992
|
+
children.push(node);
|
|
993
|
+
}
|
|
994
|
+
for (const node of tail) {
|
|
995
|
+
node.#index = children.length;
|
|
996
|
+
children.push(node);
|
|
997
|
+
}
|
|
718
998
|
}
|
|
719
999
|
/** Connectedness to a document. */
|
|
720
1000
|
get isConnected() {
|
|
@@ -729,7 +1009,11 @@ var Node = class Node extends EventTarget {
|
|
|
729
1009
|
set nodeValue(_value) {}
|
|
730
1010
|
/** Text contained by this node. */
|
|
731
1011
|
get textContent() {
|
|
732
|
-
|
|
1012
|
+
const children = this.#childNodes;
|
|
1013
|
+
if (!children?.length) return "";
|
|
1014
|
+
const only = children[0];
|
|
1015
|
+
if (children.length === 1 && only instanceof Text) return only.data;
|
|
1016
|
+
return collectText(children);
|
|
733
1017
|
}
|
|
734
1018
|
set textContent(value) {
|
|
735
1019
|
this.replaceChildren();
|
|
@@ -744,41 +1028,45 @@ var Node = class Node extends EventTarget {
|
|
|
744
1028
|
const node = child;
|
|
745
1029
|
if (node === this || node.contains(this)) throw new Error("The new child is an ancestor of this node");
|
|
746
1030
|
if (child instanceof DocumentFragment) {
|
|
747
|
-
|
|
1031
|
+
this.#adoptChildren(child, null);
|
|
748
1032
|
return child;
|
|
749
1033
|
}
|
|
750
1034
|
child.parentNode?.removeChild(child);
|
|
751
1035
|
child.parentNode = this;
|
|
752
1036
|
child.setOwnerDocument(this.documentForCreation());
|
|
753
|
-
this
|
|
1037
|
+
const children = this.#childNodes ??= [];
|
|
1038
|
+
node.#index = children.length;
|
|
1039
|
+
children.push(child);
|
|
754
1040
|
return child;
|
|
755
1041
|
}
|
|
756
1042
|
/** Insert a node before a current child, or append for null. */
|
|
757
1043
|
insertBefore(child, reference) {
|
|
758
1044
|
if (reference === null) return this.appendChild(child);
|
|
759
|
-
const index = this
|
|
1045
|
+
const index = this.#childIndex(reference);
|
|
760
1046
|
if (index < 0) throw new Error("The reference node is not a child of this node");
|
|
761
1047
|
if (child instanceof DocumentFragment) {
|
|
762
|
-
|
|
1048
|
+
this.#adoptChildren(child, index);
|
|
763
1049
|
return child;
|
|
764
1050
|
}
|
|
765
1051
|
child.parentNode?.removeChild(child);
|
|
766
1052
|
child.parentNode = this;
|
|
767
1053
|
child.setOwnerDocument(this.documentForCreation());
|
|
1054
|
+
const node = child;
|
|
1055
|
+
node.#index = index;
|
|
768
1056
|
this.childNodes.splice(index, 0, child);
|
|
769
1057
|
return child;
|
|
770
1058
|
}
|
|
771
1059
|
/** Replace a current child with another node. */
|
|
772
1060
|
replaceChild(child, previous) {
|
|
773
|
-
const index = this
|
|
1061
|
+
const index = this.#childIndex(previous);
|
|
774
1062
|
if (index < 0) throw new Error("The node to replace is not a child of this node");
|
|
775
1063
|
this.removeChild(previous);
|
|
776
|
-
this.insertBefore(child, this
|
|
1064
|
+
this.insertBefore(child, this.#childNodes?.[index] ?? null);
|
|
777
1065
|
return previous;
|
|
778
1066
|
}
|
|
779
1067
|
/** Remove a current child. */
|
|
780
1068
|
removeChild(child) {
|
|
781
|
-
const index = this
|
|
1069
|
+
const index = this.#childIndex(child);
|
|
782
1070
|
if (index < 0) throw new Error("The node to remove is not a child of this node");
|
|
783
1071
|
this.childNodes.splice(index, 1);
|
|
784
1072
|
child.parentNode = null;
|
|
@@ -786,8 +1074,9 @@ var Node = class Node extends EventTarget {
|
|
|
786
1074
|
}
|
|
787
1075
|
/** Replace all children with nodes or strings. */
|
|
788
1076
|
replaceChildren(...children) {
|
|
789
|
-
|
|
790
|
-
|
|
1077
|
+
const previous = this.#childNodes;
|
|
1078
|
+
if (previous) for (const child of previous) child.parentNode = null;
|
|
1079
|
+
this.#childNodes = void 0;
|
|
791
1080
|
this.append(...children);
|
|
792
1081
|
}
|
|
793
1082
|
/** Append nodes or strings. */
|
|
@@ -818,7 +1107,7 @@ var Node = class Node extends EventTarget {
|
|
|
818
1107
|
/** Clone this node, optionally including descendants. */
|
|
819
1108
|
cloneNode(deep = false) {
|
|
820
1109
|
const clone = new Node(this.nodeType, this.nodeName, this.ownerDocument);
|
|
821
|
-
if (deep) for (const child of this
|
|
1110
|
+
if (deep && this.#childNodes) for (const child of this.#childNodes) clone.appendChild(child.cloneNode(true));
|
|
822
1111
|
return clone;
|
|
823
1112
|
}
|
|
824
1113
|
/** Compare tree position sufficiently for document-order consumers. */
|
|
@@ -830,14 +1119,15 @@ var Node = class Node extends EventTarget {
|
|
|
830
1119
|
const nodes = [];
|
|
831
1120
|
const visit = (node) => {
|
|
832
1121
|
nodes.push(node);
|
|
833
|
-
for (const child of node
|
|
1122
|
+
for (const child of node.#childNodes ?? []) visit(child);
|
|
834
1123
|
};
|
|
835
1124
|
visit(root);
|
|
836
1125
|
return nodes.indexOf(this) < nodes.indexOf(other) ? 4 : 2;
|
|
837
1126
|
}
|
|
838
1127
|
setOwnerDocument(document) {
|
|
839
1128
|
if (this.nodeType !== 9) this.ownerDocument = document;
|
|
840
|
-
|
|
1129
|
+
const children = this.#childNodes;
|
|
1130
|
+
if (children) for (const child of children) child.setOwnerDocument(document);
|
|
841
1131
|
}
|
|
842
1132
|
documentForCreation() {
|
|
843
1133
|
if (this instanceof Document) return this;
|
|
@@ -924,7 +1214,11 @@ var NamedNodeMap = class extends Array {
|
|
|
924
1214
|
/** Find an attribute case-insensitively. */
|
|
925
1215
|
getNamedItem(name) {
|
|
926
1216
|
const normalized = name.toLowerCase();
|
|
927
|
-
|
|
1217
|
+
for (let index = 0; index < this.length; index++) {
|
|
1218
|
+
const attr = this[index];
|
|
1219
|
+
if (attr.name === normalized || attr.name.toLowerCase() === normalized) return attr;
|
|
1220
|
+
}
|
|
1221
|
+
return null;
|
|
928
1222
|
}
|
|
929
1223
|
/** Set an attribute object and return the prior one. */
|
|
930
1224
|
setNamedItem(attr) {
|
|
@@ -975,7 +1269,7 @@ var DOMTokenList = class {
|
|
|
975
1269
|
}
|
|
976
1270
|
/** Whether a class token exists. */
|
|
977
1271
|
contains(token) {
|
|
978
|
-
return this.#
|
|
1272
|
+
return hasClassToken(this.#element.className, token);
|
|
979
1273
|
}
|
|
980
1274
|
/** Toggle a class token. */
|
|
981
1275
|
toggle(token, force) {
|
|
@@ -1007,13 +1301,18 @@ var DOMTokenList = class {
|
|
|
1007
1301
|
};
|
|
1008
1302
|
/** Mutable inline style declaration. */
|
|
1009
1303
|
var CSSStyleDeclaration = class {
|
|
1010
|
-
|
|
1304
|
+
/** Allocated on the first non-empty declaration. */
|
|
1305
|
+
#values;
|
|
1306
|
+
/** Serialized declarations; `undefined` after a change until the next read. */
|
|
1307
|
+
#cssText = "";
|
|
1011
1308
|
/** Serialized declarations. */
|
|
1012
1309
|
get cssText() {
|
|
1013
|
-
|
|
1310
|
+
this.#cssText ??= this.#values ? [...this.#values].map(([name, value]) => `${name}: ${value};`).join(" ") : "";
|
|
1311
|
+
return this.#cssText;
|
|
1014
1312
|
}
|
|
1015
1313
|
set cssText(value) {
|
|
1016
|
-
this.#values
|
|
1314
|
+
this.#values?.clear();
|
|
1315
|
+
this.#cssText = void 0;
|
|
1017
1316
|
for (const declaration of value.split(";")) {
|
|
1018
1317
|
const colon = declaration.indexOf(":");
|
|
1019
1318
|
if (colon > 0) this.setProperty(declaration.slice(0, colon).trim(), declaration.slice(colon + 1).trim());
|
|
@@ -1021,31 +1320,42 @@ var CSSStyleDeclaration = class {
|
|
|
1021
1320
|
}
|
|
1022
1321
|
/** Read a CSS property. */
|
|
1023
1322
|
getPropertyValue(name) {
|
|
1024
|
-
return this.#values
|
|
1323
|
+
return this.#values?.get(name) ?? "";
|
|
1025
1324
|
}
|
|
1026
1325
|
/** Set a CSS property. */
|
|
1027
1326
|
setProperty(name, value, _priority) {
|
|
1028
|
-
if (value === null || value === "")
|
|
1029
|
-
|
|
1327
|
+
if (value === null || value === "") {
|
|
1328
|
+
if (this.#values?.delete(name)) this.#cssText = void 0;
|
|
1329
|
+
return;
|
|
1330
|
+
}
|
|
1331
|
+
this.#values ??= /* @__PURE__ */ new Map();
|
|
1332
|
+
this.#values.set(name, String(value));
|
|
1333
|
+
this.#cssText = void 0;
|
|
1030
1334
|
}
|
|
1031
1335
|
/** Remove and return a CSS property. */
|
|
1032
1336
|
removeProperty(name) {
|
|
1033
1337
|
const value = this.getPropertyValue(name);
|
|
1034
|
-
this.#values
|
|
1338
|
+
if (this.#values?.delete(name)) this.#cssText = void 0;
|
|
1035
1339
|
return value;
|
|
1036
1340
|
}
|
|
1037
1341
|
};
|
|
1038
1342
|
const HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
|
|
1039
1343
|
const SVG_NAMESPACE = "http://www.w3.org/2000/svg";
|
|
1344
|
+
/** An element's inline style when one has been created; bound to Element's private field. */
|
|
1345
|
+
let inlineStyleOf;
|
|
1040
1346
|
/** DOM element with attributes, selectors, and HTML serialization. */
|
|
1041
1347
|
var Element = class Element extends Node {
|
|
1042
1348
|
localName;
|
|
1043
1349
|
tagName;
|
|
1044
1350
|
namespaceURI;
|
|
1045
1351
|
qualifiedName;
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1352
|
+
/** Attribute, class-list and style objects are created on first use. */
|
|
1353
|
+
#attributes;
|
|
1354
|
+
#classList;
|
|
1355
|
+
#style;
|
|
1356
|
+
static {
|
|
1357
|
+
inlineStyleOf = (element) => element.#style;
|
|
1358
|
+
}
|
|
1049
1359
|
constructor(tagName, ownerDocument = null, namespaceURI = HTML_NAMESPACE) {
|
|
1050
1360
|
const localName = tagName.toLowerCase();
|
|
1051
1361
|
const qualified = namespaceURI === HTML_NAMESPACE ? localName.toUpperCase() : tagName;
|
|
@@ -1054,29 +1364,58 @@ var Element = class Element extends Node {
|
|
|
1054
1364
|
this.tagName = qualified;
|
|
1055
1365
|
this.qualifiedName = tagName;
|
|
1056
1366
|
this.namespaceURI = namespaceURI;
|
|
1057
|
-
|
|
1367
|
+
}
|
|
1368
|
+
/** Attribute collection. */
|
|
1369
|
+
get attributes() {
|
|
1370
|
+
this.#attributes ??= new NamedNodeMap();
|
|
1371
|
+
return this.#attributes;
|
|
1372
|
+
}
|
|
1373
|
+
/** Class token list over the `class` attribute. */
|
|
1374
|
+
get classList() {
|
|
1375
|
+
this.#classList ??= new DOMTokenList(this);
|
|
1376
|
+
return this.#classList;
|
|
1377
|
+
}
|
|
1378
|
+
/** Inline style declaration. */
|
|
1379
|
+
get style() {
|
|
1380
|
+
this.#style ??= new CSSStyleDeclaration();
|
|
1381
|
+
return this.#style;
|
|
1382
|
+
}
|
|
1383
|
+
/** Whether the element has any attribute objects (without allocating the collection). */
|
|
1384
|
+
hasAttributes() {
|
|
1385
|
+
return this.#attributes !== void 0 && this.#attributes.length > 0;
|
|
1058
1386
|
}
|
|
1059
1387
|
/** Element children. */
|
|
1060
1388
|
get children() {
|
|
1061
|
-
return this
|
|
1389
|
+
return childElements(this);
|
|
1062
1390
|
}
|
|
1063
1391
|
/** First element child. */
|
|
1064
1392
|
get firstElementChild() {
|
|
1065
|
-
return this
|
|
1393
|
+
return firstElementIn(this);
|
|
1066
1394
|
}
|
|
1067
1395
|
/** Last element child. */
|
|
1068
1396
|
get lastElementChild() {
|
|
1069
|
-
|
|
1070
|
-
return children[children.length - 1] ?? null;
|
|
1397
|
+
return lastElementIn(this);
|
|
1071
1398
|
}
|
|
1072
1399
|
/** Previous sibling that is an element. */
|
|
1073
1400
|
get previousElementSibling() {
|
|
1074
|
-
|
|
1401
|
+
const index = indexInParent(this);
|
|
1402
|
+
if (index < 0) return null;
|
|
1403
|
+
const siblings = this.parentNode.childNodes;
|
|
1404
|
+
for (let position = index - 1; position >= 0; position--) {
|
|
1405
|
+
const sibling = siblings[position];
|
|
1406
|
+
if (sibling instanceof Element) return sibling;
|
|
1407
|
+
}
|
|
1075
1408
|
return null;
|
|
1076
1409
|
}
|
|
1077
1410
|
/** Next sibling that is an element. */
|
|
1078
1411
|
get nextElementSibling() {
|
|
1079
|
-
|
|
1412
|
+
const index = indexInParent(this);
|
|
1413
|
+
if (index < 0) return null;
|
|
1414
|
+
const siblings = this.parentNode.childNodes;
|
|
1415
|
+
for (let position = index + 1; position < siblings.length; position++) {
|
|
1416
|
+
const sibling = siblings[position];
|
|
1417
|
+
if (sibling instanceof Element) return sibling;
|
|
1418
|
+
}
|
|
1080
1419
|
return null;
|
|
1081
1420
|
}
|
|
1082
1421
|
/** Attribute-backed element id. */
|
|
@@ -1120,11 +1459,11 @@ var Element = class Element extends Node {
|
|
|
1120
1459
|
get text() {}
|
|
1121
1460
|
/** HTML contained inside this element. */
|
|
1122
1461
|
get innerHTML() {
|
|
1123
|
-
return this
|
|
1462
|
+
return serializeChildren(this);
|
|
1124
1463
|
}
|
|
1125
1464
|
set innerHTML(value) {
|
|
1126
1465
|
this.replaceChildren();
|
|
1127
|
-
|
|
1466
|
+
parseInto(value, this.documentForCreation(), this);
|
|
1128
1467
|
}
|
|
1129
1468
|
/** Serialized element and descendants. */
|
|
1130
1469
|
get outerHTML() {
|
|
@@ -1133,30 +1472,34 @@ var Element = class Element extends Node {
|
|
|
1133
1472
|
set outerHTML(value) {
|
|
1134
1473
|
const parent = this.parentNode;
|
|
1135
1474
|
if (!parent) return;
|
|
1136
|
-
|
|
1137
|
-
for (const child of Array.from(fragment.childNodes)) parent.insertBefore(child, this);
|
|
1475
|
+
parent.insertBefore(parseFragment(value, this.documentForCreation()), this);
|
|
1138
1476
|
parent.removeChild(this);
|
|
1139
1477
|
}
|
|
1140
1478
|
/** Read an attribute. */
|
|
1141
1479
|
getAttribute(name) {
|
|
1142
|
-
|
|
1143
|
-
|
|
1480
|
+
const style = this.#style;
|
|
1481
|
+
if (style && name.toLowerCase() === "style") {
|
|
1482
|
+
const cssText = style.cssText;
|
|
1483
|
+
if (cssText) return cssText;
|
|
1484
|
+
}
|
|
1485
|
+
return this.#attributes?.getNamedItem(name)?.value ?? null;
|
|
1144
1486
|
}
|
|
1145
1487
|
/** Read an attribute object. */
|
|
1146
1488
|
getAttributeNode(name) {
|
|
1147
|
-
return this
|
|
1489
|
+
return this.#attributes?.getNamedItem(name) ?? null;
|
|
1148
1490
|
}
|
|
1149
1491
|
/** Whether an attribute exists. */
|
|
1150
1492
|
hasAttribute(name) {
|
|
1151
|
-
return this
|
|
1493
|
+
return (this.#attributes?.getNamedItem(name) ?? null) !== null || this.#style !== void 0 && name.toLowerCase() === "style" && Boolean(this.#style.cssText);
|
|
1152
1494
|
}
|
|
1153
1495
|
/** Set an attribute. */
|
|
1154
1496
|
setAttribute(name, value) {
|
|
1155
1497
|
const normalized = name.toLowerCase();
|
|
1156
1498
|
if (normalized === "style") this.style.cssText = String(value);
|
|
1157
|
-
const
|
|
1499
|
+
const attributes = this.attributes;
|
|
1500
|
+
const existing = attributes.getNamedItem(normalized);
|
|
1158
1501
|
if (existing) existing.value = String(value);
|
|
1159
|
-
else
|
|
1502
|
+
else attributes.unshift(new Attr(name, String(value), this.ownerDocument));
|
|
1160
1503
|
}
|
|
1161
1504
|
/** Set a namespaced attribute. */
|
|
1162
1505
|
setAttributeNS(_namespace, name, value) {
|
|
@@ -1164,13 +1507,14 @@ var Element = class Element extends Node {
|
|
|
1164
1507
|
}
|
|
1165
1508
|
/** Remove an attribute. */
|
|
1166
1509
|
removeAttribute(name) {
|
|
1167
|
-
const
|
|
1168
|
-
|
|
1169
|
-
if (
|
|
1510
|
+
const attributes = this.#attributes;
|
|
1511
|
+
const existing = attributes?.getNamedItem(name);
|
|
1512
|
+
if (attributes && existing) attributes.splice(attributes.indexOf(existing), 1);
|
|
1513
|
+
if (this.#style && name.toLowerCase() === "style") this.#style.cssText = "";
|
|
1170
1514
|
}
|
|
1171
1515
|
/** Find the first descendant matching a selector. */
|
|
1172
1516
|
querySelector(selector) {
|
|
1173
|
-
return
|
|
1517
|
+
return querySelectorFrom(this, selector);
|
|
1174
1518
|
}
|
|
1175
1519
|
/** Find all descendants matching a selector. */
|
|
1176
1520
|
querySelectorAll(selector) {
|
|
@@ -1182,8 +1526,7 @@ var Element = class Element extends Node {
|
|
|
1182
1526
|
}
|
|
1183
1527
|
/** Find the nearest matching ancestor including this element. */
|
|
1184
1528
|
closest(selector) {
|
|
1185
|
-
|
|
1186
|
-
return null;
|
|
1529
|
+
return closestMatching(this, selector);
|
|
1187
1530
|
}
|
|
1188
1531
|
/** Descendant elements with a tag name. */
|
|
1189
1532
|
getElementsByTagName(tagName) {
|
|
@@ -1192,7 +1535,10 @@ var Element = class Element extends Node {
|
|
|
1192
1535
|
/** Descendant elements containing all requested class tokens. */
|
|
1193
1536
|
getElementsByClassName(classNames) {
|
|
1194
1537
|
const tokens = classNames.trim().split(/\s+/).filter(Boolean);
|
|
1195
|
-
return querySelectorAllFrom(this, "*", false).filter((element) =>
|
|
1538
|
+
return querySelectorAllFrom(this, "*", false).filter((element) => {
|
|
1539
|
+
const className = element.className;
|
|
1540
|
+
return tokens.every((token) => hasClassToken(className, token));
|
|
1541
|
+
});
|
|
1196
1542
|
}
|
|
1197
1543
|
/**
|
|
1198
1544
|
* Return a zero-sized rectangle because this parser DOM has no layout.
|
|
@@ -1229,11 +1575,12 @@ var Element = class Element extends Node {
|
|
|
1229
1575
|
}
|
|
1230
1576
|
cloneNode(deep = false) {
|
|
1231
1577
|
const clone = this.ownerDocument?.createElementNS(this.namespaceURI, this.qualifiedName) ?? new Element(this.qualifiedName, null, this.namespaceURI);
|
|
1232
|
-
|
|
1233
|
-
|
|
1578
|
+
const attributes = this.#attributes;
|
|
1579
|
+
if (attributes) for (let index = attributes.length - 1; index >= 0; index--) {
|
|
1580
|
+
const attr = attributes[index];
|
|
1234
1581
|
clone.setAttribute(attr.name, attr.value);
|
|
1235
1582
|
}
|
|
1236
|
-
if (deep) for (const child of this.childNodes) clone.appendChild(child.cloneNode(true));
|
|
1583
|
+
if (deep && this.hasChildNodes()) for (const child of this.childNodes) clone.appendChild(child.cloneNode(true));
|
|
1237
1584
|
return clone;
|
|
1238
1585
|
}
|
|
1239
1586
|
};
|
|
@@ -1301,20 +1648,19 @@ var DocumentFragment = class DocumentFragment extends Node {
|
|
|
1301
1648
|
}
|
|
1302
1649
|
/** Element children. */
|
|
1303
1650
|
get children() {
|
|
1304
|
-
return this
|
|
1651
|
+
return childElements(this);
|
|
1305
1652
|
}
|
|
1306
1653
|
/** First element child. */
|
|
1307
1654
|
get firstElementChild() {
|
|
1308
|
-
return this
|
|
1655
|
+
return firstElementIn(this);
|
|
1309
1656
|
}
|
|
1310
1657
|
/** Last element child. */
|
|
1311
1658
|
get lastElementChild() {
|
|
1312
|
-
|
|
1313
|
-
return children[children.length - 1] ?? null;
|
|
1659
|
+
return lastElementIn(this);
|
|
1314
1660
|
}
|
|
1315
1661
|
/** First matching descendant. */
|
|
1316
1662
|
querySelector(selector) {
|
|
1317
|
-
return
|
|
1663
|
+
return querySelectorFrom(this, selector);
|
|
1318
1664
|
}
|
|
1319
1665
|
/** All matching descendants. */
|
|
1320
1666
|
querySelectorAll(selector) {
|
|
@@ -1334,11 +1680,11 @@ var HTMLTemplateElement = class HTMLTemplateElement extends HTMLElement {
|
|
|
1334
1680
|
this.content = new DocumentFragment(ownerDocument);
|
|
1335
1681
|
}
|
|
1336
1682
|
get innerHTML() {
|
|
1337
|
-
return this.content
|
|
1683
|
+
return serializeChildren(this.content);
|
|
1338
1684
|
}
|
|
1339
1685
|
set innerHTML(value) {
|
|
1340
1686
|
this.content.replaceChildren();
|
|
1341
|
-
|
|
1687
|
+
parseInto(value, this.documentForCreation(), this.content);
|
|
1342
1688
|
}
|
|
1343
1689
|
get textContent() {
|
|
1344
1690
|
return this.content.textContent ?? "";
|
|
@@ -1379,28 +1725,28 @@ var Document = class Document extends Node {
|
|
|
1379
1725
|
}
|
|
1380
1726
|
/** Root element of the document. */
|
|
1381
1727
|
get documentElement() {
|
|
1382
|
-
return this
|
|
1728
|
+
return firstElementIn(this);
|
|
1383
1729
|
}
|
|
1384
1730
|
/** Element children. */
|
|
1385
1731
|
get children() {
|
|
1386
|
-
return this
|
|
1732
|
+
return childElements(this);
|
|
1387
1733
|
}
|
|
1388
1734
|
/** HTML body, or a detached empty body when absent like linkedom. */
|
|
1389
1735
|
get body() {
|
|
1390
|
-
const body = this
|
|
1736
|
+
const body = querySelectorFrom(this, "body");
|
|
1391
1737
|
return body instanceof HTMLElement ? body : this.createElement("body");
|
|
1392
1738
|
}
|
|
1393
1739
|
/** HTML head, or a detached empty head when absent. */
|
|
1394
1740
|
get head() {
|
|
1395
|
-
const head = this
|
|
1741
|
+
const head = querySelectorFrom(this, "head");
|
|
1396
1742
|
return head instanceof HTMLElement ? head : this.createElement("head");
|
|
1397
1743
|
}
|
|
1398
1744
|
/** Document title text. */
|
|
1399
1745
|
get title() {
|
|
1400
|
-
return this
|
|
1746
|
+
return querySelectorFrom(this, "title")?.textContent ?? "";
|
|
1401
1747
|
}
|
|
1402
1748
|
set title(value) {
|
|
1403
|
-
let title = this
|
|
1749
|
+
let title = querySelectorFrom(this, "title");
|
|
1404
1750
|
if (!title) {
|
|
1405
1751
|
title = this.createElement("title");
|
|
1406
1752
|
this.head.appendChild(title);
|
|
@@ -1444,12 +1790,12 @@ var Document = class Document extends Node {
|
|
|
1444
1790
|
}
|
|
1445
1791
|
/** Find the first element by id. */
|
|
1446
1792
|
getElementById(id) {
|
|
1447
|
-
const element =
|
|
1793
|
+
const element = SELECTOR_SAFE_ID.test(id) ? findElementById(this, id) : querySelectorFrom(this, `#${cssEscapeIdentifier(id)}`);
|
|
1448
1794
|
return element instanceof HTMLElement ? element : null;
|
|
1449
1795
|
}
|
|
1450
1796
|
/** Find the first matching descendant. */
|
|
1451
1797
|
querySelector(selector) {
|
|
1452
|
-
return
|
|
1798
|
+
return querySelectorFrom(this, selector);
|
|
1453
1799
|
}
|
|
1454
1800
|
/** Find all matching descendants. */
|
|
1455
1801
|
querySelectorAll(selector) {
|
|
@@ -1462,7 +1808,10 @@ var Document = class Document extends Node {
|
|
|
1462
1808
|
/** Descendant elements containing all class tokens. */
|
|
1463
1809
|
getElementsByClassName(classNames) {
|
|
1464
1810
|
const tokens = classNames.trim().split(/\s+/).filter(Boolean);
|
|
1465
|
-
return this.querySelectorAll("*").filter((element) =>
|
|
1811
|
+
return this.querySelectorAll("*").filter((element) => {
|
|
1812
|
+
const className = element.className;
|
|
1813
|
+
return tokens.every((token) => hasClassToken(className, token));
|
|
1814
|
+
});
|
|
1466
1815
|
}
|
|
1467
1816
|
/** Adopt a node into this document. */
|
|
1468
1817
|
adoptNode(node) {
|
|
@@ -1581,31 +1930,98 @@ const BOOLEAN_ATTRIBUTES = {
|
|
|
1581
1930
|
reversed: true,
|
|
1582
1931
|
selected: true
|
|
1583
1932
|
};
|
|
1933
|
+
const TEXT_ESCAPE_PATTERN = /[&\u00a0<>]/;
|
|
1934
|
+
/** Ids whose escaped `#id` selector parses as one plain id compound (no combinators, lists, quotes or groups). */
|
|
1935
|
+
const SELECTOR_SAFE_ID = /^[^\s,>+~"'[\]()\\]+$/;
|
|
1584
1936
|
function escapeText(value) {
|
|
1585
|
-
|
|
1937
|
+
if (!TEXT_ESCAPE_PATTERN.test(value)) return value;
|
|
1938
|
+
return value.replace(/&/g, "&").replace(/\u00a0/g, " ").replace(/</g, "<").replace(/>/g, ">");
|
|
1586
1939
|
}
|
|
1587
1940
|
function escapeAttribute(value) {
|
|
1588
|
-
return value.replace(/"/g, """);
|
|
1941
|
+
return value.includes("\"") ? value.replace(/"/g, """) : value;
|
|
1942
|
+
}
|
|
1943
|
+
/** Serialize a node's children; `raw` emits text data unescaped (script/style content). */
|
|
1944
|
+
function serializeChildren(parent, raw = false) {
|
|
1945
|
+
if (!parent.hasChildNodes()) return "";
|
|
1946
|
+
let html = "";
|
|
1947
|
+
for (const child of parent.childNodes) html += raw && child instanceof Text ? child.data : serializeNode(child);
|
|
1948
|
+
return html;
|
|
1589
1949
|
}
|
|
1590
1950
|
/** Serialize a DOM node as HTML. */
|
|
1591
1951
|
function serializeNode(node) {
|
|
1592
1952
|
if (node instanceof Comment) return `<!--${node.data}-->`;
|
|
1593
1953
|
if (node instanceof Text) return node.serializeRaw ? node.data : escapeText(node.data);
|
|
1594
|
-
if (node instanceof Document || node instanceof DocumentFragment) return node
|
|
1954
|
+
if (node instanceof Document || node instanceof DocumentFragment) return serializeChildren(node);
|
|
1595
1955
|
if (!(node instanceof Element)) return "";
|
|
1596
|
-
|
|
1597
|
-
const
|
|
1598
|
-
const opening
|
|
1956
|
+
let opening = `<${node.qualifiedName}`;
|
|
1957
|
+
const hasAttributes = node.hasAttributes();
|
|
1958
|
+
if (hasAttributes) for (const attr of node.attributes) opening += attr.value === "" && BOOLEAN_ATTRIBUTES[attr.name.toLowerCase()] ? ` ${attr.name}` : ` ${attr.name}="${escapeAttribute(attr.value)}"`;
|
|
1959
|
+
const cssText = inlineStyleOf(node)?.cssText;
|
|
1960
|
+
if (cssText && !(hasAttributes && node.attributes.getNamedItem("style"))) opening += ` style="${escapeAttribute(cssText)}"`;
|
|
1961
|
+
opening += ">";
|
|
1599
1962
|
if (VOID_ELEMENTS[node.localName]) return opening;
|
|
1600
1963
|
const raw = node.localName === "script" || node.localName === "style";
|
|
1601
|
-
const
|
|
1602
|
-
return `${opening}${
|
|
1964
|
+
const content = serializeChildren(node instanceof HTMLTemplateElement ? node.content : node, raw);
|
|
1965
|
+
return `${opening}${content}</${node.qualifiedName}>`;
|
|
1966
|
+
}
|
|
1967
|
+
function childElements(parent) {
|
|
1968
|
+
return parent.hasChildNodes() ? parent.childNodes.filter((child) => child instanceof Element) : [];
|
|
1969
|
+
}
|
|
1970
|
+
function firstElementIn(parent) {
|
|
1971
|
+
if (!parent.hasChildNodes()) return null;
|
|
1972
|
+
for (const child of parent.childNodes) if (child instanceof Element) return child;
|
|
1973
|
+
return null;
|
|
1974
|
+
}
|
|
1975
|
+
function lastElementIn(parent) {
|
|
1976
|
+
if (!parent.hasChildNodes()) return null;
|
|
1977
|
+
const children = parent.childNodes;
|
|
1978
|
+
for (let index = children.length - 1; index >= 0; index--) {
|
|
1979
|
+
const child = children[index];
|
|
1980
|
+
if (child instanceof Element) return child;
|
|
1981
|
+
}
|
|
1982
|
+
return null;
|
|
1983
|
+
}
|
|
1984
|
+
/** First descendant element in document order whose `id` equals `id`. */
|
|
1985
|
+
function findElementById(parent, id) {
|
|
1986
|
+
if (!parent.hasChildNodes()) return null;
|
|
1987
|
+
for (const child of parent.childNodes) {
|
|
1988
|
+
if (child instanceof Element && child.id === id) return child;
|
|
1989
|
+
const found = findElementById(child, id);
|
|
1990
|
+
if (found) return found;
|
|
1991
|
+
}
|
|
1992
|
+
return null;
|
|
1993
|
+
}
|
|
1994
|
+
/**
|
|
1995
|
+
* Concatenate descendant text iteratively, mirroring each node type's `textContent`: character data and
|
|
1996
|
+
* attributes contribute their value, documents nothing, templates their content fragment.
|
|
1997
|
+
*/
|
|
1998
|
+
function collectText(children) {
|
|
1999
|
+
let text = "";
|
|
2000
|
+
const pending = [];
|
|
2001
|
+
for (let index = children.length - 1; index >= 0; index--) pending.push(children[index]);
|
|
2002
|
+
while (pending.length > 0) {
|
|
2003
|
+
const node = pending.pop();
|
|
2004
|
+
if (node instanceof Text) {
|
|
2005
|
+
text += node.data;
|
|
2006
|
+
continue;
|
|
2007
|
+
}
|
|
2008
|
+
if (node instanceof Attr) {
|
|
2009
|
+
text += node.value;
|
|
2010
|
+
continue;
|
|
2011
|
+
}
|
|
2012
|
+
if (node instanceof Document) continue;
|
|
2013
|
+
const owner = node instanceof HTMLTemplateElement ? node.content : node;
|
|
2014
|
+
if (!owner.hasChildNodes()) continue;
|
|
2015
|
+
const nested = owner.childNodes;
|
|
2016
|
+
for (let index = nested.length - 1; index >= 0; index--) pending.push(nested[index]);
|
|
2017
|
+
}
|
|
2018
|
+
return text;
|
|
1603
2019
|
}
|
|
1604
2020
|
function cssEscapeIdentifier(value) {
|
|
1605
2021
|
return value.replace(/([^a-zA-Z0-9_-])/g, "\\$1");
|
|
1606
2022
|
}
|
|
1607
2023
|
//#endregion
|
|
1608
|
-
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.
|
|
2024
|
+
//#region node_modules/.pnpm/@oh-my-pi+pi-utils@18.12.6/node_modules/@oh-my-pi/pi-utils/src/dom.ts
|
|
1609
2025
|
/** Behavior-compatible reimplementation of linkedom's used surface. */
|
|
1610
2026
|
/** Parse HTML or XML-like markup into a lightweight window and document. */
|
|
1611
2027
|
function parseHTML(html) {
|