Cross origin iframe support (#1035)

* Add `recordCrossOriginIframe` setting

* Set up messaging between iframes

* should emit full snapshot event from iframe as mutation event

* this.mirror was dropped on attachIframe

* should use unique id for child of iframe

* Cross origin iframe recording in `yarn live-stream`

* Root iframe check thats supported by firefox

* Live stream: Inject script in all frames

* Record same origin and cross origin iframes differently

* Should map Input events correctly

* Turn on other tests

* Fix compatibility with newer puppeteer

* puppeteer vs 12 seems stable without to many changes needed

* normalize port numbers in snapshots

* Handle scroll and ViewportResize events in cross origin iframe

* Correctly map cross origin mutations

* Map selection events for cross origin iframes

* Map canvas mutations for cross origin iframes

* Update snapshot to include canvas events

* Skip all meta events

* Support custom events as best we can in cross origin iframes

* Use earliest version of puppeteer that works with cross origin live-stream

* Map mouse/touch interaction events

* Update snapshots for correctly mapped click events

* Tweak tests for new puppeteer version

* Map MediaInteraction correctly for cross origin iframes

* Make tests consistent between high and low dpi devices

* Make test less flaky

* Make test less flaky

* Make test less flaky

* Make test less flaky

* Add support for styles in cross origin iframes

* Map traditional stylesheet mutations on cross origin iframes

* Add todo

* Add iframe mirror

* Get iframe manager to use iframe mirrors internally

* Rename `IframeMirror` to `CrossOriginIframeMirror`

* Setup basic cross origin canvas webrtc streaming

* Clean up removed canvas elements

* reset style mirror on new full snapshot

* Fix cross origin canvas webrtc streaming

* Make emit optional

* Run tests on github actions

* Upload image artifacts from failed tests

* Use newer github actions

* Test: hopefully adding more wait will fix it

* add extra wait

* Fix image snapshot tests

* Make tests run with new puppeteer version

* upgrade eslint-plugin-jest

* Chore: Remove travis ci as ci's running on github actions

* Chore: Support recording cross origin iframe in repl

* Force developers to update the cross origin iframe mapping when adding new events

https://github.com/rrweb-io/rrweb/pull/1035#discussion_r1012516277

* Document cross origin iframe recording

* Docs: cross origin iframes recording methods

* Docs: AI translated, cross origin iframe recording

* rename getParentId to getId

* Migrate to @rrweb/types

* Run on pull request

* doc: improve Chinese doc

* Rename `parentId` to `Id`

Co-authored-by: Mark-Fenng <f18846188605@gmail.com>
This commit is contained in:
Justin Halsall
2026-04-01 12:00:00 +08:00
committed by GitHub
parent df5d547446
commit 2cd3d2afe9
38 changed files with 7362 additions and 1038 deletions

View File

@@ -216,6 +216,23 @@ export type SamplingStrategy = Partial<{
canvas: 'all' | number;
}>;
export interface ICrossOriginIframeMirror {
getId(
iframe: HTMLIFrameElement,
remoteId: number,
parentToRemoteMap?: Map<number, number>,
remoteToParentMap?: Map<number, number>,
): number;
getIds(iframe: HTMLIFrameElement, remoteId: number[]): number[];
getRemoteId(
iframe: HTMLIFrameElement,
parentId: number,
map?: Map<number, number>,
): number;
getRemoteIds(iframe: HTMLIFrameElement, parentId: number[]): number[];
reset(iframe?: HTMLIFrameElement): void;
}
export type RecordPlugin<TOptions = unknown> = {
name: string;
observer?: (
@@ -224,7 +241,11 @@ export type RecordPlugin<TOptions = unknown> = {
options: TOptions,
) => listenerHandler;
eventProcessor?: <TExtend>(event: eventWithTime) => eventWithTime & TExtend;
getMirror?: (mirror: Mirror) => void;
getMirror?: (mirrors: {
nodeMirror: Mirror;
crossOriginIframeMirror: ICrossOriginIframeMirror;
crossOriginIframeStyleMirror: ICrossOriginIframeMirror;
}) => void;
options: TOptions;
};
@@ -636,3 +657,16 @@ declare global {
export type IWindow = Window & typeof globalThis;
export type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
export type GetTypedKeys<Obj extends object, ValueType> = TakeTypeHelper<
Obj,
ValueType
>[keyof TakeTypeHelper<Obj, ValueType>];
export type TakeTypeHelper<Obj extends object, ValueType> = {
[K in keyof Obj]: Obj[K] extends ValueType ? K : never;
};
export type TakeTypedKeyValues<Obj extends object, Type> = Pick<
Obj,
TakeTypeHelper<Obj, Type>[keyof TakeTypeHelper<Obj, Type>]
>;