diff --git a/src/rewriter.test.ts b/src/rewriter.test.ts index 7620094..65a54f4 100644 --- a/src/rewriter.test.ts +++ b/src/rewriter.test.ts @@ -107,4 +107,14 @@ describe("HTMLRewriter integration", () => { expect(resp.headers.get("content-security-policy")).toBeNull(); expect(resp.headers.get("access-control-allow-origin")).toBe("*"); }); + + it("rewrites data-src attributes for lazy-loaded images", async () => { + const resp = await worker.fetch("/browse/https://www.wired.com"); + if (resp.status !== 200) return; + const html = await resp.text(); + const dataSrcMatches = html.match(/data-src="([^"]*)"/g) || []; + if (dataSrcMatches.length === 0) return; // skip if wired changed their pattern + const allProxied = dataSrcMatches.every((m) => m.includes("/browse/")); + expect(allProxied).toBe(true); + }); }); diff --git a/src/rewriter.ts b/src/rewriter.ts index 9917f1e..e654b2c 100644 --- a/src/rewriter.ts +++ b/src/rewriter.ts @@ -59,10 +59,13 @@ class URLRewriter implements HTMLRewriterElementContentHandlers { } class SrcsetRewriter implements HTMLRewriterElementContentHandlers { - constructor(private baseUrl: string) {} + constructor( + private baseUrl: string, + private attr: string = "srcset", + ) {} element(el: Element) { - const srcset = el.getAttribute("srcset"); + const srcset = el.getAttribute(this.attr); if (!srcset) return; const rewritten = srcset .split(",") @@ -74,7 +77,7 @@ class SrcsetRewriter implements HTMLRewriterElementContentHandlers { return parts.join(" "); }) .join(", "); - el.setAttribute("srcset", rewritten); + el.setAttribute(this.attr, rewritten); } } @@ -108,7 +111,9 @@ export function buildRewriter(targetUrl: string): HTMLRewriter { .on("meta", new MetaCSPRemover()) .on("a, area", new URLRewriter(targetUrl, "href")) .on("img", new URLRewriter(targetUrl, "src")) + .on("img, source", new URLRewriter(targetUrl, "data-src")) .on("img, source", new SrcsetRewriter(targetUrl)) + .on("img, source", new SrcsetRewriter(targetUrl, "data-srcset")) .on("video", new URLRewriter(targetUrl, "src")) .on("video", new URLRewriter(targetUrl, "poster")) .on("audio", new URLRewriter(targetUrl, "src"))