impl shadow DOM manager
part of #38 1. observe DOM mutations in shadow DOM 2. rebuild DOM mutations in shadow DOM
This commit is contained in:
@@ -5,7 +5,7 @@ import {
|
||||
MaskInputOptions,
|
||||
SlimDOMOptions,
|
||||
IGNORED_NODE,
|
||||
NodeType,
|
||||
isShadowRoot,
|
||||
} from 'rrweb-snapshot';
|
||||
import {
|
||||
mutationRecord,
|
||||
@@ -16,8 +16,16 @@ import {
|
||||
removedNodeMutation,
|
||||
addedNodeMutation,
|
||||
} from '../types';
|
||||
import { mirror, isBlocked, isAncestorRemoved, isIgnored } from '../utils';
|
||||
import {
|
||||
mirror,
|
||||
isBlocked,
|
||||
isAncestorRemoved,
|
||||
isIgnored,
|
||||
isIframeINode,
|
||||
hasShadowRoot,
|
||||
} from '../utils';
|
||||
import { IframeManager } from './iframe-manager';
|
||||
import { ShadowDomManager } from './shadow-dom-manager';
|
||||
|
||||
type DoubleLinkedListNode = {
|
||||
previous: DoubleLinkedListNode | null;
|
||||
@@ -158,6 +166,7 @@ export default class MutationBuffer {
|
||||
private doc: Document;
|
||||
|
||||
private iframeManager: IframeManager;
|
||||
private shadowDomManager: ShadowDomManager;
|
||||
|
||||
public init(
|
||||
cb: mutationCallBack,
|
||||
@@ -169,6 +178,7 @@ export default class MutationBuffer {
|
||||
slimDOMOptions: SlimDOMOptions,
|
||||
doc: Document,
|
||||
iframeManager: IframeManager,
|
||||
shadowDomManager: ShadowDomManager,
|
||||
) {
|
||||
this.blockClass = blockClass;
|
||||
this.blockSelector = blockSelector;
|
||||
@@ -179,6 +189,7 @@ export default class MutationBuffer {
|
||||
this.emissionCallback = cb;
|
||||
this.doc = doc;
|
||||
this.iframeManager = iframeManager;
|
||||
this.shadowDomManager = shadowDomManager;
|
||||
}
|
||||
|
||||
public freeze() {
|
||||
@@ -236,10 +247,14 @@ export default class MutationBuffer {
|
||||
return nextId;
|
||||
};
|
||||
const pushAdd = (n: Node) => {
|
||||
if (!n.parentNode || !this.doc.contains(n)) {
|
||||
const shadowHost: Element | null = (n.getRootNode() as ShadowRoot)?.host;
|
||||
const notInDoc = !this.doc.contains(n) && !this.doc.contains(shadowHost);
|
||||
if (!n.parentNode || notInDoc) {
|
||||
return;
|
||||
}
|
||||
const parentId = mirror.getId((n.parentNode as Node) as INode);
|
||||
const parentId = isShadowRoot(n.parentNode)
|
||||
? mirror.getId((shadowHost as unknown) as INode)
|
||||
: mirror.getId((n.parentNode as Node) as INode);
|
||||
const nextId = getNextId(n);
|
||||
if (parentId === -1 || nextId === -1) {
|
||||
return addList.addNode(n);
|
||||
@@ -255,13 +270,11 @@ export default class MutationBuffer {
|
||||
slimDOMOptions: this.slimDOMOptions,
|
||||
recordCanvas: this.recordCanvas,
|
||||
onSerialize: (currentN) => {
|
||||
if (
|
||||
currentN.__sn.type === NodeType.Element &&
|
||||
currentN.__sn.tagName === 'iframe'
|
||||
) {
|
||||
this.iframeManager.addIframe(
|
||||
(currentN as unknown) as HTMLIFrameElement,
|
||||
);
|
||||
if (isIframeINode(currentN)) {
|
||||
this.iframeManager.addIframe(currentN);
|
||||
}
|
||||
if (hasShadowRoot(n)) {
|
||||
this.shadowDomManager.addShadowRoot(n.shadowRoot, document);
|
||||
}
|
||||
},
|
||||
onIframeLoad: (iframe, childSn) => {
|
||||
@@ -418,6 +431,7 @@ export default class MutationBuffer {
|
||||
// overwrite attribute if the mutations was triggered in same time
|
||||
item.attributes[m.attributeName!] = transformAttribute(
|
||||
this.doc,
|
||||
(m.target as HTMLElement).tagName,
|
||||
m.attributeName!,
|
||||
value!,
|
||||
);
|
||||
@@ -427,7 +441,9 @@ export default class MutationBuffer {
|
||||
m.addedNodes.forEach((n) => this.genAdds(n, m.target));
|
||||
m.removedNodes.forEach((n) => {
|
||||
const nodeId = mirror.getId(n as INode);
|
||||
const parentId = mirror.getId(m.target as INode);
|
||||
const parentId = isShadowRoot(m.target)
|
||||
? mirror.getId((m.target.host as unknown) as INode)
|
||||
: mirror.getId(m.target as INode);
|
||||
if (
|
||||
isBlocked(n, this.blockClass) ||
|
||||
isBlocked(m.target, this.blockClass) ||
|
||||
@@ -463,6 +479,7 @@ export default class MutationBuffer {
|
||||
this.removes.push({
|
||||
parentId,
|
||||
id: nodeId,
|
||||
isShadow: isShadowRoot(m.target) ? true : undefined,
|
||||
});
|
||||
}
|
||||
this.mapRemoves.push(n);
|
||||
|
||||
Reference in New Issue
Block a user