From dcaf9cf03756413559ee04b46385fd9250479835 Mon Sep 17 00:00:00 2001 From: John Pham Date: Mon, 4 Oct 2021 10:49:16 -0700 Subject: [PATCH] gc virtual style map when DOM has been removed --- package.json | 2 +- src/replay/index.ts | 3 +++ src/replay/virtual-styles.ts | 25 +++++++++++++------------ 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index 604c9dab..6ba9e9f2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@highlight-run/rrweb", - "version": "0.12.12", + "version": "0.12.13", "description": "record and replay the web", "scripts": { "test": "npm run bundle:browser && cross-env TS_NODE_CACHE=false TS_NODE_FILES=true mocha -r ts-node/register -r ignore-styles -r jsdom-global/register test/**.test.ts", diff --git a/src/replay/index.ts b/src/replay/index.ts index 46285c9b..fb8f91e0 100644 --- a/src/replay/index.ts +++ b/src/replay/index.ts @@ -1378,6 +1378,9 @@ export class Replayer { if (!target) { return this.warnNodeNotFound(d, mutation.id); } + if (this.virtualStyleRulesMap.has(target)) { + this.virtualStyleRulesMap.delete(target); + } let parent: INode | null | ShadowRoot = this.mirror.getNode( mutation.parentId, ); diff --git a/src/replay/virtual-styles.ts b/src/replay/virtual-styles.ts index 8dab9a8f..5e0ee281 100644 --- a/src/replay/virtual-styles.ts +++ b/src/replay/virtual-styles.ts @@ -66,18 +66,22 @@ export function applyVirtualStyleRulesToNode( storedRules: VirtualStyleRules, styleNode: HTMLStyleElement, ) { + const { sheet } = styleNode; + if (!sheet) { + // styleNode without sheet means the DOM has been removed + // so the rules no longer need to be applied + return; + } + storedRules.forEach((rule) => { if (rule.type === StyleRuleType.Insert) { try { if (Array.isArray(rule.index)) { const { positions, index } = getPositionsAndIndex(rule.index); - const nestedRule = getNestedRule( - styleNode.sheet!.cssRules, - positions, - ); + const nestedRule = getNestedRule(sheet.cssRules, positions); nestedRule.insertRule(rule.cssText, index); } else { - styleNode.sheet?.insertRule(rule.cssText, rule.index); + sheet.insertRule(rule.cssText, rule.index); } } catch (e) { /** @@ -89,13 +93,10 @@ export function applyVirtualStyleRulesToNode( try { if (Array.isArray(rule.index)) { const { positions, index } = getPositionsAndIndex(rule.index); - const nestedRule = getNestedRule( - styleNode.sheet!.cssRules, - positions, - ); + const nestedRule = getNestedRule(sheet.cssRules, positions); nestedRule.deleteRule(index || 0); } else { - styleNode.sheet?.deleteRule(rule.index); + sheet.deleteRule(rule.index); } } catch (e) { /** @@ -107,13 +108,13 @@ export function applyVirtualStyleRulesToNode( restoreSnapshotOfStyleRulesToNode(rule.cssTexts, styleNode); } else if (rule.type === StyleRuleType.SetProperty) { const nativeRule = (getNestedRule( - styleNode.sheet!.cssRules, + sheet.cssRules, rule.index, ) as unknown) as CSSStyleRule; nativeRule.style.setProperty(rule.property, rule.value, rule.priority); } else if (rule.type === StyleRuleType.RemoveProperty) { const nativeRule = (getNestedRule( - styleNode.sheet!.cssRules, + sheet.cssRules, rule.index, ) as unknown) as CSSStyleRule; nativeRule.style.removeProperty(rule.property);