Impl record iframe (#481)

* Impl record iframe

* iframe observe

* temp: add bundle file to git

* update bundle

* update with pick

* update bundle

* fix fragment map remove

* feat: add an option to determine whether to pause CSS animation when playback is paused (#428)

set pauseAnimation to true by default

* fix: elements would lose some states like scroll position because of "virtual parent" optimization (#427)

* fix: elements would lose some state like scroll position because of "virtual parent" optimization

* refactor: the bugfix code

bug: elements would lose some state like scroll position because of "virtual parent" optimization

* fix: an error occured at applyMutation(remove nodes part)

error message:
Uncaught (in promise) DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node

* pick fixes

* revert ignore file

* re-impl iframe record

* re-impl iframe replay

* code housekeeping

* move multi layer dimension calculation to replay side

* update test cases

* teardown test server

* upgrade rrweb-snapshot with iframe load timeout

Co-authored-by: Lucky Feng <yun.feng@smartx.com>
This commit is contained in:
yz-yu
2026-04-01 12:00:00 +08:00
committed by GitHub
parent b99e843e2a
commit 33f0ac5cfe
24 changed files with 1414 additions and 246 deletions

View File

@@ -1,8 +1,4 @@
import {
EventType,
eventWithTime,
IncrementalSource
} from '../../src/types';
import { EventType, eventWithTime, IncrementalSource } from '../../src/types';
const now = Date.now();
const events: eventWithTime[] = [
@@ -27,68 +23,124 @@ const events: eventWithTime[] = [
},
// full snapshot:
{
"data": {
"node": {
"id": 1, "type": 0, "childNodes": [{ "id": 2, "name": "html", "type": 1, "publicId": "", "systemId": "" }, {
"id": 3, "type": 2, "tagName": "html", "attributes": { "lang": "en" }, "childNodes": [{
"id": 4, "type": 2, "tagName": "head", "attributes": {}, "childNodes": [
data: {
node: {
id: 1,
type: 0,
childNodes: [
{ id: 2, name: 'html', type: 1, publicId: '', systemId: '' },
{
id: 3,
type: 2,
tagName: 'html',
attributes: { lang: 'en' },
childNodes: [
{
"id": 101, "type": 2, "tagName": "style", "attributes": { "data-jss": "", "data-meta": "sk, Unthemed, Static" }, "childNodes": [{ "id": 102, "type": 3, "isStyle": true, "textContent": "\n.c01x {\n opacity: 1;\n transform: translateX(0);\n}\n" }]
id: 4,
type: 2,
tagName: 'head',
attributes: {},
childNodes: [
{
id: 101,
type: 2,
tagName: 'style',
attributes: {
'data-jss': '',
'data-meta': 'sk, Unthemed, Static',
},
childNodes: [
{
id: 102,
type: 3,
isStyle: true,
textContent:
'\n.c01x {\n opacity: 1;\n transform: translateX(0);\n}\n',
},
],
},
{
id: 105,
type: 2,
tagName: 'style',
attributes: {
_cssText:
'.css-1uxxxx3 { position: fixed; top: 0px; right: 0px; left: 4rem; z-index: 15; flex-shrink: 0; height: 0.25rem; overflow: hidden; background-color: rgb(17, 171, 209); }.css-1c9xxxx { height: 0.25rem; background-color: rgb(190, 232, 242); opacity: 0; transition: opacity 0.5s ease 0s; }.css-lsxxx { padding-left: 4rem; }',
'data-emotion': 'css',
},
childNodes: [
{ id: 106, type: 3, isStyle: true, textContent: '' },
],
},
],
},
{
"id": 105, "type": 2, "tagName": "style", "attributes":
{ "_cssText": ".css-1uxxxx3 { position: fixed; top: 0px; right: 0px; left: 4rem; z-index: 15; flex-shrink: 0; height: 0.25rem; overflow: hidden; background-color: rgb(17, 171, 209); }.css-1c9xxxx { height: 0.25rem; background-color: rgb(190, 232, 242); opacity: 0; transition: opacity 0.5s ease 0s; }.css-lsxxx { padding-left: 4rem; }", "data-emotion": "css" }, "childNodes": [{ "id": 106, "type": 3, "isStyle": true, "textContent": "" }]
}]
}, {
"id": 107, "type": 2, "tagName": "body", "attributes": {}, "childNodes": []
}]
}]
}, "initialOffset": { "top": 0, "left": 0 }
id: 107,
type: 2,
tagName: 'body',
attributes: {},
childNodes: [],
},
],
},
],
},
initialOffset: { top: 0, left: 0 },
},
"type": EventType.FullSnapshot,
"timestamp": now + 100
type: EventType.FullSnapshot,
timestamp: now + 100,
},
// mutation that adds stylesheet
{
"data": {
"adds": [
data: {
adds: [
{
"node": {
"id": 255, "type": 2, "tagName": "style", "attributes": { "data-jss": "", "data-meta": "Col, Themed, Dynamic" }, "childNodes": []
node: {
id: 255,
type: 2,
tagName: 'style',
attributes: { 'data-jss': '', 'data-meta': 'Col, Themed, Dynamic' },
childNodes: [],
},
"nextId": 101,
"parentId": 4
nextId: 101,
parentId: 4,
},
{
"node": {
"id": 256, "type": 3, "isStyle": true, "textContent": "\n.c011xx {\n padding: 1.3125rem;\n flex: none;\n width: 100%;\n}\n"
node: {
id: 256,
type: 3,
isStyle: true,
textContent:
'\n.c011xx {\n padding: 1.3125rem;\n flex: none;\n width: 100%;\n}\n',
},
"nextId": null,
"parentId": 255
nextId: null,
parentId: 255,
},
],
"texts": [],
"source": IncrementalSource.Mutation,
"removes": [],
"attributes": []
texts: [],
source: IncrementalSource.Mutation,
removes: [],
attributes: [],
},
"type": EventType.IncrementalSnapshot,
"timestamp": now + 500
type: EventType.IncrementalSnapshot,
timestamp: now + 500,
},
// adds StyleSheetRule
{
"data": {
"id": 105, "adds": [
data: {
id: 105,
adds: [
{
"rule": ".css-1fbxx79{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;min-width:60rem;min-height:100vh;}",
"index": 2
}
rule:
'.css-1fbxx79{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;min-width:60rem;min-height:100vh;}',
index: 2,
},
],
"source": IncrementalSource.StyleSheetRule
source: IncrementalSource.StyleSheetRule,
},
"type": EventType.IncrementalSnapshot,
"timestamp": now + 1000
}
type: EventType.IncrementalSnapshot,
timestamp: now + 1000,
},
];
export default events;
export default events;