Skip to content

Commit

Permalink
fix: wrong rootId value in special iframes (#1100)
Browse files Browse the repository at this point in the history
1. When some same-origin iframes are nested in cross-origin iframes, their `rootId`s are wrong.

2. The property `rootId` is missing in serialized cross-origin iframes
  • Loading branch information
YunFeng0817 authored Feb 9, 2023
1 parent cb15800 commit 0732618
Show file tree
Hide file tree
Showing 5 changed files with 639 additions and 6 deletions.
22 changes: 20 additions & 2 deletions packages/rrweb/src/record/iframe-manager.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Mirror, serializedNodeWithId } from 'rrweb-snapshot';
import { genId } from 'rrweb-snapshot';
import { genId, NodeType } from 'rrweb-snapshot';
import type { CrossOriginIframeMessageEvent } from '../types';
import CrossOriginIframeMirror from './cross-origin-iframe-mirror';
import { EventType, IncrementalSource } from '@rrweb/types';
Expand All @@ -14,6 +14,10 @@ export class IframeManager {
> = new WeakMap();
public crossOriginIframeMirror = new CrossOriginIframeMirror(genId);
public crossOriginIframeStyleMirror: CrossOriginIframeMirror;
public crossOriginIframeRootIdMap: WeakMap<
HTMLIFrameElement,
number
> = new WeakMap();
private mirror: Mirror;
private mutationCb: mutationCallBack;
private wrappedEmit: (e: eventWithTime, isCheckout?: boolean) => void;
Expand Down Expand Up @@ -121,6 +125,9 @@ export class IframeManager {
* Replaces the original id of the iframe with a new set of unique ids
*/
this.replaceIdOnNode(e.data.node, iframeEl);
const rootId = e.data.node.id;
this.crossOriginIframeRootIdMap.set(iframeEl, rootId);
this.patchRootIdOnNode(e.data.node, rootId);
return {
timestamp: e.timestamp,
type: EventType.IncrementalSnapshot,
Expand Down Expand Up @@ -171,6 +178,8 @@ export class IframeManager {
'previousId',
]);
this.replaceIdOnNode(n.node, iframeEl);
const rootId = this.crossOriginIframeRootIdMap.get(iframeEl);
rootId && this.patchRootIdOnNode(n.node, rootId);
});
e.data.removes.forEach((n) => {
this.replaceIds(n, iframeEl, ['parentId', 'id']);
Expand Down Expand Up @@ -273,11 +282,20 @@ export class IframeManager {
node: serializedNodeWithId,
iframeEl: HTMLIFrameElement,
) {
this.replaceIds(node, iframeEl, ['id']);
this.replaceIds(node, iframeEl, ['id', 'rootId']);
if ('childNodes' in node) {
node.childNodes.forEach((child) => {
this.replaceIdOnNode(child, iframeEl);
});
}
}

private patchRootIdOnNode(node: serializedNodeWithId, rootId: number) {
if (node.type !== NodeType.Document && !node.rootId) node.rootId = rootId;
if ('childNodes' in node) {
node.childNodes.forEach((child) => {
this.patchRootIdOnNode(child, rootId);
});
}
}
}
3 changes: 2 additions & 1 deletion packages/rrweb/test/benchmark/dom-mutation.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import * as fs from 'fs';
import * as path from 'path';
import type { Page } from 'puppeteer';
import type { eventWithTime, recordOptions } from '../../src/types';
import type { eventWithTime } from '@rrweb/types';
import type { recordOptions } from '../../src/types';
import { startServer, launchPuppeteer, ISuite, getServerURL } from '../utils';

const suites: Array<
Expand Down
3 changes: 2 additions & 1 deletion packages/rrweb/test/benchmark/replay-fast-forward.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as fs from 'fs';
import * as path from 'path';
import type { eventWithTime, recordOptions } from '../../src/types';
import type { eventWithTime } from '@rrweb/types';
import type { recordOptions } from '../../src/types';
import { launchPuppeteer, ISuite } from '../utils';

const suites: Array<{
Expand Down
Loading

0 comments on commit 0732618

Please sign in to comment.