@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 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
- function parseFragmentOrDocument(html) {
105
- const wrapped = !/^(?:<!doctype|<html[\s>/])/i.test(
106
- html.replace(/^(?:\s|<!--(?:>|->|[\s\S]*?-->))*/, "")
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
- function parseFragmentOrDocument(html) {
2520
- const wrapped = !/^(?:<!doctype|<html[\s>/])/i.test(
2521
- html.replace(/^(?:\s|<!--(?:>|->|[\s\S]*?-->))*/, "")
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.8",
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.8"
142
+ "@hyperframes/core": "0.9.9"
143
143
  },
144
144
  "scripts": {
145
145
  "build": "tsup",