ui: rewrite css parser -> urlResolve.ts
This commit is contained in:
parent
c36946ee9e
commit
b928ddb53c
1 changed files with 31 additions and 49 deletions
|
|
@ -1,64 +1,46 @@
|
|||
export function resolveURL(baseURL: string, relURL: string): string {
|
||||
if (relURL.startsWith('#') || relURL === "") {
|
||||
if (relURL.startsWith('#') || relURL === '') {
|
||||
return relURL;
|
||||
}
|
||||
return new URL(relURL, baseURL).toString();
|
||||
}
|
||||
|
||||
// url("url") or url('url') or url(url)
|
||||
const re1 = /url\(("[^"]*"|'[^']*'|[^)]*)\)/g
|
||||
// @import "url" or @import 'url'
|
||||
const re2 = /@import (["'])(.*?)\1/g
|
||||
function cssUrlsIndex(css: string): Array<[number, number]> {
|
||||
const idxs: Array<[number, number]> = [];
|
||||
const i1 = css.matchAll(re1);
|
||||
// @ts-ignore
|
||||
for (let m of i1) {
|
||||
// @ts-ignore
|
||||
const s: number = m.index + m[0].indexOf(m[1]);
|
||||
const e: number = s + m[1].length;
|
||||
idxs.push([s, e]);
|
||||
function rewriteCSSLinks(
|
||||
css: string,
|
||||
rewriter: (rawurl: string) => string
|
||||
): string {
|
||||
// Replace url() functions
|
||||
css = css.replace(/url\(\s*(['"]?)(.*?)\1\s*\)/gs, (match, quote, url) => {
|
||||
let newurl = rewriter(url.trim());
|
||||
return `url(${quote}${newurl}${quote})`;
|
||||
});
|
||||
|
||||
// Replace @import statements
|
||||
css = css.replace(
|
||||
/@import\s+(url\(\s*(['"]?)(.*?)\2\s*\)|(['"])(.*?)\4)([^;]*);?/gs,
|
||||
(match, _, quote1, url1, quote2, url2, media) => {
|
||||
let url = url1 || url2;
|
||||
let newurl = rewriter(url.trim());
|
||||
let quote = quote1 || quote2 || '';
|
||||
return `@import ${
|
||||
quote ? `url(${quote}${newurl}${quote})` : `"${newurl}"`
|
||||
}${media};`;
|
||||
}
|
||||
const i2 = css.matchAll(re2);
|
||||
// @ts-ignore
|
||||
for (let m of i2) {
|
||||
// @ts-ignore
|
||||
const s = m.index + m[0].indexOf(m[1]);
|
||||
const e = s + m[1].length;
|
||||
idxs.push([s, e])
|
||||
}
|
||||
return idxs.reverse()
|
||||
}
|
||||
function unquote(str: string): [string, string] {
|
||||
if (str.length <= 2) {
|
||||
return [str, ""]
|
||||
}
|
||||
if (str[0] == '"' && str[str.length-1] == '"') {
|
||||
return [ str.substring(1, str.length-1), "\""];
|
||||
}
|
||||
if (str[0] == '\'' && str[str.length-1] == '\'') {
|
||||
return [ str.substring(1, str.length-1), "'" ];
|
||||
}
|
||||
return [str, ""]
|
||||
}
|
||||
function rewriteCSSLinks(css: string, rewriter: (rawurl: string) => string): string {
|
||||
for (let idx of cssUrlsIndex(css)) {
|
||||
const f = idx[0]
|
||||
const t = idx[1]
|
||||
const [ rawurl, q ] = unquote(css.substring(f, t));
|
||||
css = css.substring(0,f) + q + rewriter(rawurl) + q + css.substring(t);
|
||||
}
|
||||
return css
|
||||
);
|
||||
|
||||
// Ensure the CSS ends with a semicolon
|
||||
const hasSemi = css.trim().endsWith(';');
|
||||
return hasSemi ? css : css + ';';
|
||||
}
|
||||
|
||||
function rewritePseudoclasses(css: string): string {
|
||||
return css
|
||||
.replace(/:hover/g, ".-openreplay-hover")
|
||||
.replace(/:focus/g, ".-openreplay-focus")
|
||||
.replace(/:hover/g, '.-openreplay-hover')
|
||||
.replace(/:focus/g, '.-openreplay-focus');
|
||||
}
|
||||
|
||||
export function resolveCSS(baseURL: string, css: string): string {
|
||||
return rewritePseudoclasses(
|
||||
rewriteCSSLinks(css, rawurl => resolveURL(baseURL, rawurl))
|
||||
rewriteCSSLinks(css, (rawurl) => resolveURL(baseURL, rawurl))
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue