change relative path into absolute path

This commit is contained in:
Yanzhen Yu
2026-04-01 12:00:00 +08:00
parent 87ff591cd1
commit e7753e1c24
5 changed files with 66 additions and 10 deletions

View File

@@ -2,8 +2,3 @@
Snapshot the DOM into a stateful and serializable data structure.
Also provide the ability to rebuild the DOM via snapshot.
## TODO
- [ ] Replace any url in css rules into absolute path.
- [ ] Select a suitable build strategy.

View File

@@ -28,6 +28,35 @@ function getCssRulesString(s: CSSStyleSheet): string | null {
}
}
const URL_IN_CSS_REF = /url\((['"])([^'"]*)\1\)/gm;
function absoluteToStylesheet(cssText: string, href: string): string {
return cssText.replace(URL_IN_CSS_REF, (_1, _2, filePath) => {
const stack = href.split('/');
const parts = filePath.split('/');
stack.pop();
for (const part of parts) {
if (part === '.') {
continue;
} else if (part === '..') {
stack.pop();
} else {
stack.push(part);
}
}
return `url('${stack.join('/')}')`;
});
}
const RELATIVE_PATH = /^(\.\.|\.|)\//;
function absoluteToDoc(doc: Document, attributeValue: string): string {
if (!RELATIVE_PATH.test(attributeValue)) {
return attributeValue;
}
const a: HTMLAnchorElement = document.createElement('a');
a.href = attributeValue;
return a.href;
}
function serializeNode(n: Node, doc: Document): serializedNode | false {
switch (n.nodeType) {
case n.DOCUMENT_NODE:
@@ -46,7 +75,12 @@ function serializeNode(n: Node, doc: Document): serializedNode | false {
const tagName = (n as HTMLElement).tagName.toLowerCase();
let attributes: attributes = {};
for (const { name, value } of Array.from((n as HTMLElement).attributes)) {
attributes[name] = value;
// relative path in attribute
if (name === 'src' || name === 'href') {
attributes[name] = absoluteToDoc(doc, value);
} else {
attributes[name] = value;
}
}
// remote css
if (tagName === 'link') {
@@ -56,7 +90,7 @@ function serializeNode(n: Node, doc: Document): serializedNode | false {
const cssText = getCssRulesString(stylesheet as CSSStyleSheet);
if (cssText) {
attributes = {
_cssText: cssText,
_cssText: absoluteToStylesheet(cssText, stylesheet!.href!),
};
}
}

View File

@@ -96,7 +96,7 @@ exports[`[html file]: iframe.html 1`] = `
<title data-rrid=\\"12\\">iframe</title>
</head>
<body data-rrid=\\"16\\">
<iframe src=\\"/html/iframe-inner.html\\" width=\\"100\\" height=\\"50\\" data-rrid=\\"18\\"></iframe>
<iframe src=\\"http://localhost:3030/html/iframe-inner.html\\" width=\\"100\\" height=\\"50\\" data-rrid=\\"18\\"></iframe>
</body></html>"
`;
@@ -110,6 +110,18 @@ exports[`[html file]: invalid-attribute.html 1`] = `
</body></html>"
`;
exports[`[html file]: with-relative-res.html 1`] = `
"<!DOCTYPE html><html xmlns=\\"http://www.w3.org/1999/xhtml\\" lang=\\"en\\" data-rrid=\\"3\\"><head data-rrid=\\"4\\">
<meta charset=\\"UTF-8\\" data-rrid=\\"6\\" />
<meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1.0\\" data-rrid=\\"8\\" />
<meta http-equiv=\\"X-UA-Compatible\\" content=\\"ie=edge\\" data-rrid=\\"10\\" />
<title data-rrid=\\"12\\">Document</title>
</head>
<body data-rrid=\\"16\\">
<a href=\\"http://localhost:3030/basic.html\\" data-rrid=\\"18\\"></a>
<img src=\\"http://localhost:3030/a.jpg\\" alt=\\"\\" srcset=\\"\\" data-rrid=\\"20\\" /></body></html>"
`;
exports[`[html file]: with-script.html 1`] = `
"<!DOCTYPE html><html xmlns=\\"http://www.w3.org/1999/xhtml\\" lang=\\"en\\" data-rrid=\\"3\\"><head data-rrid=\\"4\\">
<meta charset=\\"UTF-8\\" data-rrid=\\"6\\" />
@@ -117,7 +129,7 @@ exports[`[html file]: with-script.html 1`] = `
<meta http-equiv=\\"X-UA-Compatible\\" content=\\"ie=edge\\" data-rrid=\\"10\\" />
<title data-rrid=\\"12\\">with script</title>
</head><body data-rrid=\\"16\\">
<noscript src=\\"/js/a.js\\" data-rrid=\\"18\\"></noscript>
<noscript src=\\"http://localhost:3030/js/a.js\\" data-rrid=\\"18\\"></noscript>
<noscript data-rrid=\\"20\\"></noscript></body></html>"
`;
@@ -127,7 +139,7 @@ exports[`[html file]: with-style-sheet.html 1`] = `
<meta name=\\"viewport\\" content=\\"width=device-width, initial-scale=1.0\\" data-rrid=\\"8\\" />
<meta http-equiv=\\"X-UA-Compatible\\" content=\\"ie=edge\\" data-rrid=\\"10\\" />
<title data-rrid=\\"12\\">with style sheet</title>
<style data-rrid=\\"15\\">body { margin: 0px; }p { color: red; }body &gt; p { color: yellow; }</style>
<style data-rrid=\\"15\\">body { margin: 0px; background: url('http://localhost:3030/a.jpg'); }p { color: red; background: url('http://localhost:3030/css/b.jpg'); }body &gt; p { color: yellow; }</style>
</head><body data-rrid=\\"18\\">
</body></html>"
`;

View File

@@ -1,8 +1,10 @@
body {
margin: 0;
background: url('../a.jpg');
}
p {
color: red;
background: url('./b.jpg');
}
body > p {
color: yellow;

View File

@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<a href="./basic.html"></a>
<img src="./a.jpg" alt="" srcset="">
</body>
</html>