-
Notifications
You must be signed in to change notification settings - Fork 0
fix: inject CSS/script into body when head tag is missing #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -81,17 +81,18 @@ class SrcsetRewriter implements HTMLRewriterElementContentHandlers { | |
| } | ||
| } | ||
|
|
||
| class HeadInjector implements HTMLRewriterElementContentHandlers { | ||
| constructor(private targetUrl: string) {} | ||
| const INJECTED_CSS = `<style>*:not(input):not(textarea):not(select):not(code):not(pre):not(script):not(style) { text-transform: uppercase !important; } code, pre, textarea, svg { text-transform: none !important; }</style>`; | ||
|
|
||
| class ScriptAndStyleInjector implements HTMLRewriterElementContentHandlers { | ||
| injected = false; | ||
|
|
||
| element(el: Element) { | ||
| // no <base> tag — it would redirect /browse/... paths to the target origin | ||
| // URLRewriter already resolves all relative URLs to absolute proxy paths | ||
| el.append( | ||
| `<style>*:not(input):not(textarea):not(select):not(code):not(pre):not(script):not(style) { text-transform: uppercase !important; } code, pre, textarea, svg { text-transform: none !important; }</style>`, | ||
| { html: true }, | ||
| ); | ||
| el.append(`<script>${uppercaseScript}</script>`, { html: true }); | ||
| if (this.injected) return; | ||
| this.injected = true; | ||
| // prepend into body (fallback for pages without <head>), append into head | ||
| const method = el.tagName === "head" ? "append" : "prepend"; | ||
| el[method](INJECTED_CSS, { html: true }); | ||
| el[method](`<script>${uppercaseScript}</script>`, { html: true }); | ||
|
Comment on lines
89
to
+95
|
||
| } | ||
| } | ||
|
|
||
|
|
@@ -106,8 +107,10 @@ class MetaCSPRemover implements HTMLRewriterElementContentHandlers { | |
|
|
||
| export function buildRewriter(targetUrl: string): HTMLRewriter { | ||
| const uppercaser = new TextUppercaser(); | ||
| const injector = new ScriptAndStyleInjector(); | ||
| return new HTMLRewriter() | ||
| .on("head", new HeadInjector(targetUrl)) | ||
| .on("head", injector) | ||
| .on("body", injector) | ||
| .on("meta", new MetaCSPRemover()) | ||
| .on("a, area", new URLRewriter(targetUrl, "href")) | ||
| .on("img", new URLRewriter(targetUrl, "src")) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test’s duplicate-script assertion is brittle: counting raw "walkAndUppercase" occurrences and bounding it (<10) will break if the script implementation changes (e.g., additional references). A more stable check is to assert a unique signature like "function walkAndUppercase" (or another sentinel) appears exactly once, or to count injected <script> blocks matching the injector output.