@levischuck/tiny-html 0.0.4 → 0.1.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/dist/index.d.ts +14 -3
- package/dist/index.js +474 -289
- package/dist/parser.d.ts +2 -2
- package/dist/safe-html.d.ts +15 -0
- package/dist/types.d.ts +76 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { ParseResult, HtmlNode, WriterOptions } from './types.ts';
|
|
1
|
+
import { ParseResult, HtmlNode, WriterOptions, SafeHtmlOptions, ParserOptions } from './types.ts';
|
|
2
2
|
/**
|
|
3
3
|
* Parses HTML string into a ParseResult containing HtmlNode
|
|
4
|
+
* @param html - The HTML string to parse
|
|
5
|
+
* @param options - Parser options including attributeNaming ('reactName' or 'exactName')
|
|
4
6
|
*/
|
|
5
|
-
export declare function readHtml(html: string): ParseResult;
|
|
7
|
+
export declare function readHtml(html: string, options?: ParserOptions): ParseResult;
|
|
6
8
|
/**
|
|
7
9
|
* Renders HtmlNode or ParseResult to HTML string
|
|
8
10
|
*/
|
|
@@ -12,8 +14,17 @@ export declare function writeHtml(input: HtmlNode | ParseResult, options?: Write
|
|
|
12
14
|
* Returns a new HtmlNode with all promises resolved
|
|
13
15
|
*/
|
|
14
16
|
export declare function awaitHtmlNode(node: HtmlNode | Promise<HtmlNode>): Promise<HtmlNode>;
|
|
17
|
+
/**
|
|
18
|
+
* Sanitizes an HtmlNode tree by removing disallowed tags, attributes, and URLs.
|
|
19
|
+
* - Tags not in allowedTags have their content retained (folded into parent)
|
|
20
|
+
* - Images replaced with their alt text when removed
|
|
21
|
+
* - Attributes not in the tag's allowed list are dropped
|
|
22
|
+
* - Classes are filtered by allowedClasses patterns (supports wildcards)
|
|
23
|
+
* - URLs not matching allowedLinkProtocols cause the element to be removed
|
|
24
|
+
*/
|
|
25
|
+
export declare function safeHtml(node: HtmlNode, options?: SafeHtmlOptions): HtmlNode;
|
|
15
26
|
export { htmlNodeTo } from './convert.ts';
|
|
16
27
|
export { decodeHtmlEntities, encodeHtmlEntities } from './entities.ts';
|
|
17
28
|
export type { CreateElementFn, CreateElementProps } from './convert.ts';
|
|
18
29
|
export { getTextContent } from './writer.ts';
|
|
19
|
-
export type { WriterOptions, ParseResult, HtmlNode, HtmlElement, HtmlProps, HtmlStyle } from './types.ts';
|
|
30
|
+
export type { WriterOptions, ParseResult, HtmlNode, HtmlElement, HtmlProps, HtmlStyle, SafeHtmlOptions, AllowedTag, ParserOptions, ParserAttributeNaming, WriterAttributeNaming, } from './types.ts';
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const $ = /* @__PURE__ */ new Set([
|
|
2
2
|
"area",
|
|
3
3
|
"base",
|
|
4
4
|
"br",
|
|
@@ -13,7 +13,7 @@ const F = /* @__PURE__ */ new Set([
|
|
|
13
13
|
"source",
|
|
14
14
|
"track",
|
|
15
15
|
"wbr"
|
|
16
|
-
]),
|
|
16
|
+
]), K = /* @__PURE__ */ new Set([
|
|
17
17
|
// Containers
|
|
18
18
|
"div",
|
|
19
19
|
"span",
|
|
@@ -110,7 +110,7 @@ const F = /* @__PURE__ */ new Set([
|
|
|
110
110
|
"body",
|
|
111
111
|
"title",
|
|
112
112
|
"meta"
|
|
113
|
-
]),
|
|
113
|
+
]), H = /* @__PURE__ */ new Map([
|
|
114
114
|
["p", /* @__PURE__ */ new Set(["p"])],
|
|
115
115
|
["li", /* @__PURE__ */ new Set(["li"])],
|
|
116
116
|
["dt", /* @__PURE__ */ new Set(["dt", "dd"])],
|
|
@@ -123,7 +123,7 @@ const F = /* @__PURE__ */ new Set([
|
|
|
123
123
|
["tr", /* @__PURE__ */ new Set(["tr"])],
|
|
124
124
|
["td", /* @__PURE__ */ new Set(["td", "th"])],
|
|
125
125
|
["th", /* @__PURE__ */ new Set(["td", "th"])]
|
|
126
|
-
]),
|
|
126
|
+
]), B = /* @__PURE__ */ new Map([
|
|
127
127
|
["altglyph", "altGlyph"],
|
|
128
128
|
["altglyphdef", "altGlyphDef"],
|
|
129
129
|
["altglyphitem", "altGlyphItem"],
|
|
@@ -161,7 +161,7 @@ const F = /* @__PURE__ */ new Set([
|
|
|
161
161
|
["lineargradient", "linearGradient"],
|
|
162
162
|
["radialgradient", "radialGradient"],
|
|
163
163
|
["textpath", "textPath"]
|
|
164
|
-
]),
|
|
164
|
+
]), V = /* @__PURE__ */ new Map([
|
|
165
165
|
["attributename", "attributeName"],
|
|
166
166
|
["attributetype", "attributeType"],
|
|
167
167
|
["basefrequency", "baseFrequency"],
|
|
@@ -220,7 +220,7 @@ const F = /* @__PURE__ */ new Set([
|
|
|
220
220
|
["xchannelselector", "xChannelSelector"],
|
|
221
221
|
["ychannelselector", "yChannelSelector"],
|
|
222
222
|
["zoomandpan", "zoomAndPan"]
|
|
223
|
-
]),
|
|
223
|
+
]), P = {
|
|
224
224
|
lt: "<",
|
|
225
225
|
gt: ">",
|
|
226
226
|
amp: "&",
|
|
@@ -291,44 +291,44 @@ const F = /* @__PURE__ */ new Set([
|
|
|
291
291
|
rArr: "⇒",
|
|
292
292
|
dArr: "⇓",
|
|
293
293
|
hArr: "⇔"
|
|
294
|
-
},
|
|
295
|
-
for (const [e,
|
|
296
|
-
|
|
297
|
-
function
|
|
298
|
-
return !e || typeof e != "string" || !e.includes("&") ? e : e.replace(/&(?:#[xX]([0-9a-fA-F]+)|#(\d+)|([a-zA-Z][a-zA-Z0-9]*));/g, (
|
|
299
|
-
if (
|
|
300
|
-
const
|
|
301
|
-
return String.fromCodePoint(
|
|
294
|
+
}, W = {};
|
|
295
|
+
for (const [e, t] of Object.entries(P))
|
|
296
|
+
W[t] || (W[t] = e);
|
|
297
|
+
function O(e) {
|
|
298
|
+
return !e || typeof e != "string" || !e.includes("&") ? e : e.replace(/&(?:#[xX]([0-9a-fA-F]+)|#(\d+)|([a-zA-Z][a-zA-Z0-9]*));/g, (t, i, l, s) => {
|
|
299
|
+
if (i) {
|
|
300
|
+
const a = parseInt(i, 16);
|
|
301
|
+
return String.fromCodePoint(a);
|
|
302
302
|
} else if (l) {
|
|
303
|
-
const
|
|
304
|
-
return String.fromCodePoint(
|
|
305
|
-
} else if (
|
|
306
|
-
return
|
|
307
|
-
return
|
|
303
|
+
const a = parseInt(l, 10);
|
|
304
|
+
return String.fromCodePoint(a);
|
|
305
|
+
} else if (s && P[s])
|
|
306
|
+
return P[s];
|
|
307
|
+
return t;
|
|
308
308
|
});
|
|
309
309
|
}
|
|
310
|
-
function
|
|
310
|
+
function G(e, t = !1) {
|
|
311
311
|
if (!e || typeof e != "string")
|
|
312
312
|
return e;
|
|
313
|
-
let
|
|
314
|
-
return
|
|
313
|
+
let i = e;
|
|
314
|
+
return i = i.replace(/&/g, "&"), i = i.replace(/</g, "<"), i = i.replace(/>/g, ">"), t && (i = i.replace(/"/g, """)), i;
|
|
315
315
|
}
|
|
316
|
-
function
|
|
316
|
+
function J(e) {
|
|
317
317
|
return e.replace(/\]\]>/g, "]]]]></g, (
|
|
319
|
+
function Z(e) {
|
|
320
|
+
return e.replace(/[-_]([a-z])/g, (t, i) => i.toUpperCase());
|
|
321
321
|
}
|
|
322
|
-
function
|
|
323
|
-
return e.replace(/[A-Z]/g, (
|
|
322
|
+
function ee(e) {
|
|
323
|
+
return e.replace(/[A-Z]/g, (t) => `-${t.toLowerCase()}`);
|
|
324
324
|
}
|
|
325
|
-
function
|
|
326
|
-
return new TextDecoder("utf-8").decode(e.slice(
|
|
325
|
+
function b(e, t, i) {
|
|
326
|
+
return new TextDecoder("utf-8").decode(e.slice(t, i));
|
|
327
327
|
}
|
|
328
|
-
function
|
|
328
|
+
function C(e) {
|
|
329
329
|
return e === 32 || e === 9 || e === 10 || e === 13;
|
|
330
330
|
}
|
|
331
|
-
function
|
|
331
|
+
function S(e) {
|
|
332
332
|
return e >= 97 && e <= 122 || // a-z
|
|
333
333
|
e >= 65 && e <= 90 || // A-Z
|
|
334
334
|
e >= 48 && e <= 57 || // 0-9
|
|
@@ -336,419 +336,604 @@ function N(e) {
|
|
|
336
336
|
e === 95 || // _
|
|
337
337
|
e === 58;
|
|
338
338
|
}
|
|
339
|
-
function
|
|
340
|
-
const
|
|
339
|
+
function te(e, t = {}) {
|
|
340
|
+
const i = t.attributeNaming ?? "reactName", s = new TextEncoder().encode(e), a = {
|
|
341
341
|
node: []
|
|
342
|
-
},
|
|
343
|
-
let
|
|
344
|
-
function
|
|
345
|
-
return o.length > 0 ? o[o.length - 1].children :
|
|
342
|
+
}, p = [], o = [];
|
|
343
|
+
let T = "HTML", n = "TEXT", r = 0, h = 0, g = 0, E = 0, N = 0, y = "", q = 0, d = null;
|
|
344
|
+
function x() {
|
|
345
|
+
return o.length > 0 ? o[o.length - 1].children : p;
|
|
346
346
|
}
|
|
347
|
-
function
|
|
348
|
-
if (
|
|
349
|
-
const
|
|
350
|
-
|
|
347
|
+
function D(f, c) {
|
|
348
|
+
if (f >= c) return;
|
|
349
|
+
const u = b(s, f, c), m = O(u);
|
|
350
|
+
m.length > 0 && x().push(m);
|
|
351
351
|
}
|
|
352
|
-
function
|
|
353
|
-
if (
|
|
354
|
-
const
|
|
355
|
-
|
|
352
|
+
function M(f, c) {
|
|
353
|
+
if (f >= c) return;
|
|
354
|
+
const u = b(s, f, c);
|
|
355
|
+
u.length > 0 && x().push(u);
|
|
356
356
|
}
|
|
357
|
-
function
|
|
358
|
-
const
|
|
359
|
-
return
|
|
357
|
+
function v(f, c) {
|
|
358
|
+
const u = f.toLowerCase();
|
|
359
|
+
return c === "SVG" && B.has(u) ? B.get(u) : u;
|
|
360
360
|
}
|
|
361
|
-
function
|
|
362
|
-
const
|
|
363
|
-
|
|
364
|
-
if (p === "for") return "htmlFor";
|
|
365
|
-
if (f === "SVG")
|
|
366
|
-
return z.has(p) ? z.get(p) : s;
|
|
367
|
-
if (f === "HTML") {
|
|
368
|
-
const T = k(p);
|
|
369
|
-
return p === "class" || p === "for" ? p === "class" ? "className" : "htmlFor" : T;
|
|
370
|
-
}
|
|
371
|
-
return p;
|
|
361
|
+
function L(f, c) {
|
|
362
|
+
const u = f.toLowerCase();
|
|
363
|
+
return u === "class" ? i === "exactName" ? "class" : "className" : u === "for" ? i === "exactName" ? "for" : "htmlFor" : c === "SVG" ? V.has(u) ? V.get(u) : f : c === "HTML" ? Z(u) : u;
|
|
372
364
|
}
|
|
373
|
-
function
|
|
374
|
-
const
|
|
375
|
-
for (let
|
|
376
|
-
if (o[
|
|
377
|
-
for (let
|
|
378
|
-
const
|
|
379
|
-
type:
|
|
365
|
+
function I(f) {
|
|
366
|
+
const c = v(f, T);
|
|
367
|
+
for (let u = o.length - 1; u >= 0; u--)
|
|
368
|
+
if (o[u].type === c) {
|
|
369
|
+
for (let m = o.length - 1; m >= u; m--) {
|
|
370
|
+
const A = o.pop(), w = {
|
|
371
|
+
type: A.type,
|
|
380
372
|
props: {
|
|
381
|
-
...
|
|
382
|
-
children:
|
|
373
|
+
...A.props,
|
|
374
|
+
children: A.children.length === 1 ? A.children[0] : A.children
|
|
383
375
|
}
|
|
384
376
|
};
|
|
385
|
-
o.length > 0 ? o[o.length - 1].children.push(
|
|
377
|
+
o.length > 0 ? o[o.length - 1].children.push(w) : p.push(w), (A.type === "svg" || A.type === "math") && (T = "HTML");
|
|
386
378
|
}
|
|
387
379
|
return;
|
|
388
380
|
}
|
|
389
381
|
}
|
|
390
|
-
function
|
|
391
|
-
const
|
|
392
|
-
if (o.length > 0 &&
|
|
393
|
-
const
|
|
394
|
-
|
|
382
|
+
function _(f, c, u) {
|
|
383
|
+
const m = v(f, T);
|
|
384
|
+
if (o.length > 0 && H.has(m)) {
|
|
385
|
+
const w = H.get(m), z = o[o.length - 1].type;
|
|
386
|
+
w.has(z) && I(z);
|
|
395
387
|
}
|
|
396
|
-
let
|
|
397
|
-
if (
|
|
398
|
-
const
|
|
399
|
-
type:
|
|
400
|
-
props:
|
|
388
|
+
let A = T;
|
|
389
|
+
if (m === "svg" ? A = "SVG" : m === "math" && (A = "MATHML"), $.has(m) || u) {
|
|
390
|
+
const w = {
|
|
391
|
+
type: m,
|
|
392
|
+
props: c
|
|
401
393
|
};
|
|
402
|
-
|
|
394
|
+
x().push(w);
|
|
403
395
|
} else {
|
|
404
|
-
const
|
|
405
|
-
type:
|
|
406
|
-
props:
|
|
396
|
+
const w = {
|
|
397
|
+
type: m,
|
|
398
|
+
props: c,
|
|
407
399
|
children: [],
|
|
408
|
-
namespace:
|
|
400
|
+
namespace: A
|
|
409
401
|
};
|
|
410
|
-
o.push(
|
|
402
|
+
o.push(w), T = A;
|
|
411
403
|
}
|
|
412
404
|
}
|
|
413
|
-
for (;
|
|
414
|
-
const
|
|
415
|
-
switch (
|
|
405
|
+
for (; r < s.length; ) {
|
|
406
|
+
const f = s[r];
|
|
407
|
+
switch (n) {
|
|
416
408
|
case "TEXT":
|
|
417
|
-
|
|
409
|
+
f === 60 && (D(h, r), n = "TAG_OPEN"), r++;
|
|
418
410
|
break;
|
|
419
411
|
case "TAG_OPEN":
|
|
420
|
-
|
|
412
|
+
f === 33 ? s[r + 1] === 45 && s[r + 2] === 45 ? (n = "COMMENT", r += 3) : s[r + 1] === 68 || s[r + 1] === 100 ? b(s, r, Math.min(r + 20, s.length)).toLowerCase().startsWith("!doctype") ? (n = "DOCTYPE", g = r, r++) : (h = r - 1, n = "TEXT") : s[r + 1] === 91 && s[r + 2] === 67 && b(s, r, Math.min(r + 9, s.length)).startsWith("![CDATA[") ? (n = "CDATA", h = r + 8, r += 8) : (h = r - 1, n = "TEXT") : f === 63 ? (n = "PROCESSING_INSTRUCTION", g = r - 1, r++) : f === 47 ? (n = "TAG_CLOSE_START", r++) : S(f) ? (g = r, n = "TAG_NAME", d = null, r++) : (h = r - 1, n = "TEXT");
|
|
421
413
|
break;
|
|
422
414
|
case "TAG_NAME":
|
|
423
|
-
if (
|
|
424
|
-
const
|
|
425
|
-
|
|
426
|
-
type:
|
|
415
|
+
if (C(f)) {
|
|
416
|
+
const c = b(s, g, r), u = c.toLowerCase();
|
|
417
|
+
d = {
|
|
418
|
+
type: c,
|
|
427
419
|
props: {},
|
|
428
420
|
children: [],
|
|
429
|
-
namespace:
|
|
430
|
-
},
|
|
431
|
-
} else if (
|
|
432
|
-
const
|
|
433
|
-
|
|
434
|
-
const
|
|
435
|
-
|
|
436
|
-
} else
|
|
421
|
+
namespace: u === "svg" ? "SVG" : u === "math" ? "MATHML" : T
|
|
422
|
+
}, n = "ATTRIBUTES", r++;
|
|
423
|
+
} else if (f === 62) {
|
|
424
|
+
const c = b(s, g, r);
|
|
425
|
+
_(c, {}, !1);
|
|
426
|
+
const u = v(c, T);
|
|
427
|
+
u === "script" ? (n = "SCRIPT_CONTENT", h = r + 1) : u === "style" ? (n = "STYLE_CONTENT", h = r + 1) : (n = "TEXT", h = r + 1), r++;
|
|
428
|
+
} else f === 47 ? (n = "TAG_CLOSE_SELF", r++) : S(f) ? r++ : (h = g - 1, n = "TEXT");
|
|
437
429
|
break;
|
|
438
430
|
case "ATTRIBUTES":
|
|
439
|
-
if (
|
|
440
|
-
|
|
441
|
-
else if (
|
|
442
|
-
const
|
|
443
|
-
|
|
444
|
-
const
|
|
445
|
-
|
|
446
|
-
} else
|
|
431
|
+
if (C(f))
|
|
432
|
+
r++;
|
|
433
|
+
else if (f === 62) {
|
|
434
|
+
const c = d.type;
|
|
435
|
+
_(c, d.props, !1);
|
|
436
|
+
const u = v(c, T);
|
|
437
|
+
u === "script" ? (n = "SCRIPT_CONTENT", h = r + 1) : u === "style" ? (n = "STYLE_CONTENT", h = r + 1) : (n = "TEXT", h = r + 1), r++;
|
|
438
|
+
} else f === 47 ? (n = "TAG_CLOSE_SELF", r++) : S(f) ? (E = r, n = "ATTRIBUTE_NAME", r++) : (h = g - 1, n = "TEXT");
|
|
447
439
|
break;
|
|
448
440
|
case "ATTRIBUTE_NAME":
|
|
449
|
-
if (
|
|
450
|
-
|
|
451
|
-
const
|
|
452
|
-
|
|
453
|
-
} else if (
|
|
454
|
-
|
|
455
|
-
else if (
|
|
456
|
-
|
|
457
|
-
const
|
|
458
|
-
|
|
459
|
-
const
|
|
460
|
-
|
|
461
|
-
const
|
|
462
|
-
|
|
463
|
-
} else if (
|
|
464
|
-
|
|
465
|
-
const
|
|
466
|
-
|
|
467
|
-
} else
|
|
441
|
+
if (C(f)) {
|
|
442
|
+
y = b(s, E, r);
|
|
443
|
+
const c = L(y, d.namespace);
|
|
444
|
+
d.props[c] = !0, y = "", n = "ATTRIBUTES", r++;
|
|
445
|
+
} else if (f === 61)
|
|
446
|
+
y = b(s, E, r), n = "ATTRIBUTE_VALUE_START", r++;
|
|
447
|
+
else if (f === 62) {
|
|
448
|
+
y = b(s, E, r);
|
|
449
|
+
const c = L(y, d.namespace);
|
|
450
|
+
d.props[c] = !0, y = "";
|
|
451
|
+
const u = d.type;
|
|
452
|
+
_(u, d.props, !1);
|
|
453
|
+
const m = v(u, T);
|
|
454
|
+
m === "script" ? (n = "SCRIPT_CONTENT", h = r + 1) : m === "style" ? (n = "STYLE_CONTENT", h = r + 1) : (n = "TEXT", h = r + 1), r++;
|
|
455
|
+
} else if (f === 47) {
|
|
456
|
+
y = b(s, E, r);
|
|
457
|
+
const c = L(y, d.namespace);
|
|
458
|
+
d.props[c] = !0, y = "", n = "TAG_CLOSE_SELF", r++;
|
|
459
|
+
} else S(f) ? r++ : (h = g - 1, n = "TEXT");
|
|
468
460
|
break;
|
|
469
461
|
case "ATTRIBUTE_VALUE_START":
|
|
470
|
-
|
|
462
|
+
C(f) ? r++ : f === 34 || f === 39 ? (q = f, N = r + 1, n = "ATTRIBUTE_VALUE_QUOTED", r++) : (N = r, n = "ATTRIBUTE_VALUE_UNQUOTED");
|
|
471
463
|
break;
|
|
472
464
|
case "ATTRIBUTE_VALUE_QUOTED":
|
|
473
|
-
if (
|
|
474
|
-
const
|
|
475
|
-
|
|
465
|
+
if (f === q) {
|
|
466
|
+
const c = b(s, N, r), u = O(c), m = L(y, d.namespace);
|
|
467
|
+
m === "style" ? d.props[m] = F(u) : d.props[m] = u, y = "", n = "ATTRIBUTES", r++;
|
|
476
468
|
} else
|
|
477
|
-
|
|
469
|
+
r++;
|
|
478
470
|
break;
|
|
479
471
|
case "ATTRIBUTE_VALUE_UNQUOTED":
|
|
480
|
-
if (
|
|
481
|
-
const
|
|
482
|
-
|
|
472
|
+
if (C(f) || f === 62 || f === 47) {
|
|
473
|
+
const c = b(s, N, r), u = O(c), m = L(y, d.namespace);
|
|
474
|
+
m === "style" ? d.props[m] = F(u) : d.props[m] = u, y = "", n = "ATTRIBUTES";
|
|
483
475
|
} else
|
|
484
|
-
|
|
476
|
+
r++;
|
|
485
477
|
break;
|
|
486
478
|
case "TAG_CLOSE_SELF":
|
|
487
|
-
if (
|
|
488
|
-
const
|
|
489
|
-
|
|
479
|
+
if (f === 62) {
|
|
480
|
+
const c = d.type;
|
|
481
|
+
_(c, d.props, !0), n = "TEXT", h = r + 1, r++;
|
|
490
482
|
} else
|
|
491
|
-
|
|
483
|
+
h = g - 1, n = "TEXT";
|
|
492
484
|
break;
|
|
493
485
|
case "TAG_CLOSE_START":
|
|
494
|
-
|
|
486
|
+
S(f) ? (g = r, n = "TAG_CLOSE_NAME", r++) : (h = r - 2, n = "TEXT");
|
|
495
487
|
break;
|
|
496
488
|
case "TAG_CLOSE_NAME":
|
|
497
|
-
if (
|
|
498
|
-
const
|
|
499
|
-
|
|
500
|
-
} else
|
|
489
|
+
if (f === 62) {
|
|
490
|
+
const c = b(s, g, r);
|
|
491
|
+
I(c), n = "TEXT", h = r + 1, r++;
|
|
492
|
+
} else C(f) || S(f) ? r++ : (h = g - 2, n = "TEXT");
|
|
501
493
|
break;
|
|
502
494
|
case "COMMENT":
|
|
503
|
-
|
|
495
|
+
f === 45 && s[r + 1] === 45 && s[r + 2] === 62 ? (n = "TEXT", h = r + 3, r += 3) : r++;
|
|
504
496
|
break;
|
|
505
497
|
case "DOCTYPE":
|
|
506
|
-
if (
|
|
507
|
-
const
|
|
508
|
-
|
|
498
|
+
if (f === 62) {
|
|
499
|
+
const c = b(s, g, r + 1);
|
|
500
|
+
a.doctype = "<" + c, n = "TEXT", h = r + 1, r++;
|
|
509
501
|
} else
|
|
510
|
-
|
|
502
|
+
r++;
|
|
511
503
|
break;
|
|
512
504
|
case "CDATA":
|
|
513
|
-
|
|
505
|
+
f === 93 && s[r + 1] === 93 && s[r + 2] === 62 ? (M(h, r), n = "TEXT", h = r + 3, r += 3) : r++;
|
|
514
506
|
break;
|
|
515
507
|
case "PROCESSING_INSTRUCTION":
|
|
516
|
-
if (
|
|
517
|
-
const
|
|
518
|
-
|
|
508
|
+
if (f === 63 && s[r + 1] === 62) {
|
|
509
|
+
const c = b(s, g, r + 2);
|
|
510
|
+
a.xml = c, n = "TEXT", h = r + 2, r += 2;
|
|
519
511
|
} else
|
|
520
|
-
|
|
512
|
+
r++;
|
|
521
513
|
break;
|
|
522
514
|
case "SCRIPT_CONTENT":
|
|
523
515
|
case "STYLE_CONTENT":
|
|
524
|
-
if (
|
|
525
|
-
const
|
|
526
|
-
if (
|
|
527
|
-
|
|
528
|
-
let
|
|
529
|
-
for (;
|
|
530
|
-
|
|
516
|
+
if (f === 60 && s[r + 1] === 47) {
|
|
517
|
+
const c = n === "SCRIPT_CONTENT" ? "script" : "style", u = "</" + c, m = b(s, r, Math.min(r + u.length + 1, s.length)).toLowerCase();
|
|
518
|
+
if (m.startsWith(u) && (m[u.length] === ">" || C(m.charCodeAt(u.length)))) {
|
|
519
|
+
M(h, r);
|
|
520
|
+
let A = r + u.length;
|
|
521
|
+
for (; A < s.length && s[A] !== 62; ) A++;
|
|
522
|
+
I(c), n = "TEXT", h = A + 1, r = A + 1;
|
|
531
523
|
} else
|
|
532
|
-
|
|
524
|
+
r++;
|
|
533
525
|
} else
|
|
534
|
-
|
|
526
|
+
r++;
|
|
535
527
|
break;
|
|
536
528
|
default:
|
|
537
|
-
|
|
529
|
+
r++;
|
|
538
530
|
}
|
|
539
531
|
}
|
|
540
|
-
for (
|
|
541
|
-
const
|
|
542
|
-
type:
|
|
532
|
+
for (n === "TEXT" ? D(h, r) : (n === "SCRIPT_CONTENT" || n === "STYLE_CONTENT") && M(h, r); o.length > 0; ) {
|
|
533
|
+
const f = o.pop(), c = {
|
|
534
|
+
type: f.type,
|
|
543
535
|
props: {
|
|
544
|
-
...
|
|
545
|
-
children:
|
|
536
|
+
...f.props,
|
|
537
|
+
children: f.children.length === 1 ? f.children[0] : f.children
|
|
546
538
|
}
|
|
547
539
|
};
|
|
548
|
-
o.length > 0 ? o[o.length - 1].children.push(
|
|
540
|
+
o.length > 0 ? o[o.length - 1].children.push(c) : p.push(c);
|
|
549
541
|
}
|
|
550
|
-
return
|
|
551
|
-
}
|
|
552
|
-
function
|
|
553
|
-
const
|
|
554
|
-
for (const
|
|
555
|
-
const
|
|
556
|
-
if (
|
|
557
|
-
const
|
|
558
|
-
|
|
542
|
+
return p.length === 0 ? a.node = null : p.length === 1 ? a.node = p[0] : a.node = p, a;
|
|
543
|
+
}
|
|
544
|
+
function F(e) {
|
|
545
|
+
const t = {}, l = O(e).split(/;(?![^(]*\))/);
|
|
546
|
+
for (const s of l) {
|
|
547
|
+
const a = s.indexOf(":");
|
|
548
|
+
if (a === -1) continue;
|
|
549
|
+
const p = s.substring(0, a).trim(), o = s.substring(a + 1).trim();
|
|
550
|
+
p && o && (t[Z(p)] = o);
|
|
559
551
|
}
|
|
560
|
-
return
|
|
552
|
+
return t;
|
|
553
|
+
}
|
|
554
|
+
const re = {
|
|
555
|
+
className: "class",
|
|
556
|
+
htmlFor: "for"
|
|
557
|
+
};
|
|
558
|
+
function se(e, t) {
|
|
559
|
+
return t === "reactName" ? e : t === "exactName" || t === "eitherName" ? re[e] ?? e : e;
|
|
561
560
|
}
|
|
562
|
-
function
|
|
563
|
-
const
|
|
564
|
-
let l,
|
|
561
|
+
function k(e, t = {}) {
|
|
562
|
+
const i = [];
|
|
563
|
+
let l, s, a;
|
|
565
564
|
if (e && typeof e == "object" && "node" in e) {
|
|
566
|
-
const
|
|
567
|
-
l =
|
|
565
|
+
const r = e;
|
|
566
|
+
l = r.node, s = r.xml ?? t.xml, a = r.doctype ?? t.doctype;
|
|
568
567
|
} else
|
|
569
|
-
l = e,
|
|
570
|
-
|
|
571
|
-
`) ||
|
|
572
|
-
`)),
|
|
573
|
-
`) ||
|
|
568
|
+
l = e, s = t.xml, a = t.doctype;
|
|
569
|
+
s && (i.push(s), s.endsWith(`
|
|
570
|
+
`) || i.push(`
|
|
571
|
+
`)), a && (i.push(a), a.endsWith(`
|
|
572
|
+
`) || i.push(`
|
|
574
573
|
`));
|
|
575
|
-
const
|
|
576
|
-
return
|
|
574
|
+
const p = t.useCDataForScripts ?? !1, o = t.useCDataForStyles ?? !1, T = t.voidTrailingSlash ?? !0, n = t.attributeNaming ?? "eitherName";
|
|
575
|
+
return R(l, i, "HTML", p, o, T, n), i.join("");
|
|
577
576
|
}
|
|
578
|
-
function
|
|
577
|
+
function R(e, t, i, l, s, a, p) {
|
|
579
578
|
if (e != null) {
|
|
580
579
|
if (typeof e == "string") {
|
|
581
|
-
|
|
580
|
+
t.push(G(e, !1));
|
|
582
581
|
return;
|
|
583
582
|
}
|
|
584
583
|
if (typeof e == "number" || typeof e == "bigint") {
|
|
585
|
-
|
|
584
|
+
t.push(String(e));
|
|
586
585
|
return;
|
|
587
586
|
}
|
|
588
587
|
if (typeof e == "boolean") {
|
|
589
|
-
|
|
588
|
+
t.push(String(e));
|
|
590
589
|
return;
|
|
591
590
|
}
|
|
592
591
|
if (Array.isArray(e)) {
|
|
593
|
-
for (const
|
|
594
|
-
|
|
592
|
+
for (const o of e)
|
|
593
|
+
R(o, t, i, l, s, a, p);
|
|
595
594
|
return;
|
|
596
595
|
}
|
|
597
596
|
if (typeof e != "function" && typeof e != "symbol" && !(e && typeof e == "object" && "then" in e && typeof e.then == "function") && e && typeof e == "object" && "type" in e && "props" in e) {
|
|
598
|
-
|
|
597
|
+
ie(e, t, i, l, s, a, p);
|
|
599
598
|
return;
|
|
600
599
|
}
|
|
601
600
|
}
|
|
602
601
|
}
|
|
603
|
-
function
|
|
604
|
-
var
|
|
605
|
-
const
|
|
606
|
-
let
|
|
607
|
-
if (
|
|
608
|
-
for (const [
|
|
609
|
-
if (
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
602
|
+
function ie(e, t, i, l, s, a, p) {
|
|
603
|
+
var h;
|
|
604
|
+
const o = e.type;
|
|
605
|
+
let T = i;
|
|
606
|
+
if (o === "svg" ? T = "SVG" : o === "math" && (T = "MATHML"), t.push("<"), t.push(o), e.props)
|
|
607
|
+
for (const [g, E] of Object.entries(e.props)) {
|
|
608
|
+
if (g === "children" || E === !1 || E === null || E === void 0)
|
|
609
|
+
continue;
|
|
610
|
+
const N = se(g, p);
|
|
611
|
+
if (E === !0)
|
|
612
|
+
t.push(" "), t.push(N);
|
|
613
|
+
else if (g === "style" && typeof E == "object") {
|
|
614
|
+
const y = ne(E);
|
|
615
|
+
y && (t.push(' style="'), t.push(G(y, !0)), t.push('"'));
|
|
616
|
+
} else
|
|
617
|
+
t.push(" "), t.push(N), t.push('="'), t.push(G(String(E), !0)), t.push('"');
|
|
618
|
+
}
|
|
619
|
+
const n = (h = e.props) == null ? void 0 : h.children;
|
|
620
|
+
let r;
|
|
621
|
+
if (n && typeof n == "object" && "then" in n && typeof n.then == "function" ? r = !1 : r = n != null && (Array.isArray(n) && n.length > 0 || !Array.isArray(n) && n !== !1), $.has(o))
|
|
622
|
+
a ? t.push(" />") : t.push(">");
|
|
623
|
+
else if (r) {
|
|
624
|
+
t.push(">");
|
|
625
|
+
const g = n;
|
|
626
|
+
o === "script" && l || o === "style" && s ? (t.push("<![CDATA["), j(g, t, T, l, s, a, p), t.push("]]>")) : o === "script" || o === "style" ? Q(g, t) : R(g, t, T, l, s, a, p), t.push("</"), t.push(o), t.push(">");
|
|
627
|
+
} else K.has(o), t.push("></"), t.push(o), t.push(">");
|
|
628
|
+
}
|
|
629
|
+
function j(e, t, i, l, s, a, p, o) {
|
|
629
630
|
if (e != null) {
|
|
630
631
|
if (typeof e == "string") {
|
|
631
|
-
|
|
632
|
+
t.push(J(e));
|
|
632
633
|
return;
|
|
633
634
|
}
|
|
634
635
|
if (typeof e == "number" || typeof e == "bigint" || typeof e == "boolean") {
|
|
635
|
-
|
|
636
|
+
t.push(String(e));
|
|
636
637
|
return;
|
|
637
638
|
}
|
|
638
639
|
if (Array.isArray(e)) {
|
|
639
|
-
for (const
|
|
640
|
-
|
|
640
|
+
for (const T of e)
|
|
641
|
+
j(T, t, i, l, s, a, p);
|
|
641
642
|
return;
|
|
642
643
|
}
|
|
643
|
-
|
|
644
|
+
R(e, t, i, l, s, a, p);
|
|
644
645
|
}
|
|
645
646
|
}
|
|
646
|
-
function
|
|
647
|
+
function Q(e, t) {
|
|
647
648
|
if (e != null) {
|
|
648
649
|
if (typeof e == "string") {
|
|
649
|
-
|
|
650
|
+
t.push(e);
|
|
650
651
|
return;
|
|
651
652
|
}
|
|
652
653
|
if (typeof e == "number" || typeof e == "bigint" || typeof e == "boolean") {
|
|
653
|
-
|
|
654
|
+
t.push(String(e));
|
|
654
655
|
return;
|
|
655
656
|
}
|
|
656
657
|
if (Array.isArray(e)) {
|
|
657
|
-
for (const
|
|
658
|
-
|
|
658
|
+
for (const i of e)
|
|
659
|
+
Q(i, t);
|
|
659
660
|
return;
|
|
660
661
|
}
|
|
661
662
|
}
|
|
662
663
|
}
|
|
663
|
-
function
|
|
664
|
-
const
|
|
665
|
-
for (const [
|
|
664
|
+
function ne(e) {
|
|
665
|
+
const t = [];
|
|
666
|
+
for (const [i, l] of Object.entries(e))
|
|
666
667
|
if (l) {
|
|
667
|
-
const
|
|
668
|
-
|
|
668
|
+
const s = ee(i);
|
|
669
|
+
t.push(`${s}: ${l}`);
|
|
669
670
|
}
|
|
670
|
-
return
|
|
671
|
-
}
|
|
672
|
-
function
|
|
673
|
-
const
|
|
674
|
-
function
|
|
675
|
-
if (typeof l == "string" &&
|
|
676
|
-
const
|
|
677
|
-
if (l.type === "script" || l.type === "style" || l.type === "template" ||
|
|
671
|
+
return t.join("; ");
|
|
672
|
+
}
|
|
673
|
+
function ye(e) {
|
|
674
|
+
const t = [];
|
|
675
|
+
function i(l) {
|
|
676
|
+
if (typeof l == "string" && t.push(l), (typeof l == "number" || typeof l == "bigint" || typeof l == "boolean") && t.push(`${l}`), typeof l == "object" && l !== null && "type" in l && l.props && "children" in l.props) {
|
|
677
|
+
const s = l.props.children;
|
|
678
|
+
if (l.type === "script" || l.type === "style" || l.type === "template" || s && typeof s == "object" && "then" in s && typeof s.then == "function")
|
|
678
679
|
return;
|
|
679
|
-
if (Array.isArray(
|
|
680
|
-
for (const
|
|
681
|
-
|
|
682
|
-
else
|
|
680
|
+
if (Array.isArray(s))
|
|
681
|
+
for (const a of s)
|
|
682
|
+
i(a);
|
|
683
|
+
else s != null && i(s);
|
|
683
684
|
}
|
|
684
685
|
if (Array.isArray(l))
|
|
685
|
-
for (const
|
|
686
|
-
|
|
686
|
+
for (const s of l)
|
|
687
|
+
i(s);
|
|
687
688
|
}
|
|
688
|
-
return
|
|
689
|
+
return i(e), t.join("");
|
|
689
690
|
}
|
|
690
|
-
async function
|
|
691
|
+
async function U(e) {
|
|
691
692
|
if (e == null)
|
|
692
693
|
return e;
|
|
693
694
|
if (e && typeof e == "object" && "then" in e && typeof e.then == "function") {
|
|
694
|
-
const
|
|
695
|
-
return
|
|
695
|
+
const t = await e;
|
|
696
|
+
return U(t);
|
|
696
697
|
}
|
|
697
698
|
if (typeof e == "string" || typeof e == "number" || typeof e == "boolean" || typeof e == "bigint")
|
|
698
699
|
return e;
|
|
699
700
|
if (typeof e != "function" && typeof e != "symbol") {
|
|
700
701
|
if (Array.isArray(e))
|
|
701
702
|
return await Promise.all(
|
|
702
|
-
e.filter((
|
|
703
|
+
e.filter((i) => !(i == null || typeof i == "function" || typeof i == "symbol")).map((i) => U(i))
|
|
703
704
|
);
|
|
704
705
|
if (e && typeof e == "object" && "type" in e && "props" in e) {
|
|
705
|
-
const
|
|
706
|
-
for (const [l,
|
|
706
|
+
const t = e, i = {};
|
|
707
|
+
for (const [l, s] of Object.entries(t.props))
|
|
707
708
|
if (l === "children") {
|
|
708
|
-
const
|
|
709
|
-
|
|
709
|
+
const a = await U(s);
|
|
710
|
+
a != null && (i.children = a);
|
|
710
711
|
} else {
|
|
711
|
-
if (typeof
|
|
712
|
+
if (typeof s == "function" || typeof s == "symbol")
|
|
712
713
|
continue;
|
|
713
|
-
|
|
714
|
+
s != null && (i[l] = s);
|
|
714
715
|
}
|
|
715
716
|
return {
|
|
716
|
-
type:
|
|
717
|
-
props:
|
|
717
|
+
type: t.type,
|
|
718
|
+
props: i
|
|
718
719
|
};
|
|
719
720
|
}
|
|
720
721
|
}
|
|
721
722
|
}
|
|
722
|
-
|
|
723
|
+
const le = [
|
|
724
|
+
"br",
|
|
725
|
+
["span", "class"],
|
|
726
|
+
"p",
|
|
727
|
+
["a", "href", "rel", "class"],
|
|
728
|
+
"pre",
|
|
729
|
+
"del",
|
|
730
|
+
"code",
|
|
731
|
+
"em",
|
|
732
|
+
"strong",
|
|
733
|
+
"i",
|
|
734
|
+
"u",
|
|
735
|
+
"ul",
|
|
736
|
+
["ol", "start", "reversed"],
|
|
737
|
+
["li", "value"],
|
|
738
|
+
"blockquote"
|
|
739
|
+
], ae = [
|
|
740
|
+
"h-*",
|
|
741
|
+
"p-*",
|
|
742
|
+
"u-*",
|
|
743
|
+
"dt-*",
|
|
744
|
+
"e-*",
|
|
745
|
+
"mention",
|
|
746
|
+
"hashtag",
|
|
747
|
+
"ellipsis",
|
|
748
|
+
"invisible"
|
|
749
|
+
], oe = ["http", "https"], fe = {
|
|
750
|
+
a: ["href"],
|
|
751
|
+
area: ["href"],
|
|
752
|
+
audio: ["src"],
|
|
753
|
+
base: ["href"],
|
|
754
|
+
blockquote: ["cite"],
|
|
755
|
+
button: ["formaction"],
|
|
756
|
+
del: ["cite"],
|
|
757
|
+
embed: ["src"],
|
|
758
|
+
form: ["action"],
|
|
759
|
+
iframe: ["src"],
|
|
760
|
+
img: ["src", "longdesc"],
|
|
761
|
+
input: ["src", "formaction"],
|
|
762
|
+
ins: ["cite"],
|
|
763
|
+
link: ["href"],
|
|
764
|
+
object: ["data"],
|
|
765
|
+
q: ["cite"],
|
|
766
|
+
script: ["src"],
|
|
767
|
+
source: ["src"],
|
|
768
|
+
track: ["src"],
|
|
769
|
+
video: ["src", "poster"]
|
|
770
|
+
};
|
|
771
|
+
function ce(e) {
|
|
772
|
+
const t = /* @__PURE__ */ new Map();
|
|
773
|
+
let i = !1, l = /* @__PURE__ */ new Set(), s = !1;
|
|
774
|
+
for (const a of e)
|
|
775
|
+
if (typeof a == "string")
|
|
776
|
+
a === "*" ? i = !0 : t.set(a.toLowerCase(), {
|
|
777
|
+
allowed: !0,
|
|
778
|
+
allowedAttributes: /* @__PURE__ */ new Set(),
|
|
779
|
+
allowAllAttributes: !1
|
|
780
|
+
});
|
|
781
|
+
else {
|
|
782
|
+
const [p, ...o] = a, T = o.includes("*");
|
|
783
|
+
p === "*" ? (i = !0, T ? s = !0 : l = new Set(o.map((n) => n.toLowerCase()))) : t.set(p.toLowerCase(), {
|
|
784
|
+
allowed: !0,
|
|
785
|
+
allowedAttributes: T ? /* @__PURE__ */ new Set() : new Set(o.map((n) => n.toLowerCase())),
|
|
786
|
+
allowAllAttributes: T
|
|
787
|
+
});
|
|
788
|
+
}
|
|
789
|
+
return { configs: t, allowAll: i, universalAttrs: l, universalAllowAllAttrs: s };
|
|
790
|
+
}
|
|
791
|
+
function ue(e) {
|
|
792
|
+
return e.includes("*") ? { patterns: [], allowAll: !0 } : { patterns: e.map((i) => {
|
|
793
|
+
const s = "^" + i.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*") + "$";
|
|
794
|
+
return new RegExp(s);
|
|
795
|
+
}), allowAll: !1 };
|
|
796
|
+
}
|
|
797
|
+
function pe(e = {}) {
|
|
798
|
+
const t = e.allowedTags ?? le, i = e.allowedClasses ?? ae, l = e.allowedLinkProtocols ?? oe, s = e.attributeNaming ?? "reactName", a = ce(t), p = ue(i);
|
|
799
|
+
return {
|
|
800
|
+
tagConfigs: a.configs,
|
|
801
|
+
classPatterns: p.patterns,
|
|
802
|
+
protocols: new Set(l.map((o) => o.toLowerCase())),
|
|
803
|
+
attributeNaming: s,
|
|
804
|
+
allowAllClasses: p.allowAll,
|
|
805
|
+
allowAllTags: a.allowAll,
|
|
806
|
+
universalAttributes: a.universalAttrs,
|
|
807
|
+
universalAllowAllAttributes: a.universalAllowAllAttrs
|
|
808
|
+
};
|
|
809
|
+
}
|
|
810
|
+
function he(e, t, i) {
|
|
811
|
+
return i ? !0 : t.some((l) => l.test(e));
|
|
812
|
+
}
|
|
813
|
+
function me(e, t, i) {
|
|
814
|
+
return i ? e : e.split(/\s+/).filter((a) => a.length > 0).filter((a) => he(a, t, i)).join(" ");
|
|
815
|
+
}
|
|
816
|
+
function Te(e, t) {
|
|
817
|
+
const i = e.trim();
|
|
818
|
+
if (t.has(".")) {
|
|
819
|
+
if (i.startsWith("/") || i.startsWith("./") || i.startsWith("../") || i.startsWith("#") || i.startsWith("?"))
|
|
820
|
+
return !0;
|
|
821
|
+
const a = i.indexOf(":"), p = i.indexOf("/");
|
|
822
|
+
if (a === -1 || p !== -1 && p < a)
|
|
823
|
+
return !0;
|
|
824
|
+
}
|
|
825
|
+
const l = i.match(/^([a-zA-Z][a-zA-Z0-9+.-]*):/);
|
|
826
|
+
if (!l || !l[1])
|
|
827
|
+
return t.has(".");
|
|
828
|
+
const s = l[1].toLowerCase();
|
|
829
|
+
return t.has(s);
|
|
830
|
+
}
|
|
831
|
+
function ge(e) {
|
|
832
|
+
return fe[e.toLowerCase()] ?? [];
|
|
833
|
+
}
|
|
834
|
+
function de(e, t, i, l) {
|
|
835
|
+
const s = {}, a = ge(e), p = i.allowAllAttributes || l.universalAllowAllAttributes, o = l.attributeNaming === "exactName" ? "class" : "className", T = l.attributeNaming === "exactName" ? "for" : "htmlFor";
|
|
836
|
+
for (const [n, r] of Object.entries(t)) {
|
|
837
|
+
if (n === "children")
|
|
838
|
+
continue;
|
|
839
|
+
const h = n.toLowerCase();
|
|
840
|
+
if (a.includes(h) && typeof r == "string" && !Te(r, l.protocols))
|
|
841
|
+
return null;
|
|
842
|
+
if ((n === "className" || n === "class") && typeof r == "string") {
|
|
843
|
+
if (p)
|
|
844
|
+
s[o] = r;
|
|
845
|
+
else if (i.allowedAttributes.has("class") || l.universalAttributes.has("class")) {
|
|
846
|
+
const g = me(r, l.classPatterns, l.allowAllClasses);
|
|
847
|
+
g && (s[o] = g);
|
|
848
|
+
}
|
|
849
|
+
continue;
|
|
850
|
+
}
|
|
851
|
+
if ((n === "htmlFor" || n === "for") && typeof r == "string") {
|
|
852
|
+
(p || i.allowedAttributes.has("for") || l.universalAttributes.has("for")) && (s[T] = r);
|
|
853
|
+
continue;
|
|
854
|
+
}
|
|
855
|
+
(p || i.allowedAttributes.has(h) || i.allowedAttributes.has(n) || l.universalAttributes.has(h) || l.universalAttributes.has(n)) && (s[n] = r);
|
|
856
|
+
}
|
|
857
|
+
return s;
|
|
858
|
+
}
|
|
859
|
+
function X(e, t) {
|
|
860
|
+
if (e == null || typeof e == "string" || typeof e == "number" || typeof e == "boolean" || typeof e == "bigint")
|
|
861
|
+
return e;
|
|
862
|
+
if (Array.isArray(e)) {
|
|
863
|
+
const o = [];
|
|
864
|
+
for (const T of e) {
|
|
865
|
+
const n = X(T, t);
|
|
866
|
+
Array.isArray(n) ? o.push(...n) : n != null && o.push(n);
|
|
867
|
+
}
|
|
868
|
+
return o.length === 0 ? [] : o.length === 1 ? o[0] : o;
|
|
869
|
+
}
|
|
870
|
+
const i = e, l = i.type.toLowerCase();
|
|
871
|
+
let s = t.tagConfigs.get(l);
|
|
872
|
+
!s && t.allowAllTags && (s = {
|
|
873
|
+
allowed: !0,
|
|
874
|
+
allowedAttributes: t.universalAttributes,
|
|
875
|
+
allowAllAttributes: t.universalAllowAllAttributes
|
|
876
|
+
});
|
|
877
|
+
const a = i.props.children !== void 0 ? X(i.props.children, t) : void 0;
|
|
878
|
+
if (!s) {
|
|
879
|
+
if (l === "img") {
|
|
880
|
+
const o = i.props.alt;
|
|
881
|
+
return typeof o == "string" && o.length > 0 ? o : void 0;
|
|
882
|
+
}
|
|
883
|
+
return a !== void 0 ? a : void 0;
|
|
884
|
+
}
|
|
885
|
+
const p = de(l, i.props, s, t);
|
|
886
|
+
if (p === null) {
|
|
887
|
+
if (l === "img") {
|
|
888
|
+
const o = i.props.alt;
|
|
889
|
+
if (typeof o == "string" && o.length > 0)
|
|
890
|
+
return o;
|
|
891
|
+
}
|
|
892
|
+
return a !== void 0 ? a : void 0;
|
|
893
|
+
}
|
|
894
|
+
return a !== void 0 && (p.children = a), {
|
|
895
|
+
type: i.type,
|
|
896
|
+
props: p
|
|
897
|
+
};
|
|
898
|
+
}
|
|
899
|
+
function Ae(e, t = {}) {
|
|
900
|
+
const i = pe(t);
|
|
901
|
+
return X(e, i);
|
|
902
|
+
}
|
|
903
|
+
function Y(e, t) {
|
|
723
904
|
if (e == null || typeof e == "string" || typeof e == "number" || typeof e == "boolean" || typeof e == "bigint")
|
|
724
905
|
return e;
|
|
725
906
|
if (Array.isArray(e))
|
|
726
|
-
return e.map((
|
|
907
|
+
return e.map((i) => Y(i, t));
|
|
727
908
|
if (typeof e == "object" && "type" in e && "props" in e) {
|
|
728
|
-
const { type:
|
|
729
|
-
if (
|
|
730
|
-
const
|
|
731
|
-
return
|
|
909
|
+
const { type: i, props: l } = e, { children: s, ...a } = l;
|
|
910
|
+
if (s !== void 0) {
|
|
911
|
+
const p = Y(s, t);
|
|
912
|
+
return p === null ? t(i, a) : Array.isArray(p) ? t(i, a, ...p) : t(i, a, p);
|
|
732
913
|
}
|
|
733
|
-
return
|
|
914
|
+
return t(i, a);
|
|
734
915
|
}
|
|
735
916
|
return null;
|
|
736
917
|
}
|
|
737
|
-
function
|
|
738
|
-
return
|
|
918
|
+
function be(e, t = {}) {
|
|
919
|
+
return te(e, t);
|
|
920
|
+
}
|
|
921
|
+
function Ee(e, t = {}) {
|
|
922
|
+
return e && typeof e == "object" && "node" in e ? k(e, t) : e === void 0 ? "" : k(e, t);
|
|
739
923
|
}
|
|
740
|
-
function
|
|
741
|
-
return
|
|
924
|
+
async function we(e) {
|
|
925
|
+
return await U(e);
|
|
742
926
|
}
|
|
743
|
-
|
|
744
|
-
return
|
|
927
|
+
function Ne(e, t = {}) {
|
|
928
|
+
return Ae(e, t);
|
|
745
929
|
}
|
|
746
930
|
export {
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
931
|
+
we as awaitHtmlNode,
|
|
932
|
+
O as decodeHtmlEntities,
|
|
933
|
+
G as encodeHtmlEntities,
|
|
934
|
+
ye as getTextContent,
|
|
751
935
|
Y as htmlNodeTo,
|
|
752
|
-
|
|
753
|
-
|
|
936
|
+
be as readHtml,
|
|
937
|
+
Ne as safeHtml,
|
|
938
|
+
Ee as writeHtml
|
|
754
939
|
};
|
package/dist/parser.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { ParseResult } from './types.ts';
|
|
2
|
-
export declare function parseHtml(html: string): ParseResult;
|
|
1
|
+
import { ParseResult, ParserOptions } from './types.ts';
|
|
2
|
+
export declare function parseHtml(html: string, options?: ParserOptions): ParseResult;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { HtmlNode, SafeHtmlOptions } from './types.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Sanitizes an HtmlNode tree by removing disallowed tags, attributes, and URLs.
|
|
4
|
+
*
|
|
5
|
+
* - Tags not in allowedTags have their content retained (folded into parent)
|
|
6
|
+
* - Images replaced with their alt text when removed
|
|
7
|
+
* - Attributes not in the tag's allowed list are dropped
|
|
8
|
+
* - Classes are filtered by allowedClasses patterns (supports wildcards like 'h-*')
|
|
9
|
+
* - URLs not matching allowedLinkProtocols cause the element to be removed
|
|
10
|
+
* - Use '.' as a protocol to allow relative URLs
|
|
11
|
+
* @param node - The HtmlNode to sanitize
|
|
12
|
+
* @param options - The SafeHtmlOptions to use
|
|
13
|
+
* @returns The sanitized HtmlNode
|
|
14
|
+
*/
|
|
15
|
+
export declare function safeHtml(node: HtmlNode, options?: SafeHtmlOptions): HtmlNode;
|
package/dist/types.d.ts
CHANGED
|
@@ -1,14 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Style attribute as a structured record.
|
|
3
|
+
*/
|
|
1
4
|
export interface HtmlStyle {
|
|
2
5
|
[key: string]: string;
|
|
3
6
|
}
|
|
7
|
+
/**
|
|
8
|
+
* Properties of an HtmlElement.
|
|
9
|
+
*/
|
|
4
10
|
export interface HtmlElement {
|
|
5
11
|
type: string;
|
|
6
12
|
props: HtmlProps;
|
|
7
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* HtmlElement properties
|
|
16
|
+
*/
|
|
8
17
|
export interface HtmlProps {
|
|
9
18
|
[key: string]: string | number | boolean | HtmlStyle | HtmlNode | Promise<HtmlNode>;
|
|
10
19
|
children?: HtmlNode | Promise<HtmlNode>;
|
|
11
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Nodes will be parsed into one of these types.
|
|
23
|
+
*/
|
|
12
24
|
export type HtmlNode = HtmlElement | string | number | bigint | boolean | null | undefined | HtmlNode[];
|
|
13
25
|
export declare enum ParserState {
|
|
14
26
|
TEXT = "TEXT",
|
|
@@ -29,6 +41,9 @@ export declare enum ParserState {
|
|
|
29
41
|
SCRIPT_CONTENT = "SCRIPT_CONTENT",
|
|
30
42
|
STYLE_CONTENT = "STYLE_CONTENT"
|
|
31
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Namespace of an element.
|
|
46
|
+
*/
|
|
32
47
|
export declare enum Namespace {
|
|
33
48
|
HTML = "HTML",
|
|
34
49
|
SVG = "SVG",
|
|
@@ -45,10 +60,71 @@ export interface ParseResult {
|
|
|
45
60
|
doctype?: string;
|
|
46
61
|
node: HtmlNode | HtmlNode[];
|
|
47
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Controls how special attributes like 'class' and 'for' are named:
|
|
65
|
+
* - 'reactName': Use React-style names (className, htmlFor) - default for parsing
|
|
66
|
+
* - 'exactName': Use exact HTML names (class, for)
|
|
67
|
+
*/
|
|
68
|
+
export type ParserAttributeNaming = 'reactName' | 'exactName';
|
|
69
|
+
/**
|
|
70
|
+
* Controls how special attributes are written:
|
|
71
|
+
* - 'reactName': Write as React-style (className, htmlFor)
|
|
72
|
+
* - 'exactName': Write as exact HTML (class, for)
|
|
73
|
+
* - 'eitherName': Normalize className->class, htmlFor->for (default)
|
|
74
|
+
*/
|
|
75
|
+
export type WriterAttributeNaming = 'reactName' | 'exactName' | 'eitherName';
|
|
76
|
+
export interface ParserOptions {
|
|
77
|
+
/**
|
|
78
|
+
* How to name special attributes like 'class' and 'for'.
|
|
79
|
+
* - 'reactName' (default): Convert to React-style (className, htmlFor)
|
|
80
|
+
* - 'exactName': Keep exact HTML names (class, for)
|
|
81
|
+
*/
|
|
82
|
+
attributeNaming?: ParserAttributeNaming;
|
|
83
|
+
}
|
|
48
84
|
export interface WriterOptions {
|
|
49
85
|
useCDataForScripts?: boolean;
|
|
50
86
|
useCDataForStyles?: boolean;
|
|
51
87
|
xml?: string;
|
|
52
88
|
doctype?: string;
|
|
53
89
|
voidTrailingSlash?: boolean;
|
|
90
|
+
/**
|
|
91
|
+
* How to write special attributes like 'class' and 'for'.
|
|
92
|
+
* - 'eitherName' (default): Normalize className->class, htmlFor->for
|
|
93
|
+
* - 'reactName': Write as-is (className, htmlFor)
|
|
94
|
+
* - 'exactName': Write as exact HTML (class, for)
|
|
95
|
+
*/
|
|
96
|
+
attributeNaming?: WriterAttributeNaming;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Allowed tag specification:
|
|
100
|
+
* - string: tag name with no custom attributes allowed (only global attrs like 'class' if classes are allowed)
|
|
101
|
+
* - [tagName, ...attrs]: tag name with specific allowed attributes
|
|
102
|
+
*/
|
|
103
|
+
export type AllowedTag = string | [string, ...string[]];
|
|
104
|
+
/**
|
|
105
|
+
* Options for the safeHtml function.
|
|
106
|
+
*/
|
|
107
|
+
export interface SafeHtmlOptions {
|
|
108
|
+
/**
|
|
109
|
+
* List of allowed tags. Can be strings (tag name only) or tuples [tagName, ...allowedAttributes].
|
|
110
|
+
* If not provided, uses default safe tags.
|
|
111
|
+
*/
|
|
112
|
+
allowedTags?: AllowedTag[];
|
|
113
|
+
/**
|
|
114
|
+
* List of allowed CSS class patterns. Supports wildcards like 'h-*', 'p-*'.
|
|
115
|
+
* If not provided, uses default allowed classes.
|
|
116
|
+
*/
|
|
117
|
+
allowedClasses?: string[];
|
|
118
|
+
/**
|
|
119
|
+
* List of allowed URL protocols for links/media. Use '.' for relative URLs.
|
|
120
|
+
* If not provided, uses default ['http', 'https'].
|
|
121
|
+
*/
|
|
122
|
+
allowedLinkProtocols?: string[];
|
|
123
|
+
/**
|
|
124
|
+
* The attribute naming convention used in the input.
|
|
125
|
+
* - 'reactName' (default): Input uses React-style names (className, htmlFor)
|
|
126
|
+
* - 'exactName': Input uses exact HTML names (class, for)
|
|
127
|
+
* When set, also affects how the output is named.
|
|
128
|
+
*/
|
|
129
|
+
attributeNaming?: ParserAttributeNaming;
|
|
54
130
|
}
|