fix: Fix CSS rules captured in Safari (#1253)
* fix: Fix CSS rules captured in Safari * Apply formatting changes * add changeset * fix --------- Co-authored-by: mydea <mydea@users.noreply.github.com>
This commit is contained in:
5
.changeset/thirty-baboons-punch.md
Normal file
5
.changeset/thirty-baboons-punch.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'rrweb-snapshot': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Fix CSS rules captured in Safari
|
||||||
@@ -22,6 +22,7 @@ import {
|
|||||||
getCssRulesString,
|
getCssRulesString,
|
||||||
getInputType,
|
getInputType,
|
||||||
toLowerCase,
|
toLowerCase,
|
||||||
|
validateStringifiedCssRule,
|
||||||
} from './utils';
|
} from './utils';
|
||||||
|
|
||||||
let _id = 1;
|
let _id = 1;
|
||||||
@@ -53,7 +54,9 @@ function getValidTagName(element: HTMLElement): Lowercase<string> {
|
|||||||
function stringifyStyleSheet(sheet: CSSStyleSheet): string {
|
function stringifyStyleSheet(sheet: CSSStyleSheet): string {
|
||||||
return sheet.cssRules
|
return sheet.cssRules
|
||||||
? Array.from(sheet.cssRules)
|
? Array.from(sheet.cssRules)
|
||||||
.map((rule) => rule.cssText || '')
|
.map((rule) =>
|
||||||
|
rule.cssText ? validateStringifiedCssRule(rule.cssText) : '',
|
||||||
|
)
|
||||||
.join('')
|
.join('')
|
||||||
: '';
|
: '';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,6 +76,17 @@ export function getCssRuleString(rule: CSSRule): string {
|
|||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return validateStringifiedCssRule(cssStringified);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function validateStringifiedCssRule(cssStringified: string): string {
|
||||||
|
// Safari does not escape selectors with : properly
|
||||||
|
if (cssStringified.includes(':')) {
|
||||||
|
// Replace e.g. [aa:bb] with [aa\\:bb]
|
||||||
|
const regex = /(\[(?:[\w-]+)[^\\])(:(?:[\w-]+)\])/gm;
|
||||||
|
return cssStringified.replace(regex, '$1\\$2');
|
||||||
|
}
|
||||||
|
|
||||||
return cssStringified;
|
return cssStringified;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { parse, Rule, Media } from '../src/css';
|
import { parse, Rule, Media } from '../src/css';
|
||||||
|
import { validateStringifiedCssRule } from './../src/utils';
|
||||||
|
|
||||||
describe('css parser', () => {
|
describe('css parser', () => {
|
||||||
it('should save the filename and source', () => {
|
it('should save the filename and source', () => {
|
||||||
@@ -106,4 +107,17 @@ describe('css parser', () => {
|
|||||||
decl = rule.declarations![0];
|
decl = rule.declarations![0];
|
||||||
expect(decl.parent).toEqual(rule);
|
expect(decl.parent).toEqual(rule);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('parses : in attribute selectors correctly', () => {
|
||||||
|
const out1 = validateStringifiedCssRule('[data-foo] { color: red; }');
|
||||||
|
expect(out1).toEqual('[data-foo] { color: red; }');
|
||||||
|
|
||||||
|
const out2 = validateStringifiedCssRule('[data-foo:other] { color: red; }');
|
||||||
|
expect(out2).toEqual('[data-foo\\:other] { color: red; }');
|
||||||
|
|
||||||
|
const out3 = validateStringifiedCssRule(
|
||||||
|
'[data-aa\\:other] { color: red; }',
|
||||||
|
);
|
||||||
|
expect(out3).toEqual('[data-aa\\:other] { color: red; }');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user