Skip to content

Commit

Permalink
Rename absoluteToStylesheet to absolutifyURLs and call it once af…
Browse files Browse the repository at this point in the history
…ter stringifying imported stylesheet
  • Loading branch information
jeffdnguyen committed Jul 16, 2024
1 parent f69e8f3 commit f26eacf
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 30 deletions.
6 changes: 3 additions & 3 deletions packages/rrweb-snapshot/src/snapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
getInputType,
toLowerCase,
extractFileExtension,
absoluteToStylesheet,
absolutifyURLs,
} from './utils';

let _id = 1;
Expand Down Expand Up @@ -193,7 +193,7 @@ export function transformAttribute(
} else if (name === 'srcset') {
return getAbsoluteSrcsetString(doc, value);
} else if (name === 'style') {
return absoluteToStylesheet(value, getHref(doc));
return absolutifyURLs(value, getHref(doc));
} else if (tagName === 'object' && name === 'data') {
return absoluteToDoc(doc, value);
}
Expand Down Expand Up @@ -523,7 +523,7 @@ function serializeTextNode(
n,
);
}
textContent = absoluteToStylesheet(textContent, getHref(options.doc));
textContent = absolutifyURLs(textContent, getHref(options.doc));
}
if (isScript) {
textContent = 'SCRIPT_PLACEHOLDER';
Expand Down
21 changes: 12 additions & 9 deletions packages/rrweb-snapshot/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,12 @@ export function escapeImportStatement(rule: CSSImportRule): string {
export function stringifyStylesheet(s: CSSStyleSheet): string | null {
try {
const rules = s.rules || s.cssRules;
const stringifiedRules = Array.from(rules, stringifyRule)
.map((rule) => {
return s.href ? absoluteToStylesheet(rule, s.href) : rule;
})
// const stringifiedRules = [];
// for (let i = 0; i < rules.length; i++) {
// stringifiedRules.push(stringifyRule(rules[i], s.href));
// }
const stringifiedRules = [...rules]
.map((rule: CSSRule) => stringifyRule(rule, s.href))
.join('');

return rules ? fixBrowserCompatibilityIssuesInCSS(stringifiedRules) : null;
Expand All @@ -108,7 +110,7 @@ export function stringifyStylesheet(s: CSSStyleSheet): string | null {
}
}

export function stringifyRule(rule: CSSRule): string {
export function stringifyRule(rule: CSSRule, sheetHref: string | null): string {
let importStringified;
if (isCSSImportRule(rule)) {
try {
Expand All @@ -118,6 +120,10 @@ export function stringifyRule(rule: CSSRule): string {
stringifyStylesheet(rule.styleSheet) ||
// work around browser issues with the raw string `@import url(...)` statement
escapeImportStatement(rule);

if (sheetHref) {
importStringified = absolutifyURLs(importStringified, sheetHref);
}
} catch (error) {
// ignore
}
Expand Down Expand Up @@ -369,10 +375,7 @@ const URL_IN_CSS_REF = /url\((?:(')([^']*)'|(")(.*?)"|([^)]*))\)/gm;
const URL_PROTOCOL_MATCH = /^(?:[a-z+]+:)?\/\//i;
const URL_WWW_MATCH = /^www\..*/i;
const DATA_URI = /^(data:)([^,]*),(.*)/i;
export function absoluteToStylesheet(
cssText: string | null,
href: string,
): string {
export function absolutifyURLs(cssText: string | null, href: string): string {
return (cssText || '').replace(
URL_IN_CSS_REF,
(
Expand Down
34 changes: 17 additions & 17 deletions packages/rrweb-snapshot/test/snapshot.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,56 +6,56 @@ import { describe, it, expect } from 'vitest';
import { serializeNodeWithId, _isBlockedElement } from '../src/snapshot';
import snapshot from '../src/snapshot';
import { serializedNodeWithId, elementNode } from '../src/types';
import { Mirror, absoluteToStylesheet } from '../src/utils';
import { Mirror, absolutifyURLs } from '../src/utils';

describe('absolute url to stylesheet', () => {
const href = 'http://localhost/css/style.css';

it('can handle relative path', () => {
expect(absoluteToStylesheet('url(a.jpg)', href)).toEqual(
expect(absolutifyURLs('url(a.jpg)', href)).toEqual(
`url(http://localhost/css/a.jpg)`,
);
});

it('can handle same level path', () => {
expect(absoluteToStylesheet('url("./a.jpg")', href)).toEqual(
expect(absolutifyURLs('url("./a.jpg")', href)).toEqual(
`url("http://localhost/css/a.jpg")`,
);
});

it('can handle parent level path', () => {
expect(absoluteToStylesheet('url("../a.jpg")', href)).toEqual(
expect(absolutifyURLs('url("../a.jpg")', href)).toEqual(
`url("http://localhost/a.jpg")`,
);
});

it('can handle absolute path', () => {
expect(absoluteToStylesheet('url("/a.jpg")', href)).toEqual(
expect(absolutifyURLs('url("/a.jpg")', href)).toEqual(
`url("http://localhost/a.jpg")`,
);
});

it('can handle external path', () => {
expect(absoluteToStylesheet('url("http://localhost/a.jpg")', href)).toEqual(
expect(absolutifyURLs('url("http://localhost/a.jpg")', href)).toEqual(
`url("http://localhost/a.jpg")`,
);
});

it('can handle single quote path', () => {
expect(absoluteToStylesheet(`url('./a.jpg')`, href)).toEqual(
expect(absolutifyURLs(`url('./a.jpg')`, href)).toEqual(
`url('http://localhost/css/a.jpg')`,
);
});

it('can handle no quote path', () => {
expect(absoluteToStylesheet('url(./a.jpg)', href)).toEqual(
expect(absolutifyURLs('url(./a.jpg)', href)).toEqual(
`url(http://localhost/css/a.jpg)`,
);
});

it('can handle multiple no quote paths', () => {
expect(
absoluteToStylesheet(
absolutifyURLs(
'background-image: url(images/b.jpg);background: #aabbcc url(images/a.jpg) 50% 50% repeat;',
href,
),
Expand All @@ -66,11 +66,11 @@ describe('absolute url to stylesheet', () => {
});

it('can handle data url image', () => {
expect(absolutifyURLs('url(data:image/gif;base64,ABC)', href)).toEqual(
'url(data:image/gif;base64,ABC)',
);
expect(
absoluteToStylesheet('url(data:image/gif;base64,ABC)', href),
).toEqual('url(data:image/gif;base64,ABC)');
expect(
absoluteToStylesheet(
absolutifyURLs(
'url(data:application/font-woff;base64,d09GMgABAAAAAAm)',
href,
),
Expand All @@ -79,23 +79,23 @@ describe('absolute url to stylesheet', () => {

it('preserves quotes around inline svgs with spaces', () => {
expect(
absoluteToStylesheet(
absolutifyURLs(
"url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%2328a745' d='M3'/%3E%3C/svg%3E\")",
href,
),
).toEqual(
"url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%2328a745' d='M3'/%3E%3C/svg%3E\")",
);
expect(
absoluteToStylesheet(
absolutifyURLs(
'url(\'data:image/svg+xml;utf8,<svg width="28" height="32" viewBox="0 0 28 32" xmlns="http://www.w3.org/2000/svg"><path d="M27 14C28" fill="white"/></svg>\')',
href,
),
).toEqual(
'url(\'data:image/svg+xml;utf8,<svg width="28" height="32" viewBox="0 0 28 32" xmlns="http://www.w3.org/2000/svg"><path d="M27 14C28" fill="white"/></svg>\')',
);
expect(
absoluteToStylesheet(
absolutifyURLs(
'url("data:image/svg+xml;utf8,<svg width="28" height="32" viewBox="0 0 28 32" xmlns="http://www.w3.org/2000/svg"><path d="M27 14C28" fill="white"/></svg>")',
href,
),
Expand All @@ -104,7 +104,7 @@ describe('absolute url to stylesheet', () => {
);
});
it('can handle empty path', () => {
expect(absoluteToStylesheet(`url('')`, href)).toEqual(`url('')`);
expect(absolutifyURLs(`url('')`, href)).toEqual(`url('')`);
});
});

Expand Down
2 changes: 1 addition & 1 deletion tsconfig.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"moduleResolution": "Node",
"rootDir": "src",
"outDir": "dist",
"lib": ["es6", "dom"],
"lib": ["es6", "dom", "dom.iterable"],
"sourceMap": true,
"skipLibCheck": true,
"declaration": true,
Expand Down

0 comments on commit f26eacf

Please sign in to comment.