clipper: serialize styles using xml serializer

This commit is contained in:
Abdullah Atta
2025-06-19 12:36:15 +05:00
parent 3dc7e70890
commit a0f5880e2c
2 changed files with 14 additions and 26 deletions

View File

@@ -20,14 +20,7 @@ import { createImage, FetchOptions } from "./fetch.js";
import { resolveAll } from "./fontfaces.js";
import { inlineAllImages } from "./images.js";
import { Options } from "./types.js";
import {
canvasToBlob,
delay,
escapeXhtml,
height,
width,
isSVGElement
} from "./utils.js";
import { canvasToBlob, delay, height, width, isSVGElement } from "./utils.js";
import { cloneNode } from "./clone.js";
// Default impl options
@@ -147,21 +140,22 @@ function makeSvgDataUri(
const xhtml = new XMLSerializer().serializeToString(body);
const xstyles = Array.from(head.getElementsByTagName("style"))
.map((s) => new XMLSerializer().serializeToString(s))
.join("\n");
const foreignObject =
'<foreignObject x="0" y="0" width="100%" height="100%">' +
xhtml +
"</foreignObject>";
const styles = Array.from(head.getElementsByTagName("style"))
.map((e) => e.outerHTML.replace(/\\"/gm, "'"))
.join("\n");
const svgStr =
'<svg xmlns="http://www.w3.org/2000/svg" width="' +
width +
'" height="' +
height +
'">' +
styles +
xstyles +
foreignObject +
"</svg>";

View File

@@ -50,8 +50,7 @@ async function clipPage(
): Promise<string | null> {
const { body, head } = await getPage(document, config, onlyVisible);
if (!body || !head) return null;
const result = toDocument(head, body, toAttributes(document.documentElement))
.documentElement.outerHTML;
const result = toDocument(head, body).documentElement.outerHTML;
return `<!doctype html>\n${result}`;
}
@@ -434,19 +433,8 @@ function getElementViewportInfo(el: HTMLElement) {
return result;
}
function toDocument(
head: HTMLElement,
body: HTMLElement,
rootAttributes?: Record<string, string>
) {
function toDocument(head: HTMLElement, body: HTMLElement) {
const doc = document.implementation.createHTMLDocument();
if (rootAttributes) {
for (const [name, value] of Object.entries(rootAttributes)) {
doc.documentElement.setAttribute(name, value);
}
}
doc.documentElement.replaceChildren(head, body);
return doc;
}
@@ -499,6 +487,12 @@ async function getPage(
await addStylesToHead(head, fetchOptions);
}
for (const [name, value] of Object.entries(
toAttributes(document.documentElement)
)) {
body.setAttribute(name, value);
}
return {
body,
head