Skip to content

[Bug]: Initial "fullSnapshot" does not include styles added via CSSStyleSheet / "adoptedStylesheets" #1626

Open
@jluxenberg

Description

Preflight Checklist

  • I have searched the issue tracker for a bug report that matches the one I want to file, without success.

What package is this bug report for?

rrweb

Version

2.0.0-alpha.18

Expected Behavior

  • The initial "fullSnapshot" frame includes styles which are synchronously added via Javascript

Actual Behavior

  • The initial "fullSnapshot" frame does NOT include styles added via creation of a new CSSStyleSheet(); added to the DOM via document.adoptedStyleSheets

Steps to Reproduce

Issue:

The Initial "fullSnapshot" in a recording does not include styles added via CSSStyleSheet / "adoptedStylesheets".

Styles added via direct DOM manipulation (e.g. "elem.style.border = ...") and via document.createElement("<style>") "work" in the sense that the initial "fullSnapshot" includes those styles.

This is a bug because the un-styled frame is never painted by the browser, but the replay includes this unstyled initial "fullSnapshot."

To reproduce:

Copy this into an HTML file and then open it, and look at the DevTools console log (or download this gist):

<html>

<head>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/rrweb@latest/dist/style.css" />

    <script type="module">
        import { record } from 'https://cdn.jsdelivr.net/npm/rrweb@2.0.0-alpha.18/+esm';
        window.events = [];

        record({
            emit(event) {
                // store the event in any way you like
                window.events.push(event);
            },
        });

        setTimeout(() => {
            const initialFrame = window.events.find(e => e.type === 2);
            const success = JSON.stringify(initialFrame).includes("lightgrey");
            if (success) {
                console.log("TEST PASSED: initial frame has our styles");
            } else {
                console.error("TEST FAILED: initial frame does not have our styles");
                const eventIdx = window.events.findIndex(e => JSON.stringify(e).includes("lightgrey"))
                console.log(`\t however; window.events[${eventIdx}] does have our styles`, window.events[eventIdx]);
            }
        }, 1500)
    </script>
</head>

<body>
    <div id="content">
        <h1>test</h1>
        <p>some text</p>
    </div>

    <script>
        // three ways to add styles via JS to `#content` div
        // the first two work, the third one fails

        // ** method (1) **
        // const elem = document.getElementById('content');
        // elem.style.border = '1px solid black';
        // elem.style.backgroundColor = 'lightgrey';

        // ** method (2) **
        // const s = document.createElement('style');
        // const cssVars = `border: 1px solid black;\nbackground-color: lightgrey;`;
        // s.type = 'text/css';
        // s.innerText = `#content { ${cssVars} }`;
        // document.head.appendChild(s);

        // ** method (3) **
        // this does not; causes unstyled initial "fullSnapshot" frame
        let sheet = new CSSStyleSheet();
        const cssVars = `border: 1px solid black;\nbackground-color: lightgrey;`;
        sheet.insertRule(`#content { ${cssVars} }`);
        document.adoptedStyleSheets = [...(document.adoptedStyleSheets ?? []), sheet];
    </script>
</body>

</html>

Testcase Gist URL

No response

Additional Information

This is related to, but slightly different from, this issue: #1230

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions