Replay fix for Firefox — add <head> and <body> separately (#1133)

* Firefox fix: Allow the <head> and <body> to be added in two stages so that (presumably) stylesheet rules are ready to be applied when the body appears

The css which triggered the bug was simply

{
  margin-left: 220px;
  transition: margin-left .448s;
}

* Add a test case which can only be appreciated if you record against this file://, save the events to a html file, and then open the file in Firefox (without this PR applied)

* Apply formatting changes

* Ensure we don't apply this branch when using rrdom, where it is not necessary

* Apply formatting changes

* Rewrite insertion in order to be compatible with rrdom

Also easier to understand

* Delete transition.html

* Create grumpy-ways-own.md

---------

Co-authored-by: Yun Feng <yun.feng0817@gmail.com>
This commit is contained in:
Eoghan Murray
2023-02-22 05:45:29 +00:00
committed by GitHub
parent be54981358
commit c28ef5f658
2 changed files with 29 additions and 0 deletions

View File

@@ -0,0 +1,7 @@
---
'rrweb-snapshot': patch
---
Fix: CSS transitions are incorrectly being applied upon rebuild in Firefox. Presumably FF doesn't finished parsing the styles in time, and applies e.g. a default margin:0 to elements which have a non-zero margin set in CSS, along with a transition on them.
Related bug report to Firefox: https://bugzilla.mozilla.org/show_bug.cgi?id=1816672

View File

@@ -438,6 +438,28 @@ export function buildNodeWithSN(
if (childN.isShadow && isElement(node) && node.shadowRoot) {
node.shadowRoot.appendChild(childNode);
} else if (
n.type === NodeType.Document &&
childN.type == NodeType.Element
) {
const htmlElement = childNode as HTMLElement;
let body: HTMLBodyElement | null = null;
htmlElement.childNodes.forEach((child) => {
if (child.nodeName === 'BODY') body = child as HTMLBodyElement;
});
if (body) {
// this branch solves a problem in Firefox where css transitions are incorrectly
// being applied upon rebuild. Presumably FF doesn't finished parsing the styles
// in time, and applies e.g. a default margin:0 to elements which have a non-zero
// margin set in CSS, along with a transition on them
htmlElement.removeChild(body);
// append <head> and <style>s
node.appendChild(childNode);
// now append <body>
htmlElement.appendChild(body);
} else {
node.appendChild(childNode);
}
} else {
node.appendChild(childNode);
}