clipper: add svg screenshots for debugging

This commit is contained in:
Abdullah Atta
2025-06-21 09:30:55 +05:00
parent c53fab603f
commit de4a660eb2
2 changed files with 36 additions and 19 deletions

View File

@@ -73,6 +73,15 @@ function toBlob(body: HTMLElement, head: HTMLHeadElement, options: Options) {
);
}
function toSvg(body: HTMLElement, head: HTMLHeadElement, options: Options) {
return makeSvg(
body,
head,
options.width || width(body),
options.height || height(body)
);
}
async function draw(
body: HTMLElement,
head: HTMLHeadElement,
@@ -80,10 +89,12 @@ async function draw(
) {
options = { ...defaultOptions, ...options };
const uri = makeSvgDataUri(
body,
head,
options.width || width(body),
options.height || height(body)
makeSvg(
body,
head,
options.width || width(body),
options.height || height(body)
)
);
return createImage(uri, options.fetchOptions)
@@ -130,7 +141,7 @@ function embedFonts(node: HTMLElement, options?: FetchOptions) {
});
}
function makeSvgDataUri(
function makeSvg(
body: HTMLElement,
head: HTMLHeadElement,
width: number,
@@ -163,7 +174,7 @@ function makeSvgDataUri(
xhtml +
"</foreignObject>";
const svgStr =
return (
'<svg xmlns="http://www.w3.org/2000/svg" width="' +
width +
'" height="' +
@@ -171,12 +182,15 @@ function makeSvgDataUri(
'">' +
xstyles +
foreignObject +
"</svg>";
return "data:image/svg+xml; charset=utf8, " + encodeURIComponent(svgStr);
"</svg>"
);
}
export { toJpeg, toBlob, toPng, getInlinedNode };
function makeSvgDataUri(str: string) {
return "data:image/svg+xml; charset=utf8, " + encodeURIComponent(str);
}
export { toJpeg, toBlob, toPng, toSvg, getInlinedNode };
function finalize(root: HTMLElement) {
for (const element of root.querySelectorAll("*")) {

View File

@@ -20,7 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import { Readability } from "@mozilla/readability";
import { injectCss } from "./utils.js";
import { app, h, text } from "hyperapp";
import { getInlinedNode, toBlob, toJpeg, toPng } from "./domtoimage.js";
import { getInlinedNode, toBlob, toJpeg, toPng, toSvg } from "./domtoimage.js";
import { Config, InlineOptions } from "./types.js";
import { FetchOptions } from "./fetch.js";
import { addStylesToHead } from "./styles.js";
@@ -85,10 +85,8 @@ async function clipArticle(
}
async function clipScreenshot<
TOutputFormat extends "jpeg" | "png" | "raw",
TOutput extends TOutputFormat extends "jpeg"
? string
: TOutputFormat extends "png"
TOutputFormat extends "jpeg" | "png" | "raw" | "svg",
TOutput extends TOutputFormat extends "jpeg" | "png" | "svg"
? string
: Blob | undefined
>(
@@ -96,15 +94,19 @@ async function clipScreenshot<
output: TOutputFormat = "jpeg" as TOutputFormat,
config?: Config
): Promise<TOutput | null> {
// const screenshotTarget = target || document.body;
const fetchOptions = resolveFetchOptions(config);
// await inlineAllImages(screenshotTarget, fetchOptions);
const { body, head } = await getPage(document, config, false);
if (!body || !head) return null;
const func = output === "jpeg" ? toJpeg : output === "png" ? toPng : toBlob;
const func =
output === "jpeg"
? toJpeg
: output === "png"
? toPng
: output === "svg"
? toSvg
: toBlob;
const screenshot = await func(body, head, {
quality: 1,
backgroundColor: "white",
@@ -121,6 +123,7 @@ async function clipScreenshot<
if (output === "jpeg" || output === "png")
return `<img width="${document.body.scrollWidth}px" height="${document.body.scrollHeight}px" src="${screenshot}" />` as TOutput;
else if (output === "svg") return screenshot as TOutput;
else return screenshot as TOutput;
}