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
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||||
const deleteRule = win.CSSStyleSheet.prototype.deleteRule;
|
const deleteRule = win.CSSStyleSheet.prototype.deleteRule;
|
||||||
win.CSSStyleSheet.prototype.deleteRule = new Proxy(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>;
|
let replace: (text: string) => Promise<CSSStyleSheet>;
|
||||||
|
|
||||||
if (win.CSSStyleSheet.prototype.replace) {
|
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`] = `
|
exports[`record > captures stylesheets in iframes with \`blob:\` url 1`] = `
|
||||||
"[
|
"[
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -297,6 +297,7 @@ describe('record', function (this: ISuite) {
|
|||||||
// begin: pre-serialization
|
// begin: pre-serialization
|
||||||
const ruleIdx0 = styleSheet.insertRule('body { background: #000; }');
|
const ruleIdx0 = styleSheet.insertRule('body { background: #000; }');
|
||||||
const ruleIdx1 = styleSheet.insertRule('body { background: #111; }');
|
const ruleIdx1 = styleSheet.insertRule('body { background: #111; }');
|
||||||
|
|
||||||
styleSheet.deleteRule(ruleIdx1);
|
styleSheet.deleteRule(ruleIdx1);
|
||||||
// end: pre-serialization
|
// end: pre-serialization
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -328,6 +329,69 @@ describe('record', function (this: ISuite) {
|
|||||||
rule: 'body { color: #fff; }',
|
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);
|
expect(removeRuleCount).toEqual(1);
|
||||||
await assertSnapshot(ctx.events);
|
await assertSnapshot(ctx.events);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user