diff --git a/packages/rrweb-snapshot/src/rebuild.ts b/packages/rrweb-snapshot/src/rebuild.ts index d79c8f8716..8d3ae851be 100644 --- a/packages/rrweb-snapshot/src/rebuild.ts +++ b/packages/rrweb-snapshot/src/rebuild.ts @@ -380,6 +380,17 @@ function buildNode( */ if (!node.shadowRoot) { node.attachShadow({ mode: 'open' }); + // @ts-expect-error TODO + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call + n.chromaticAdoptedStylesheets.forEach( + // @ts-expect-error TODO + (chromaticAdoptedStylesheet) => { + const styleSheet = new CSSStyleSheet(); + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument + styleSheet.replaceSync(chromaticAdoptedStylesheet); + node.shadowRoot?.adoptedStyleSheets.push(styleSheet); + }, + ); } else { while (node.shadowRoot.firstChild) { node.shadowRoot.removeChild(node.shadowRoot.firstChild); @@ -443,6 +454,18 @@ export function buildNodeWithSN( if (!node) { return null; } + // // @ts-expect-error TODO + // if (n.chromaticAdoptedStylesheets) { + // // @ts-expect-error TODO + // // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call + // n.chromaticAdoptedStylesheets.forEach((sheet) => { + // const styleSheet = new CSSStyleSheet(); + // // eslint-disable-next-line @typescript-eslint/no-unsafe-argument + // styleSheet.replaceSync(sheet); + // // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call + // doc.adoptedStyleSheets.push(styleSheet); + // }); + // } // If the snapshot is created by checkout, the rootId doesn't change but the iframe's document can be changed automatically when a new iframe element is created. if (n.rootId && (mirror.getNode(n.rootId) as Document) !== doc) { mirror.replace(n.rootId, doc); diff --git a/packages/rrweb-snapshot/src/snapshot.ts b/packages/rrweb-snapshot/src/snapshot.ts index cd3d7189b7..1c878a8fe4 100644 --- a/packages/rrweb-snapshot/src/snapshot.ts +++ b/packages/rrweb-snapshot/src/snapshot.ts @@ -1020,13 +1020,41 @@ export function serializeNodeWithId( onSerialize(n); } let recordChild = !skipChild; + // @ts-expect-error TODO + if (n.adoptedStyleSheets) { + // @ts-expect-error TODO + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call + serializedNode.chromaticAdoptedStylesheets = + // @ts-expect-error TODO + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call + n.adoptedStyleSheets.map( + // @ts-expect-error TODO + (sheet) => + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access + Array.from(sheet.cssRules) + // @ts-expect-error TODO + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + .map((rule) => rule.cssText) + .join(' '), + ); + } if (serializedNode.type === NodeType.Element) { recordChild = recordChild && !serializedNode.needBlock; // this property was not needed in replay side delete serializedNode.needBlock; const shadowRootEl = dom.shadowRoot(n); - if (shadowRootEl && isNativeShadowDom(shadowRootEl)) + if (shadowRootEl && isNativeShadowDom(shadowRootEl)) { serializedNode.isShadowHost = true; + if (shadowRootEl.adoptedStyleSheets) { + // @ts-expect-error TODO + serializedNode.chromaticAdoptedStylesheets = + shadowRootEl.adoptedStyleSheets.map((sheet) => + Array.from(sheet.cssRules) + .map((rule) => rule.cssText) + .join(' '), + ); + } + } } if ( (serializedNode.type === NodeType.Document ||