Added support for deprecated addRule & removeRule methods (#1515)
* Added support for deprecated addRule & removeRule methods * Respect addRule default value
This commit is contained in:
6
.changeset/great-cows-camp.md
Normal file
6
.changeset/great-cows-camp.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@rrweb/record": patch
|
||||
"rrweb": patch
|
||||
---
|
||||
|
||||
Added support for deprecated addRule & removeRule methods
|
||||
@@ -659,6 +659,17 @@ function initStyleSheetObserver(
|
||||
),
|
||||
});
|
||||
|
||||
// Support for deprecated addRule method
|
||||
win.CSSStyleSheet.prototype.addRule = function (
|
||||
this: CSSStyleSheet,
|
||||
selector: string,
|
||||
styleBlock: string,
|
||||
index: number = this.cssRules.length,
|
||||
) {
|
||||
const rule = `${selector} { ${styleBlock} }`;
|
||||
return win.CSSStyleSheet.prototype.insertRule.apply(this, [rule, index]);
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
const deleteRule = win.CSSStyleSheet.prototype.deleteRule;
|
||||
win.CSSStyleSheet.prototype.deleteRule = new Proxy(deleteRule, {
|
||||
@@ -688,6 +699,14 @@ function initStyleSheetObserver(
|
||||
),
|
||||
});
|
||||
|
||||
// Support for deprecated removeRule method
|
||||
win.CSSStyleSheet.prototype.removeRule = function (
|
||||
this: CSSStyleSheet,
|
||||
index: number,
|
||||
) {
|
||||
return win.CSSStyleSheet.prototype.deleteRule.apply(this, [index]);
|
||||
};
|
||||
|
||||
let replace: (text: string) => Promise<CSSStyleSheet>;
|
||||
|
||||
if (win.CSSStyleSheet.prototype.replace) {
|
||||
|
||||
@@ -2196,6 +2196,146 @@ exports[`record > captures stylesheet rules 1`] = `
|
||||
]"
|
||||
`;
|
||||
|
||||
exports[`record > captures stylesheet rules with deprecated addRule & removeRule properties 1`] = `
|
||||
"[
|
||||
{
|
||||
\\"type\\": 4,
|
||||
\\"data\\": {
|
||||
\\"href\\": \\"about:blank\\",
|
||||
\\"width\\": 1920,
|
||||
\\"height\\": 1080
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"data\\": {
|
||||
\\"node\\": {
|
||||
\\"type\\": 0,
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 1,
|
||||
\\"name\\": \\"html\\",
|
||||
\\"publicId\\": \\"\\",
|
||||
\\"systemId\\": \\"\\",
|
||||
\\"id\\": 2
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"html\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"head\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [],
|
||||
\\"id\\": 4
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"body\\",
|
||||
\\"attributes\\": {},
|
||||
\\"childNodes\\": [
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\",
|
||||
\\"id\\": 6
|
||||
},
|
||||
{
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"input\\",
|
||||
\\"attributes\\": {
|
||||
\\"type\\": \\"text\\",
|
||||
\\"size\\": \\"40\\"
|
||||
},
|
||||
\\"childNodes\\": [],
|
||||
\\"id\\": 7
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"textContent\\": \\"\\\\n \\\\n \\\\n \\",
|
||||
\\"id\\": 8
|
||||
}
|
||||
],
|
||||
\\"id\\": 5
|
||||
}
|
||||
],
|
||||
\\"id\\": 3
|
||||
}
|
||||
],
|
||||
\\"id\\": 1
|
||||
},
|
||||
\\"initialOffset\\": {
|
||||
\\"left\\": 0,
|
||||
\\"top\\": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"data\\": {
|
||||
\\"source\\": 0,
|
||||
\\"texts\\": [],
|
||||
\\"attributes\\": [],
|
||||
\\"removes\\": [],
|
||||
\\"adds\\": [
|
||||
{
|
||||
\\"parentId\\": 4,
|
||||
\\"nextId\\": null,
|
||||
\\"node\\": {
|
||||
\\"type\\": 2,
|
||||
\\"tagName\\": \\"style\\",
|
||||
\\"attributes\\": {
|
||||
\\"_cssText\\": \\"body { background: rgb(0, 0, 0); }\\"
|
||||
},
|
||||
\\"childNodes\\": [],
|
||||
\\"id\\": 9
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"data\\": {
|
||||
\\"source\\": 8,
|
||||
\\"id\\": 9,
|
||||
\\"adds\\": [
|
||||
{
|
||||
\\"rule\\": \\"body { color: #fff; }\\",
|
||||
\\"index\\": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"data\\": {
|
||||
\\"source\\": 8,
|
||||
\\"id\\": 9,
|
||||
\\"removes\\": [
|
||||
{
|
||||
\\"index\\": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
\\"type\\": 3,
|
||||
\\"data\\": {
|
||||
\\"source\\": 8,
|
||||
\\"id\\": 9,
|
||||
\\"adds\\": [
|
||||
{
|
||||
\\"rule\\": \\"body { color: #ccc; }\\",
|
||||
\\"index\\": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]"
|
||||
`;
|
||||
|
||||
exports[`record > captures stylesheets in iframes with \`blob:\` url 1`] = `
|
||||
"[
|
||||
{
|
||||
|
||||
@@ -297,6 +297,7 @@ describe('record', function (this: ISuite) {
|
||||
// begin: pre-serialization
|
||||
const ruleIdx0 = styleSheet.insertRule('body { background: #000; }');
|
||||
const ruleIdx1 = styleSheet.insertRule('body { background: #111; }');
|
||||
|
||||
styleSheet.deleteRule(ruleIdx1);
|
||||
// end: pre-serialization
|
||||
setTimeout(() => {
|
||||
@@ -328,6 +329,69 @@ describe('record', function (this: ISuite) {
|
||||
rule: 'body { color: #fff; }',
|
||||
},
|
||||
]);
|
||||
expect((addRules[1].data as styleSheetRuleData).adds).toEqual([
|
||||
{
|
||||
rule: 'body { color: #ccc; }',
|
||||
},
|
||||
]);
|
||||
expect(removeRuleCount).toEqual(1);
|
||||
await assertSnapshot(ctx.events);
|
||||
});
|
||||
|
||||
it('captures stylesheet rules with deprecated addRule & removeRule properties', async () => {
|
||||
await ctx.page.evaluate(() => {
|
||||
const { record } = (window as unknown as IWindow).rrweb;
|
||||
|
||||
record({
|
||||
emit: (window as unknown as IWindow).emit,
|
||||
});
|
||||
|
||||
const styleElement = document.createElement('style');
|
||||
document.head.appendChild(styleElement);
|
||||
|
||||
const styleSheet = <CSSStyleSheet>styleElement.sheet;
|
||||
// begin: pre-serialization
|
||||
const ruleIdx0 = styleSheet.addRule('body', 'background: #000;');
|
||||
const ruleIdx1 = styleSheet.addRule('body', 'background: #111;');
|
||||
|
||||
styleSheet.removeRule(ruleIdx1);
|
||||
// end: pre-serialization
|
||||
setTimeout(() => {
|
||||
styleSheet.addRule('body', 'color: #fff;');
|
||||
}, 0);
|
||||
setTimeout(() => {
|
||||
styleSheet.removeRule(ruleIdx0);
|
||||
}, 5);
|
||||
setTimeout(() => {
|
||||
styleSheet.addRule('body', 'color: #ccc;');
|
||||
}, 10);
|
||||
});
|
||||
await ctx.page.waitForTimeout(50);
|
||||
const styleSheetRuleEvents = ctx.events.filter(
|
||||
(e) =>
|
||||
e.type === EventType.IncrementalSnapshot &&
|
||||
e.data.source === IncrementalSource.StyleSheetRule,
|
||||
);
|
||||
const addRules = styleSheetRuleEvents.filter((e) =>
|
||||
Boolean((e.data as styleSheetRuleData).adds),
|
||||
);
|
||||
const removeRuleCount = styleSheetRuleEvents.filter((e) =>
|
||||
Boolean((e.data as styleSheetRuleData).removes),
|
||||
).length;
|
||||
// pre-serialization insert/delete should be ignored
|
||||
expect(addRules.length).toEqual(2);
|
||||
expect((addRules[0].data as styleSheetRuleData).adds).toEqual([
|
||||
{
|
||||
index: 1,
|
||||
rule: 'body { color: #fff; }',
|
||||
},
|
||||
]);
|
||||
expect((addRules[1].data as styleSheetRuleData).adds).toEqual([
|
||||
{
|
||||
index: 1,
|
||||
rule: 'body { color: #ccc; }',
|
||||
},
|
||||
]);
|
||||
expect(removeRuleCount).toEqual(1);
|
||||
await assertSnapshot(ctx.events);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user