From 9949db91ff75b236b546c08a40072911326863ec Mon Sep 17 00:00:00 2001 From: Eoghan Murray Date: Fri, 4 Feb 2022 17:22:24 +0000 Subject: [PATCH 1/2] Was experiencing an issue where the virtual parent optimization was destroying already applied styles during mutations --- packages/rrweb/src/replay/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/rrweb/src/replay/index.ts b/packages/rrweb/src/replay/index.ts index 66e727b134..01f1df5355 100644 --- a/packages/rrweb/src/replay/index.ts +++ b/packages/rrweb/src/replay/index.ts @@ -1401,11 +1401,13 @@ export class Replayer { /** * Why !isIframeINode(parent)? If parent element is an iframe, iframe document can't be appended to virtual parent. * Why !hasIframeChild? If we move iframe elements from dom to fragment document, we will lose the contentDocument of iframe. So we need to disable the virtual dom optimization if a parent node contains iframe elements. + * Why parent.tagName !== 'HEAD'? moving stylesheets out of the element removes the styles from the document (and they don't get replaced at `parent = virtualParent` */ if ( useVirtualParent && parentInDocument && !isIframeINode(parent) && + ((parent as unknown) as HTMLElement).tagName !== 'HEAD' && !hasIframeChild ) { const virtualParent = (document.createDocumentFragment() as unknown) as INode; From b27789eb6a59c4f549b93d00b52d99b398e139b7 Mon Sep 17 00:00:00 2001 From: Eoghan Murray Date: Mon, 14 Feb 2022 16:04:00 +0000 Subject: [PATCH 2/2] There is some sort of bug in fragmentParentMap flushing where if prevent a new parent from using virtual parent, then any new children get lost --- packages/rrweb/src/replay/index.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/rrweb/src/replay/index.ts b/packages/rrweb/src/replay/index.ts index 01f1df5355..3854c84bde 100644 --- a/packages/rrweb/src/replay/index.ts +++ b/packages/rrweb/src/replay/index.ts @@ -1403,11 +1403,13 @@ export class Replayer { * Why !hasIframeChild? If we move iframe elements from dom to fragment document, we will lose the contentDocument of iframe. So we need to disable the virtual dom optimization if a parent node contains iframe elements. * Why parent.tagName !== 'HEAD'? moving stylesheets out of the element removes the styles from the document (and they don't get replaced at `parent = virtualParent` */ + if (((parent as unknown) as HTMLElement).tagName === 'HEAD') { + useVirtualParent = false; // cancel for this and any other additions in same mutation + } if ( useVirtualParent && parentInDocument && !isIframeINode(parent) && - ((parent as unknown) as HTMLElement).tagName !== 'HEAD' && !hasIframeChild ) { const virtualParent = (document.createDocumentFragment() as unknown) as INode;