@hyperframes/parsers 0.9.8 → 0.9.9
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/hfIds.js +33 -3
- package/dist/index.js +33 -3
- package/package.json +2 -2
package/dist/hfIds.js
CHANGED
|
@@ -96,15 +96,45 @@ function assignHfIds(body) {
|
|
|
96
96
|
|
|
97
97
|
// src/hfIds.ts
|
|
98
98
|
function ensureHfIds(html) {
|
|
99
|
+
if (alreadyStamped(html)) return html;
|
|
99
100
|
const { document, wrapped } = parseFragmentOrDocument(html);
|
|
100
101
|
if (!document.body) return html;
|
|
101
102
|
assignHfIds(document.body);
|
|
102
103
|
return wrapped ? document.body.innerHTML || "" : document.toString();
|
|
103
104
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
105
|
+
var isFragment = (html) => !/^(?:<!doctype|<html[\s>/])/i.test(html.replace(/^(?:\s|<!--(?:>|->|[\s\S]*?-->))*/, ""));
|
|
106
|
+
function alreadyStamped(html) {
|
|
107
|
+
const tags = startTags(html);
|
|
108
|
+
if (!tags) return false;
|
|
109
|
+
const body = isFragment(html) ? -1 : tags.findIndex((tag) => tag.name === "body");
|
|
110
|
+
if (!isFragment(html) && !opensHeadThenBody(html, tags, body)) return false;
|
|
111
|
+
return tags.slice(body + 1).every(
|
|
112
|
+
(tag) => !IMPLIED.has(tag.name) && tag.name !== "table" && (EXCLUDED_TAGS.has(tag.name) || hasHfId(html, tag))
|
|
107
113
|
);
|
|
114
|
+
}
|
|
115
|
+
var HEAD_CONTENT = /* @__PURE__ */ new Set(["meta", "link", "base", "title", "style", "script"]);
|
|
116
|
+
function opensHeadThenBody(html, tags, body) {
|
|
117
|
+
const [first, head] = tags;
|
|
118
|
+
if (body < 0 || first?.name !== "html" || head?.name !== "head") return false;
|
|
119
|
+
const inHead = tags.slice(2, body);
|
|
120
|
+
return inHead.every((tag) => HEAD_CONTENT.has(tag.name)) && closesHead(html, inHead.at(-1) ?? head, tags[body]);
|
|
121
|
+
}
|
|
122
|
+
function closesHead(html, last, body) {
|
|
123
|
+
const from = RAW_TEXT.has(last.name) ? rawTextEnd(html, last.name, last.bracket) : last.bracket;
|
|
124
|
+
const between = html.slice(from, html.lastIndexOf("<", body.nameEnd));
|
|
125
|
+
const marks = between.matchAll(/<!--[\s\S]*?-->|<\/head\s*>/gi);
|
|
126
|
+
return from >= 0 && [...marks].some((mark) => !mark[0].startsWith("<!--"));
|
|
127
|
+
}
|
|
128
|
+
function hasHfId(html, tag) {
|
|
129
|
+
const open = html.slice(tag.nameEnd, tag.bracket);
|
|
130
|
+
const name = /\sdata-hf-id\s*=\s*/i.exec(outsideQuotes(open));
|
|
131
|
+
if (!name) return false;
|
|
132
|
+
const value = open.slice(name.index + name[0].length);
|
|
133
|
+
const quote = value[0] === '"' || value[0] === "'" ? value[0] : "";
|
|
134
|
+
return quote ? value.length > 1 && value[1] !== quote : /^[^\s>]/.test(value);
|
|
135
|
+
}
|
|
136
|
+
function parseFragmentOrDocument(html) {
|
|
137
|
+
const wrapped = isFragment(html);
|
|
108
138
|
const { document } = wrapped ? parseHTML(`<!DOCTYPE html><html><head></head><body>${html}</body></html>`) : parseHTML(html);
|
|
109
139
|
return { document, wrapped };
|
|
110
140
|
}
|
package/dist/index.js
CHANGED
|
@@ -2511,15 +2511,45 @@ function assignHfIds(body) {
|
|
|
2511
2511
|
|
|
2512
2512
|
// src/hfIds.ts
|
|
2513
2513
|
function ensureHfIds(html) {
|
|
2514
|
+
if (alreadyStamped(html)) return html;
|
|
2514
2515
|
const { document, wrapped } = parseFragmentOrDocument(html);
|
|
2515
2516
|
if (!document.body) return html;
|
|
2516
2517
|
assignHfIds(document.body);
|
|
2517
2518
|
return wrapped ? document.body.innerHTML || "" : document.toString();
|
|
2518
2519
|
}
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2520
|
+
var isFragment = (html) => !/^(?:<!doctype|<html[\s>/])/i.test(html.replace(/^(?:\s|<!--(?:>|->|[\s\S]*?-->))*/, ""));
|
|
2521
|
+
function alreadyStamped(html) {
|
|
2522
|
+
const tags = startTags(html);
|
|
2523
|
+
if (!tags) return false;
|
|
2524
|
+
const body = isFragment(html) ? -1 : tags.findIndex((tag) => tag.name === "body");
|
|
2525
|
+
if (!isFragment(html) && !opensHeadThenBody(html, tags, body)) return false;
|
|
2526
|
+
return tags.slice(body + 1).every(
|
|
2527
|
+
(tag) => !IMPLIED.has(tag.name) && tag.name !== "table" && (EXCLUDED_TAGS.has(tag.name) || hasHfId(html, tag))
|
|
2522
2528
|
);
|
|
2529
|
+
}
|
|
2530
|
+
var HEAD_CONTENT = /* @__PURE__ */ new Set(["meta", "link", "base", "title", "style", "script"]);
|
|
2531
|
+
function opensHeadThenBody(html, tags, body) {
|
|
2532
|
+
const [first, head] = tags;
|
|
2533
|
+
if (body < 0 || first?.name !== "html" || head?.name !== "head") return false;
|
|
2534
|
+
const inHead = tags.slice(2, body);
|
|
2535
|
+
return inHead.every((tag) => HEAD_CONTENT.has(tag.name)) && closesHead(html, inHead.at(-1) ?? head, tags[body]);
|
|
2536
|
+
}
|
|
2537
|
+
function closesHead(html, last, body) {
|
|
2538
|
+
const from = RAW_TEXT.has(last.name) ? rawTextEnd(html, last.name, last.bracket) : last.bracket;
|
|
2539
|
+
const between = html.slice(from, html.lastIndexOf("<", body.nameEnd));
|
|
2540
|
+
const marks = between.matchAll(/<!--[\s\S]*?-->|<\/head\s*>/gi);
|
|
2541
|
+
return from >= 0 && [...marks].some((mark) => !mark[0].startsWith("<!--"));
|
|
2542
|
+
}
|
|
2543
|
+
function hasHfId(html, tag) {
|
|
2544
|
+
const open = html.slice(tag.nameEnd, tag.bracket);
|
|
2545
|
+
const name = /\sdata-hf-id\s*=\s*/i.exec(outsideQuotes(open));
|
|
2546
|
+
if (!name) return false;
|
|
2547
|
+
const value = open.slice(name.index + name[0].length);
|
|
2548
|
+
const quote = value[0] === '"' || value[0] === "'" ? value[0] : "";
|
|
2549
|
+
return quote ? value.length > 1 && value[1] !== quote : /^[^\s>]/.test(value);
|
|
2550
|
+
}
|
|
2551
|
+
function parseFragmentOrDocument(html) {
|
|
2552
|
+
const wrapped = isFragment(html);
|
|
2523
2553
|
const { document } = wrapped ? parseHTML(`<!DOCTYPE html><html><head></head><body>${html}</body></html>`) : parseHTML(html);
|
|
2524
2554
|
return { document, wrapped };
|
|
2525
2555
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hyperframes/parsers",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.9",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/heygen-com/hyperframes",
|
|
@@ -139,7 +139,7 @@
|
|
|
139
139
|
"tsx": "^4.21.0",
|
|
140
140
|
"typescript": "^5.0.0",
|
|
141
141
|
"vitest": "^4.1.11",
|
|
142
|
-
"@hyperframes/core": "0.9.
|
|
142
|
+
"@hyperframes/core": "0.9.9"
|
|
143
143
|
},
|
|
144
144
|
"scripts": {
|
|
145
145
|
"build": "tsup",
|