Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Single style capture #1437

Open
wants to merge 20 commits into
base: master
Choose a base branch
from

Conversation

eoghanmurray
Copy link
Contributor

@eoghanmurray eoghanmurray commented Apr 5, 2024

Prep PR for async <style> serialization via assets: refactor stringifyStylesheet to happen in a single place during initial snapshot.

  • initial motivation was to change the approach on stringifying <style> elements to do so in a single place
  • I then learned that we need the style content present on child text elements, in order to support mutation
  • this is still supported, however the css content is now preferably stored in parent <style> element in that _cssText attribute, rather than in the (natural) position in the child text elements of that element. This is to support the stylesheet-assets PR which will delay population of the _cssText attribute, but the snapshot will otherwise be the same with those blankTextNodes
  • on rebuild, this content can now be 'spread' out to child text nodes (usually there's only one!) in order to give a correct target for any further text mutations on these children.
  • there is a new complex but comprehensive test 'can record and replay style text mutations' which covers all of this; it has been designed to ensure that it fails if css text is populated in the wrong way (e.g. putting the entire cssText on the first of many text children and leaving the others blank)

Copy link

changeset-bot bot commented Apr 5, 2024

🦋 Changeset detected

Latest commit: 938aeea

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 8 packages
Name Type
rrweb-snapshot Patch
rrweb Patch
rrdom Patch
rrdom-nodejs Patch
rrweb-player Patch
@rrweb/types Patch
@rrweb/web-extension Patch
rrvideo Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@@ -463,6 +465,7 @@ function serializeNode(
recordCanvas,
keepIframeSrcFn,
newlyAddedElement = false,
blankTextNodes = false,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This addition is to prevent extra 'reading' of the textContent, while still generating an id for the text node.
However, if there's multiple text node children on the <style> we still will have to 'read' the textContent in findCssTextSplits

// support legacy style
return doc.createTextNode(adaptCssForReplay(n.textContent, cache));
}
return doc.createTextNode(n.textContent);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This diff is intended to be functionally the same, but rewritten to show that the isStyle marker is no longer expected

\\"attributes\\": {
\\"_cssText\\": \\"div { color: red; }section { color: blue; }\\",
\\"_cssTextSplits\\": \\"19 43\\"
},
\\"childNodes\\": [
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So @Juice10 I think you had a question here about why I am moving things up to _cssText and adding _cssTextSplits rather than just storing everything in the childNodes ...
I suppose the "real reason" is that in the asset version of this code, we don't have the _cssText or _cssTextSplits attributes at all, but instead get these later as part of the asset event. So with the asset version, we are avoiding the inclusion of the css text content twice (in terms of size of total recording).

[key: string]: string | number | true | null;
type cssTextKeyAttr = {
_cssText?: string;
_cssTextSplits?: string;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is to ensure that if these two are defined that they can't be number/boolean/null (typescript was complaining without this)

…hat the css hasn't been altered server-side/in-transit
…ion, even if there is only one text element on the <style>.

Recent conversation with Justin has firmed up my thinking on why we look at .sheet in the first place (it's not because we want to get rid of vendor prefixes, which may actually be undesirable where they are useful for accurate replay in the replayer - but rather it's to ensure we don't miss any programmatic style mutations that have happened - have added comments to reflect this)
rrweb:test:     test/utils.ts:181:43 - error TS2345: Argument of type 'elementNode & { rootId?: number | undefined; isShadowHost?: boolean | undefined; isShadow?: boolean | undefined; } & { id: number; }' is not assignable to parameter of type '{ attributes: { src?: string | undefined; }; }'.
rrweb:test:       Types of property 'attributes' are incompatible.
rrweb:test:         Type 'attributes' has no properties in common with type '{ src?: string | undefined; }'.
rrweb:test:
rrweb:test:     181               stripBlobURLsFromAttributes(add.node);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant