Skip to content

Commit 4b706df

Browse files
committed
fix(shared): keep HTML bootstrap outside quoted attributes
1 parent bc8583b commit 4b706df

2 files changed

Lines changed: 18 additions & 2 deletions

File tree

‎packages/shared/src/htmlRender.test.ts‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,22 @@ describe("injectHtmlRenderBootstrap", () => {
2121
expect(injected).toContain('name="viewport"');
2222
});
2323

24+
it.each([
25+
"<html><head data-condition='x > 0'>",
26+
'<html><head data-condition="x > 0" data-label=\'it "works"\'>',
27+
"<html data-condition='x > 0'>",
28+
'<html data-condition="x > 0" data-label="it \'works\'">',
29+
])("keeps the bootstrap after the complete opening tag: %s", (opening) => {
30+
const prefix = `<!doctype html>${opening}`;
31+
const head = opening.startsWith("<html><head") ? "" : "<head>";
32+
const content = `${head ? "" : "<title>Report</title></head>"}<body><p>Report</p></body></html>`;
33+
const injected = injectHtmlRenderBootstrap(prefix + content);
34+
expect(injected.startsWith(`${prefix}${head}<meta charset="utf-8">`)).toBe(true);
35+
expect(injected.indexOf('<style id="t3-theme">')).toBeGreaterThan(prefix.length);
36+
expect(injected).toContain("<script>");
37+
expect(injected.endsWith(content)).toBe(true);
38+
});
39+
2440
it("wraps fragments without a head and keeps existing meta tags", () => {
2541
const fragment =
2642
'<meta charset="utf-8"><meta name="viewport" content="width=device-width"><p>hi</p>';

‎packages/shared/src/htmlRender.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,12 +415,12 @@ const blankNonMarkup = (html: string) => {
415415
export function injectHtmlRenderBootstrap(html: string): string {
416416
const scan = blankNonMarkup(html);
417417
const markup = bootstrapMarkup(scan);
418-
const headOpen = /<head(?:\s[^>]*)?>/i.exec(scan);
418+
const headOpen = /<head(?:\s(?:[^"'>]|"[^"]*"|'[^']*')*)?>/i.exec(scan);
419419
if (headOpen) {
420420
const at = headOpen.index + headOpen[0].length;
421421
return html.slice(0, at) + markup + html.slice(at);
422422
}
423-
const htmlOpen = /<html(?:\s[^>]*)?>/i.exec(scan);
423+
const htmlOpen = /<html(?:\s(?:[^"'>]|"[^"]*"|'[^']*')*)?>/i.exec(scan);
424424
if (htmlOpen) {
425425
const at = htmlOpen.index + htmlOpen[0].length;
426426
return `${html.slice(0, at)}<head>${markup}</head>${html.slice(at)}`;

0 commit comments

Comments
 (0)