Skip to content

Commit

Permalink
keep mirror meta synced
Browse files Browse the repository at this point in the history
  • Loading branch information
billyvg committed Jan 16, 2025
1 parent 473eacf commit f398551
Showing 1 changed file with 27 additions and 39 deletions.
66 changes: 27 additions & 39 deletions packages/rrweb/src/replay/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -933,10 +933,7 @@ export class Replayer {
sn?.tagName.toUpperCase() === 'HTML'
) {
const { documentElement, head } = iframeEl.contentDocument!;
this.insertStyleRules(
documentElement as HTMLElement | RRElement,
head as HTMLElement | RRElement,
);
this.insertStyleRules(documentElement, head);
}

// Skip the plugin onBuild callback in the virtual dom mode
Expand Down Expand Up @@ -1302,7 +1299,7 @@ export class Replayer {
if (!target) {
return this.debugNodeNotFound(d, d.id);
}
const mediaEl = target as HTMLMediaElement | RRMediaElement;
const mediaEl = target;
const { events } = this.service.state.context;

this.mediaManager.mediaMutation({
Expand Down Expand Up @@ -1439,13 +1436,13 @@ export class Replayer {
return this.warnNodeNotFound(d, mutation.parentId);
}
if (mutation.isShadow && hasShadowRoot(parent as Node)) {
parent = (parent as Element | RRElement).shadowRoot;
parent = parent.shadowRoot;
}
// target may be removed with its parents before
mirror.removeNodeFromMap(target as Node & RRNode);
mirror.removeNodeFromMap(target);
if (parent)
try {
parent.removeChild(target as Node & RRNode);
parent.removeChild(target);
/**
* https://github.com/rrweb-io/rrweb/pull/887
* Remove any virtual style rules for stylesheets if a child text node is removed.
Expand Down Expand Up @@ -1513,8 +1510,8 @@ export class Replayer {
// If the parent is attached a shadow dom after it's created, it won't have a shadow root.
if (!hasShadowRoot(parent)) {
(parent as Element | RRElement).attachShadow({ mode: 'open' });
parent = (parent as Element | RRElement).shadowRoot! as Node | RRNode;
} else parent = parent.shadowRoot as Node | RRNode;
parent = (parent as Element | RRElement).shadowRoot!;
} else parent = parent.shadowRoot;
}

let previous: Node | RRNode | null = null;
Expand All @@ -1539,10 +1536,7 @@ export class Replayer {
? this.virtualDom
: this.iframe.contentDocument;
if (isSerializedIframe<typeof parent>(parent, mirror)) {
this.attachDocumentToIframe(
mutation,
parent as HTMLIFrameElement | RRIFrameElement,
);
this.attachDocumentToIframe(mutation, parent);
return;
}
const afterAppend = (node: Node | RRNode, id: number) => {
Expand Down Expand Up @@ -1598,7 +1592,7 @@ export class Replayer {
// parent is textarea, will only keep one child node as the value
for (const c of prospectiveSiblings) {
if (c.nodeType === parent.TEXT_NODE) {
parent.removeChild(c as Node & RRNode);
parent.removeChild(c);
}
}
} else if (
Expand Down Expand Up @@ -1626,7 +1620,7 @@ export class Replayer {
* After the change of document, we may get another mutation which adds a new doctype or a HTML element, while the old one still exists in the dom.
* So, we need to remove the old one first to avoid collision.
*/
const parentDoc = parent as Document | RRDocument;
const parentDoc = parent;
/**
* To detect the exist of the old doctype before adding a new doctype.
* We need to remove the old doctype before adding the new one. Otherwise, code will throw "mutation Failed to execute 'insertBefore' on 'Node': Only one doctype on document allowed".
Expand All @@ -1635,15 +1629,13 @@ export class Replayer {
mutation.node.type === NodeType.DocumentType &&
parentDoc.childNodes[0]?.nodeType === Node.DOCUMENT_TYPE_NODE
)
parentDoc.removeChild(parentDoc.childNodes[0] as Node & RRNode);
parentDoc.removeChild(parentDoc.childNodes[0]);
/**
* To detect the exist of the old HTML element before adding a new HTML element.
* The reason is similar to the above. One document only allows exactly one DocType and one HTML Element.
*/
if (target.nodeName === 'HTML' && parentDoc.documentElement)
parentDoc.removeChild(
parentDoc.documentElement as HTMLElement & RRNode,
);
parentDoc.removeChild(parentDoc.documentElement);
}

if (previous && previous.nextSibling && previous.nextSibling.parentNode) {
Expand Down Expand Up @@ -1748,7 +1740,7 @@ export class Replayer {
return this.warnNodeNotFound(d, mutation.id);
}

const parentEl = target.parentElement as Element | RRElement;
const parentEl = target.parentElement;
if (mutation.value && parentEl && parentEl.tagName === 'STYLE') {
// assumes hackCss: true (which isn't currently configurable from rrweb)
target.textContent = adaptCssForReplay(mutation.value, this.cache);
Expand Down Expand Up @@ -1778,7 +1770,7 @@ export class Replayer {
if (typeof attributeName === 'string') {
const value = mutation.attributes[attributeName];
if (value === null) {
(target as Element | RRElement).removeAttribute(attributeName);
target.removeAttribute(attributeName);
if (attributeName === 'open')
removeDialogFromTopLevel(target, mutation);
} else if (typeof value === 'string') {
Expand All @@ -1790,7 +1782,7 @@ export class Replayer {
) {
try {
const newSn = mirror.getMeta(
target as Node & RRNode,
target,
) as serializedElementNodeWithId;
const newNode = buildNodeWithSN(
{
Expand All @@ -1808,15 +1800,17 @@ export class Replayer {
cache: this.cache,
},
);
// Update mirror meta's attributes
Object.assign(
newSn.attributes,
mutation.attributes as attributes,
);
const siblingNode = target.nextSibling;
const parentNode = target.parentNode;
if (newNode && parentNode) {
parentNode.removeChild(target as Node & RRNode);
parentNode.insertBefore(
newNode as Node & RRNode,
siblingNode as (Node & RRNode) | null,
);
mirror.replace(mutation.id, newNode as Node & RRNode);
parentNode.removeChild(target);
parentNode.insertBefore(newNode, siblingNode);
mirror.replace(mutation.id, newNode);
break;
}
} catch (e) {
Expand All @@ -1836,10 +1830,7 @@ export class Replayer {
textarea.appendChild(tn as TNode);
}
} else {
(target as Element | RRElement).setAttribute(
attributeName,
value,
);
target.setAttribute(attributeName, value);
}

if (
Expand All @@ -1856,7 +1847,7 @@ export class Replayer {
}
} else if (attributeName === 'style') {
const styleValues = value;
const targetEl = target as HTMLElement | RRElement;
const targetEl = target;
for (const s in styleValues) {
if (styleValues[s] === false) {
targetEl.style.removeProperty(s);
Expand Down Expand Up @@ -2131,7 +2122,7 @@ export class Replayer {
const nextInMap = nextId && map[nextId];
if (previousInMap) {
const { node, mutation } = previousInMap;
parent.insertBefore(node as Node & RRNode, target as Node & RRNode);
parent.insertBefore(node, target);
delete map[mutation.node.id];
delete this.legacy_missingNodeRetryMap[mutation.node.id];
if (mutation.previousId || mutation.nextId) {
Expand All @@ -2140,10 +2131,7 @@ export class Replayer {
}
if (nextInMap) {
const { node, mutation } = nextInMap;
parent.insertBefore(
node as Node & RRNode,
target.nextSibling as Node & RRNode,
);
parent.insertBefore(node, target.nextSibling);
delete map[mutation.node.id];
delete this.legacy_missingNodeRetryMap[mutation.node.id];
if (mutation.previousId || mutation.nextId) {
Expand Down

0 comments on commit f398551

Please sign in to comment.