Skip to content

Commit

Permalink
fix: inserted styles lost when moving elements
Browse files Browse the repository at this point in the history
  • Loading branch information
jaj1014 committed Nov 20, 2023
1 parent 8aea5b0 commit 588d002
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 0 deletions.
25 changes: 25 additions & 0 deletions packages/rrdom/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import type {
styleSheetRuleData,
styleDeclarationData,
} from '@rrweb/types';
import { IncrementalSource } from '@rrweb/types';
import {
BaseRRNode as RRNode,
BaseRRCDATASectionImpl,
Expand Down Expand Up @@ -248,6 +249,30 @@ export function buildFromNode(
for (const { name, value } of Array.from(elementNode.attributes)) {
rrElement.attributes[name] = value;
}

// CSSRules inserted by earlier mutations can be dropped if diff'ing
// results in the style element's position in the DOM changing
// since inserted rules are not persisted with the element to it's new location
if (tagName === 'STYLE') {
const cssElementNode = elementNode as HTMLStyleElement;

if (cssElementNode.sheet?.cssRules.length) {
const cssRules = cssElementNode.sheet.cssRules;

for (let i = 0; i < cssRules.length; i++) {
(rrNode as RRStyleElement).rules.push({
source: IncrementalSource.StyleSheetRule,
adds: [
{
index: i,
rule: cssRules[i].cssText,
},
],
});
}
}
}

elementNode.scrollLeft && (rrElement.scrollLeft = elementNode.scrollLeft);
elementNode.scrollTop && (rrElement.scrollTop = elementNode.scrollTop);
/**
Expand Down
32 changes: 32 additions & 0 deletions packages/rrdom/test/virtual-dom.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
RRCanvasElement,
RRDocument,
RRElement,
RRStyleElement,
BaseRRNode as RRNode,
} from '../src';
import { compileTSCode } from './utils';
Expand Down Expand Up @@ -207,6 +208,37 @@ describe('RRDocument for browser environment', () => {
expect((rrNode as RRElement).tagName).toEqual('SHADOWROOT');
expect(rrNode).toBe(parentRRNode.shadowRoot);
});

it('can copy CSSRules for style elements to RRNode', () => {
const styleElement = document.createElement('style') as HTMLStyleElement;
styleElement.innerHTML =
'.new-element-class {font-size: 32px; color: tomato;}';
document.body.appendChild(styleElement);
styleElement.sheet?.insertRule(
'.target-element {background-color: teal;}',
);
const rrdom = new RRDocument();

let rrNode = buildFromNode(styleElement, rrdom, mirror);

expect((rrNode as RRStyleElement).rules).toEqual([
{
adds: [
{ index: 0, rule: '.target-element {background-color: teal;}' },
],
source: 8,
},
{
adds: [
{
index: 1,
rule: '.new-element-class {font-size: 32px; color: tomato;}',
},
],
source: 8,
},
]);
});
});

describe('create a RRDocument from a html document', () => {
Expand Down

0 comments on commit 588d002

Please sign in to comment.