feat: switch to new css rewriter

This commit is contained in:
Percs 2024-10-26 22:56:07 -05:00
parent 257b700e25
commit b9be6e8c7a
2 changed files with 155 additions and 178 deletions

View file

@ -1,64 +1,42 @@
// This CSS rewriter uses code from Meteor
// You can find the original source code at https://github.com/MeteorProxy/Meteor
import { URLMeta, rewriteUrl, unrewriteUrl } from "./url"; import { URLMeta, rewriteUrl, unrewriteUrl } from "./url";
export function rewriteCss(css: string, meta: URLMeta) { export function rewriteCss(css: string, meta: URLMeta) {
const regex = handleCss("unrewrite", css, meta);
/(@import\s+(?!url\())?\s*url\(\s*(['"]?)([^'")]+)\2\s*\)|@import\s+(['"])([^'"]+)\4/g;
return css.replace(
regex,
(
match,
importStatement,
urlQuote,
urlContent,
importQuote,
importContent
) => {
const url = urlContent || importContent;
const encodedUrl = rewriteUrl(url.trim(), meta);
if (importStatement) {
return `@import url(${urlQuote}${encodedUrl}${urlQuote})`;
}
if (importQuote) {
return `@import ${importQuote}${encodedUrl}${importQuote}`;
}
return `url(${urlQuote}${encodedUrl}${urlQuote})`;
}
);
} }
export function unrewriteCss(css: string) { export function unrewriteCss(css: string) {
const regex = handleCss("rewrite", css);
/(@import\s+(?!url\())?\s*url\(\s*(['"]?)([^'")]+)\2\s*\)|@import\s+(['"])([^'"]+)\4/g; }
return css.replace( function handleCss(type: "rewrite" | "unrewrite", css: string, meta?: URLMeta) {
regex, const urlRegex = /url\(['"]?(.+?)['"]?\)/gm;
( const Atruleregex =
match, /@import\s+(url\s*?\(.{0,9999}?\)|['"].{0,9999}?['"]|.{0,9999}?)($|\s|;)/gm;
importStatement, css = new String(css).toString();
urlQuote, css = css.replace(urlRegex, (match, url) => {
urlContent, const encodedUrl =
importQuote, type === "rewrite"
importContent ? rewriteUrl(url.trim(), meta)
) => { : unrewriteUrl(url.trim());
const url = urlContent || importContent;
const encodedUrl = unrewriteUrl(url.trim()); return match.replace(url, encodedUrl);
});
if (importStatement) { css = css.replace(Atruleregex, (_, importStatement) => {
return `@import url(${urlQuote}${encodedUrl}${urlQuote})`; return importStatement.replace(
} /^(url\(['"]?|['"]|)(.+?)(['"]|['"]?\)|)$/gm,
(match, firstQuote, url, endQuote) => {
if (importQuote) { if (firstQuote.startsWith("url")) {
return `@import ${importQuote}${encodedUrl}${importQuote}`; return match;
} }
const encodedUrl =
return `url(${urlQuote}${encodedUrl}${urlQuote})`; type === "rewrite"
} ? rewriteUrl(url.trim(), meta)
); : unrewriteUrl(url.trim());
return `${firstQuote}${encodedUrl}${endQuote}`;
}
);
});
return css;
} }

View file

@ -12,138 +12,137 @@ export function errorTemplate(trace: string, fetchedURL: string) {
`; `;
return `<!DOCTYPE html> return `<!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<title>Scramjet</title> <title>Scramjet</title>
<style> <style>
:root { :root {
--deep: #080602; --deep: #080602;
--shallow: #181412; --shallow: #181412;
--beach: #f1e8e1; --beach: #f1e8e1;
--shore: #b1a8a1; --shore: #b1a8a1;
--accent: #ffa938; --accent: #ffa938;
--font-sans: -apple-system, system-ui, BlinkMacSystemFont, sans-serif; --font-sans: -apple-system, system-ui, BlinkMacSystemFont, sans-serif;
--font-monospace: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; --font-monospace: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
} }
*:not(div,p,span,ul,li,i,span) { *:not(div,p,span,ul,li,i,span) {
background-color: var(--deep); background-color: var(--deep);
color: var(--beach); color: var(--beach);
font-family: var(--font-sans); font-family: var(--font-sans);
} }
textarea, textarea,
button { button {
background-color: var(--shallow); background-color: var(--shallow);
border-radius: 0.6em; border-radius: 0.6em;
padding: 0.6em; padding: 0.6em;
border: none; border: none;
appearance: none; appearance: none;
font-family: var(--font-sans); font-family: var(--font-sans);
color: var(--beach); color: var(--beach);
} }
button.primary { button.primary {
background-color: var(--accent); background-color: var(--accent);
color: var(--deep); color: var(--deep);
font-weight: bold; font-weight: bold;
} }
textarea { textarea {
resize: none; resize: none;
height: 20em; height: 20em;
text-align: left; text-align: left;
font-family: var(--font-monospace); font-family: var(--font-monospace);
} }
body { body {
width: 100vw; width: 100vw;
height: 100vh; height: 100vh;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
} }
body, body,
html, html,
#inner { #inner {
display: flex; display: flex;
align-items: center; align-items: center;
flex-direction: column; flex-direction: column;
gap: 0.5em; gap: 0.5em;
overflow: hidden; overflow: hidden;
} }
#inner { #inner {
z-index: 100; z-index: 100;
} }
#cover { #cover {
position: absolute; position: absolute;
width: 100%; width: 100%;
height: 100%; height: 100%;
background-color: color-mix(in srgb, var(--deep) 70%, transparent); background-color: color-mix(in srgb, var(--deep) 70%, transparent);
z-index: 99; z-index: 99;
} }
#info { #info {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: flex-start; align-items: flex-start;
gap: 1em; gap: 1em;
} }
#version-wrapper { #version-wrapper {
width: 100%; width: 100%;
text-align: center; text-align: center;
position: absolute; position: absolute;
bottom: 0.2rem; bottom: 0.2rem;
font-size: 0.8rem; font-size: 0.8rem;
color: var(--shore)!important; color: var(--shore)!important;
i { i {
background-color: color-mix(in srgb, var(--deep), transparent 50%); background-color: color-mix(in srgb, var(--deep), transparent 50%);
border-radius: 9999px; border-radius: 9999px;
padding: 0.2em 0.5em; padding: 0.2em 0.5em;
} }
z-index: 101; z-index: 101;
} }
</style> </style>
</head> </head>
<body> <body>
<div id="cover"></div> <div id="cover"></div>
<div id="inner"> <div id="inner">
<h1 id="errorTitle">Uh oh!</h1> <h1 id="errorTitle">Uh oh!</h1>
<p>There was an error loading <b id="fetchedURL"></b></p> <p>There was an error loading <b id="fetchedURL"></b></p>
<!-- <p id="errorMessage">Internal Server Error</p> --> <!-- <p id="errorMessage">Internal Server Error</p> -->
<div id="info">
<textarea id="errorTrace" cols="40" rows="10" readonly>
</textarea>
<div id="troubleshooting">
<p>Try:</p>
<ul>
<li>Checking your internet connection</li>
<li>Verifying you entered the correct address</li>
<li>Clearing the site data</li>
<li>Contacting <b id="hostname"></b>'s administrator</li>
<li>Verify the server isn't censored</li>
</ul>
<p>If you're the administrator of <b id="hostname"></b>, try:</p>
<ul>
<li>Restarting your server</li>
<li>Updating Scramjet</li>
<li>Troubleshooting the error on the <a href="https://github.com/MercuryWorkshop/scramjet" target="_blank">GitHub repository</a></li>
</ul>
</div>
</div>
<br>
<button id="reload" class="primary">Reload</button>
</div>
<p id="version-wrapper"><i>Scramjet v<span id="version"></span> (build <span id="build"></span>)</i></p>
<script src="${"data:application/javascript," + encodeURIComponent(script)}"></script>
</body>
</html>
<div id="info">
<textarea id="errorTrace" cols="40" rows="10" readonly>
</textarea>
<div id="troubleshooting">
<p>Try:</p>
<ul>
<li>Checking your internet connection</li>
<li>Verifying you entered the correct address</li>
<li>Clearing the site data</li>
<li>Contacting <b id="hostname"></b>'s administrator</li>
<li>Verify the server isn't censored</li>
</ul>
<p>If you're the administrator of <b id="hostname"></b>, try:</p>
<ul>
<li>Restarting your server</li>
<li>Updating Scramjet</li>
<li>Troubleshooting the error on the <a href="https://github.com/MercuryWorkshop/scramjet" target="_blank">GitHub repository</a></li>
</ul>
</div>
</div>
<br>
<button id="reload" class="primary">Reload</button>
</div>
<p id="version-wrapper"><i>Scramjet v<span id="version"></span> (build <span id="build"></span>)</i></p>
<script src="${"data:application/javascript," + encodeURIComponent(script)}"></script>
</body>
</html>
`; `;
} }