diff --git a/.gitignore b/.gitignore index de1069e3..ceafb636 100644 --- a/.gitignore +++ b/.gitignore @@ -9,5 +9,3 @@ es lib temp - -*.log diff --git a/.npmignore b/.npmignore index c20d3312..50d10e91 100644 --- a/.npmignore +++ b/.npmignore @@ -1,7 +1 @@ -.vscode -.idea -node_modules -package-lock.json -yarn.lock -temp -*.log +!**/node_modules \ No newline at end of file diff --git a/README.md b/README.md index e05dd057..c631cf0a 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,6 @@ # rrweb -**[We are hiring!(in mainland China)](https://mp.weixin.qq.com/s/VhFwemIzaXec-hI3zyltfg)** - **[The new adventure of the rrweb community](http://www.myriptide.com/rrweb-community/)** [![Build Status](https://travis-ci.org/rrweb-io/rrweb.svg?branch=master)](https://travis-ci.org/rrweb-io/rrweb) diff --git a/README.zh_CN.md b/README.zh_CN.md index b2e5acb2..a26a2127 100644 --- a/README.zh_CN.md +++ b/README.zh_CN.md @@ -7,8 +7,6 @@ # rrweb -**[招聘:和我们一起,做难的事情!](https://mp.weixin.qq.com/s/VhFwemIzaXec-hI3zyltfg)** - **[rrweb 社区新的征程](http://www.myriptide.com/rrweb-community-cn/)** [![Build Status](https://travis-ci.org/rrweb-io/rrweb.svg?branch=master)](https://travis-ci.org/rrweb-io/rrweb) diff --git a/docs/observer.md b/docs/observer.md index 20417b42..6e5f8e2e 100644 --- a/docs/observer.md +++ b/docs/observer.md @@ -53,7 +53,7 @@ In the first case, two mutation records will be generated, namely adding node n1 Due to the second case, when processing new nodes we must traverse all its descendants to ensure that all new nodes are recorded, however this strategy will cause n2 to be (incorrectly) recorded during the first record. Then, when processing the second record, adding a the node for a second time will result in a DOM structure that is inconsistent with the original page during replay. -Therefore, when dealing with multiple mutation records in a callback, we need to "lazily" process the newly-added nodes, that is, first collect all raw, unprocessed nodes when we go through each mutation record, and then after we've been through all the mutation records we determine the order in which the nodes were added to the DOM. When these new nodes are added, we perform deduplication to ensure that each node is only recorded once and we check no nodes were missed. +Therefore, when dealing with multiple mutation records in a callback, we need to "lazily" process the newly-added nodes, that is, first collect all raw, unprocessed nodes when we go through each mutation record, and then after we've been through all the mutation records we determine the the order nodes were added to the DOM. When new these nodes are added we perform deduplication to ensure that each node is only recorded once and we check no nodes were missed. We already introduced in the [serialization design document](./serialization.md) that we need to maintain a mapping of `id -> Node`, so when new nodes appear, we need to serialize the new nodes and add them to the map. But since we want to perform deduplication, and thus only serialize after all the mutation records have been processed, some problems may arise, as demonstrated in the following example: diff --git a/docs/recipes/customize-replayer.md b/docs/recipes/customize-replayer.md index a066f199..de2bcec8 100644 --- a/docs/recipes/customize-replayer.md +++ b/docs/recipes/customize-replayer.md @@ -53,17 +53,17 @@ And there are some ways to listen rrweb-player's state: ```js // get current timing rrwebPlayer.addEventListener('ui-update-current-time', (event) => { - console.log(event.payload); + console.log(event.detail.payload); }); // get current state rrwebPlayer.addEventListener('ui-update-player-state', (event) => { - console.log(event.payload); + console.log(event.detail.payload); }); // get current progress rrwebPlayer.addEventListener('ui-update-progress', (event) => { - console.log(event.payload); + console.log(event.detail.payload); }); ``` diff --git a/docs/recipes/customize-replayer.zh_CN.md b/docs/recipes/customize-replayer.zh_CN.md index 7d76e2ab..e0db0d27 100644 --- a/docs/recipes/customize-replayer.zh_CN.md +++ b/docs/recipes/customize-replayer.zh_CN.md @@ -53,17 +53,17 @@ rrwebPlayer.goto(3000); ```js // 当前播放时间 rrwebPlayer.addEventListener('ui-update-current-time', (event) => { - console.log(event.payload); + console.log(event.detail.payload); }); // 当前播放状态 rrwebPlayer.addEventListener('ui-update-player-state', (event) => { - console.log(event.payload); + console.log(event.detail.payload); }); // 当前播放进度 rrwebPlayer.addEventListener('ui-update-progress', (event) => { - console.log(event.payload); + console.log(event.detail.payload); }); ``` diff --git a/guide.md b/guide.md index 87fc4700..81ffd52e 100644 --- a/guide.md +++ b/guide.md @@ -1,6 +1,6 @@ # Guide -[中文指南](./guide.zh_CN.md) +[中文指南](./guide.md) > You may also want to read the [recipes](./docs/recipes/index.md) to find some use real-world use case, or read the [design docs](./docs) to know more technical details of rrweb. @@ -142,11 +142,8 @@ The parameter of `rrweb.record` accepts the following options. | checkoutEveryNms | - | take a full snapshot after every N ms
refer to the [checkout](#checkout) chapter | | blockClass | 'rr-block' | Use a string or RegExp to configure which elements should be blocked, refer to the [privacy](#privacy) chapter | | ignoreClass | 'rr-ignore' | Use a string or RegExp to configure which elements should be ignored, refer to the [privacy](#privacy) chapter | -| blockSelector | null | Use a string or RegExp to configure which selector should be blocked, refer to the [privacy](#privacy) chapter | | maskAllInputs | false | mask all input content as \* | | maskInputOptions | {} | mask some kinds of input \*
refer to the [list](https://github.com/rrweb-io/rrweb-snapshot/blob/6728d12b3cddd96951c86d948578f99ada5749ff/src/types.ts#L72) | -| maskInputFn | - | customize mask input content recording logic | -| slimDOMOptions | {} | remove unnecessary parts of the DOM
refer to the [list](https://github.com/rrweb-io/rrweb-snapshot/blob/6728d12b3cddd96951c86d948578f99ada5749ff/src/types.ts#L91) | | inlineStylesheet | true | whether to inline the stylesheet in the events | | hooks | {} | hooks for events
refer to the [list](https://github.com/rrweb-io/rrweb/blob/9488deb6d54a5f04350c063d942da5e96ab74075/src/types.ts#L207) | | packFn | - | refer to the [storage optimization recipe](./docs/recipes/optimize-storage.md) | @@ -290,7 +287,7 @@ The replayer accepts options as its constructor's second parameter, and it has t | showDebug | false | whether to print debug messages during replay | | blockClass | 'rr-block' | element with the class name will display as a blocked area | | liveMode | false | whether to enable live mode | -| insertStyleRules | [] | accepts multiple CSS rule string, which will be injected into the replay iframe | +| inertStyleRules | [] | accepts multiple CSS rule string, which will be injected into the replay iframe | | triggerFocus | true | whether to trigger focus during replay | | UNSAFE_replayCanvas | false | whether to replay the canvas element. **Enable this will remove the sandbox, which is unsafe.** | | mouseTail | true | whether to show mouse tail during replay. Set to false to disable mouse tail. A complete config can be found in this [type](https://github.com/rrweb-io/rrweb/blob/9488deb6d54a5f04350c063d942da5e96ab74075/src/types.ts#L407) | @@ -378,9 +375,9 @@ And there are three rrweb-replayer event will be emitted in the same way: | Event | Description | Value | | ---------------------- | -------------------------------- | ----------------------- | -| ui-update-current-time | current time has changed | { payload } | -| ui-update-player-state | current player state has changed | { payload } | -| ui-update-progress | current progress has changed | { payload } | +| ui-update-current-time | current time has changed | { detail: { payload } } | +| ui-update-player-state | current player state has changed | { detail: { payload } } | +| ui-update-progress | current progress has changed | { detail: { payload } } | ## REPL tool diff --git a/guide.zh_CN.md b/guide.zh_CN.md index 9a54488d..893c2789 100644 --- a/guide.zh_CN.md +++ b/guide.zh_CN.md @@ -137,19 +137,16 @@ setInterval(save, 10 * 1000); | checkoutEveryNth | - | 每 N 次事件重新制作一次全量快照
详见[“重新制作快照”](#重新制作快照)章节 | | checkoutEveryNms | - | 每 N 毫秒重新制作一次全量快照
详见[“重新制作快照”](#重新制作快照)章节 | | blockClass | 'rr-block' | 字符串或正则表达式,可用于自定义屏蔽元素的类名,详见[“隐私”](#隐私)章节 | -| blockSelector | null | 字符串或正则表达式,可用于自定义屏蔽元素的选择器,详见[“隐私”](#隐私)章节 | | ignoreClass | 'rr-ignore' | 字符串或正则表达式,可用于自定义忽略元素的类名,详见[“隐私”](#隐私)章节 | | maskAllInputs | false | 将所有输入内容记录为 \* | | maskInputOptions | {} | 选择将特定类型的输入框内容记录为 \*
类型详见[列表](https://github.com/rrweb-io/rrweb-snapshot/blob/6728d12b3cddd96951c86d948578f99ada5749ff/src/types.ts#L72) | -| maskInputFn | - | 自定义特定类型的输入框内容记录逻辑 | -| slimDOMOptions | {} | 去除 DOM 中不必要的部分
类型详见[列表](https://github.com/rrweb-io/rrweb-snapshot/blob/6728d12b3cddd96951c86d948578f99ada5749ff/src/types.ts#L91) | | inlineStylesheet | true | 是否将样式表内联 | | hooks | {} | 各类事件的回调
类型详见[列表](https://github.com/rrweb-io/rrweb/blob/9488deb6d54a5f04350c063d942da5e96ab74075/src/types.ts#L207) | | packFn | - | 数据压缩函数,详见[优化存储策略](./docs/recipes/optimize-storage.zh_CN.md) | | sampling | - | 数据抽样策略,详见[优化存储策略](./docs/recipes/optimize-storage.zh_CN.md) | | recordCanvas | false | 是否记录 canvas 内容 | | collectFonts | false | 是否记录页面中的字体文件 | -| recordLog | false | 是否记录 console 输出,详见[console 录制和播放](./docs/recipes/console.zh_CN.md) | +| recordLog | false | 是否记录console 输出,详见[console录制和播放](./docs/recipes/console.zh_CN.md) | #### 隐私 @@ -286,12 +283,12 @@ replayer.pause(5000); | showDebug | false | 是否在回放过程中打印 debug 信息 | | blockClass | 'rr-block' | 需要在回放时展示为隐藏区域的元素类名 | | liveMode | false | 是否开启直播模式 | -| insertStyleRules | [] | 可以传入多个 CSS rule string,用于自定义回放时 iframe 内的样式 | +| inertStyleRules | [] | 可以传入多个 CSS rule string,用于自定义回放时 iframe 内的样式 | | triggerFocus | true | 回放时是否回放 focus 交互 | | UNSAFE_replayCanvas | false | 回放时是否回放 canvas 内容,**开启后将会关闭沙盒策略,导致一定风险** | | mouseTail | true | 是否在回放时增加鼠标轨迹。传入 false 可关闭,传入对象可以定制轨迹持续时间、样式等,配置详见[类型](https://github.com/rrweb-io/rrweb/blob/9488deb6d54a5f04350c063d942da5e96ab74075/src/types.ts#L407) | | unpackFn | - | 数据解压缩函数,详见[优化存储策略](./docs/recipes/optimize-storage.zh_CN.md) | -| logConfig | - | console logger 数据播放设置,详见[console 录制和播放](./docs/recipes/console.zh_CN.md) | +| logConfig | - | console logger数据播放设置,详见[console录制和播放](./docs/recipes/console.zh_CN.md) | #### 使用 rrweb-player @@ -376,9 +373,9 @@ replayer.on(EVENT_NAME, (payload) => { | 事件类型 | 描述 | 值 | | ---------------------- | -------------- | ----------------------- | -| ui-update-current-time | 当前回放时间点 | { payload } | -| ui-update-player-state | 当前回放状态 | { payload } | -| ui-update-progress | 当前回放百分比 | { payload } | +| ui-update-current-time | 当前回放时间点 | { detail: { payload } } | +| ui-update-player-state | 当前回放状态 | { detail: { payload } } | +| ui-update-progress | 当前回放百分比 | { detail: { payload } } | ## REPL 工具 diff --git a/package.json b/package.json index 531b7241..fc4e5a2b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@highlight-run/rrweb", - "version": "0.10.5", + "version": "0.10.6", "description": "record and replay the web", "scripts": { "test": "npm run bundle:browser && cross-env TS_NODE_CACHE=false TS_NODE_FILES=true mocha -r ts-node/register test/**/*.test.ts", @@ -44,13 +44,11 @@ "jest-snapshot": "^23.6.0", "mini-css-extract-plugin": "^1.3.8", "mocha": "^5.2.0", - "prettier": "2.2.1", "puppeteer": "^1.11.0", "rollup": "^2.3.3", "rollup-plugin-commonjs": "^9.2.0", "rollup-plugin-node-resolve": "^3.4.0", "rollup-plugin-postcss": "^3.1.1", - "rollup-plugin-rename-node-modules": "^1.1.0", "rollup-plugin-terser": "^5.3.0", "rollup-plugin-typescript": "^1.0.0", "style-loader": "^2.0.0", diff --git a/rollup.config.js b/rollup.config.js index 3381a518..135dba4d 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -2,7 +2,6 @@ import typescript from 'rollup-plugin-typescript'; import resolve from 'rollup-plugin-node-resolve'; import { terser } from 'rollup-plugin-terser'; import postcss from 'rollup-plugin-postcss'; -import renameNodeModules from 'rollup-plugin-rename-node-modules'; import pkg from './package.json'; function toRecordPath(path) { @@ -138,7 +137,6 @@ for (const c of baseConfigs) { { format: 'esm', dir: 'es/rrweb', - plugins: [renameNodeModules('ext')], }, ], }); diff --git a/scripts/repl.ts b/scripts/repl.ts index 1b933079..41755254 100644 --- a/scripts/repl.ts +++ b/scripts/repl.ts @@ -81,11 +81,7 @@ function getCode(): string { width: 1600, height: 900, }, - args: [ - '--start-maximized', - '--ignore-certificate-errors', - '--no-sandbox', - ], + args: ['--start-maximized', '--ignore-certificate-errors'], }); const page = await browser.newPage(); await page.goto(url, { @@ -132,7 +128,7 @@ function getCode(): string { width: 1600, height: 900, }, - args: ['--start-maximized', '--no-sandbox'], + args: ['--start-maximized'], }); const page = await browser.newPage(); await page.goto('about:blank'); diff --git a/src/index.ts b/src/index.ts index e57b8e42..5ff42d87 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,6 +8,7 @@ export { IncrementalSource, MouseInteractions, ReplayerEvents, + HighlightConfiguration, } from './types'; const { addCustomEvent } = record; diff --git a/src/record/iframe-manager.ts b/src/record/iframe-manager.ts deleted file mode 100644 index 92909fcb..00000000 --- a/src/record/iframe-manager.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { serializedNodeWithId, INode } from '../snapshot'; -import { mutationCallBack } from '../types'; - -export class IframeManager { - private iframes: WeakMap = new WeakMap(); - private mutationCb: mutationCallBack; - private loadListener?: (iframeEl: HTMLIFrameElement) => unknown; - - constructor(options: { mutationCb: mutationCallBack }) { - this.mutationCb = options.mutationCb; - } - - public addIframe(iframeEl: HTMLIFrameElement) { - this.iframes.set(iframeEl, true); - } - - public addLoadListener(cb: (iframeEl: HTMLIFrameElement) => unknown) { - this.loadListener = cb; - } - - public attachIframe(iframeEl: INode, childSn: serializedNodeWithId) { - this.mutationCb({ - adds: [ - { - parentId: iframeEl.__sn.id, - nextId: null, - node: childSn, - }, - ], - removes: [], - texts: [], - attributes: [], - isAttachIframe: true, - }); - this.loadListener?.((iframeEl as unknown) as HTMLIFrameElement); - } -} diff --git a/src/record/index.ts b/src/record/index.ts index 2d2234e0..95396d20 100644 --- a/src/record/index.ts +++ b/src/record/index.ts @@ -1,13 +1,11 @@ import { snapshot, MaskInputOptions, SlimDOMOptions } from '../snapshot'; -import { initObservers, mutationBuffers } from './observer'; +import { initObservers, mutationBuffer } from './observer'; import { mirror, on, getWindowWidth, getWindowHeight, polyfill, - isIframeINode, - hasShadowRoot, } from '../utils'; import { EventType, @@ -17,10 +15,7 @@ import { IncrementalSource, listenerHandler, LogRecordOptions, - mutationCallbackParam, } from '../types'; -import { IframeManager } from './iframe-manager'; -import { ShadowDomManager } from './shadow-dom-manager'; function wrapEvent(e: event): eventWithTime { return { @@ -31,8 +26,6 @@ function wrapEvent(e: event): eventWithTime { let wrappedEmit!: (e: eventWithTime, isCheckout?: boolean) => void; -let takeFullSnapshot!: (isCheckout?: boolean) => void; - function record( options: recordOptions = {}, ): listenerHandler | undefined { @@ -147,7 +140,7 @@ function record( let incrementalSnapshotCount = 0; wrappedEmit = (e: eventWithTime, isCheckout?: boolean) => { if ( - mutationBuffers[0]?.isFrozen() && + mutationBuffer.isFrozen() && e.type !== EventType.FullSnapshot && !( e.type === EventType.IncrementalSnapshot && @@ -156,7 +149,8 @@ function record( ) { // we've got a user initiated event so first we need to apply // all DOM changes that have been buffering during paused state - mutationBuffers.forEach((buf) => buf.unfreeze()); + mutationBuffer.emit(); + mutationBuffer.unfreeze(); } emit(((packFn ? packFn(e) : e) as unknown) as T, isCheckout); @@ -164,14 +158,6 @@ function record( lastFullSnapshotEvent = e; incrementalSnapshotCount = 0; } else if (e.type === EventType.IncrementalSnapshot) { - // attch iframe should be considered as full snapshot - if ( - e.data.source === IncrementalSource.Mutation && - e.data.isAttachIframe - ) { - return; - } - incrementalSnapshotCount++; const exceedCount = checkoutEveryNth && incrementalSnapshotCount >= checkoutEveryNth; @@ -184,37 +170,7 @@ function record( } }; - const wrappedMutationEmit = (m: mutationCallbackParam) => { - wrappedEmit( - wrapEvent({ - type: EventType.IncrementalSnapshot, - data: { - source: IncrementalSource.Mutation, - ...m, - }, - }), - ); - }; - - const iframeManager = new IframeManager({ - mutationCb: wrappedMutationEmit, - }); - - const shadowDomManager = new ShadowDomManager({ - mutationCb: wrappedMutationEmit, - bypassOptions: { - blockClass, - blockSelector, - inlineStylesheet, - maskInputOptions, - recordCanvas, - slimDOMOptions, - iframeManager, - enableStrictPrivacy, - }, - }); - - takeFullSnapshot = (isCheckout = false) => { + function takeFullSnapshot(isCheckout = false) { wrappedEmit( wrapEvent({ type: EventType.Meta, @@ -227,7 +183,8 @@ function record( isCheckout, ); - mutationBuffers.forEach((buf) => buf.lock()); // don't allow any mirror modifications during snapshotting + let wasFrozen = mutationBuffer.isFrozen(); + mutationBuffer.freeze(); // don't allow any mirror modifications during snapshotting const [node, idNodeMap] = snapshot(document, { blockClass, blockSelector, @@ -236,17 +193,6 @@ function record( slimDOM: slimDOMOptions, recordCanvas, enableStrictPrivacy, - onSerialize: (n) => { - if (isIframeINode(n)) { - iframeManager.addIframe(n); - } - if (hasShadowRoot(n)) { - shadowDomManager.addShadowRoot(n.shadowRoot, document); - } - }, - onIframeLoad: (iframe, childSn) => { - iframeManager.attachIframe(iframe, childSn); - }, }); if (!node) { @@ -278,8 +224,11 @@ function record( }, }), ); - mutationBuffers.forEach((buf) => buf.unlock()); // generate & emit any mutations that happened during snapshotting, as can now apply against the newly built mirror - }; + if (!wasFrozen) { + mutationBuffer.emit(); // emit anything queued up now + mutationBuffer.unfreeze(); + } + } try { const handlers: listenerHandler[] = []; @@ -293,138 +242,137 @@ function record( ); }), ); - - const observe = (doc: Document) => { - return initObservers( - { - mutationCb: wrappedMutationEmit, - mousemoveCb: (positions, source) => - wrappedEmit( - wrapEvent({ - type: EventType.IncrementalSnapshot, - data: { - source, - positions, - }, - }), - ), - mouseInteractionCb: (d) => - wrappedEmit( - wrapEvent({ - type: EventType.IncrementalSnapshot, - data: { - source: IncrementalSource.MouseInteraction, - ...d, - }, - }), - ), - scrollCb: (p) => - wrappedEmit( - wrapEvent({ - type: EventType.IncrementalSnapshot, - data: { - source: IncrementalSource.Scroll, - ...p, - }, - }), - ), - viewportResizeCb: (d) => - wrappedEmit( - wrapEvent({ - type: EventType.IncrementalSnapshot, - data: { - source: IncrementalSource.ViewportResize, - ...d, - }, - }), - ), - inputCb: (v) => - wrappedEmit( - wrapEvent({ - type: EventType.IncrementalSnapshot, - data: { - source: IncrementalSource.Input, - ...v, - }, - }), - ), - mediaInteractionCb: (p) => - wrappedEmit( - wrapEvent({ - type: EventType.IncrementalSnapshot, - data: { - source: IncrementalSource.MediaInteraction, - ...p, - }, - }), - ), - styleSheetRuleCb: (r) => - wrappedEmit( - wrapEvent({ - type: EventType.IncrementalSnapshot, - data: { - source: IncrementalSource.StyleSheetRule, - ...r, - }, - }), - ), - canvasMutationCb: (p) => - wrappedEmit( - wrapEvent({ - type: EventType.IncrementalSnapshot, - data: { - source: IncrementalSource.CanvasMutation, - ...p, - }, - }), - ), - fontCb: (p) => - wrappedEmit( - wrapEvent({ - type: EventType.IncrementalSnapshot, - data: { - source: IncrementalSource.Font, - ...p, - }, - }), - ), - logCb: (p) => - wrappedEmit( - wrapEvent({ - type: EventType.IncrementalSnapshot, - data: { - source: IncrementalSource.Log, - ...p, - }, - }), - ), - blockClass, - ignoreClass, - maskInputOptions, - inlineStylesheet, - sampling, - recordCanvas, - collectFonts, - doc, - maskInputFn, - logOptions, - blockSelector, - slimDOMOptions, - iframeManager, - shadowDomManager, - enableStrictPrivacy, - }, - hooks, - ); - }; - - iframeManager.addLoadListener((iframeEl) => { - handlers.push(observe(iframeEl.contentDocument!)); - }); - const init = () => { takeFullSnapshot(); - handlers.push(observe(document)); + handlers.push( + initObservers( + { + mutationCb: (m) => + wrappedEmit( + wrapEvent({ + type: EventType.IncrementalSnapshot, + data: { + source: IncrementalSource.Mutation, + ...m, + }, + }), + ), + mousemoveCb: (positions, source) => + wrappedEmit( + wrapEvent({ + type: EventType.IncrementalSnapshot, + data: { + source, + positions, + }, + }), + ), + mouseInteractionCb: (d) => + wrappedEmit( + wrapEvent({ + type: EventType.IncrementalSnapshot, + data: { + source: IncrementalSource.MouseInteraction, + ...d, + }, + }), + ), + scrollCb: (p) => + wrappedEmit( + wrapEvent({ + type: EventType.IncrementalSnapshot, + data: { + source: IncrementalSource.Scroll, + ...p, + }, + }), + ), + viewportResizeCb: (d) => + wrappedEmit( + wrapEvent({ + type: EventType.IncrementalSnapshot, + data: { + source: IncrementalSource.ViewportResize, + ...d, + }, + }), + ), + inputCb: (v) => + wrappedEmit( + wrapEvent({ + type: EventType.IncrementalSnapshot, + data: { + source: IncrementalSource.Input, + ...v, + }, + }), + ), + mediaInteractionCb: (p) => + wrappedEmit( + wrapEvent({ + type: EventType.IncrementalSnapshot, + data: { + source: IncrementalSource.MediaInteraction, + ...p, + }, + }), + ), + styleSheetRuleCb: (r) => + wrappedEmit( + wrapEvent({ + type: EventType.IncrementalSnapshot, + data: { + source: IncrementalSource.StyleSheetRule, + ...r, + }, + }), + ), + canvasMutationCb: (p) => + wrappedEmit( + wrapEvent({ + type: EventType.IncrementalSnapshot, + data: { + source: IncrementalSource.CanvasMutation, + ...p, + }, + }), + ), + fontCb: (p) => + wrappedEmit( + wrapEvent({ + type: EventType.IncrementalSnapshot, + data: { + source: IncrementalSource.Font, + ...p, + }, + }), + ), + logCb: (p) => + wrappedEmit( + wrapEvent({ + type: EventType.IncrementalSnapshot, + data: { + source: IncrementalSource.Log, + ...p, + }, + }), + ), + blockClass, + blockSelector, + ignoreClass, + maskInputOptions, + maskInputFn, + inlineStylesheet, + sampling, + recordCanvas, + collectFonts, + slimDOMOptions, + logOptions, + enableStrictPrivacy, + }, + hooks, + ), + ); }; if ( document.readyState === 'interactive' || @@ -473,14 +421,7 @@ record.addCustomEvent = (tag: string, payload: T) => { }; record.freezePage = () => { - mutationBuffers.forEach((buf) => buf.freeze()); -}; - -record.takeFullSnapshot = (isCheckout?: boolean) => { - if (!takeFullSnapshot) { - throw new Error('please take full snapshot after start recording'); - } - takeFullSnapshot(isCheckout); + mutationBuffer.freeze(); }; export default record; diff --git a/src/record/mutation.ts b/src/record/mutation.ts index b5ffb9ce..a58e266e 100644 --- a/src/record/mutation.ts +++ b/src/record/mutation.ts @@ -5,7 +5,6 @@ import { MaskInputOptions, SlimDOMOptions, IGNORED_NODE, - isShadowRoot, } from '../snapshot'; import { mutationRecord, @@ -16,16 +15,7 @@ import { removedNodeMutation, addedNodeMutation, } from '../types'; -import { - mirror, - isBlocked, - isAncestorRemoved, - isIgnored, - isIframeINode, - hasShadowRoot, -} from '../utils'; -import { IframeManager } from './iframe-manager'; -import { ShadowDomManager } from './shadow-dom-manager'; +import { mirror, isBlocked, isAncestorRemoved, isIgnored } from '../utils'; type DoubleLinkedListNode = { previous: DoubleLinkedListNode | null; @@ -70,11 +60,7 @@ class DoubleLinkedList { if (current) { current.previous = node; } - } else if ( - n.nextSibling && - isNodeInLinkedList(n.nextSibling) && - n.nextSibling.__ln.previous - ) { + } else if (n.nextSibling && isNodeInLinkedList(n.nextSibling)) { const current = n.nextSibling.__ln.previous; node.previous = current; node.next = n.nextSibling.__ln; @@ -126,7 +112,6 @@ function isINode(n: Node | INode): n is INode { */ export default class MutationBuffer { private frozen: boolean = false; - private locked: boolean = false; private texts: textCursor[] = []; private attributes: attributeCursor[] = []; @@ -164,10 +149,6 @@ export default class MutationBuffer { private recordCanvas: boolean; private enableStrictPrivacy: boolean; private slimDOMOptions: SlimDOMOptions; - private doc: Document; - - private iframeManager: IframeManager; - private shadowDomManager: ShadowDomManager; public init( cb: mutationCallBack, @@ -177,9 +158,6 @@ export default class MutationBuffer { maskInputOptions: MaskInputOptions, recordCanvas: boolean, slimDOMOptions: SlimDOMOptions, - doc: Document, - iframeManager: IframeManager, - shadowDomManager: ShadowDomManager, enableStrictPrivacy: boolean, ) { this.blockClass = blockClass; @@ -190,9 +168,6 @@ export default class MutationBuffer { this.slimDOMOptions = slimDOMOptions; this.enableStrictPrivacy = enableStrictPrivacy; this.emissionCallback = cb; - this.doc = doc; - this.iframeManager = iframeManager; - this.shadowDomManager = shadowDomManager; } public freeze() { @@ -201,32 +176,20 @@ export default class MutationBuffer { public unfreeze() { this.frozen = false; - this.emit(); } public isFrozen() { return this.frozen; } - public lock() { - this.locked = true; - } - - public unlock() { - this.locked = false; - this.emit(); - } - public processMutations = (mutations: mutationRecord[]) => { mutations.forEach(this.processMutation); - this.emit(); + if (!this.frozen) { + this.emit(); + } }; public emit = () => { - if (this.frozen || this.locked) { - return; - } - // delay any modification of the mirror until this function // so that the mirror for takeFullSnapshot doesn't get mutated while it's event is being processed @@ -250,20 +213,16 @@ export default class MutationBuffer { return nextId; }; const pushAdd = (n: Node) => { - const shadowHost: Element | null = (n.getRootNode() as ShadowRoot)?.host; - const notInDoc = !this.doc.contains(n) && !this.doc.contains(shadowHost); - if (!n.parentNode || notInDoc) { + if (!n.parentNode || !document.contains(n)) { return; } - const parentId = isShadowRoot(n.parentNode) - ? mirror.getId((shadowHost as unknown) as INode) - : mirror.getId((n.parentNode as Node) as INode); + const parentId = mirror.getId((n.parentNode as Node) as INode); const nextId = getNextId(n); if (parentId === -1 || nextId === -1) { return addList.addNode(n); } let sn = serializeNodeWithId(n, { - doc: this.doc, + doc: document, map: mirror.map, blockClass: this.blockClass, blockSelector: this.blockSelector, @@ -273,17 +232,6 @@ export default class MutationBuffer { slimDOMOptions: this.slimDOMOptions, recordCanvas: this.recordCanvas, enableStrictPrivacy: this.enableStrictPrivacy, - onSerialize: (currentN) => { - if (isIframeINode(currentN)) { - this.iframeManager.addIframe(currentN); - } - if (hasShadowRoot(n)) { - this.shadowDomManager.addShadowRoot(n.shadowRoot, document); - } - }, - onIframeLoad: (iframe, childSn) => { - this.iframeManager.attachIframe(iframe, childSn); - }, }); if (sn) { adds.push({ @@ -442,8 +390,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, + document, m.attributeName!, value!, ); @@ -453,9 +400,7 @@ 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 = isShadowRoot(m.target) - ? mirror.getId((m.target.host as unknown) as INode) - : mirror.getId(m.target as INode); + const parentId = mirror.getId(m.target as INode); if ( isBlocked(n, this.blockClass) || isBlocked(m.target, this.blockClass) || @@ -491,7 +436,6 @@ export default class MutationBuffer { this.removes.push({ parentId, id: nodeId, - isShadow: isShadowRoot(m.target) ? true : undefined, }); } this.mapRemoves.push(n); diff --git a/src/record/observer.ts b/src/record/observer.ts index c74d549e..317beef0 100644 --- a/src/record/observer.ts +++ b/src/record/observer.ts @@ -43,36 +43,25 @@ import { } from '../types'; import MutationBuffer from './mutation'; import { stringify } from './stringify'; -import { IframeManager } from './iframe-manager'; -import { ShadowDomManager } from './shadow-dom-manager'; -type WindowWithStoredMutationObserver = Window & { - __rrMutationObserver?: MutationObserver; -}; type WindowWithAngularZone = Window & { Zone?: { __symbol__?: (key: string) => string; }; }; -export const mutationBuffers: MutationBuffer[] = []; +export const mutationBuffer = new MutationBuffer(); -export function initMutationObserver( +function initMutationObserver( cb: mutationCallBack, - doc: Document, blockClass: blockClass, blockSelector: string | null, inlineStylesheet: boolean, maskInputOptions: MaskInputOptions, recordCanvas: boolean, slimDOMOptions: SlimDOMOptions, - iframeManager: IframeManager, - shadowDomManager: ShadowDomManager, - rootEl: Node, enableStrictPrivacy: boolean, ): MutationObserver { - const mutationBuffer = new MutationBuffer(); - mutationBuffers.push(mutationBuffer); // see mutation.ts for details mutationBuffer.init( cb, @@ -82,22 +71,9 @@ export function initMutationObserver( maskInputOptions, recordCanvas, slimDOMOptions, - doc, - iframeManager, - shadowDomManager, enableStrictPrivacy, ); - let mutationObserverCtor = - window.MutationObserver || - /** - * Some websites may disable MutationObserver by removing it from the window object. - * If someone is using rrweb to build a browser extention or things like it, they - * could not change the website's code but can have an opportunity to inject some - * code before the website executing its JS logic. - * Then they can do this to store the native MutationObserver: - * window.__rrMutationObserver = MutationObserver - */ - (window as WindowWithStoredMutationObserver).__rrMutationObserver; + let mutationBufferCtor = window.MutationObserver; const angularZoneSymbol = (window as WindowWithAngularZone)?.Zone?.__symbol__?.( 'MutationObserver', ); @@ -107,15 +83,15 @@ export function initMutationObserver( angularZoneSymbol ] ) { - mutationObserverCtor = ((window as unknown) as Record< + mutationBufferCtor = ((window as unknown) as Record< string, typeof MutationObserver >)[angularZoneSymbol]; } - const observer = new mutationObserverCtor( + const observer = new mutationBufferCtor( mutationBuffer.processMutations.bind(mutationBuffer), ); - observer.observe(rootEl, { + observer.observe(document, { attributes: true, attributeOldValue: true, characterData: true, @@ -129,7 +105,6 @@ export function initMutationObserver( function initMoveObserver( cb: mousemoveCallBack, sampling: SamplingStrategy, - doc: Document, ): listenerHandler { if (sampling.mousemove === false) { return () => {}; @@ -137,10 +112,6 @@ function initMoveObserver( const threshold = typeof sampling.mousemove === 'number' ? sampling.mousemove : 50; - const callbackThreshold = - typeof sampling.mousemoveCallback === 'number' - ? sampling.mousemoveCallback - : 500; let positions: mousePosition[] = []; let timeBaseline: number | null; @@ -155,7 +126,7 @@ function initMoveObserver( ); positions = []; timeBaseline = null; - }, callbackThreshold); + }, 500); const updatePosition = throttle( (evt) => { const { target } = evt; @@ -179,8 +150,8 @@ function initMoveObserver( }, ); const handlers = [ - on('mousemove', updatePosition, doc), - on('touchmove', updatePosition, doc), + on('mousemove', updatePosition), + on('touchmove', updatePosition), ]; return () => { handlers.forEach((h) => h()); @@ -189,7 +160,6 @@ function initMoveObserver( function initMouseInteractionObserver( cb: mouseInteractionCallBack, - doc: Document, blockClass: blockClass, sampling: SamplingStrategy, ): listenerHandler { @@ -208,12 +178,10 @@ function initMouseInteractionObserver( if (isBlocked(event.target as Node, blockClass)) { return; } - const e = isTouchEvent(event) ? event.changedTouches[0] : event; - if (!e) { - return; - } const id = mirror.getId(event.target as INode); - const { clientX, clientY } = e; + const { clientX, clientY } = isTouchEvent(event) + ? event.changedTouches[0] + : event; cb({ type: MouseInteractions[eventKey], id, @@ -232,7 +200,7 @@ function initMouseInteractionObserver( .forEach((eventKey: keyof typeof MouseInteractions) => { const eventName = eventKey.toLowerCase(); const handler = getHandler(eventKey); - handlers.push(on(eventName, handler, doc)); + handlers.push(on(eventName, handler)); }); return () => { handlers.forEach((h) => h()); @@ -241,7 +209,6 @@ function initMouseInteractionObserver( function initScrollObserver( cb: scrollCallback, - doc: Document, blockClass: blockClass, sampling: SamplingStrategy, ): listenerHandler { @@ -250,8 +217,8 @@ function initScrollObserver( return; } const id = mirror.getId(evt.target as INode); - if (evt.target === doc) { - const scrollEl = (doc.scrollingElement || doc.documentElement)!; + if (evt.target === document) { + const scrollEl = (document.scrollingElement || document.documentElement)!; cb({ id, x: scrollEl.scrollLeft, @@ -271,18 +238,18 @@ function initScrollObserver( function initViewportResizeObserver( cb: viewportResizeCallback, ): listenerHandler { - let lastH = -1; - let lastW = -1; + let last_h = -1; + let last_w = -1; const updateDimension = throttle(() => { const height = getWindowHeight(); const width = getWindowWidth(); - if (lastH !== height || lastW !== width) { + if (last_h !== height || last_w != width) { cb({ width: Number(width), height: Number(height), }); - lastH = height; - lastW = width; + last_h = height; + last_w = width; } }, 200); return on('resize', updateDimension, window); @@ -292,7 +259,6 @@ export const INPUT_TAGS = ['INPUT', 'TEXTAREA', 'SELECT']; const lastInputValueMap: WeakMap = new WeakMap(); function initInputObserver( cb: inputCallback, - doc: Document, blockClass: blockClass, ignoreClass: string, maskInputOptions: MaskInputOptions, @@ -337,7 +303,7 @@ function initInputObserver( // the other radios with the same name attribute will be unchecked. const name: string | undefined = (target as HTMLInputElement).name; if (type === 'radio' && name && isChecked) { - doc + document .querySelectorAll(`input[type="radio"][name="${name}"]`) .forEach((el) => { if (el !== target) { @@ -367,7 +333,7 @@ function initInputObserver( const events = sampling.input === 'last' ? ['change'] : ['input', 'change']; const handlers: Array< listenerHandler | hookResetter - > = events.map((eventName) => on(eventName, eventHandler, doc)); + > = events.map((eventName) => on(eventName, eventHandler)); const propertyDescriptor = Object.getOwnPropertyDescriptor( HTMLInputElement.prototype, 'value', @@ -572,30 +538,24 @@ function initLogObserver( logOptions: LogRecordOptions, ): listenerHandler { const logger = logOptions.logger; - if (!logger) { - return () => {}; - } + if (!logger) return () => {}; let logCount = 0; - const cancelHandlers: listenerHandler[] = []; + const cancelHandlers: any[] = []; // add listener to thrown errors if (logOptions.level!.includes('error')) { if (window) { const originalOnError = window.onerror; - // tslint:disable-next-line:no-any window.onerror = (...args: any[]) => { - if (originalOnError) { - originalOnError.apply(this, args); - } - let stack: string[] = []; - if (args[args.length - 1] instanceof Error) { + originalOnError && originalOnError.apply(this, args); + let stack: Array = []; + if (args[args.length - 1] instanceof Error) // 0(the second parameter) tells parseStack that every stack in Error is useful stack = parseStack(args[args.length - 1].stack, 0); - } const payload = [stringify(args[0], logOptions.stringifyOptions)]; cb({ level: 'error', trace: stack, - payload, + payload: payload, }); }; cancelHandlers.push(() => { @@ -603,9 +563,8 @@ function initLogObserver( }); } } - for (const levelType of logOptions.level!) { + for (const levelType of logOptions.level!) cancelHandlers.push(replace(logger, levelType)); - } return () => { cancelHandlers.forEach((h) => h()); }; @@ -615,13 +574,10 @@ function initLogObserver( * @param logger the logger object such as Console * @param level the name of log function to be replaced */ - function replace(_logger: Logger, level: LogLevel) { - if (!_logger[level]) { - return () => {}; - } + function replace(logger: Logger, level: LogLevel) { + if (!logger[level]) return () => {}; // replace the logger.{level}. return a restore function - return patch(_logger, level, (original) => { - // tslint:disable-next-line:no-any + return patch(logger, level, (original) => { return (...args: any[]) => { original.apply(this, args); try { @@ -630,13 +586,13 @@ function initLogObserver( stringify(s, logOptions.stringifyOptions), ); logCount++; - if (logCount < logOptions.lengthThreshold!) { + if (logCount < logOptions.lengthThreshold!) cb({ - level, + level: level, trace: stack, - payload, + payload: payload, }); - } else if (logCount === logOptions.lengthThreshold) { + else if (logCount === logOptions.lengthThreshold) // notify the user cb({ level: 'warn', @@ -645,7 +601,6 @@ function initLogObserver( stringify('The number of log records reached the threshold.'), ], }); - } } catch (error) { original('rrweb logger error:', error, ...args); } @@ -660,7 +615,7 @@ function initLogObserver( function parseStack( stack: string | undefined, omitDepth: number = 1, - ): string[] { + ): Array { let stacks: string[] = []; if (stack) { stacks = stack @@ -761,35 +716,28 @@ export function initObservers( mergeHooks(o, hooks); const mutationObserver = initMutationObserver( o.mutationCb, - o.doc, o.blockClass, o.blockSelector, o.inlineStylesheet, o.maskInputOptions, o.recordCanvas, o.slimDOMOptions, - o.iframeManager, - o.shadowDomManager, - o.doc, o.enableStrictPrivacy, ); - const mousemoveHandler = initMoveObserver(o.mousemoveCb, o.sampling, o.doc); + const mousemoveHandler = initMoveObserver(o.mousemoveCb, o.sampling); const mouseInteractionHandler = initMouseInteractionObserver( o.mouseInteractionCb, - o.doc, o.blockClass, o.sampling, ); const scrollHandler = initScrollObserver( o.scrollCb, - o.doc, o.blockClass, o.sampling, ); const viewportResizeHandler = initViewportResizeObserver(o.viewportResizeCb); const inputHandler = initInputObserver( o.inputCb, - o.doc, o.blockClass, o.ignoreClass, o.maskInputOptions, diff --git a/src/record/shadow-dom-manager.ts b/src/record/shadow-dom-manager.ts deleted file mode 100644 index 1e77ceac..00000000 --- a/src/record/shadow-dom-manager.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { mutationCallBack, blockClass } from '../types'; -import { MaskInputOptions, SlimDOMOptions } from '../snapshot'; -import { IframeManager } from './iframe-manager'; -import { initMutationObserver } from './observer'; - -type BypassOptions = { - blockClass: blockClass; - blockSelector: string | null; - inlineStylesheet: boolean; - maskInputOptions: MaskInputOptions; - recordCanvas: boolean; - slimDOMOptions: SlimDOMOptions; - iframeManager: IframeManager; - enableStrictPrivacy: boolean; -}; - -export class ShadowDomManager { - private mutationCb: mutationCallBack; - private bypassOptions: BypassOptions; - - constructor(options: { - mutationCb: mutationCallBack; - bypassOptions: BypassOptions; - }) { - this.mutationCb = options.mutationCb; - this.bypassOptions = options.bypassOptions; - } - - public addShadowRoot(shadowRoot: ShadowRoot, doc: Document) { - initMutationObserver( - this.mutationCb, - doc, - this.bypassOptions.blockClass, - this.bypassOptions.blockSelector, - this.bypassOptions.inlineStylesheet, - this.bypassOptions.maskInputOptions, - this.bypassOptions.recordCanvas, - this.bypassOptions.slimDOMOptions, - this.bypassOptions.iframeManager, - this, - shadowRoot, - this.bypassOptions.enableStrictPrivacy, - ); - } -} diff --git a/src/record/stringify.ts b/src/record/stringify.ts index b1c69b81..0547f2f3 100644 --- a/src/record/stringify.ts +++ b/src/record/stringify.ts @@ -1,4 +1,3 @@ -// tslint:disable:no-any no-bitwise forin /** * this file is used to serialize log message to string * @@ -15,21 +14,18 @@ function pathToSelector(node: HTMLElement): string | '' { return ''; } - let path = ''; + var path = ''; while (node.parentElement) { - let name = node.localName; - if (!name) { - break; - } + var name = node.localName; + if (!name) break; name = name.toLowerCase(); - let parent = node.parentElement; + var parent = node.parentElement; - let domSiblings = []; + var domSiblings = []; if (parent.children && parent.children.length > 0) { - // tslint:disable-next-line:prefer-for-of - for (let i = 0; i < parent.children.length; i++) { - let sibling = parent.children[i]; + for (var i = 0; i < parent.children.length; i++) { + var sibling = parent.children[i]; if (sibling.localName && sibling.localName.toLowerCase) { if (sibling.localName.toLowerCase() === name) { domSiblings.push(sibling); @@ -60,55 +56,45 @@ export function stringify( numOfKeysLimit: 50, }; Object.assign(options, stringifyOptions); - const stack: any[] = []; - const keys: any[] = []; + let stack: any[] = [], + keys: any[] = []; return JSON.stringify(obj, function (key, value) { /** * forked from https://github.com/moll/json-stringify-safe/blob/master/stringify.js * to deCycle the object */ if (stack.length > 0) { - const thisPos = stack.indexOf(this); + var thisPos = stack.indexOf(this); ~thisPos ? stack.splice(thisPos + 1) : stack.push(this); ~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key); if (~stack.indexOf(value)) { - if (stack[0] === value) { - value = '[Circular ~]'; - } else { + if (stack[0] === value) value = '[Circular ~]'; + else value = '[Circular ~.' + keys.slice(0, stack.indexOf(value)).join('.') + ']'; - } } - } else { - stack.push(value); - } + } else stack.push(value); /* END of the FORK */ - if (value === null || value === undefined) { - return value; - } + if (value === null || value === undefined) return value; if (shouldToString(value)) { return toString(value); } if (value instanceof Event) { const eventResult: any = {}; - for (const eventKey in value) { - const eventValue = (value as any)[eventKey]; - if (Array.isArray(eventValue)) { - eventResult[eventKey] = pathToSelector( + for (const key in value) { + const eventValue = (value as any)[key]; + if (Array.isArray(eventValue)) + eventResult[key] = pathToSelector( eventValue.length ? eventValue[0] : null, ); - } else { - eventResult[eventKey] = eventValue; - } + else eventResult[key] = eventValue; } return eventResult; } else if (value instanceof Node) { - if (value instanceof HTMLElement) { - return value ? value.outerHTML : ''; - } + if (value instanceof HTMLElement) return value ? value.outerHTML : ''; return value.nodeName; } return value; @@ -117,24 +103,21 @@ export function stringify( /** * whether we should call toString function of this object */ - function shouldToString(_obj: object): boolean { + function shouldToString(obj: object): boolean { if ( - typeof _obj === 'object' && - Object.keys(_obj).length > options.numOfKeysLimit - ) { - return true; - } - if (typeof _obj === 'function') { + typeof obj === 'object' && + Object.keys(obj).length > options.numOfKeysLimit + ) return true; - } + if (typeof obj === 'function') return true; return false; } /** * limit the toString() result according to option */ - function toString(_obj: object): string { - let str = _obj.toString(); + function toString(obj: object): string { + let str = obj.toString(); if (options.stringLengthLimit && str.length > options.stringLengthLimit) { str = `${str.slice(0, options.stringLengthLimit)}...`; } diff --git a/src/replay/index.ts b/src/replay/index.ts index 2d6456fc..a5b90c24 100644 --- a/src/replay/index.ts +++ b/src/replay/index.ts @@ -11,7 +11,7 @@ import { MouseInteractions, playerConfig, playerMetaData, - viewportResizeDimension, + viewportResizeDimention, missingNodeMap, addedNodeMutation, missingNode, @@ -38,10 +38,6 @@ import { TreeIndex, queueToResolveTrees, iterateResolveTree, - AppendedIframe, - isIframeINode, - getBaseDimension, - hasShadowRoot, } from '../utils'; import getInjectStyleRules from './styles/inject-style'; import './styles/style.css'; @@ -56,11 +52,6 @@ const SKIP_DURATION_LIMIT = 60 * 60 * 1000; const mitt = (mittProxy as any).default || mittProxy; const REPLAY_CONSOLE_PREFIX = '[replayer]'; -const ORIGINAL_ATTRIBUTE_NAME = '__rrweb_original__'; - -type PatchedConsoleLog = { - [ORIGINAL_ATTRIBUTE_NAME]: typeof console.log; -}; const defaultMouseTailConfig = { duration: 500, @@ -112,8 +103,6 @@ export class Replayer { private emitter: Emitter = mitt(); - private nextUserInteractionEvent: eventWithTime | null; - private activityIntervals: Array = []; private inactiveEndTimestamp: number | null; @@ -126,8 +115,6 @@ export class Replayer { private imageMap: Map = new Map(); - private newDocumentQueue: addedNodeMutation[] = []; - constructor( events: Array, config?: Partial, @@ -137,7 +124,6 @@ export class Replayer { } const defaultConfig: playerConfig = { speed: 1, - maxSpeed: 360, root: document.body, loadTimeout: 0, skipInactive: false, @@ -155,9 +141,8 @@ export class Replayer { inactiveSkipTime: SKIP_TIME_INTERVAL, }; this.config = Object.assign({}, defaultConfig, config); - if (!this.config.logConfig.replayLogger) { + if (!this.config.logConfig.replayLogger) this.config.logConfig.replayLogger = this.getConsoleLogger(); - } this.handleResize = this.handleResize.bind(this); this.getCastFn = this.getCastFn.bind(this); @@ -253,11 +238,8 @@ export class Replayer { }, 0); } if (firstFullsnapshot) { + (firstFullsnapshot as fullSnapshotEvent).isFirstFullSnapshot = true; setTimeout(() => { - // when something has been played, there is no need to rebuild poster - if (this.timer.timeOffset > 0) { - return; - } this.rebuildFullSnapshot( firstFullsnapshot as fullSnapshotEvent & { timestamp: number }, ); @@ -524,7 +506,7 @@ export class Replayer { } } - private handleResize(dimension: viewportResizeDimension) { + private handleResize(dimension: viewportResizeDimention) { this.iframe.style.display = 'inherit'; for (const el of [this.mouseTail, this.iframe]) { if (!el) { @@ -563,8 +545,10 @@ export class Replayer { break; case EventType.FullSnapshot: castFn = () => { - this.rebuildFullSnapshot(event, isSync); - this.iframe.contentWindow!.scrollTo(event.data.initialOffset); + if (!event.isFirstFullSnapshot) { + this.rebuildFullSnapshot(event, isSync); + this.iframe.contentWindow!.scrollTo(event.data.initialOffset); + } this.handleInactivity(event.timestamp); }; break; @@ -576,39 +560,6 @@ export class Replayer { return; } this.handleInactivity(event.timestamp); - if (event === this.nextUserInteractionEvent) { - this.nextUserInteractionEvent = null; - this.backToNormal(); - } - if (this.config.skipInactive && !this.nextUserInteractionEvent) { - for (const _event of this.service.state.context.events) { - if (_event.timestamp! <= event.timestamp!) { - continue; - } - if (this.isUserInteraction(_event)) { - if ( - _event.delay! - event.delay! > - SKIP_TIME_THRESHOLD * - this.speedService.state.context.timer.speed - ) { - this.nextUserInteractionEvent = _event; - } - break; - } - } - if (this.nextUserInteractionEvent) { - const skipTime = - this.nextUserInteractionEvent.delay! - event.delay!; - const payload = { - speed: Math.min( - Math.round(skipTime / SKIP_TIME_INTERVAL), - this.config.maxSpeed, - ), - }; - this.speedService.send({ type: 'FAST_FORWARD', payload }); - this.emitter.emit(ReplayerEvents.SkipStart, payload); - } - } }; break; default: @@ -694,46 +645,12 @@ export class Replayer { ); } this.legacy_missingNodeRetryMap = {}; - const collected: AppendedIframe[] = []; mirror.map = rebuild(event.data.node, { doc: this.iframe.contentDocument, - afterAppend: (builtNode) => { - this.collectIframeAndAttachDocument(collected, builtNode); - }, })[1]; - for (const { mutationInQueue, builtNode } of collected) { - this.attachDocumentToIframe(mutationInQueue, builtNode); - this.newDocumentQueue = this.newDocumentQueue.filter( - (m) => m !== mutationInQueue, - ); - if (builtNode.contentDocument) { - const { documentElement, head } = builtNode.contentDocument; - this.insertStyleRules(documentElement, head); - } - } - const { documentElement, head } = this.iframe.contentDocument; - this.insertStyleRules(documentElement, head); - if (!this.service.state.matches('playing')) { - this.iframe.contentDocument - .getElementsByTagName('html')[0] - .classList.add('rrweb-paused'); - } - this.emitter.emit(ReplayerEvents.FullsnapshotRebuilded, event); - if (!isSync) { - this.waitForStylesheetLoad(); - } - if (this.config.UNSAFE_replayCanvas) { - this.preloadAllImages(); - } - } - - private insertStyleRules( - documentElement: HTMLElement, - head: HTMLHeadElement, - ) { const styleEl = document.createElement('style'); + const { documentElement, head } = this.iframe.contentDocument; documentElement!.insertBefore(styleEl, head); - console.log(this.config.blockClass); const injectStylesRules = getInjectStyleRules( this.config.blockClass, ).concat(this.config.insertStyleRules); @@ -742,48 +659,20 @@ export class Replayer { 'html.rrweb-paused * { animation-play-state: paused !important; }', ); } + if (!this.service.state.matches('playing')) { + this.iframe.contentDocument + .getElementsByTagName('html')[0] + .classList.add('rrweb-paused'); + } for (let idx = 0; idx < injectStylesRules.length; idx++) { (styleEl.sheet! as CSSStyleSheet).insertRule(injectStylesRules[idx], idx); } - } - - private attachDocumentToIframe( - mutation: addedNodeMutation, - iframeEl: HTMLIFrameElement, - ) { - const collected: AppendedIframe[] = []; - buildNodeWithSN(mutation.node, { - doc: iframeEl.contentDocument!, - map: mirror.map, - hackCss: true, - skipChild: false, - afterAppend: (builtNode) => { - this.collectIframeAndAttachDocument(collected, builtNode); - }, - }); - for (const { mutationInQueue, builtNode } of collected) { - this.attachDocumentToIframe(mutationInQueue, builtNode); - this.newDocumentQueue = this.newDocumentQueue.filter( - (m) => m !== mutationInQueue, - ); - if (builtNode.contentDocument) { - const { documentElement, head } = builtNode.contentDocument; - this.insertStyleRules(documentElement, head); - } + this.emitter.emit(ReplayerEvents.FullsnapshotRebuilded, event); + if (!isSync) { + this.waitForStylesheetLoad(); } - } - - private collectIframeAndAttachDocument( - collected: AppendedIframe[], - builtNode: INode, - ) { - if (isIframeINode(builtNode)) { - const mutationInQueue = this.newDocumentQueue.find( - (m) => m.parentId === builtNode.__sn.id, - ); - if (mutationInQueue) { - collected.push({ mutationInQueue, builtNode }); - } + if (this.config.UNSAFE_replayCanvas) { + this.preloadAllImages(); } } @@ -1171,9 +1060,8 @@ export class Replayer { try { const logData = e.data as logData; const replayLogger = this.config.logConfig.replayLogger!; - if (typeof replayLogger[logData.level] === 'function') { + if (typeof replayLogger[logData.level] === 'function') replayLogger[logData.level]!(logData); - } } catch (error) { if (this.config.showWarning) { console.warn(error); @@ -1190,18 +1078,14 @@ export class Replayer { if (!target) { return this.warnNodeNotFound(d, mutation.id); } - let parent: INode | null | ShadowRoot = mirror.getNode(mutation.parentId); + const parent = mirror.getNode(mutation.parentId); if (!parent) { return this.warnNodeNotFound(d, mutation.parentId); } - if (mutation.isShadow && hasShadowRoot(parent)) { - parent = parent.shadowRoot; - } // target may be removed with its parents before mirror.removeNodeFromMap(target); if (parent) { - const realParent = - '__sn' in parent ? this.fragmentParentMap.get(parent) : undefined; + const realParent = this.fragmentParentMap.get(parent); if (realParent && realParent.contains(target)) { realParent.removeChild(target); } else if (this.fragmentParentMap.has(target)) { @@ -1246,12 +1130,8 @@ export class Replayer { if (!this.iframe.contentDocument) { return console.warn('Looks like your replayer has been destroyed.'); } - let parent: INode | null | ShadowRoot = mirror.getNode(mutation.parentId); + let parent = mirror.getNode(mutation.parentId); if (!parent) { - if (mutation.node.type === NodeType.Document) { - // is newly added document, maybe the document node of an iframe - return this.newDocumentQueue.push(mutation); - } return queue.push(mutation); } @@ -1264,8 +1144,7 @@ export class Replayer { parentInDocument = this.iframe.contentDocument.body.contains(parent); } - // if parent element is an iframe, iframe document can't be appended to virtual parent - if (useVirtualParent && parentInDocument && !isIframeINode(parent)) { + if (useVirtualParent && parentInDocument) { const virtualParent = (document.createDocumentFragment() as unknown) as INode; mirror.map[mutation.parentId] = virtualParent; this.fragmentParentMap.set(virtualParent, parent); @@ -1279,10 +1158,6 @@ export class Replayer { parent = virtualParent; } - if (mutation.node.isShadow && hasShadowRoot(parent)) { - parent = parent.shadowRoot; - } - let previous: Node | null = null; let next: Node | null = null; if (mutation.previousId) { @@ -1295,23 +1170,12 @@ export class Replayer { return queue.push(mutation); } - if (mutation.node.rootId && !mirror.getNode(mutation.node.rootId)) { - return; - } - - const targetDoc = mutation.node.rootId - ? mirror.getNode(mutation.node.rootId) - : this.iframe.contentDocument; - if (isIframeINode(parent)) { - this.attachDocumentToIframe(mutation, parent); - return; - } const target = buildNodeWithSN(mutation.node, { - doc: targetDoc as Document, + doc: this.iframe.contentDocument, map: mirror.map, skipChild: true, hackCss: true, - }) as INode; + }) as Node; // legacy data, we should not have -1 siblings any more if (mutation.previousId === -1 || mutation.nextId === -1) { @@ -1331,34 +1195,9 @@ export class Replayer { ? parent.insertBefore(target, next) : parent.insertBefore(target, null); } else { - /** - * Sometimes the document changes and the MutationObserver is disconnected, so the removal of child elements can't be detected and recorded. After the change of document, we may get another mutation which adds a new html element, while the old html element still exists in the dom, and we need to remove the old html element first to avoid collision. - */ - if (parent === targetDoc) { - while (targetDoc.firstChild) { - targetDoc.removeChild(targetDoc.firstChild); - } - } - parent.appendChild(target); } - if (isIframeINode(target)) { - const mutationInQueue = this.newDocumentQueue.find( - (m) => m.parentId === target.__sn.id, - ); - if (mutationInQueue) { - this.attachDocumentToIframe(mutationInQueue, target); - this.newDocumentQueue = this.newDocumentQueue.filter( - (m) => m !== mutationInQueue, - ); - } - if (target.contentDocument) { - const { documentElement, head } = target.contentDocument; - this.insertStyleRules(documentElement, head); - } - } - if (mutation.previousId || mutation.nextId) { this.legacy_resolveMissingNode( legacy_missingNodeMap, @@ -1489,9 +1328,7 @@ export class Replayer { * @param data the log data */ private formatMessage(data: logData): string { - if (data.trace.length === 0) { - return ''; - } + if (data.trace.length === 0) return ''; const stackPrefix = '\n\tat '; let result = stackPrefix; result += data.trace.join(stackPrefix); @@ -1502,38 +1339,29 @@ export class Replayer { * generate a console log replayer which implement the interface ReplayLogger */ private getConsoleLogger(): ReplayLogger { + const rrwebOriginal = '__rrweb_original__'; const replayLogger: ReplayLogger = {}; - for (const level of this.config.logConfig.level!) { - if (level === 'trace') { + for (const level of this.config.logConfig.level!) + if (level === 'trace') replayLogger[level] = (data: logData) => { - const logger = ((console.log as unknown) as PatchedConsoleLog)[ - ORIGINAL_ATTRIBUTE_NAME - ] - ? ((console.log as unknown) as PatchedConsoleLog)[ - ORIGINAL_ATTRIBUTE_NAME - ] + const logger = (console.log as any)[rrwebOriginal] + ? (console.log as any)[rrwebOriginal] : console.log; logger( ...data.payload.map((s) => JSON.parse(s)), this.formatMessage(data), ); }; - } else { + else replayLogger[level] = (data: logData) => { - const logger = ((console[level] as unknown) as PatchedConsoleLog)[ - ORIGINAL_ATTRIBUTE_NAME - ] - ? ((console[level] as unknown) as PatchedConsoleLog)[ - ORIGINAL_ATTRIBUTE_NAME - ] + const logger = (console[level] as any)[rrwebOriginal] + ? (console[level] as any)[rrwebOriginal] : console[level]; logger( ...data.payload.map((s) => JSON.parse(s)), this.formatMessage(data), ); }; - } - } return replayLogger; } @@ -1567,18 +1395,14 @@ export class Replayer { } private moveAndHover(d: incrementalData, x: number, y: number, id: number) { + this.mouse.style.left = `${x}px`; + this.mouse.style.top = `${y}px`; + this.drawMouseTail({ x, y }); + const target = mirror.getNode(id); if (!target) { return this.debugNodeNotFound(d, id); } - - const base = getBaseDimension(target, this.iframe); - const _x = x * base.absoluteScale + base.x; - const _y = y * base.absoluteScale + base.y; - - this.mouse.style.left = `${_x}px`; - this.mouse.style.top = `${_y}px`; - this.drawMouseTail({ x: _x, y: _y }); this.hoverElements((target as Node) as Element); } diff --git a/src/replay/machine.ts b/src/replay/machine.ts index 8df67474..fc53b023 100644 --- a/src/replay/machine.ts +++ b/src/replay/machine.ts @@ -165,6 +165,7 @@ export function createPlayerService( }; }), play(ctx) { + console.warn('play'); const { timer, events, baselineTime, lastPlayedEvent } = ctx; timer.clear(); for (const event of events) { diff --git a/src/replay/styles/inject-style.ts b/src/replay/styles/inject-style.ts index 6ddafc03..01981354 100644 --- a/src/replay/styles/inject-style.ts +++ b/src/replay/styles/inject-style.ts @@ -1,5 +1,5 @@ const rules: (blockClass: string) => string[] = (blockClass: string) => [ - `.${blockClass} { background: #ccc }`, + `iframe, .${blockClass} { background: #ccc }`, 'noscript { display: none !important; }', `.${blockClass} { background: black; border-radius: 5px; }`, `.${blockClass}:hover::after {content: 'Redacted'; color: white; text-align: center; width: 100%; display: block;}`, diff --git a/src/replay/timer.ts b/src/replay/timer.ts index e5eefa04..1ec786da 100644 --- a/src/replay/timer.ts +++ b/src/replay/timer.ts @@ -30,7 +30,7 @@ export class Timer { * @param actions */ public addActions(actions: actionWithDelay[]) { - this.actions = this.actions.concat(actions); + this.actions.push(...actions); } public start() { diff --git a/src/rrdom/index.ts b/src/rrdom/index.ts deleted file mode 100644 index 28b5e590..00000000 --- a/src/rrdom/index.ts +++ /dev/null @@ -1,173 +0,0 @@ -import { RRdomTreeNode, AnyObject } from './tree-node'; - -class RRdomTree { - private readonly symbol = '__rrdom__'; - - public initialize(object: AnyObject) { - this._node(object); - - return object; - } - - public hasChildren(object: AnyObject): boolean { - return Boolean(this._node(object).hasChildren); - } - - public firstChild(object: AnyObject) { - return this._node(object).firstChild || null; - } - - public lastChild(object: AnyObject) { - return this._node(object).lastChild || null; - } - - public previousSibling(object: AnyObject) { - return this._node(object).previousSibling || null; - } - - public nextSibling(object: AnyObject) { - return this._node(object).nextSibling || null; - } - - public parent(object: AnyObject) { - return this._node(object).parent || null; - } - - public insertAfter(referenceObject: AnyObject, newObject: AnyObject) { - const referenceNode = this._node(referenceObject); - const nextNode = this._node(referenceNode.nextSibling); - const newNode = this._node(newObject); - const parentNode = this._node(referenceNode.parent); - - if (newNode.isAttached) { - throw new Error('Node already attached'); - } - if (!referenceNode) { - throw new Error('Reference node not attached'); - } - - newNode.parent = referenceNode.parent; - newNode.previousSibling = referenceObject; - newNode.nextSibling = referenceNode.nextSibling; - referenceNode.nextSibling = newObject; - - if (nextNode) { - nextNode.previousSibling = newObject; - } - - if (parentNode && parentNode.lastChild === referenceObject) { - parentNode.lastChild = newObject; - } - - if (parentNode) { - parentNode.childrenChanged(); - } - - return newObject; - } - - public insertBefore(referenceObject: AnyObject, newObject: AnyObject) { - const referenceNode = this._node(referenceObject); - const prevNode = this._node(referenceNode.previousSibling); - const newNode = this._node(newObject); - const parentNode = this._node(referenceNode.parent); - - if (newNode.isAttached) { - throw new Error('Node already attached'); - } - if (!referenceNode) { - throw new Error('Reference node not attached'); - } - - newNode.parent = referenceNode.parent; - newNode.previousSibling = referenceNode.previousSibling; - newNode.nextSibling = referenceObject; - referenceNode.previousSibling = newObject; - - if (prevNode) { - prevNode.nextSibling = newObject; - } - - if (parentNode && parentNode.firstChild === referenceObject) { - parentNode.firstChild = newObject; - } - - if (parentNode) { - parentNode.childrenChanged(); - } - - return newObject; - } - - public appendChild(referenceObject: AnyObject, newObject: AnyObject) { - const referenceNode = this._node(referenceObject); - const newNode = this._node(newObject); - - if (newNode.isAttached) { - throw new Error('Node already attached'); - } - if (!referenceNode) { - throw new Error('Reference node not attached'); - } - - if (referenceNode.hasChildren) { - this.insertAfter(referenceNode.lastChild!, newObject); - } else { - newNode.parent = referenceObject; - referenceNode.firstChild = newObject; - referenceNode.lastChild = newObject; - referenceNode.childrenChanged(); - } - - return newObject; - } - - public remove(removeObject: AnyObject) { - const removeNode = this._node(removeObject); - const parentNode = this._node(removeNode.parent); - const prevNode = this._node(removeNode.previousSibling); - const nextNode = this._node(removeNode.nextSibling); - - if (parentNode) { - if (parentNode.firstChild === removeObject) { - parentNode.firstChild = removeNode.nextSibling; - } - - if (parentNode.lastChild === removeObject) { - parentNode.lastChild = removeNode.previousSibling; - } - } - - if (prevNode) { - prevNode.nextSibling = removeNode.nextSibling; - } - - if (nextNode) { - nextNode.previousSibling = removeNode.previousSibling; - } - - removeNode.parent = null; - removeNode.previousSibling = null; - removeNode.nextSibling = null; - removeNode.cachedIndex = -1; - removeNode.cachedIndexVersion = NaN; - - if (parentNode) { - parentNode.childrenChanged(); - } - - return removeObject; - } - - private _node(object: AnyObject | null): RRdomTreeNode { - if (!object) { - throw new Error('Object is falsy'); - } - - if (this.symbol in object) { - return object[this.symbol] as RRdomTreeNode; - } - - return (object[this.symbol] = new RRdomTreeNode()); - } -} diff --git a/src/rrdom/tree-node.ts b/src/rrdom/tree-node.ts deleted file mode 100644 index 828e0aa8..00000000 --- a/src/rrdom/tree-node.ts +++ /dev/null @@ -1,52 +0,0 @@ -// tslint:disable-next-line: no-any -export type AnyObject = { [key: string]: any; __rrdom__?: RRdomTreeNode }; - -export class RRdomTreeNode implements AnyObject { - public parent: AnyObject | null = null; - public previousSibling: AnyObject | null = null; - public nextSibling: AnyObject | null = null; - - public firstChild: AnyObject | null = null; - public lastChild: AnyObject | null = null; - - // This value is incremented anytime a children is added or removed - public childrenVersion = 0; - // The last child object which has a cached index - public childIndexCachedUpTo: AnyObject | null = null; - - /** - * This value represents the cached node index, as long as - * cachedIndexVersion matches with the childrenVersion of the parent - */ - public cachedIndex = -1; - public cachedIndexVersion = NaN; - - public get isAttached() { - return Boolean(this.parent || this.previousSibling || this.nextSibling); - } - - public get hasChildren() { - return Boolean(this.firstChild); - } - - public childrenChanged() { - // tslint:disable-next-line: no-bitwise - this.childrenVersion = (this.childrenVersion + 1) & 0xffffffff; - this.childIndexCachedUpTo = null; - } - - public getCachedIndex(parentNode: AnyObject) { - if (this.cachedIndexVersion !== parentNode.childrenVersion) { - this.cachedIndexVersion = NaN; - // cachedIndex is no longer valid - return -1; - } - - return this.cachedIndex; - } - - public setCachedIndex(parentNode: AnyObject, index: number) { - this.cachedIndexVersion = parentNode.childrenVersion; - this.cachedIndex = index; - } -} diff --git a/src/snapshot/index.ts b/src/snapshot/index.ts index 9c1fd389..20d5b02d 100644 --- a/src/snapshot/index.ts +++ b/src/snapshot/index.ts @@ -7,7 +7,6 @@ import snapshot, { } from './snapshot'; import rebuild, { buildNodeWithSN, addHoverClass } from './rebuild'; export * from './types'; -export * from './utils'; export { snapshot, diff --git a/src/snapshot/rebuild.ts b/src/snapshot/rebuild.ts index 9ab83156..fc475781 100644 --- a/src/snapshot/rebuild.ts +++ b/src/snapshot/rebuild.ts @@ -7,7 +7,6 @@ import { idNodeMap, INode, } from './types'; -import { isElement } from './utils'; const tagMap: tagMap = { script: 'noscript', @@ -59,6 +58,9 @@ function getTagName(n: elementNode): string { const HOVER_SELECTOR = /([^\\]):hover/g; export function addHoverClass(cssText: string): string { + if (!window.HIG_CONFIGURATION.enableOnHoverClass) { + return cssText; + } const ast = parse(cssText, { silent: true }); if (!ast.stylesheet) { return cssText; @@ -178,25 +180,6 @@ function buildNode( } } } - if (n.isShadowHost) { - /** - * Since node is newly rebuilt, it should be a normal element - * without shadowRoot. - * But if there are some weird situations that has defined - * custom element in the scope before we rebuild node, it may - * register the shadowRoot earlier. - * The logic in the 'else' block is just a try-my-best solution - * for the corner case, please let we know if it is wrong and - * we can remove it. - */ - if (!node.shadowRoot) { - node.attachShadow({ mode: 'open' }); - } else { - while (node.shadowRoot.firstChild) { - node.shadowRoot.removeChild(node.shadowRoot.firstChild); - } - } - } return node; case NodeType.Text: return doc.createTextNode( @@ -218,20 +201,13 @@ export function buildNodeWithSN( map: idNodeMap; skipChild?: boolean; hackCss: boolean; - afterAppend?: (n: INode) => unknown; }, ): INode | null { - const { doc, map, skipChild = false, hackCss = true, afterAppend } = options; + const { doc, map, skipChild = false, hackCss = true } = options; let node = buildNode(n, { doc, hackCss }); if (!node) { return null; } - if (n.rootId) { - console.assert( - ((map[n.rootId] as unknown) as Document) === doc, - 'Target document should has the same root id.', - ); - } // use target document as root document if (n.type === NodeType.Document) { // close before open to make sure document was closed @@ -242,7 +218,6 @@ export function buildNodeWithSN( (node as INode).__sn = n; map[n.id] = node as INode; - if ( (n.type === NodeType.Document || n.type === NodeType.Element) && !skipChild @@ -253,24 +228,14 @@ export function buildNodeWithSN( map, skipChild: false, hackCss, - afterAppend, }); if (!childNode) { console.warn('Failed to rebuild', childN); - continue; - } - - if (childN.isShadow && isElement(node) && node.shadowRoot) { - node.shadowRoot.appendChild(childNode); } else { node.appendChild(childNode); } - if (afterAppend) { - afterAppend(childNode); - } } } - return node as INode; } @@ -312,17 +277,15 @@ function rebuild( doc: Document; onVisit?: (node: INode) => unknown; hackCss?: boolean; - afterAppend?: (n: INode) => unknown; }, ): [Node | null, idNodeMap] { - const { doc, onVisit, hackCss = true, afterAppend } = options; + const { doc, onVisit, hackCss = true } = options; const idNodeMap: idNodeMap = {}; const node = buildNodeWithSN(n, { doc, map: idNodeMap, skipChild: false, hackCss, - afterAppend, }); visit(idNodeMap, (visitedNode) => { if (onVisit) { diff --git a/src/snapshot/snapshot.ts b/src/snapshot/snapshot.ts index fb1ad7bc..8c819787 100644 --- a/src/snapshot/snapshot.ts +++ b/src/snapshot/snapshot.ts @@ -8,10 +8,9 @@ import { MaskInputOptions, SlimDOMOptions, } from './types'; -import { isElement, isShadowRoot } from './utils'; let _id = 1; -const tagNameRegex = RegExp('[^a-z0-9-_]'); +const tagNameRegex = RegExp('[^a-z1-6-_]'); export const IGNORED_NODE = -2; @@ -159,19 +158,12 @@ function getHref() { export function transformAttribute( doc: Document, - tagName: string, name: string, value: string, ): string { // relative path in attribute if (name === 'src' || ((name === 'href' || name === 'xlink:href') && value)) { return absoluteToDoc(doc, value); - } else if ( - name === 'background' && - value && - (tagName === 'table' || tagName === 'td' || tagName === 'th') - ) { - return absoluteToDoc(doc, value); } else if (name === 'srcset' && value) { return getAbsoluteSrcsetString(doc, value); } else if (name === 'style' && value) { @@ -191,13 +183,11 @@ export function _isBlockedElement( return true; } } else { - // tslint:disable-next-line: prefer-for-of - for (let eIndex = 0; eIndex < element.classList.length; eIndex++) { - const className = element.classList[eIndex]; + element.classList.forEach((className) => { if (blockClass.test(className)) { return true; } - } + }); } if (blockSelector) { return element.matches(blockSelector); @@ -206,53 +196,6 @@ export function _isBlockedElement( return false; } -// https://stackoverflow.com/a/36155560 -function onceIframeLoaded( - iframeEl: HTMLIFrameElement, - listener: () => unknown, - iframeLoadTimeout: number, -) { - const win = iframeEl.contentWindow; - if (!win) { - return; - } - // document is loading - let fired = false; - - let readyState: DocumentReadyState; - try { - readyState = win.document.readyState; - } catch (error) { - return; - } - if (readyState !== 'complete') { - const timer = setTimeout(() => { - if (!fired) { - listener(); - fired = true; - } - }, iframeLoadTimeout); - iframeEl.addEventListener('load', () => { - clearTimeout(timer); - fired = true; - listener(); - }); - return; - } - // check blank frame for Chrome - const blankUrl = 'about:blank'; - if ( - win.location.href !== blankUrl || - iframeEl.src === blankUrl || - iframeEl.src === '' - ) { - listener(); - return; - } - // use default listener - iframeEl.addEventListener('load', listener); -} - function serializeNode( n: Node, options: { @@ -275,18 +218,11 @@ function serializeNode( enableStrictPrivacy, } = options; - // Only record root id when document object is not the base document - let rootId: number | undefined; - if (((doc as unknown) as INode).__sn) { - const docId = ((doc as unknown) as INode).__sn.id; - rootId = docId === 1 ? undefined : docId; - } switch (n.nodeType) { case n.DOCUMENT_NODE: return { type: NodeType.Document, childNodes: [], - rootId, }; case n.DOCUMENT_TYPE_NODE: return { @@ -294,7 +230,6 @@ function serializeNode( name: (n as DocumentType).name, publicId: (n as DocumentType).publicId, systemId: (n as DocumentType).systemId, - rootId, }; case n.ELEMENT_NODE: let needBlock = _isBlockedElement( @@ -305,7 +240,7 @@ function serializeNode( const tagName = getValidTagName(n as HTMLElement); let attributes: attributes = {}; for (const { name, value } of Array.from((n as HTMLElement).attributes)) { - attributes[name] = transformAttribute(doc, tagName, name, value); + attributes[name] = transformAttribute(doc, name, value); } // remote css if (tagName === 'link' && inlineStylesheet) { @@ -387,7 +322,6 @@ function serializeNode( if ((n as HTMLElement).scrollTop) { attributes.rr_scrollTop = (n as HTMLElement).scrollTop; } - // block element if (needBlock || (tagName === 'img' && enableStrictPrivacy)) { const { width, height } = (n as HTMLElement).getBoundingClientRect(); attributes = { @@ -395,10 +329,7 @@ function serializeNode( rr_width: `${width}px`, rr_height: `${height}px`, }; - } - // iframe - if (tagName === 'iframe') { - delete attributes.src; + needBlock = true; } return { type: NodeType.Element, @@ -407,7 +338,6 @@ function serializeNode( childNodes: [], isSVG: isSVGElement(n as Element) || undefined, needBlock, - rootId, }; case n.TEXT_NODE: // The parent node may not be a html element which has a tagName attribute. @@ -453,19 +383,16 @@ function serializeNode( type: NodeType.Text, textContent: textContent || '', isStyle, - rootId, }; case n.CDATA_SECTION_NODE: return { type: NodeType.CDATA, textContent: '', - rootId, }; case n.COMMENT_NODE: return { type: NodeType.Comment, textContent: (n as Comment).textContent || '', - rootId, }; default: return false; @@ -578,9 +505,6 @@ export function serializeNodeWithId( recordCanvas?: boolean; preserveWhiteSpace?: boolean; enableStrictPrivacy: boolean; - onSerialize?: (n: INode) => unknown; - onIframeLoad?: (iframeINode: INode, node: serializedNodeWithId) => unknown; - iframeLoadTimeout?: number; }, ): serializedNodeWithId | null { const { @@ -594,9 +518,6 @@ export function serializeNodeWithId( slimDOMOptions, recordCanvas = false, enableStrictPrivacy, - onSerialize, - onIframeLoad, - iframeLoadTimeout = 5000, } = options; let { preserveWhiteSpace = true } = options; const _serializedNode = serializeNode(n, { @@ -635,9 +556,6 @@ export function serializeNodeWithId( return null; // slimDOM } map[id] = n as INode; - if (onSerialize) { - onSerialize(n as INode); - } let recordChild = !skipChild; if (serializedNode.type === NodeType.Element) { recordChild = recordChild && !serializedNode.needBlock; @@ -667,80 +585,25 @@ export function serializeNodeWithId( ) { preserveWhiteSpace = false; } - const bypassOptions = { - doc, - map, - blockClass, - blockSelector, - skipChild, - inlineStylesheet, - maskInputOptions, - slimDOMOptions, - recordCanvas, - preserveWhiteSpace, - enableStrictPrivacy, - onSerialize, - onIframeLoad, - iframeLoadTimeout, - }; for (const childN of Array.from(n.childNodes)) { - const serializedChildNode = serializeNodeWithId(childN, bypassOptions); + const serializedChildNode = serializeNodeWithId(childN, { + doc, + map, + blockClass, + blockSelector, + skipChild, + inlineStylesheet, + maskInputOptions, + slimDOMOptions, + recordCanvas, + preserveWhiteSpace, + enableStrictPrivacy, + }); if (serializedChildNode) { serializedNode.childNodes.push(serializedChildNode); } } - - if (isElement(n) && n.shadowRoot) { - serializedNode.isShadowHost = true; - for (const childN of Array.from(n.shadowRoot.childNodes)) { - const serializedChildNode = serializeNodeWithId(childN, bypassOptions); - if (serializedChildNode) { - serializedChildNode.isShadow = true; - serializedNode.childNodes.push(serializedChildNode); - } - } - } - } - - if (n.parentNode && isShadowRoot(n.parentNode)) { - serializedNode.isShadow = true; } - - if ( - serializedNode.type === NodeType.Element && - serializedNode.tagName === 'iframe' - ) { - onceIframeLoaded( - n as HTMLIFrameElement, - () => { - const iframeDoc = (n as HTMLIFrameElement).contentDocument; - if (iframeDoc && onIframeLoad) { - const serializedIframeNode = serializeNodeWithId(iframeDoc, { - doc: iframeDoc, - map, - blockClass, - blockSelector, - skipChild: false, - inlineStylesheet, - maskInputOptions, - slimDOMOptions, - recordCanvas, - preserveWhiteSpace, - onSerialize, - onIframeLoad, - iframeLoadTimeout, - enableStrictPrivacy, - }); - - if (serializedIframeNode) { - onIframeLoad(n as INode, serializedIframeNode); - } - } - }, - iframeLoadTimeout, - ); - } - return serializedNode; } @@ -754,10 +617,6 @@ function snapshot( recordCanvas?: boolean; blockSelector?: string | null; enableStrictPrivacy: boolean; - preserveWhiteSpace?: boolean; - onSerialize?: (n: INode) => unknown; - onIframeLoad?: (iframeINode: INode, node: serializedNodeWithId) => unknown; - iframeLoadTimeout?: number; }, ): [serializedNodeWithId | null, idNodeMap] { const { @@ -768,10 +627,6 @@ function snapshot( maskAllInputs = false, slimDOM = false, enableStrictPrivacy = false, - preserveWhiteSpace, - onSerialize, - onIframeLoad, - iframeLoadTimeout, } = options || {}; const idNodeMap: idNodeMap = {}; const maskInputOptions: MaskInputOptions = @@ -826,10 +681,6 @@ function snapshot( slimDOMOptions, recordCanvas, enableStrictPrivacy, - preserveWhiteSpace, - onSerialize, - onIframeLoad, - iframeLoadTimeout, }), idNodeMap, ]; diff --git a/src/snapshot/types.ts b/src/snapshot/types.ts index 0a9eb630..9a53c012 100644 --- a/src/snapshot/types.ts +++ b/src/snapshot/types.ts @@ -47,18 +47,13 @@ export type commentNode = { textContent: string; }; -export type serializedNode = ( +export type serializedNode = | documentNode | documentTypeNode | elementNode | textNode | cdataNode - | commentNode -) & { - rootId?: number; - isShadowHost?: boolean; - isShadow?: boolean; -}; + | commentNode; export type serializedNodeWithId = serializedNode & { id: number }; diff --git a/src/snapshot/utils.ts b/src/snapshot/utils.ts deleted file mode 100644 index df6cf20b..00000000 --- a/src/snapshot/utils.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { INode } from './types'; - -export function isElement(n: Node | INode): n is Element { - return n.nodeType === n.ELEMENT_NODE; -} - -export function isShadowRoot(n: Node): n is ShadowRoot { - const host: Element | null = (n as ShadowRoot)?.host; - return Boolean(host && host.shadowRoot && host.shadowRoot === n); -} diff --git a/src/types.ts b/src/types.ts index 2a16bf04..6f7da278 100644 --- a/src/types.ts +++ b/src/types.ts @@ -7,8 +7,6 @@ import { } from './snapshot'; import { PackFn, UnpackFn } from './packer/base'; import { FontFaceDescriptors } from 'css-font-loading-module'; -import { IframeManager } from './record/iframe-manager'; -import { ShadowDomManager } from './record/shadow-dom-manager'; export enum EventType { DomContentLoaded, @@ -45,6 +43,7 @@ export type fullSnapshotEvent = { left: number; }; }; + isFirstFullSnapshot?: boolean; }; export type incrementalSnapshotEvent = { @@ -110,7 +109,7 @@ export type scrollData = { export type viewportResizeData = { source: IncrementalSource.ViewportResize; -} & viewportResizeDimension; +} & viewportResizeDimention; export type inputData = { source: IncrementalSource.Input; @@ -172,10 +171,6 @@ export type SamplingStrategy = Partial<{ * number is the throttle threshold of recording mouse/touch move */ mousemove: boolean | number; - /** - * number is the throttle threshold of mouse/touch move callback - */ - mousemoveCallback: number; /** * false means not to record mouse interaction events * can also specify record some kinds of mouse interactions @@ -244,9 +239,6 @@ export type observerParam = { collectFonts: boolean; slimDOMOptions: SlimDOMOptions; enableStrictPrivacy: boolean; - doc: Document; - iframeManager: IframeManager; - shadowDomManager: ShadowDomManager; }; export type hooksParam = { @@ -298,7 +290,6 @@ export type attributeMutation = { export type removedNodeMutation = { parentId: number; id: number; - isShadow?: boolean; }; export type addedNodeMutation = { @@ -309,12 +300,11 @@ export type addedNodeMutation = { node: serializedNodeWithId; }; -export type mutationCallbackParam = { +type mutationCallbackParam = { texts: textMutation[]; attributes: attributeMutation[]; removes: removedNodeMutation[]; adds: addedNodeMutation[]; - isAttachIframe?: true; }; export type mutationCallBack = (m: mutationCallbackParam) => void; @@ -418,25 +408,25 @@ export type LogLevel = /* fork from interface Console */ // all kinds of console functions export type Logger = { - assert?: typeof console.assert; - clear?: typeof console.clear; - count?: typeof console.count; - countReset?: typeof console.countReset; - debug?: typeof console.debug; - dir?: typeof console.dir; - dirxml?: typeof console.dirxml; - error?: typeof console.error; - group?: typeof console.group; - groupCollapsed?: typeof console.groupCollapsed; + assert?: (value: any, message?: string, ...optionalParams: any[]) => void; + clear?: () => void; + count?: (label?: string) => void; + countReset?: (label?: string) => void; + debug?: (message?: any, ...optionalParams: any[]) => void; + dir?: (obj: any, options?: NodeJS.InspectOptions) => void; + dirxml?: (...data: any[]) => void; + error?: (message?: any, ...optionalParams: any[]) => void; + group?: (...label: any[]) => void; + groupCollapsed?: (label?: any[]) => void; groupEnd?: () => void; - info?: typeof console.info; - log?: typeof console.log; - table?: typeof console.table; - time?: typeof console.time; - timeEnd?: typeof console.timeEnd; - timeLog?: typeof console.timeLog; - trace?: typeof console.trace; - warn?: typeof console.warn; + info?: (message?: any, ...optionalParams: any[]) => void; + log?: (message?: any, ...optionalParams: any[]) => void; + table?: (tabularData: any, properties?: ReadonlyArray) => void; + time?: (label?: string) => void; + timeEnd?: (label?: string) => void; + timeLog?: (label?: string, ...data: any[]) => void; + trace?: (message?: any, ...optionalParams: any[]) => void; + warn?: (message?: any, ...optionalParams: any[]) => void; }; /** @@ -447,20 +437,20 @@ export type ReplayLogger = Partial void>>; export type LogParam = { level: LogLevel; - trace: string[]; - payload: string[]; + trace: Array; + payload: Array; }; export type fontCallback = (p: fontParam) => void; export type logCallback = (p: LogParam) => void; -export type viewportResizeDimension = { +export type viewportResizeDimention = { width: number; height: number; }; -export type viewportResizeCallback = (d: viewportResizeDimension) => void; +export type viewportResizeCallback = (d: viewportResizeDimention) => void; export type inputValue = { text: string; @@ -481,15 +471,6 @@ export type mediaInteractionParam = { export type mediaInteractionCallback = (p: mediaInteractionParam) => void; -export type DocumentDimension = { - x: number; - y: number; - // scale value relative to its parent iframe - relativeScale: number; - // scale value relative to the root iframe - absoluteScale: number; -}; - export type Mirror = { map: idNodeMap; getId: (n: INode) => number; @@ -508,7 +489,6 @@ export type hookResetter = () => void; export type playerConfig = { speed: number; - maxSpeed: number; root: Element; loadTimeout: number; skipInactive: boolean; @@ -535,7 +515,7 @@ export type playerConfig = { }; export type LogReplayConfig = { - level?: LogLevel[] | undefined; + level?: Array | undefined; replayLogger: ReplayLogger | undefined; }; @@ -607,8 +587,18 @@ export type StringifyOptions = { }; export type LogRecordOptions = { - level?: LogLevel[] | undefined; + level?: Array | undefined; lengthThreshold?: number; stringifyOptions?: StringifyOptions; logger?: Logger; }; + +export interface HighlightConfiguration { + enableOnHoverClass?: boolean; +} + +declare global { + interface Window { + HIG_CONFIGURATION: HighlightConfiguration; + } +} diff --git a/src/utils.ts b/src/utils.ts index 1d4667a2..c5e0b0c8 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -14,15 +14,8 @@ import { mutationData, scrollData, inputData, - DocumentDimension, } from './types'; -import { - INode, - IGNORED_NODE, - serializedNodeWithId, - NodeType, - isShadowRoot, -} from './snapshot'; +import { INode, IGNORED_NODE } from './snapshot'; export function on( type: string, @@ -214,9 +207,6 @@ export function isIgnored(n: Node | INode): boolean { } export function isAncestorRemoved(target: INode): boolean { - if (isShadowRoot(target)) { - return false; - } const id = mirror.getId(target); if (!mirror.has(id)) { return true; @@ -537,59 +527,3 @@ export function iterateResolveTree( iterateResolveTree(tree.children[i], cb); } } - -type HTMLIFrameINode = HTMLIFrameElement & { - __sn: serializedNodeWithId; -}; -export type AppendedIframe = { - mutationInQueue: addedNodeMutation; - builtNode: HTMLIFrameINode; -}; - -export function isIframeINode( - node: INode | ShadowRoot, -): node is HTMLIFrameINode { - if ('__sn' in node) { - return ( - node.__sn.type === NodeType.Element && node.__sn.tagName === 'iframe' - ); - } - // node can be document fragment when using the virtual parent feature - return false; -} - -export function getBaseDimension( - node: Node, - rootIframe: Node, -): DocumentDimension { - const frameElement = node.ownerDocument?.defaultView?.frameElement; - if (!frameElement || frameElement === rootIframe) { - return { - x: 0, - y: 0, - relativeScale: 1, - absoluteScale: 1, - }; - } - - const frameDimension = frameElement.getBoundingClientRect(); - const frameBaseDimension = getBaseDimension(frameElement, rootIframe); - // the iframe element may have a scale transform - const relativeScale = frameDimension.height / frameElement.clientHeight; - return { - x: - frameDimension.x * frameBaseDimension.relativeScale + - frameBaseDimension.x, - y: - frameDimension.y * frameBaseDimension.relativeScale + - frameBaseDimension.y, - relativeScale, - absoluteScale: frameBaseDimension.absoluteScale * relativeScale, - }; -} - -export function hasShadowRoot( - n: T, -): n is T & { shadowRoot: ShadowRoot } { - return Boolean(((n as unknown) as Element)?.shadowRoot); -} diff --git a/test/__snapshots__/integration.test.ts.snap b/test/__snapshots__/integration.test.ts.snap index 35bd2406..19f34fb6 100644 --- a/test/__snapshots__/integration.test.ts.snap +++ b/test/__snapshots__/integration.test.ts.snap @@ -1727,7 +1727,7 @@ exports[`frozen 1`] = ` ]" `; -exports[`iframe 1`] = ` +exports[`ignore 1`] = ` "[ { \\"type\\": 0, @@ -1745,53 +1745,6 @@ exports[`iframe 1`] = ` \\"height\\": 1080 } }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 0, - \\"adds\\": [ - { - \\"parentId\\": 19, - \\"nextId\\": null, - \\"node\\": { - \\"type\\": 0, - \\"childNodes\\": [ - { - \\"type\\": 2, - \\"tagName\\": \\"html\\", - \\"attributes\\": {}, - \\"childNodes\\": [ - { - \\"type\\": 2, - \\"tagName\\": \\"head\\", - \\"attributes\\": {}, - \\"childNodes\\": [], - \\"rootId\\": 20, - \\"id\\": 22 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"body\\", - \\"attributes\\": {}, - \\"childNodes\\": [], - \\"rootId\\": 20, - \\"id\\": 23 - } - ], - \\"rootId\\": 20, - \\"id\\": 21 - } - ], - \\"id\\": 20 - } - } - ], - \\"removes\\": [], - \\"texts\\": [], - \\"attributes\\": [], - \\"isAttachIframe\\": true - } - }, { \\"type\\": 2, \\"data\\": { @@ -1853,48 +1806,44 @@ exports[`iframe 1`] = ` }, { \\"type\\": 2, - \\"tagName\\": \\"title\\", - \\"attributes\\": {}, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"Main\\", - \\"id\\": 11 - } - ], + \\"tagName\\": \\"meta\\", + \\"attributes\\": { + \\"http-equiv\\": \\"X-UA-Compatible\\", + \\"content\\": \\"ie=edge\\" + }, + \\"childNodes\\": [], \\"id\\": 10 }, { \\"type\\": 3, \\"textContent\\": \\"\\\\n \\", - \\"id\\": 12 + \\"id\\": 11 }, { \\"type\\": 2, - \\"tagName\\": \\"style\\", + \\"tagName\\": \\"title\\", \\"attributes\\": {}, \\"childNodes\\": [ { \\"type\\": 3, - \\"textContent\\": \\"\\\\n iframe {\\\\n width: 500px;\\\\n height: 500px;\\\\n }\\\\n \\", - \\"isStyle\\": true, - \\"id\\": 14 + \\"textContent\\": \\"ignore fields\\", + \\"id\\": 13 } ], - \\"id\\": 13 + \\"id\\": 12 }, { \\"type\\": 3, \\"textContent\\": \\"\\\\n \\", - \\"id\\": 15 + \\"id\\": 14 } ], \\"id\\": 4 }, { \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 16 + \\"textContent\\": \\"\\\\n\\\\n \\", + \\"id\\": 15 }, { \\"type\\": 2, @@ -1904,39 +1853,94 @@ exports[`iframe 1`] = ` { \\"type\\": 3, \\"textContent\\": \\"\\\\n \\", - \\"id\\": 18 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"iframe\\", - \\"attributes\\": { - \\"id\\": \\"one\\" - }, - \\"childNodes\\": [], - \\"id\\": 19 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\\\n \\", - \\"id\\": 24 + \\"id\\": 17 }, { \\"type\\": 2, - \\"tagName\\": \\"script\\", + \\"tagName\\": \\"form\\", \\"attributes\\": {}, \\"childNodes\\": [ { \\"type\\": 3, - \\"textContent\\": \\"SCRIPT_PLACEHOLDER\\", - \\"id\\": 26 + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 19 + }, + { + \\"type\\": 2, + \\"tagName\\": \\"label\\", + \\"attributes\\": { + \\"for\\": \\"password\\" + }, + \\"childNodes\\": [ + { + \\"type\\": 3, + \\"textContent\\": \\" \\", + \\"id\\": 21 + }, + { + \\"type\\": 2, + \\"tagName\\": \\"input\\", + \\"attributes\\": { + \\"type\\": \\"password\\" + }, + \\"childNodes\\": [], + \\"id\\": 22 + }, + { + \\"type\\": 3, + \\"textContent\\": \\" \\", + \\"id\\": 23 + } + ], + \\"id\\": 20 + }, + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 24 + }, + { + \\"type\\": 2, + \\"tagName\\": \\"label\\", + \\"attributes\\": { + \\"for\\": \\"ignore text\\" + }, + \\"childNodes\\": [ + { + \\"type\\": 3, + \\"textContent\\": \\" \\", + \\"id\\": 26 + }, + { + \\"type\\": 2, + \\"tagName\\": \\"input\\", + \\"attributes\\": { + \\"type\\": \\"text\\", + \\"class\\": \\"rr-ignore\\" + }, + \\"childNodes\\": [], + \\"id\\": 27 + }, + { + \\"type\\": 3, + \\"textContent\\": \\" \\", + \\"id\\": 28 + } + ], + \\"id\\": 25 + }, + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 29 } ], - \\"id\\": 25 + \\"id\\": 18 }, { \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\\\n \\\\n \\", - \\"id\\": 27 + \\"textContent\\": \\"\\\\n \\\\n \\", + \\"id\\": 30 }, { \\"type\\": 2, @@ -1946,18 +1950,18 @@ exports[`iframe 1`] = ` { \\"type\\": 3, \\"textContent\\": \\"SCRIPT_PLACEHOLDER\\", - \\"id\\": 29 + \\"id\\": 32 } ], - \\"id\\": 28 + \\"id\\": 31 }, { \\"type\\": 3, - \\"textContent\\": \\"\\\\n\\\\n\\", - \\"id\\": 30 + \\"textContent\\": \\"\\\\n \\\\n \\\\n\\\\n\\", + \\"id\\": 33 } ], - \\"id\\": 17 + \\"id\\": 16 } ], \\"id\\": 3 @@ -1974,467 +1978,354 @@ exports[`iframe 1`] = ` { \\"type\\": 3, \\"data\\": { - \\"source\\": 0, - \\"texts\\": [], - \\"attributes\\": [], - \\"removes\\": [], - \\"adds\\": [ - { - \\"parentId\\": 17, - \\"nextId\\": null, - \\"node\\": { - \\"type\\": 2, - \\"tagName\\": \\"iframe\\", - \\"attributes\\": { - \\"id\\": \\"two\\" - }, - \\"childNodes\\": [], - \\"id\\": 31 - } - } - ] + \\"source\\": 2, + \\"type\\": 5, + \\"id\\": 22 } }, { \\"type\\": 3, \\"data\\": { - \\"source\\": 0, - \\"adds\\": [ - { - \\"parentId\\": 47, - \\"nextId\\": null, - \\"node\\": { - \\"type\\": 0, + \\"source\\": 2, + \\"type\\": 6, + \\"id\\": 22 + } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 2, + \\"type\\": 5, + \\"id\\": 27 + } + } +]" +`; + +exports[`log`] = ` +"[ + { + \\"type\\": 0, + \\"data\\": {} + }, + { + \\"type\\": 1, + \\"data\\": {} + }, + { + \\"type\\": 4, + \\"data\\": { + \\"href\\": \\"about:blank\\", + \\"width\\": 1920, + \\"height\\": 1080 + } + }, + { + \\"type\\": 2, + \\"data\\": { + \\"node\\": { + \\"type\\": 0, + \\"childNodes\\": [ + { + \\"type\\": 1, + \\"name\\": \\"html\\", + \\"publicId\\": \\"\\", + \\"systemId\\": \\"\\", + \\"id\\": 2 + }, + { + \\"type\\": 2, + \\"tagName\\": \\"html\\", + \\"attributes\\": { + \\"lang\\": \\"en\\" + }, \\"childNodes\\": [ { \\"type\\": 2, - \\"tagName\\": \\"html\\", + \\"tagName\\": \\"head\\", \\"attributes\\": {}, \\"childNodes\\": [ { - \\"type\\": 2, - \\"tagName\\": \\"head\\", - \\"attributes\\": {}, - \\"childNodes\\": [], - \\"rootId\\": 48, - \\"id\\": 50 + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 5 }, { \\"type\\": 2, - \\"tagName\\": \\"body\\", - \\"attributes\\": {}, + \\"tagName\\": \\"meta\\", + \\"attributes\\": { + \\"charset\\": \\"UTF-8\\" + }, \\"childNodes\\": [], - \\"rootId\\": 48, - \\"id\\": 51 - } - ], - \\"rootId\\": 48, - \\"id\\": 49 - } - ], - \\"id\\": 48 - } - } - ], - \\"removes\\": [], - \\"texts\\": [], - \\"attributes\\": [], - \\"isAttachIframe\\": true - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 0, - \\"adds\\": [ - { - \\"parentId\\": 53, - \\"nextId\\": null, - \\"node\\": { - \\"type\\": 0, - \\"childNodes\\": [ - { - \\"type\\": 1, - \\"name\\": \\"html\\", - \\"publicId\\": \\"\\", - \\"systemId\\": \\"\\", - \\"rootId\\": 54, - \\"id\\": 55 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"html\\", - \\"attributes\\": { - \\"lang\\": \\"en\\" - }, - \\"childNodes\\": [ + \\"id\\": 6 + }, + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 7 + }, { \\"type\\": 2, - \\"tagName\\": \\"head\\", - \\"attributes\\": {}, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"rootId\\": 54, - \\"id\\": 58 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"meta\\", - \\"attributes\\": { - \\"charset\\": \\"UTF-8\\" - }, - \\"childNodes\\": [], - \\"rootId\\": 54, - \\"id\\": 59 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"rootId\\": 54, - \\"id\\": 60 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"meta\\", - \\"attributes\\": { - \\"name\\": \\"viewport\\", - \\"content\\": \\"width=device-width, initial-scale=1.0\\" - }, - \\"childNodes\\": [], - \\"rootId\\": 54, - \\"id\\": 61 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"rootId\\": 54, - \\"id\\": 62 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"title\\", - \\"attributes\\": {}, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"Frame 2\\", - \\"rootId\\": 54, - \\"id\\": 64 - } - ], - \\"rootId\\": 54, - \\"id\\": 63 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"rootId\\": 54, - \\"id\\": 65 - } - ], - \\"rootId\\": 54, - \\"id\\": 57 + \\"tagName\\": \\"meta\\", + \\"attributes\\": { + \\"name\\": \\"viewport\\", + \\"content\\": \\"width=device-width, initial-scale=1.0\\" + }, + \\"childNodes\\": [], + \\"id\\": 8 }, { \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"rootId\\": 54, - \\"id\\": 66 + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 9 + }, + { + \\"type\\": 2, + \\"tagName\\": \\"meta\\", + \\"attributes\\": { + \\"http-equiv\\": \\"X-UA-Compatible\\", + \\"content\\": \\"ie=edge\\" + }, + \\"childNodes\\": [], + \\"id\\": 10 + }, + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 11 }, { \\"type\\": 2, - \\"tagName\\": \\"body\\", + \\"tagName\\": \\"title\\", \\"attributes\\": {}, \\"childNodes\\": [ { \\"type\\": 3, - \\"textContent\\": \\"\\\\n frame 2\\\\n \\\\n \\", - \\"rootId\\": 54, - \\"id\\": 68 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"script\\", - \\"attributes\\": {}, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"SCRIPT_PLACEHOLDER\\", - \\"rootId\\": 54, - \\"id\\": 70 - } - ], - \\"rootId\\": 54, - \\"id\\": 69 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n\\\\n\\", - \\"rootId\\": 54, - \\"id\\": 71 + \\"textContent\\": \\"Log record\\", + \\"id\\": 13 } ], - \\"rootId\\": 54, - \\"id\\": 67 + \\"id\\": 12 + }, + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 14 } ], - \\"rootId\\": 54, - \\"id\\": 56 - } - ], - \\"id\\": 54 - } - } - ], - \\"removes\\": [], - \\"texts\\": [], - \\"attributes\\": [], - \\"isAttachIframe\\": true - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 0, - \\"adds\\": [ - { - \\"parentId\\": 31, - \\"nextId\\": null, - \\"node\\": { - \\"type\\": 0, - \\"childNodes\\": [ + \\"id\\": 4 + }, { - \\"type\\": 1, - \\"name\\": \\"html\\", - \\"publicId\\": \\"\\", - \\"systemId\\": \\"\\", - \\"rootId\\": 32, - \\"id\\": 33 + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 15 }, { \\"type\\": 2, - \\"tagName\\": \\"html\\", - \\"attributes\\": { - \\"lang\\": \\"en\\" - }, + \\"tagName\\": \\"body\\", + \\"attributes\\": {}, \\"childNodes\\": [ - { - \\"type\\": 2, - \\"tagName\\": \\"head\\", - \\"attributes\\": {}, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"rootId\\": 32, - \\"id\\": 36 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"meta\\", - \\"attributes\\": { - \\"charset\\": \\"UTF-8\\" - }, - \\"childNodes\\": [], - \\"rootId\\": 32, - \\"id\\": 37 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"rootId\\": 32, - \\"id\\": 38 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"meta\\", - \\"attributes\\": { - \\"name\\": \\"viewport\\", - \\"content\\": \\"width=device-width, initial-scale=1.0\\" - }, - \\"childNodes\\": [], - \\"rootId\\": 32, - \\"id\\": 39 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"rootId\\": 32, - \\"id\\": 40 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"title\\", - \\"attributes\\": {}, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"Frame 1\\", - \\"rootId\\": 32, - \\"id\\": 42 - } - ], - \\"rootId\\": 32, - \\"id\\": 41 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"rootId\\": 32, - \\"id\\": 43 - } - ], - \\"rootId\\": 32, - \\"id\\": 35 - }, { \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"rootId\\": 32, - \\"id\\": 44 + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 17 }, { \\"type\\": 2, - \\"tagName\\": \\"body\\", + \\"tagName\\": \\"script\\", \\"attributes\\": {}, \\"childNodes\\": [ { \\"type\\": 3, - \\"textContent\\": \\"\\\\n frame 1\\\\n \\", - \\"rootId\\": 32, - \\"id\\": 46 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"iframe\\", - \\"attributes\\": { - \\"id\\": \\"three\\", - \\"frameborder\\": \\"0\\" - }, - \\"childNodes\\": [], - \\"rootId\\": 32, - \\"id\\": 47 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"rootId\\": 32, - \\"id\\": 52 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"iframe\\", - \\"attributes\\": { - \\"id\\": \\"four\\", - \\"frameborder\\": \\"0\\" - }, - \\"childNodes\\": [], - \\"rootId\\": 32, - \\"id\\": 53 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\\\n\\\\n\\", - \\"rootId\\": 32, - \\"id\\": 72 + \\"textContent\\": \\"SCRIPT_PLACEHOLDER\\", + \\"id\\": 19 } ], - \\"rootId\\": 32, - \\"id\\": 45 + \\"id\\": 18 + }, + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\\\n \\\\n\\\\n\\", + \\"id\\": 20 } ], - \\"rootId\\": 32, - \\"id\\": 34 + \\"id\\": 16 } ], - \\"id\\": 32 + \\"id\\": 3 } - } - ], - \\"removes\\": [], - \\"texts\\": [], - \\"attributes\\": [], - \\"isAttachIframe\\": true + ], + \\"id\\": 1 + }, + \\"initialOffset\\": { + \\"left\\": 0, + \\"top\\": 0 + } } }, { \\"type\\": 3, \\"data\\": { - \\"source\\": 0, - \\"adds\\": [ - { - \\"parentId\\": 73, - \\"nextId\\": null, - \\"node\\": { - \\"type\\": 0, - \\"childNodes\\": [ - { - \\"type\\": 2, - \\"tagName\\": \\"html\\", - \\"attributes\\": {}, - \\"childNodes\\": [ - { - \\"type\\": 2, - \\"tagName\\": \\"head\\", - \\"attributes\\": {}, - \\"childNodes\\": [], - \\"rootId\\": 74, - \\"id\\": 76 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"body\\", - \\"attributes\\": {}, - \\"childNodes\\": [], - \\"rootId\\": 74, - \\"id\\": 77 - } - ], - \\"rootId\\": 74, - \\"id\\": 75 - } - ], - \\"id\\": 74 - } - } - ], - \\"removes\\": [], - \\"texts\\": [], - \\"attributes\\": [], - \\"isAttachIframe\\": true + \\"source\\": 11, + \\"level\\": \\"assert\\", + \\"payload\\": [ + \\"true\\", + \\"\\"assert\\"\\" + ] } }, { \\"type\\": 3, \\"data\\": { - \\"source\\": 0, - \\"texts\\": [], - \\"attributes\\": [], - \\"removes\\": [], - \\"adds\\": [ - { - \\"parentId\\": 67, - \\"nextId\\": null, - \\"node\\": { - \\"type\\": 2, - \\"tagName\\": \\"iframe\\", - \\"attributes\\": { - \\"id\\": \\"five\\" - }, - \\"childNodes\\": [], - \\"rootId\\": 54, - \\"id\\": 73 - } - } + \\"source\\": 11, + \\"level\\": \\"count\\", + \\"payload\\": [ + \\"\\"count\\"\\" + ] + } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 11, + \\"level\\": \\"countReset\\", + \\"payload\\": [ + \\"\\"count\\"\\" + ] + } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 11, + \\"level\\": \\"debug\\", + \\"payload\\": [ + \\"\\"debug\\"\\" + ] + } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 11, + \\"level\\": \\"dir\\", + \\"payload\\": [ + \\"\\"dir\\"\\" + ] + } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 11, + \\"level\\": \\"dirxml\\", + \\"payload\\": [ + \\"\\"dirxml\\"\\" + ] + } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 11, + \\"level\\": \\"group\\", + \\"payload\\": [] + } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 11, + \\"level\\": \\"groupCollapsed\\", + \\"payload\\": [] + } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 11, + \\"level\\": \\"info\\", + \\"payload\\": [ + \\"\\"info\\"\\" + ] + } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 11, + \\"level\\": \\"log\\", + \\"payload\\": [ + \\"\\"log\\"\\" + ] + } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 11, + \\"level\\": \\"table\\", + \\"payload\\": [ + \\"\\"table\\"\\" + ] + } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 11, + \\"level\\": \\"time\\", + \\"payload\\": [] + } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 11, + \\"level\\": \\"timeEnd\\", + \\"payload\\": [] + } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 11, + \\"level\\": \\"timeLog\\", + \\"payload\\": [] + } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 11, + \\"level\\": \\"trace\\", + \\"payload\\": [ + \\"\\"trace\\"\\" + ] + } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 11, + \\"level\\": \\"warn\\", + \\"payload\\": [ + \\"\\"warn\\"\\" ] } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 11, + \\"level\\": \\"clear\\", + \\"payload\\": [] + } } ]" `; -exports[`ignore 1`] = ` +exports[`log 1`] = ` "[ { \\"type\\": 0, @@ -2533,7 +2424,7 @@ exports[`ignore 1`] = ` \\"childNodes\\": [ { \\"type\\": 3, - \\"textContent\\": \\"ignore fields\\", + \\"textContent\\": \\"Log record\\", \\"id\\": 13 } ], @@ -2549,7 +2440,7 @@ exports[`ignore 1`] = ` }, { \\"type\\": 3, - \\"textContent\\": \\"\\\\n\\\\n \\", + \\"textContent\\": \\"\\\\n \\", \\"id\\": 15 }, { @@ -2564,108 +2455,21 @@ exports[`ignore 1`] = ` }, { \\"type\\": 2, - \\"tagName\\": \\"form\\", + \\"tagName\\": \\"script\\", \\"attributes\\": {}, \\"childNodes\\": [ { \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", + \\"textContent\\": \\"SCRIPT_PLACEHOLDER\\", \\"id\\": 19 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"label\\", - \\"attributes\\": { - \\"for\\": \\"password\\" - }, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\" \\", - \\"id\\": 21 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"input\\", - \\"attributes\\": { - \\"type\\": \\"password\\" - }, - \\"childNodes\\": [], - \\"id\\": 22 - }, - { - \\"type\\": 3, - \\"textContent\\": \\" \\", - \\"id\\": 23 - } - ], - \\"id\\": 20 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 24 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"label\\", - \\"attributes\\": { - \\"for\\": \\"ignore text\\" - }, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\" \\", - \\"id\\": 26 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"input\\", - \\"attributes\\": { - \\"type\\": \\"text\\", - \\"class\\": \\"rr-ignore\\" - }, - \\"childNodes\\": [], - \\"id\\": 27 - }, - { - \\"type\\": 3, - \\"textContent\\": \\" \\", - \\"id\\": 28 - } - ], - \\"id\\": 25 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 29 } ], \\"id\\": 18 }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\\\n \\", - \\"id\\": 30 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"script\\", - \\"attributes\\": {}, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"SCRIPT_PLACEHOLDER\\", - \\"id\\": 32 - } - ], - \\"id\\": 31 - }, { \\"type\\": 3, \\"textContent\\": \\"\\\\n \\\\n \\\\n\\\\n\\", - \\"id\\": 33 + \\"id\\": 20 } ], \\"id\\": 16 @@ -2685,31 +2489,234 @@ exports[`ignore 1`] = ` { \\"type\\": 3, \\"data\\": { - \\"source\\": 2, - \\"type\\": 5, - \\"id\\": 22 + \\"source\\": 11, + \\"level\\": \\"assert\\", + \\"trace\\": [ + \\"__puppeteer_evalu\\", + \\"ion_script__:2:37\\" + ], + \\"payload\\": [ + \\"true\\", + \\"\\\\\\"assert\\\\\\"\\" + ] } }, { \\"type\\": 3, \\"data\\": { - \\"source\\": 2, - \\"type\\": 6, - \\"id\\": 22 + \\"source\\": 11, + \\"level\\": \\"count\\", + \\"trace\\": [ + \\"__puppeteer_evalu\\", + \\"ion_script__:3:37\\" + ], + \\"payload\\": [ + \\"\\\\\\"count\\\\\\"\\" + ] } }, { \\"type\\": 3, \\"data\\": { - \\"source\\": 2, - \\"type\\": 5, - \\"id\\": 27 + \\"source\\": 11, + \\"level\\": \\"countReset\\", + \\"trace\\": [ + \\"__puppeteer_evalu\\", + \\"ion_script__:4:37\\" + ], + \\"payload\\": [ + \\"\\\\\\"count\\\\\\"\\" + ] + } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 11, + \\"level\\": \\"debug\\", + \\"trace\\": [ + \\"__puppeteer_evalu\\", + \\"ion_script__:5:37\\" + ], + \\"payload\\": [ + \\"\\\\\\"debug\\\\\\"\\" + ] + } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 11, + \\"level\\": \\"dir\\", + \\"trace\\": [ + \\"__puppeteer_evalu\\", + \\"ion_script__:6:37\\" + ], + \\"payload\\": [ + \\"\\\\\\"dir\\\\\\"\\" + ] + } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 11, + \\"level\\": \\"dirxml\\", + \\"trace\\": [ + \\"__puppeteer_evalu\\", + \\"ion_script__:7:37\\" + ], + \\"payload\\": [ + \\"\\\\\\"dirxml\\\\\\"\\" + ] + } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 11, + \\"level\\": \\"group\\", + \\"trace\\": [ + \\"__puppeteer_evalu\\", + \\"ion_script__:8:37\\" + ], + \\"payload\\": [] + } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 11, + \\"level\\": \\"groupCollapsed\\", + \\"trace\\": [ + \\"__puppeteer_evalu\\", + \\"ion_script__:9:37\\" + ], + \\"payload\\": [] + } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 11, + \\"level\\": \\"info\\", + \\"trace\\": [ + \\"__puppeteer_evalu\\", + \\"ion_script__:10:37\\" + ], + \\"payload\\": [ + \\"\\\\\\"info\\\\\\"\\" + ] + } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 11, + \\"level\\": \\"log\\", + \\"trace\\": [ + \\"__puppeteer_evalu\\", + \\"ion_script__:11:37\\" + ], + \\"payload\\": [ + \\"\\\\\\"log\\\\\\"\\" + ] + } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 11, + \\"level\\": \\"table\\", + \\"trace\\": [ + \\"__puppeteer_evalu\\", + \\"ion_script__:12:37\\" + ], + \\"payload\\": [ + \\"\\\\\\"table\\\\\\"\\" + ] + } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 11, + \\"level\\": \\"time\\", + \\"trace\\": [ + \\"__puppeteer_evalu\\", + \\"ion_script__:13:37\\" + ], + \\"payload\\": [] + } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 11, + \\"level\\": \\"timeEnd\\", + \\"trace\\": [ + \\"__puppeteer_evalu\\", + \\"ion_script__:14:37\\" + ], + \\"payload\\": [] + } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 11, + \\"level\\": \\"timeLog\\", + \\"trace\\": [ + \\"__puppeteer_evalu\\", + \\"ion_script__:15:37\\" + ], + \\"payload\\": [] + } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 11, + \\"level\\": \\"trace\\", + \\"trace\\": [ + \\"__puppeteer_evalu\\", + \\"ion_script__:16:37\\" + ], + \\"payload\\": [ + \\"\\\\\\"trace\\\\\\"\\" + ] + } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 11, + \\"level\\": \\"warn\\", + \\"trace\\": [ + \\"__puppeteer_evalu\\", + \\"ion_script__:17:37\\" + ], + \\"payload\\": [ + \\"\\\\\\"warn\\\\\\"\\" + ] + } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 11, + \\"level\\": \\"clear\\", + \\"trace\\": [ + \\"__puppeteer_evalu\\", + \\"ion_script__:18:37\\" + ], + \\"payload\\": [] } } ]" `; -exports[`log`] = ` +exports[`mask 1`] = ` "[ { \\"type\\": 0, @@ -2754,7 +2761,7 @@ exports[`log`] = ` \\"childNodes\\": [ { \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", + \\"textContent\\": \\"\\\\n \\", \\"id\\": 5 }, { @@ -2768,7 +2775,7 @@ exports[`log`] = ` }, { \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", + \\"textContent\\": \\"\\\\n \\", \\"id\\": 7 }, { @@ -2783,7 +2790,7 @@ exports[`log`] = ` }, { \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", + \\"textContent\\": \\"\\\\n \\", \\"id\\": 9 }, { @@ -2798,7 +2805,7 @@ exports[`log`] = ` }, { \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", + \\"textContent\\": \\"\\\\n \\", \\"id\\": 11 }, { @@ -2808,7 +2815,7 @@ exports[`log`] = ` \\"childNodes\\": [ { \\"type\\": 3, - \\"textContent\\": \\"Log record\\", + \\"textContent\\": \\"form fields\\", \\"id\\": 13 } ], @@ -2816,7 +2823,7 @@ exports[`log`] = ` }, { \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", + \\"textContent\\": \\"\\\\n\\", \\"id\\": 14 } ], @@ -2824,7 +2831,7 @@ exports[`log`] = ` }, { \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", + \\"textContent\\": \\"\\\\n\\\\n\\", \\"id\\": 15 }, { @@ -2834,607 +2841,581 @@ exports[`log`] = ` \\"childNodes\\": [ { \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", + \\"textContent\\": \\"\\\\n \\", \\"id\\": 17 }, { \\"type\\": 2, - \\"tagName\\": \\"script\\", + \\"tagName\\": \\"form\\", \\"attributes\\": {}, \\"childNodes\\": [ { \\"type\\": 3, - \\"textContent\\": \\"SCRIPT_PLACEHOLDER\\", + \\"textContent\\": \\"\\\\n \\", \\"id\\": 19 + }, + { + \\"type\\": 2, + \\"tagName\\": \\"label\\", + \\"attributes\\": { + \\"for\\": \\"text\\" + }, + \\"childNodes\\": [ + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 21 + }, + { + \\"type\\": 2, + \\"tagName\\": \\"input\\", + \\"attributes\\": { + \\"type\\": \\"text\\" + }, + \\"childNodes\\": [], + \\"id\\": 22 + }, + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 23 + } + ], + \\"id\\": 20 + }, + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 24 + }, + { + \\"type\\": 2, + \\"tagName\\": \\"label\\", + \\"attributes\\": { + \\"for\\": \\"radio\\" + }, + \\"childNodes\\": [ + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 26 + }, + { + \\"type\\": 2, + \\"tagName\\": \\"input\\", + \\"attributes\\": { + \\"type\\": \\"radio\\" + }, + \\"childNodes\\": [], + \\"id\\": 27 + }, + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 28 + } + ], + \\"id\\": 25 + }, + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 29 + }, + { + \\"type\\": 2, + \\"tagName\\": \\"label\\", + \\"attributes\\": { + \\"for\\": \\"checkbox\\" + }, + \\"childNodes\\": [ + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 31 + }, + { + \\"type\\": 2, + \\"tagName\\": \\"input\\", + \\"attributes\\": { + \\"type\\": \\"checkbox\\" + }, + \\"childNodes\\": [], + \\"id\\": 32 + }, + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 33 + } + ], + \\"id\\": 30 + }, + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 34 + }, + { + \\"type\\": 2, + \\"tagName\\": \\"label\\", + \\"attributes\\": { + \\"for\\": \\"textarea\\" + }, + \\"childNodes\\": [ + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 36 + }, + { + \\"type\\": 2, + \\"tagName\\": \\"textarea\\", + \\"attributes\\": { + \\"name\\": \\"\\", + \\"id\\": \\"\\", + \\"cols\\": \\"30\\", + \\"rows\\": \\"10\\" + }, + \\"childNodes\\": [], + \\"id\\": 37 + }, + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 38 + } + ], + \\"id\\": 35 + }, + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 39 + }, + { + \\"type\\": 2, + \\"tagName\\": \\"label\\", + \\"attributes\\": { + \\"for\\": \\"select\\" + }, + \\"childNodes\\": [ + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 41 + }, + { + \\"type\\": 2, + \\"tagName\\": \\"select\\", + \\"attributes\\": { + \\"name\\": \\"\\", + \\"id\\": \\"\\", + \\"value\\": \\"*\\" + }, + \\"childNodes\\": [ + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 43 + }, + { + \\"type\\": 2, + \\"tagName\\": \\"option\\", + \\"attributes\\": { + \\"value\\": \\"1\\", + \\"selected\\": true + }, + \\"childNodes\\": [ + { + \\"type\\": 3, + \\"textContent\\": \\"1\\", + \\"id\\": 45 + } + ], + \\"id\\": 44 + }, + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 46 + }, + { + \\"type\\": 2, + \\"tagName\\": \\"option\\", + \\"attributes\\": { + \\"value\\": \\"2\\" + }, + \\"childNodes\\": [ + { + \\"type\\": 3, + \\"textContent\\": \\"2\\", + \\"id\\": 48 + } + ], + \\"id\\": 47 + }, + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 49 + } + ], + \\"id\\": 42 + }, + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 50 + } + ], + \\"id\\": 40 + }, + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 51 } ], \\"id\\": 18 }, { \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\\\n \\\\n\\\\n\\", - \\"id\\": 20 - } - ], - \\"id\\": 16 - } - ], - \\"id\\": 3 - } - ], - \\"id\\": 1 - }, - \\"initialOffset\\": { - \\"left\\": 0, - \\"top\\": 0 - } - } - }, - { + \\"textContent\\": \\"\\\\n\\\\n \\", + \\"id\\": 52 + }, + { + \\"type\\": 2, + \\"tagName\\": \\"script\\", + \\"attributes\\": {}, + \\"childNodes\\": [ + { + \\"type\\": 3, + \\"textContent\\": \\"SCRIPT_PLACEHOLDER\\", + \\"id\\": 54 + } + ], + \\"id\\": 53 + }, + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\\\n \\\\n\\\\n\\\\n\\", + \\"id\\": 55 + } + ], + \\"id\\": 16 + } + ], + \\"id\\": 3 + } + ], + \\"id\\": 1 + }, + \\"initialOffset\\": { + \\"left\\": 0, + \\"top\\": 0 + } + } + }, + { \\"type\\": 3, \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"assert\\", - \\"payload\\": [ - \\"true\\", - \\"\\"assert\\"\\" - ] + \\"source\\": 2, + \\"type\\": 5, + \\"id\\": 22 } }, { \\"type\\": 3, \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"count\\", - \\"payload\\": [ - \\"\\"count\\"\\" - ] + \\"source\\": 5, + \\"text\\": \\"*\\", + \\"isChecked\\": false, + \\"id\\": 22 } }, { \\"type\\": 3, \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"countReset\\", - \\"payload\\": [ - \\"\\"count\\"\\" - ] + \\"source\\": 5, + \\"text\\": \\"**\\", + \\"isChecked\\": false, + \\"id\\": 22 } }, { \\"type\\": 3, \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"debug\\", - \\"payload\\": [ - \\"\\"debug\\"\\" - ] + \\"source\\": 5, + \\"text\\": \\"***\\", + \\"isChecked\\": false, + \\"id\\": 22 } }, { \\"type\\": 3, \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"dir\\", - \\"payload\\": [ - \\"\\"dir\\"\\" - ] + \\"source\\": 5, + \\"text\\": \\"****\\", + \\"isChecked\\": false, + \\"id\\": 22 } }, { \\"type\\": 3, \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"dirxml\\", - \\"payload\\": [ - \\"\\"dirxml\\"\\" - ] + \\"source\\": 2, + \\"type\\": 1, + \\"id\\": 27 } }, { \\"type\\": 3, \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"group\\", - \\"payload\\": [] + \\"source\\": 2, + \\"type\\": 6, + \\"id\\": 22 } }, { \\"type\\": 3, \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"groupCollapsed\\", - \\"payload\\": [] + \\"source\\": 2, + \\"type\\": 5, + \\"id\\": 27 } }, { \\"type\\": 3, \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"info\\", - \\"payload\\": [ - \\"\\"info\\"\\" - ] + \\"source\\": 2, + \\"type\\": 0, + \\"id\\": 27 } }, { \\"type\\": 3, \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"log\\", - \\"payload\\": [ - \\"\\"log\\"\\" - ] + \\"source\\": 2, + \\"type\\": 2, + \\"id\\": 27 } }, { \\"type\\": 3, \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"table\\", - \\"payload\\": [ - \\"\\"table\\"\\" - ] + \\"source\\": 5, + \\"text\\": \\"on\\", + \\"isChecked\\": true, + \\"id\\": 27 } }, { \\"type\\": 3, \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"time\\", - \\"payload\\": [] + \\"source\\": 2, + \\"type\\": 1, + \\"id\\": 32 } }, { \\"type\\": 3, \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"timeEnd\\", - \\"payload\\": [] + \\"source\\": 2, + \\"type\\": 6, + \\"id\\": 27 } }, { \\"type\\": 3, \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"timeLog\\", - \\"payload\\": [] + \\"source\\": 2, + \\"type\\": 5, + \\"id\\": 32 } }, { \\"type\\": 3, \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"trace\\", - \\"payload\\": [ - \\"\\"trace\\"\\" - ] + \\"source\\": 2, + \\"type\\": 0, + \\"id\\": 32 } }, { \\"type\\": 3, \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"warn\\", - \\"payload\\": [ - \\"\\"warn\\"\\" - ] + \\"source\\": 2, + \\"type\\": 2, + \\"id\\": 32 } }, { \\"type\\": 3, \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"clear\\", - \\"payload\\": [] + \\"source\\": 5, + \\"text\\": \\"on\\", + \\"isChecked\\": true, + \\"id\\": 32 } - } -]" -`; - -exports[`log 1`] = ` -"[ + }, { - \\"type\\": 0, - \\"data\\": {} + \\"type\\": 3, + \\"data\\": { + \\"source\\": 2, + \\"type\\": 6, + \\"id\\": 32 + } }, { - \\"type\\": 1, - \\"data\\": {} + \\"type\\": 3, + \\"data\\": { + \\"source\\": 2, + \\"type\\": 5, + \\"id\\": 37 + } }, { - \\"type\\": 4, + \\"type\\": 3, \\"data\\": { - \\"href\\": \\"about:blank\\", - \\"width\\": 1920, - \\"height\\": 1080 + \\"source\\": 5, + \\"text\\": \\"*\\", + \\"isChecked\\": false, + \\"id\\": 37 } }, { - \\"type\\": 2, + \\"type\\": 3, \\"data\\": { - \\"node\\": { - \\"type\\": 0, - \\"childNodes\\": [ - { - \\"type\\": 1, - \\"name\\": \\"html\\", - \\"publicId\\": \\"\\", - \\"systemId\\": \\"\\", - \\"id\\": 2 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"html\\", - \\"attributes\\": { - \\"lang\\": \\"en\\" - }, - \\"childNodes\\": [ - { - \\"type\\": 2, - \\"tagName\\": \\"head\\", - \\"attributes\\": {}, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 5 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"meta\\", - \\"attributes\\": { - \\"charset\\": \\"UTF-8\\" - }, - \\"childNodes\\": [], - \\"id\\": 6 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 7 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"meta\\", - \\"attributes\\": { - \\"name\\": \\"viewport\\", - \\"content\\": \\"width=device-width, initial-scale=1.0\\" - }, - \\"childNodes\\": [], - \\"id\\": 8 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 9 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"meta\\", - \\"attributes\\": { - \\"http-equiv\\": \\"X-UA-Compatible\\", - \\"content\\": \\"ie=edge\\" - }, - \\"childNodes\\": [], - \\"id\\": 10 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 11 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"title\\", - \\"attributes\\": {}, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"Log record\\", - \\"id\\": 13 - } - ], - \\"id\\": 12 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 14 - } - ], - \\"id\\": 4 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 15 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"body\\", - \\"attributes\\": {}, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 17 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"script\\", - \\"attributes\\": {}, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"SCRIPT_PLACEHOLDER\\", - \\"id\\": 19 - } - ], - \\"id\\": 18 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\\\n \\\\n\\\\n\\", - \\"id\\": 20 - } - ], - \\"id\\": 16 - } - ], - \\"id\\": 3 - } - ], - \\"id\\": 1 - }, - \\"initialOffset\\": { - \\"left\\": 0, - \\"top\\": 0 - } + \\"source\\": 5, + \\"text\\": \\"**\\", + \\"isChecked\\": false, + \\"id\\": 37 } }, { \\"type\\": 3, \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"assert\\", - \\"trace\\": [ - \\"__puppeteer_evalu\\", - \\"ion_script__:2:37\\" - ], - \\"payload\\": [ - \\"true\\", - \\"\\\\\\"assert\\\\\\"\\" - ] + \\"source\\": 5, + \\"text\\": \\"***\\", + \\"isChecked\\": false, + \\"id\\": 37 } }, { \\"type\\": 3, \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"count\\", - \\"trace\\": [ - \\"__puppeteer_evalu\\", - \\"ion_script__:3:37\\" - ], - \\"payload\\": [ - \\"\\\\\\"count\\\\\\"\\" - ] + \\"source\\": 5, + \\"text\\": \\"****\\", + \\"isChecked\\": false, + \\"id\\": 37 } }, { \\"type\\": 3, \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"countReset\\", - \\"trace\\": [ - \\"__puppeteer_evalu\\", - \\"ion_script__:4:37\\" - ], - \\"payload\\": [ - \\"\\\\\\"count\\\\\\"\\" - ] + \\"source\\": 5, + \\"text\\": \\"*****\\", + \\"isChecked\\": false, + \\"id\\": 37 } }, { \\"type\\": 3, \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"debug\\", - \\"trace\\": [ - \\"__puppeteer_evalu\\", - \\"ion_script__:5:37\\" - ], - \\"payload\\": [ - \\"\\\\\\"debug\\\\\\"\\" - ] + \\"source\\": 5, + \\"text\\": \\"******\\", + \\"isChecked\\": false, + \\"id\\": 37 } }, { \\"type\\": 3, \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"dir\\", - \\"trace\\": [ - \\"__puppeteer_evalu\\", - \\"ion_script__:6:37\\" - ], - \\"payload\\": [ - \\"\\\\\\"dir\\\\\\"\\" - ] + \\"source\\": 5, + \\"text\\": \\"*******\\", + \\"isChecked\\": false, + \\"id\\": 37 } }, { \\"type\\": 3, \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"dirxml\\", - \\"trace\\": [ - \\"__puppeteer_evalu\\", - \\"ion_script__:7:37\\" - ], - \\"payload\\": [ - \\"\\\\\\"dirxml\\\\\\"\\" - ] + \\"source\\": 5, + \\"text\\": \\"********\\", + \\"isChecked\\": false, + \\"id\\": 37 } }, { \\"type\\": 3, \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"group\\", - \\"trace\\": [ - \\"__puppeteer_evalu\\", - \\"ion_script__:8:37\\" - ], - \\"payload\\": [] + \\"source\\": 5, + \\"text\\": \\"*********\\", + \\"isChecked\\": false, + \\"id\\": 37 } }, { \\"type\\": 3, \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"groupCollapsed\\", - \\"trace\\": [ - \\"__puppeteer_evalu\\", - \\"ion_script__:9:37\\" - ], - \\"payload\\": [] + \\"source\\": 5, + \\"text\\": \\"**********\\", + \\"isChecked\\": false, + \\"id\\": 37 } }, { \\"type\\": 3, \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"info\\", - \\"trace\\": [ - \\"__puppeteer_evalu\\", - \\"ion_script__:10:37\\" - ], - \\"payload\\": [ - \\"\\\\\\"info\\\\\\"\\" - ] + \\"source\\": 5, + \\"text\\": \\"***********\\", + \\"isChecked\\": false, + \\"id\\": 37 } }, { \\"type\\": 3, \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"log\\", - \\"trace\\": [ - \\"__puppeteer_evalu\\", - \\"ion_script__:11:37\\" - ], - \\"payload\\": [ - \\"\\\\\\"log\\\\\\"\\" - ] + \\"source\\": 5, + \\"text\\": \\"************\\", + \\"isChecked\\": false, + \\"id\\": 37 } }, { \\"type\\": 3, \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"table\\", - \\"trace\\": [ - \\"__puppeteer_evalu\\", - \\"ion_script__:12:37\\" - ], - \\"payload\\": [ - \\"\\\\\\"table\\\\\\"\\" - ] + \\"source\\": 5, + \\"text\\": \\"*************\\", + \\"isChecked\\": false, + \\"id\\": 37 } }, { \\"type\\": 3, \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"time\\", - \\"trace\\": [ - \\"__puppeteer_evalu\\", - \\"ion_script__:13:37\\" - ], - \\"payload\\": [] + \\"source\\": 5, + \\"text\\": \\"*\\", + \\"isChecked\\": false, + \\"id\\": 42 } + } +]" +`; + +exports[`maskInputOptions 1`] = ` +"[ + { + \\"type\\": 0, + \\"data\\": {} }, { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"timeEnd\\", - \\"trace\\": [ - \\"__puppeteer_evalu\\", - \\"ion_script__:14:37\\" - ], - \\"payload\\": [] - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"timeLog\\", - \\"trace\\": [ - \\"__puppeteer_evalu\\", - \\"ion_script__:15:37\\" - ], - \\"payload\\": [] - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"trace\\", - \\"trace\\": [ - \\"__puppeteer_evalu\\", - \\"ion_script__:16:37\\" - ], - \\"payload\\": [ - \\"\\\\\\"trace\\\\\\"\\" - ] - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"warn\\", - \\"trace\\": [ - \\"__puppeteer_evalu\\", - \\"ion_script__:17:37\\" - ], - \\"payload\\": [ - \\"\\\\\\"warn\\\\\\"\\" - ] - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 11, - \\"level\\": \\"clear\\", - \\"trace\\": [ - \\"__puppeteer_evalu\\", - \\"ion_script__:18:37\\" - ], - \\"payload\\": [] - } - } -]" -`; - -exports[`mask 1`] = ` -"[ - { - \\"type\\": 0, - \\"data\\": {} - }, - { - \\"type\\": 1, - \\"data\\": {} - }, - { - \\"type\\": 4, + \\"type\\": 1, + \\"data\\": {} + }, + { + \\"type\\": 4, \\"data\\": { \\"href\\": \\"about:blank\\", \\"width\\": 1920, @@ -3718,7 +3699,7 @@ exports[`mask 1`] = ` \\"attributes\\": { \\"name\\": \\"\\", \\"id\\": \\"\\", - \\"value\\": \\"*\\" + \\"value\\": \\"1\\" }, \\"childNodes\\": [ { @@ -3836,7 +3817,7 @@ exports[`mask 1`] = ` \\"type\\": 3, \\"data\\": { \\"source\\": 5, - \\"text\\": \\"*\\", + \\"text\\": \\"t\\", \\"isChecked\\": false, \\"id\\": 22 } @@ -3845,7 +3826,7 @@ exports[`mask 1`] = ` \\"type\\": 3, \\"data\\": { \\"source\\": 5, - \\"text\\": \\"**\\", + \\"text\\": \\"te\\", \\"isChecked\\": false, \\"id\\": 22 } @@ -3854,7 +3835,7 @@ exports[`mask 1`] = ` \\"type\\": 3, \\"data\\": { \\"source\\": 5, - \\"text\\": \\"***\\", + \\"text\\": \\"tes\\", \\"isChecked\\": false, \\"id\\": 22 } @@ -3863,7 +3844,7 @@ exports[`mask 1`] = ` \\"type\\": 3, \\"data\\": { \\"source\\": 5, - \\"text\\": \\"****\\", + \\"text\\": \\"test\\", \\"isChecked\\": false, \\"id\\": 22 } @@ -3986,7 +3967,7 @@ exports[`mask 1`] = ` \\"type\\": 3, \\"data\\": { \\"source\\": 5, - \\"text\\": \\"*\\", + \\"text\\": \\"t\\", \\"isChecked\\": false, \\"id\\": 37 } @@ -3995,7 +3976,7 @@ exports[`mask 1`] = ` \\"type\\": 3, \\"data\\": { \\"source\\": 5, - \\"text\\": \\"**\\", + \\"text\\": \\"te\\", \\"isChecked\\": false, \\"id\\": 37 } @@ -4004,7 +3985,7 @@ exports[`mask 1`] = ` \\"type\\": 3, \\"data\\": { \\"source\\": 5, - \\"text\\": \\"***\\", + \\"text\\": \\"tex\\", \\"isChecked\\": false, \\"id\\": 37 } @@ -4013,7 +3994,7 @@ exports[`mask 1`] = ` \\"type\\": 3, \\"data\\": { \\"source\\": 5, - \\"text\\": \\"****\\", + \\"text\\": \\"text\\", \\"isChecked\\": false, \\"id\\": 37 } @@ -4022,7 +4003,7 @@ exports[`mask 1`] = ` \\"type\\": 3, \\"data\\": { \\"source\\": 5, - \\"text\\": \\"*****\\", + \\"text\\": \\"texta\\", \\"isChecked\\": false, \\"id\\": 37 } @@ -4031,7 +4012,7 @@ exports[`mask 1`] = ` \\"type\\": 3, \\"data\\": { \\"source\\": 5, - \\"text\\": \\"******\\", + \\"text\\": \\"textar\\", \\"isChecked\\": false, \\"id\\": 37 } @@ -4040,7 +4021,7 @@ exports[`mask 1`] = ` \\"type\\": 3, \\"data\\": { \\"source\\": 5, - \\"text\\": \\"*******\\", + \\"text\\": \\"textare\\", \\"isChecked\\": false, \\"id\\": 37 } @@ -4049,7 +4030,7 @@ exports[`mask 1`] = ` \\"type\\": 3, \\"data\\": { \\"source\\": 5, - \\"text\\": \\"********\\", + \\"text\\": \\"textarea\\", \\"isChecked\\": false, \\"id\\": 37 } @@ -4058,7 +4039,7 @@ exports[`mask 1`] = ` \\"type\\": 3, \\"data\\": { \\"source\\": 5, - \\"text\\": \\"*********\\", + \\"text\\": \\"textarea \\", \\"isChecked\\": false, \\"id\\": 37 } @@ -4067,7 +4048,7 @@ exports[`mask 1`] = ` \\"type\\": 3, \\"data\\": { \\"source\\": 5, - \\"text\\": \\"**********\\", + \\"text\\": \\"textarea t\\", \\"isChecked\\": false, \\"id\\": 37 } @@ -4076,7 +4057,7 @@ exports[`mask 1`] = ` \\"type\\": 3, \\"data\\": { \\"source\\": 5, - \\"text\\": \\"***********\\", + \\"text\\": \\"textarea te\\", \\"isChecked\\": false, \\"id\\": 37 } @@ -4085,7 +4066,7 @@ exports[`mask 1`] = ` \\"type\\": 3, \\"data\\": { \\"source\\": 5, - \\"text\\": \\"************\\", + \\"text\\": \\"textarea tes\\", \\"isChecked\\": false, \\"id\\": 37 } @@ -4094,7 +4075,7 @@ exports[`mask 1`] = ` \\"type\\": 3, \\"data\\": { \\"source\\": 5, - \\"text\\": \\"*************\\", + \\"text\\": \\"textarea test\\", \\"isChecked\\": false, \\"id\\": 37 } @@ -4103,7 +4084,7 @@ exports[`mask 1`] = ` \\"type\\": 3, \\"data\\": { \\"source\\": 5, - \\"text\\": \\"*\\", + \\"text\\": \\"1\\", \\"isChecked\\": false, \\"id\\": 42 } @@ -4111,7 +4092,7 @@ exports[`mask 1`] = ` ]" `; -exports[`maskInputOptions 1`] = ` +exports[`move-node-1 1`] = ` "[ { \\"type\\": 0, @@ -4135,349 +4116,111 @@ exports[`maskInputOptions 1`] = ` \\"node\\": { \\"type\\": 0, \\"childNodes\\": [ - { - \\"type\\": 1, - \\"name\\": \\"html\\", - \\"publicId\\": \\"\\", - \\"systemId\\": \\"\\", - \\"id\\": 2 - }, { \\"type\\": 2, \\"tagName\\": \\"html\\", - \\"attributes\\": { - \\"lang\\": \\"en\\" - }, + \\"attributes\\": {}, \\"childNodes\\": [ { \\"type\\": 2, \\"tagName\\": \\"head\\", \\"attributes\\": {}, + \\"childNodes\\": [], + \\"id\\": 3 + }, + { + \\"type\\": 2, + \\"tagName\\": \\"body\\", + \\"attributes\\": {}, \\"childNodes\\": [ { \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", + \\"textContent\\": \\"\\\\n \\", \\"id\\": 5 }, { \\"type\\": 2, - \\"tagName\\": \\"meta\\", - \\"attributes\\": { - \\"charset\\": \\"UTF-8\\" - }, - \\"childNodes\\": [], - \\"id\\": 6 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 7 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"meta\\", - \\"attributes\\": { - \\"name\\": \\"viewport\\", - \\"content\\": \\"width=device-width, initial-scale=1.0\\" - }, - \\"childNodes\\": [], - \\"id\\": 8 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 9 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"meta\\", - \\"attributes\\": { - \\"http-equiv\\": \\"X-UA-Compatible\\", - \\"content\\": \\"ie=edge\\" - }, - \\"childNodes\\": [], - \\"id\\": 10 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 11 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"title\\", + \\"tagName\\": \\"div\\", \\"attributes\\": {}, \\"childNodes\\": [ { \\"type\\": 3, - \\"textContent\\": \\"form fields\\", - \\"id\\": 13 + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 7 + }, + { + \\"type\\": 2, + \\"tagName\\": \\"p\\", + \\"attributes\\": {}, + \\"childNodes\\": [], + \\"id\\": 8 + }, + { + \\"type\\": 3, + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 9 } ], - \\"id\\": 12 + \\"id\\": 6 }, { \\"type\\": 3, - \\"textContent\\": \\"\\\\n\\", - \\"id\\": 14 - } - ], - \\"id\\": 4 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n\\\\n\\", - \\"id\\": 15 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"body\\", - \\"attributes\\": {}, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 17 + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 10 }, { \\"type\\": 2, - \\"tagName\\": \\"form\\", + \\"tagName\\": \\"span\\", \\"attributes\\": {}, \\"childNodes\\": [ { \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 19 + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 12 }, { \\"type\\": 2, - \\"tagName\\": \\"label\\", - \\"attributes\\": { - \\"for\\": \\"text\\" - }, + \\"tagName\\": \\"i\\", + \\"attributes\\": {}, \\"childNodes\\": [ { \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 21 + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 14 }, { \\"type\\": 2, - \\"tagName\\": \\"input\\", - \\"attributes\\": { - \\"type\\": \\"text\\" - }, - \\"childNodes\\": [], - \\"id\\": 22 + \\"tagName\\": \\"b\\", + \\"attributes\\": {}, + \\"childNodes\\": [ + { + \\"type\\": 3, + \\"textContent\\": \\"1\\", + \\"id\\": 16 + } + ], + \\"id\\": 15 }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 23 - } - ], - \\"id\\": 20 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 24 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"label\\", - \\"attributes\\": { - \\"for\\": \\"radio\\" - }, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 26 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"input\\", - \\"attributes\\": { - \\"type\\": \\"radio\\" - }, - \\"childNodes\\": [], - \\"id\\": 27 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 28 - } - ], - \\"id\\": 25 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 29 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"label\\", - \\"attributes\\": { - \\"for\\": \\"checkbox\\" - }, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 31 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"input\\", - \\"attributes\\": { - \\"type\\": \\"checkbox\\" - }, - \\"childNodes\\": [], - \\"id\\": 32 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 33 - } - ], - \\"id\\": 30 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 34 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"label\\", - \\"attributes\\": { - \\"for\\": \\"textarea\\" - }, - \\"childNodes\\": [ { \\"type\\": 3, \\"textContent\\": \\"\\\\n \\", - \\"id\\": 36 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"textarea\\", - \\"attributes\\": { - \\"name\\": \\"\\", - \\"id\\": \\"\\", - \\"cols\\": \\"30\\", - \\"rows\\": \\"10\\" - }, - \\"childNodes\\": [], - \\"id\\": 37 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 38 + \\"id\\": 17 } ], - \\"id\\": 35 + \\"id\\": 13 }, { \\"type\\": 3, \\"textContent\\": \\"\\\\n \\", - \\"id\\": 39 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"label\\", - \\"attributes\\": { - \\"for\\": \\"select\\" - }, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 41 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"select\\", - \\"attributes\\": { - \\"name\\": \\"\\", - \\"id\\": \\"\\", - \\"value\\": \\"1\\" - }, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 43 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"option\\", - \\"attributes\\": { - \\"value\\": \\"1\\", - \\"selected\\": true - }, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"1\\", - \\"id\\": 45 - } - ], - \\"id\\": 44 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 46 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"option\\", - \\"attributes\\": { - \\"value\\": \\"2\\" - }, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"2\\", - \\"id\\": 48 - } - ], - \\"id\\": 47 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 49 - } - ], - \\"id\\": 42 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 50 - } - ], - \\"id\\": 40 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 51 + \\"id\\": 18 } ], - \\"id\\": 18 + \\"id\\": 11 }, { \\"type\\": 3, - \\"textContent\\": \\"\\\\n\\\\n \\", - \\"id\\": 52 + \\"textContent\\": \\"\\\\n \\\\n \\", + \\"id\\": 19 }, { \\"type\\": 2, @@ -4487,471 +4230,21 @@ exports[`maskInputOptions 1`] = ` { \\"type\\": 3, \\"textContent\\": \\"SCRIPT_PLACEHOLDER\\", - \\"id\\": 54 + \\"id\\": 21 } ], - \\"id\\": 53 + \\"id\\": 20 }, { \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\\\n \\\\n\\\\n\\\\n\\", - \\"id\\": 55 + \\"textContent\\": \\"\\\\n \\\\n \\\\n\\\\n\\", + \\"id\\": 22 } ], - \\"id\\": 16 + \\"id\\": 4 } ], - \\"id\\": 3 - } - ], - \\"id\\": 1 - }, - \\"initialOffset\\": { - \\"left\\": 0, - \\"top\\": 0 - } - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 2, - \\"type\\": 5, - \\"id\\": 22 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 5, - \\"text\\": \\"t\\", - \\"isChecked\\": false, - \\"id\\": 22 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 5, - \\"text\\": \\"te\\", - \\"isChecked\\": false, - \\"id\\": 22 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 5, - \\"text\\": \\"tes\\", - \\"isChecked\\": false, - \\"id\\": 22 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 5, - \\"text\\": \\"test\\", - \\"isChecked\\": false, - \\"id\\": 22 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 2, - \\"type\\": 1, - \\"id\\": 27 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 2, - \\"type\\": 6, - \\"id\\": 22 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 2, - \\"type\\": 5, - \\"id\\": 27 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 2, - \\"type\\": 0, - \\"id\\": 27 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 2, - \\"type\\": 2, - \\"id\\": 27 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 5, - \\"text\\": \\"on\\", - \\"isChecked\\": true, - \\"id\\": 27 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 2, - \\"type\\": 1, - \\"id\\": 32 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 2, - \\"type\\": 6, - \\"id\\": 27 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 2, - \\"type\\": 5, - \\"id\\": 32 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 2, - \\"type\\": 0, - \\"id\\": 32 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 2, - \\"type\\": 2, - \\"id\\": 32 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 5, - \\"text\\": \\"on\\", - \\"isChecked\\": true, - \\"id\\": 32 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 2, - \\"type\\": 6, - \\"id\\": 32 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 2, - \\"type\\": 5, - \\"id\\": 37 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 5, - \\"text\\": \\"t\\", - \\"isChecked\\": false, - \\"id\\": 37 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 5, - \\"text\\": \\"te\\", - \\"isChecked\\": false, - \\"id\\": 37 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 5, - \\"text\\": \\"tex\\", - \\"isChecked\\": false, - \\"id\\": 37 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 5, - \\"text\\": \\"text\\", - \\"isChecked\\": false, - \\"id\\": 37 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 5, - \\"text\\": \\"texta\\", - \\"isChecked\\": false, - \\"id\\": 37 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 5, - \\"text\\": \\"textar\\", - \\"isChecked\\": false, - \\"id\\": 37 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 5, - \\"text\\": \\"textare\\", - \\"isChecked\\": false, - \\"id\\": 37 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 5, - \\"text\\": \\"textarea\\", - \\"isChecked\\": false, - \\"id\\": 37 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 5, - \\"text\\": \\"textarea \\", - \\"isChecked\\": false, - \\"id\\": 37 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 5, - \\"text\\": \\"textarea t\\", - \\"isChecked\\": false, - \\"id\\": 37 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 5, - \\"text\\": \\"textarea te\\", - \\"isChecked\\": false, - \\"id\\": 37 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 5, - \\"text\\": \\"textarea tes\\", - \\"isChecked\\": false, - \\"id\\": 37 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 5, - \\"text\\": \\"textarea test\\", - \\"isChecked\\": false, - \\"id\\": 37 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 5, - \\"text\\": \\"1\\", - \\"isChecked\\": false, - \\"id\\": 42 - } - } -]" -`; - -exports[`move-node-1 1`] = ` -"[ - { - \\"type\\": 0, - \\"data\\": {} - }, - { - \\"type\\": 1, - \\"data\\": {} - }, - { - \\"type\\": 4, - \\"data\\": { - \\"href\\": \\"about:blank\\", - \\"width\\": 1920, - \\"height\\": 1080 - } - }, - { - \\"type\\": 2, - \\"data\\": { - \\"node\\": { - \\"type\\": 0, - \\"childNodes\\": [ - { - \\"type\\": 2, - \\"tagName\\": \\"html\\", - \\"attributes\\": {}, - \\"childNodes\\": [ - { - \\"type\\": 2, - \\"tagName\\": \\"head\\", - \\"attributes\\": {}, - \\"childNodes\\": [], - \\"id\\": 3 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"body\\", - \\"attributes\\": {}, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 5 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"div\\", - \\"attributes\\": {}, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 7 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"p\\", - \\"attributes\\": {}, - \\"childNodes\\": [], - \\"id\\": 8 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 9 - } - ], - \\"id\\": 6 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 10 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"span\\", - \\"attributes\\": {}, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 12 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"i\\", - \\"attributes\\": {}, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 14 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"b\\", - \\"attributes\\": {}, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"1\\", - \\"id\\": 16 - } - ], - \\"id\\": 15 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 17 - } - ], - \\"id\\": 13 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 18 - } - ], - \\"id\\": 11 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\\\n \\", - \\"id\\": 19 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"script\\", - \\"attributes\\": {}, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"SCRIPT_PLACEHOLDER\\", - \\"id\\": 21 - } - ], - \\"id\\": 20 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\\\n \\\\n\\\\n\\", - \\"id\\": 22 - } - ], - \\"id\\": 4 - } - ], - \\"id\\": 2 + \\"id\\": 2 } ], \\"id\\": 1 @@ -6280,7 +5573,6 @@ exports[`select2 1`] = ` \\"id\\": 36, \\"attributes\\": { \\"id\\": \\"select2-drop\\", - \\"style\\": \\"left: Npx; width: Npx; top: Npx; bottom: auto; display: block;\\", \\"class\\": \\"select2-drop select2-display-none select2-with-searchbox select2-drop-active\\" } }, @@ -6429,8 +5721,7 @@ exports[`select2 1`] = ` \\"tagName\\": \\"div\\", \\"attributes\\": { \\"class\\": \\"select2-drop select2-display-none select2-with-searchbox select2-drop-active\\", - \\"id\\": \\"select2-drop\\", - \\"style\\": \\"left: Npx; width: Npx; top: Npx; bottom: auto; display: block;\\" + \\"id\\": \\"select2-drop\\" }, \\"childNodes\\": [], \\"id\\": 36 @@ -6491,295 +5782,101 @@ exports[`select2 1`] = ` } }, { - \\"parentId\\": 38, - \\"nextId\\": 43, - \\"node\\": { - \\"type\\": 2, - \\"tagName\\": \\"input\\", - \\"attributes\\": { - \\"type\\": \\"text\\", - \\"autocomplete\\": \\"off\\", - \\"autocorrect\\": \\"off\\", - \\"autocapitalize\\": \\"off\\", - \\"spellcheck\\": \\"false\\", - \\"class\\": \\"select2-input select2-focused\\", - \\"role\\": \\"combobox\\", - \\"aria-expanded\\": \\"true\\", - \\"aria-autocomplete\\": \\"list\\", - \\"aria-owns\\": \\"select2-results-1\\", - \\"id\\": \\"s2id_autogen1_search\\", - \\"placeholder\\": \\"\\", - \\"aria-activedescendant\\": \\"select2-result-label-2\\" - }, - \\"childNodes\\": [], - \\"id\\": 42 - } - }, - { - \\"parentId\\": 38, - \\"nextId\\": null, - \\"node\\": { - \\"type\\": 3, - \\"textContent\\": \\" \\", - \\"id\\": 43 - } - }, - { - \\"parentId\\": 36, - \\"nextId\\": 45, - \\"node\\": { - \\"type\\": 3, - \\"textContent\\": \\" \\", - \\"id\\": 44 - } - }, - { - \\"parentId\\": 36, - \\"nextId\\": null, - \\"node\\": { - \\"type\\": 2, - \\"tagName\\": \\"ul\\", - \\"attributes\\": { - \\"class\\": \\"select2-results\\", - \\"role\\": \\"listbox\\", - \\"id\\": \\"select2-results-1\\" - }, - \\"childNodes\\": [], - \\"id\\": 45 - } - }, - { - \\"parentId\\": 45, - \\"nextId\\": null, - \\"node\\": { - \\"type\\": 2, - \\"tagName\\": \\"li\\", - \\"attributes\\": { - \\"class\\": \\"select2-results-dept-0 select2-result select2-result-selectable\\", - \\"role\\": \\"presentation\\" - }, - \\"childNodes\\": [], - \\"id\\": 67 - } - }, - { - \\"parentId\\": 67, - \\"nextId\\": null, - \\"node\\": { - \\"type\\": 2, - \\"tagName\\": \\"div\\", - \\"attributes\\": { - \\"class\\": \\"select2-result-label\\", - \\"id\\": \\"select2-result-label-3\\", - \\"role\\": \\"option\\" - }, - \\"childNodes\\": [], - \\"id\\": 68 - } - }, - { - \\"parentId\\": 68, - \\"nextId\\": null, - \\"node\\": { - \\"type\\": 3, - \\"textContent\\": \\"B\\", - \\"id\\": 69 - } - }, - { - \\"parentId\\": 18, - \\"nextId\\": 36, - \\"node\\": { - \\"type\\": 2, - \\"tagName\\": \\"div\\", - \\"attributes\\": { - \\"id\\": \\"select2-drop-mask\\", - \\"class\\": \\"select2-drop-mask\\", - \\"style\\": \\"\\" - }, - \\"childNodes\\": [], - \\"id\\": 70 - } - }, - { - \\"parentId\\": 62, - \\"nextId\\": null, - \\"node\\": { - \\"type\\": 3, - \\"textContent\\": \\"2 results are available, use up and down arrow keys to navigate.\\", - \\"id\\": 71 - } - }, - { - \\"parentId\\": 45, - \\"nextId\\": 67, - \\"node\\": { - \\"type\\": 2, - \\"tagName\\": \\"li\\", - \\"attributes\\": { - \\"class\\": \\"select2-results-dept-0 select2-result select2-result-selectable select2-highlighted\\", - \\"role\\": \\"presentation\\" - }, - \\"childNodes\\": [], - \\"id\\": 72 - } - }, - { - \\"parentId\\": 72, - \\"nextId\\": null, - \\"node\\": { - \\"type\\": 2, - \\"tagName\\": \\"div\\", - \\"attributes\\": { - \\"class\\": \\"select2-result-label\\", - \\"id\\": \\"select2-result-label-2\\", - \\"role\\": \\"option\\" - }, - \\"childNodes\\": [], - \\"id\\": 73 - } - }, - { - \\"parentId\\": 73, - \\"nextId\\": null, - \\"node\\": { - \\"type\\": 3, - \\"textContent\\": \\"A\\", - \\"id\\": 74 - } - }, - { - \\"parentId\\": 73, - \\"nextId\\": 74, - \\"node\\": { - \\"type\\": 2, - \\"tagName\\": \\"span\\", - \\"attributes\\": { - \\"class\\": \\"select2-match\\" - }, - \\"childNodes\\": [], - \\"id\\": 75 - } - }, - { - \\"parentId\\": 68, - \\"nextId\\": 69, - \\"node\\": { - \\"type\\": 2, - \\"tagName\\": \\"span\\", - \\"attributes\\": { - \\"class\\": \\"select2-match\\" - }, - \\"childNodes\\": [], - \\"id\\": 76 - } - } - ] - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 2, - \\"type\\": 0, - \\"id\\": 70 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 5, - \\"text\\": \\"\\", - \\"isChecked\\": false, - \\"id\\": 42 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 5, - \\"text\\": \\"\\", - \\"isChecked\\": false, - \\"id\\": 35 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 2, - \\"type\\": 1, - \\"id\\": 70 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 2, - \\"type\\": 6, - \\"id\\": 42 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 2, - \\"type\\": 5, - \\"id\\": 35 - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 0, - \\"texts\\": [], - \\"attributes\\": [ - { - \\"id\\": 70, - \\"attributes\\": { - \\"style\\": \\"display: none;\\" - } - }, - { - \\"id\\": 36, - \\"attributes\\": { - \\"id\\": null, - \\"style\\": \\"left: Npx; width: Npx; top: Npx; bottom: auto; display: none;\\" + \\"parentId\\": 38, + \\"nextId\\": 43, + \\"node\\": { + \\"type\\": 2, + \\"tagName\\": \\"input\\", + \\"attributes\\": { + \\"type\\": \\"text\\", + \\"autocomplete\\": \\"off\\", + \\"autocorrect\\": \\"off\\", + \\"autocapitalize\\": \\"off\\", + \\"spellcheck\\": \\"false\\", + \\"class\\": \\"select2-input select2-focused\\", + \\"role\\": \\"combobox\\", + \\"aria-expanded\\": \\"true\\", + \\"aria-autocomplete\\": \\"list\\", + \\"aria-owns\\": \\"select2-results-1\\", + \\"id\\": \\"s2id_autogen1_search\\", + \\"placeholder\\": \\"\\", + \\"aria-activedescendant\\": \\"select2-result-label-2\\" + }, + \\"childNodes\\": [], + \\"id\\": 42 } }, { - \\"id\\": 25, - \\"attributes\\": { - \\"class\\": \\"select2-container select2-container-active\\" + \\"parentId\\": 38, + \\"nextId\\": null, + \\"node\\": { + \\"type\\": 3, + \\"textContent\\": \\" \\", + \\"id\\": 43 } }, { - \\"id\\": 35, - \\"attributes\\": { - \\"disabled\\": null + \\"parentId\\": 36, + \\"nextId\\": 45, + \\"node\\": { + \\"type\\": 3, + \\"textContent\\": \\" \\", + \\"id\\": 44 } }, { - \\"id\\": 42, - \\"attributes\\": { - \\"class\\": \\"select2-input\\" + \\"parentId\\": 36, + \\"nextId\\": null, + \\"node\\": { + \\"type\\": 2, + \\"tagName\\": \\"ul\\", + \\"attributes\\": { + \\"class\\": \\"select2-results\\", + \\"role\\": \\"listbox\\", + \\"id\\": \\"select2-results-1\\" + }, + \\"childNodes\\": [], + \\"id\\": 45 } - } - ], - \\"removes\\": [ - { - \\"parentId\\": 18, - \\"id\\": 70 }, { \\"parentId\\": 45, - \\"id\\": 72 + \\"nextId\\": null, + \\"node\\": { + \\"type\\": 2, + \\"tagName\\": \\"li\\", + \\"attributes\\": { + \\"class\\": \\"select2-results-dept-0 select2-result select2-result-selectable\\", + \\"role\\": \\"presentation\\" + }, + \\"childNodes\\": [], + \\"id\\": 67 + } }, { - \\"parentId\\": 45, - \\"id\\": 67 - } - ], - \\"adds\\": [ + \\"parentId\\": 67, + \\"nextId\\": null, + \\"node\\": { + \\"type\\": 2, + \\"tagName\\": \\"div\\", + \\"attributes\\": { + \\"class\\": \\"select2-result-label\\", + \\"id\\": \\"select2-result-label-3\\", + \\"role\\": \\"option\\" + }, + \\"childNodes\\": [], + \\"id\\": 68 + } + }, + { + \\"parentId\\": 68, + \\"nextId\\": null, + \\"node\\": { + \\"type\\": 3, + \\"textContent\\": \\"B\\", + \\"id\\": 69 + } + }, { \\"parentId\\": 18, \\"nextId\\": 36, @@ -6789,321 +5886,254 @@ exports[`select2 1`] = ` \\"attributes\\": { \\"id\\": \\"select2-drop-mask\\", \\"class\\": \\"select2-drop-mask\\", - \\"style\\": \\"display: none;\\" + \\"style\\": \\"\\" }, \\"childNodes\\": [], \\"id\\": 70 } - } - ] - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 2, - \\"type\\": 0, - \\"id\\": 26 - } - } -]" -`; - -exports[`serialize-before-record 1`] = ` -"[ - { - \\"type\\": 0, - \\"data\\": {} - }, - { - \\"type\\": 1, - \\"data\\": {} - }, - { - \\"type\\": 4, - \\"data\\": { - \\"href\\": \\"about:blank\\", - \\"width\\": 1920, - \\"height\\": 1080 - } - }, - { - \\"type\\": 2, - \\"data\\": { - \\"node\\": { - \\"type\\": 0, - \\"childNodes\\": [ - { - \\"type\\": 2, - \\"tagName\\": \\"html\\", - \\"attributes\\": {}, - \\"childNodes\\": [ - { - \\"type\\": 2, - \\"tagName\\": \\"head\\", - \\"attributes\\": {}, - \\"childNodes\\": [], - \\"id\\": 3 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"body\\", - \\"attributes\\": {}, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 5 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"p\\", - \\"attributes\\": {}, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"mutation observer\\", - \\"id\\": 7 - } - ], - \\"id\\": 6 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 8 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"ul\\", - \\"attributes\\": {}, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 10 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"li\\", - \\"attributes\\": {}, - \\"childNodes\\": [], - \\"id\\": 11 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 12 - } - ], - \\"id\\": 9 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n\\\\n \\", - \\"id\\": 13 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"script\\", - \\"attributes\\": {}, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"SCRIPT_PLACEHOLDER\\", - \\"id\\": 15 - } - ], - \\"id\\": 14 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\\\n \\", - \\"id\\": 16 - } - ], - \\"id\\": 4 - } - ], - \\"id\\": 2 - } - ], - \\"id\\": 1 - }, - \\"initialOffset\\": { - \\"left\\": 0, - \\"top\\": 0 - } - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 0, - \\"texts\\": [], - \\"attributes\\": [], - \\"removes\\": [], - \\"adds\\": [ + }, { - \\"parentId\\": 9, + \\"parentId\\": 62, \\"nextId\\": null, + \\"node\\": { + \\"type\\": 3, + \\"textContent\\": \\"2 results are available, use up and down arrow keys to navigate.\\", + \\"id\\": 71 + } + }, + { + \\"parentId\\": 45, + \\"nextId\\": 67, \\"node\\": { \\"type\\": 2, \\"tagName\\": \\"li\\", - \\"attributes\\": {}, + \\"attributes\\": { + \\"class\\": \\"select2-results-dept-0 select2-result select2-result-selectable select2-highlighted\\", + \\"role\\": \\"presentation\\" + }, \\"childNodes\\": [], - \\"id\\": 17 + \\"id\\": 72 } }, { - \\"parentId\\": 9, - \\"nextId\\": 17, + \\"parentId\\": 72, + \\"nextId\\": null, \\"node\\": { \\"type\\": 2, - \\"tagName\\": \\"li\\", - \\"attributes\\": {}, + \\"tagName\\": \\"div\\", + \\"attributes\\": { + \\"class\\": \\"select2-result-label\\", + \\"id\\": \\"select2-result-label-2\\", + \\"role\\": \\"option\\" + }, \\"childNodes\\": [], - \\"id\\": 18 + \\"id\\": 73 } }, { - \\"parentId\\": 9, - \\"nextId\\": 18, + \\"parentId\\": 73, + \\"nextId\\": null, + \\"node\\": { + \\"type\\": 3, + \\"textContent\\": \\"A\\", + \\"id\\": 74 + } + }, + { + \\"parentId\\": 73, + \\"nextId\\": 74, \\"node\\": { \\"type\\": 2, - \\"tagName\\": \\"li\\", - \\"attributes\\": {}, + \\"tagName\\": \\"span\\", + \\"attributes\\": { + \\"class\\": \\"select2-match\\" + }, \\"childNodes\\": [], - \\"id\\": 19 + \\"id\\": 75 + } + }, + { + \\"parentId\\": 68, + \\"nextId\\": 69, + \\"node\\": { + \\"type\\": 2, + \\"tagName\\": \\"span\\", + \\"attributes\\": { + \\"class\\": \\"select2-match\\" + }, + \\"childNodes\\": [], + \\"id\\": 76 } } ] } - } -]" -`; - -exports[`shadow-dom 1`] = ` -"[ + }, { - \\"type\\": 0, - \\"data\\": {} + \\"type\\": 3, + \\"data\\": { + \\"source\\": 2, + \\"type\\": 0, + \\"id\\": 70 + } }, { - \\"type\\": 1, - \\"data\\": {} + \\"type\\": 3, + \\"data\\": { + \\"source\\": 5, + \\"text\\": \\"\\", + \\"isChecked\\": false, + \\"id\\": 42 + } }, { - \\"type\\": 4, + \\"type\\": 3, \\"data\\": { - \\"href\\": \\"about:blank\\", - \\"width\\": 1920, - \\"height\\": 1080 + \\"source\\": 5, + \\"text\\": \\"\\", + \\"isChecked\\": false, + \\"id\\": 35 } }, { - \\"type\\": 2, + \\"type\\": 3, \\"data\\": { - \\"node\\": { - \\"type\\": 0, - \\"childNodes\\": [ - { - \\"type\\": 1, - \\"name\\": \\"html\\", - \\"publicId\\": \\"\\", - \\"systemId\\": \\"\\", - \\"id\\": 2 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"html\\", - \\"attributes\\": { - \\"lang\\": \\"en\\" - }, - \\"childNodes\\": [ - { - \\"type\\": 2, - \\"tagName\\": \\"head\\", - \\"attributes\\": {}, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 5 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"meta\\", - \\"attributes\\": { - \\"charset\\": \\"UTF-8\\" - }, - \\"childNodes\\": [], - \\"id\\": 6 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 7 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"meta\\", - \\"attributes\\": { - \\"name\\": \\"viewport\\", - \\"content\\": \\"width=device-width, initial-scale=1.0\\" - }, - \\"childNodes\\": [], - \\"id\\": 8 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 9 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"title\\", - \\"attributes\\": {}, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"Shadow DOM Observer\\", - \\"id\\": 11 - } - ], - \\"id\\": 10 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 12 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"style\\", - \\"attributes\\": {}, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n .my-element {\\\\n margin: 0 0 1rem 0;\\\\n }\\\\n iframe {\\\\n border: 0;\\\\n width: 100%;\\\\n padding: 0;\\\\n }\\\\n\\\\n body {\\\\n max-width: 400px;\\\\n margin: 1rem auto;\\\\n padding: 0 1rem;\\\\n font-family: 'comic sans ms';\\\\n }\\\\n \\", - \\"isStyle\\": true, - \\"id\\": 14 - } - ], - \\"id\\": 13 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 15 - } - ], - \\"id\\": 4 - }, + \\"source\\": 2, + \\"type\\": 1, + \\"id\\": 70 + } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 2, + \\"type\\": 6, + \\"id\\": 42 + } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 2, + \\"type\\": 5, + \\"id\\": 35 + } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 0, + \\"texts\\": [], + \\"attributes\\": [ + { + \\"id\\": 70, + \\"attributes\\": { + \\"style\\": \\"display: none;\\" + } + }, + { + \\"id\\": 36, + \\"attributes\\": { + \\"id\\": null + } + }, + { + \\"id\\": 25, + \\"attributes\\": { + \\"class\\": \\"select2-container select2-container-active\\" + } + }, + { + \\"id\\": 35, + \\"attributes\\": { + \\"disabled\\": null + } + }, + { + \\"id\\": 42, + \\"attributes\\": { + \\"class\\": \\"select2-input\\" + } + } + ], + \\"removes\\": [ + { + \\"parentId\\": 18, + \\"id\\": 70 + }, + { + \\"parentId\\": 45, + \\"id\\": 72 + }, + { + \\"parentId\\": 45, + \\"id\\": 67 + } + ], + \\"adds\\": [ + { + \\"parentId\\": 18, + \\"nextId\\": 36, + \\"node\\": { + \\"type\\": 2, + \\"tagName\\": \\"div\\", + \\"attributes\\": { + \\"id\\": \\"select2-drop-mask\\", + \\"class\\": \\"select2-drop-mask\\", + \\"style\\": \\"display: none;\\" + }, + \\"childNodes\\": [], + \\"id\\": 70 + } + } + ] + } + }, + { + \\"type\\": 3, + \\"data\\": { + \\"source\\": 2, + \\"type\\": 0, + \\"id\\": 26 + } + } +]" +`; + +exports[`serialize-before-record 1`] = ` +"[ + { + \\"type\\": 0, + \\"data\\": {} + }, + { + \\"type\\": 1, + \\"data\\": {} + }, + { + \\"type\\": 4, + \\"data\\": { + \\"href\\": \\"about:blank\\", + \\"width\\": 1920, + \\"height\\": 1080 + } + }, + { + \\"type\\": 2, + \\"data\\": { + \\"node\\": { + \\"type\\": 0, + \\"childNodes\\": [ + { + \\"type\\": 2, + \\"tagName\\": \\"html\\", + \\"attributes\\": {}, + \\"childNodes\\": [ { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 16 + \\"type\\": 2, + \\"tagName\\": \\"head\\", + \\"attributes\\": {}, + \\"childNodes\\": [], + \\"id\\": 3 }, { \\"type\\": 2, @@ -7112,8 +6142,8 @@ exports[`shadow-dom 1`] = ` \\"childNodes\\": [ { \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 18 + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 5 }, { \\"type\\": 2, @@ -7122,130 +6152,46 @@ exports[`shadow-dom 1`] = ` \\"childNodes\\": [ { \\"type\\": 3, - \\"textContent\\": \\"\\\\n Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellat odit\\\\n officiis necessitatibus laborum asperiores et adipisci dolores corporis,\\\\n vero distinctio voluptas, suscipit commodi architecto, aliquam fugit.\\\\n Nesciunt labore reiciendis blanditiis!\\\\n \\", - \\"id\\": 20 + \\"textContent\\": \\"mutation observer\\", + \\"id\\": 7 } ], - \\"id\\": 19 + \\"id\\": 6 }, { \\"type\\": 3, - \\"textContent\\": \\"\\\\n\\\\n \\", - \\"id\\": 21 + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 8 }, { \\"type\\": 2, - \\"tagName\\": \\"div\\", - \\"attributes\\": { - \\"class\\": \\"my-element\\" - }, + \\"tagName\\": \\"ul\\", + \\"attributes\\": {}, \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 23 - }, - { - \\"type\\": 5, - \\"textContent\\": \\" Also could be a \\\\n \\\\n \\", - \\"id\\": 24 - }, { \\"type\\": 3, \\"textContent\\": \\"\\\\n \\", - \\"id\\": 25 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 26, - \\"isShadow\\": true - }, - { - \\"type\\": 2, - \\"tagName\\": \\"style\\", - \\"attributes\\": {}, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n body { /* for fallback iframe */\\\\n margin: 0;\\\\n }\\\\n p { \\\\n border: 1px solid #ccc;\\\\n padding: 1rem;\\\\n color: red;\\\\n font-family: sans-serif;\\\\n }\\\\n \\", - \\"isStyle\\": true, - \\"id\\": 28 - } - ], - \\"id\\": 27, - \\"isShadow\\": true - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n\\\\n \\", - \\"id\\": 29, - \\"isShadow\\": true + \\"id\\": 10 }, { \\"type\\": 2, - \\"tagName\\": \\"p\\", + \\"tagName\\": \\"li\\", \\"attributes\\": {}, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"Element with Shadow DOM\\", - \\"id\\": 31 - } - ], - \\"id\\": 30, - \\"isShadow\\": true + \\"childNodes\\": [], + \\"id\\": 11 }, { \\"type\\": 3, - \\"textContent\\": \\"\\\\n\\", - \\"id\\": 32, - \\"isShadow\\": true + \\"textContent\\": \\"\\\\n \\", + \\"id\\": 12 } ], - \\"id\\": 22, - \\"isShadowHost\\": true + \\"id\\": 9 }, { \\"type\\": 3, \\"textContent\\": \\"\\\\n\\\\n \\", - \\"id\\": 33 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"p\\", - \\"attributes\\": {}, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellat odit\\\\n officiis necessitatibus laborum asperiores et adipisci dolores corporis,\\\\n vero distinctio voluptas, suscipit commodi architecto, aliquam fugit.\\\\n Nesciunt labore reiciendis blanditiis!\\\\n \\", - \\"id\\": 35 - } - ], - \\"id\\": 34 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\", - \\"id\\": 36 - }, - { - \\"type\\": 2, - \\"tagName\\": \\"script\\", - \\"attributes\\": {}, - \\"childNodes\\": [ - { - \\"type\\": 3, - \\"textContent\\": \\"SCRIPT_PLACEHOLDER\\", - \\"id\\": 38 - } - ], - \\"id\\": 37 - }, - { - \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\\\n \\\\n \\", - \\"id\\": 39 + \\"id\\": 13 }, { \\"type\\": 2, @@ -7255,21 +6201,21 @@ exports[`shadow-dom 1`] = ` { \\"type\\": 3, \\"textContent\\": \\"SCRIPT_PLACEHOLDER\\", - \\"id\\": 41 + \\"id\\": 15 } ], - \\"id\\": 40 + \\"id\\": 14 }, { \\"type\\": 3, - \\"textContent\\": \\"\\\\n \\\\n \\\\n\\\\n\\", - \\"id\\": 42 + \\"textContent\\": \\"\\\\n \\\\n \\", + \\"id\\": 16 } ], - \\"id\\": 17 + \\"id\\": 4 } ], - \\"id\\": 3 + \\"id\\": 2 } ], \\"id\\": 1 @@ -7289,98 +6235,36 @@ exports[`shadow-dom 1`] = ` \\"removes\\": [], \\"adds\\": [ { - \\"parentId\\": 22, + \\"parentId\\": 9, \\"nextId\\": null, \\"node\\": { \\"type\\": 2, - \\"tagName\\": \\"p\\", + \\"tagName\\": \\"li\\", \\"attributes\\": {}, \\"childNodes\\": [], - \\"id\\": 43, - \\"isShadow\\": true + \\"id\\": 17 } - } - ] - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 0, - \\"texts\\": [], - \\"attributes\\": [], - \\"removes\\": [], - \\"adds\\": [ + }, { - \\"parentId\\": 43, - \\"nextId\\": null, + \\"parentId\\": 9, + \\"nextId\\": 17, \\"node\\": { \\"type\\": 2, - \\"tagName\\": \\"p\\", + \\"tagName\\": \\"li\\", \\"attributes\\": {}, \\"childNodes\\": [], - \\"id\\": 44 - } - } - ] - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 0, - \\"texts\\": [], - \\"attributes\\": [], - \\"removes\\": [ - { - \\"parentId\\": 22, - \\"id\\": 30, - \\"isShadow\\": true - } - ], - \\"adds\\": [] - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 0, - \\"texts\\": [], - \\"attributes\\": [], - \\"removes\\": [], - \\"adds\\": [ - { - \\"parentId\\": 44, - \\"nextId\\": null, - \\"node\\": { - \\"type\\": 3, - \\"textContent\\": \\"hi\\", - \\"id\\": 45 + \\"id\\": 18 } - } - ] - } - }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 0, - \\"texts\\": [], - \\"attributes\\": [], - \\"removes\\": [ - { - \\"parentId\\": 44, - \\"id\\": 45 - } - ], - \\"adds\\": [ + }, { - \\"parentId\\": 44, - \\"nextId\\": null, + \\"parentId\\": 9, + \\"nextId\\": 18, \\"node\\": { - \\"type\\": 3, - \\"textContent\\": \\"123\\", - \\"id\\": 46 + \\"type\\": 2, + \\"tagName\\": \\"li\\", + \\"attributes\\": {}, + \\"childNodes\\": [], + \\"id\\": 19 } } ] diff --git a/test/events/style-sheet-rule-events.ts b/test/events/style-sheet-rule-events.ts index 5740f502..e0e9682e 100644 --- a/test/events/style-sheet-rule-events.ts +++ b/test/events/style-sheet-rule-events.ts @@ -1,4 +1,8 @@ -import { EventType, eventWithTime, IncrementalSource } from '../../src/types'; +import { + EventType, + eventWithTime, + IncrementalSource +} from '../../src/types'; const now = Date.now(); const events: eventWithTime[] = [ @@ -23,124 +27,68 @@ 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: [ + "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": [ { - 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": 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: 107, - type: 2, - tagName: 'body', - attributes: {}, - childNodes: [], - }, - ], - }, - ], - }, - initialOffset: { top: 0, left: 0 }, + "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 } }, - 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; \ No newline at end of file diff --git a/test/html/frame1.html b/test/html/frame1.html deleted file mode 100644 index 8810af46..00000000 --- a/test/html/frame1.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - Frame 1 - - - frame 1 - - - - diff --git a/test/html/frame2.html b/test/html/frame2.html deleted file mode 100644 index 6344438c..00000000 --- a/test/html/frame2.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - Frame 2 - - - frame 2 - - - diff --git a/test/html/main.html b/test/html/main.html deleted file mode 100644 index a37d9bea..00000000 --- a/test/html/main.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - Main - - - - - - - diff --git a/test/html/shadow-dom.html b/test/html/shadow-dom.html deleted file mode 100644 index bf4c6837..00000000 --- a/test/html/shadow-dom.html +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - Shadow DOM Observer - - - -

- Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellat odit - officiis necessitatibus laborum asperiores et adipisci dolores corporis, - vero distinctio voluptas, suscipit commodi architecto, aliquam fugit. - Nesciunt labore reiciendis blanditiis! -

- -
- -
- -

- Lorem ipsum dolor sit amet, consectetur adipisicing elit. Repellat odit - officiis necessitatibus laborum asperiores et adipisci dolores corporis, - vero distinctio voluptas, suscipit commodi architecto, aliquam fugit. - Nesciunt labore reiciendis blanditiis! -

- - - - diff --git a/test/integration.test.ts b/test/integration.test.ts index f0eddb5b..68c4e3ad 100644 --- a/test/integration.test.ts +++ b/test/integration.test.ts @@ -1,7 +1,5 @@ import * as fs from 'fs'; import * as path from 'path'; -import * as http from 'http'; -import * as url from 'url'; import * as puppeteer from 'puppeteer'; import { assertSnapshot, launchPuppeteer } from './utils'; import { Suite } from 'mocha'; @@ -10,48 +8,10 @@ import { recordOptions, eventWithTime, EventType } from '../src/types'; import { visitSnapshot, NodeType } from '../src/snapshot'; interface ISuite extends Suite { - server: http.Server; code: string; browser: puppeteer.Browser; } -interface IMimeType { - [key: string]: string; -} - -const server = () => - new Promise((resolve) => { - const mimeType: IMimeType = { - '.html': 'text/html', - '.js': 'text/javascript', - '.css': 'text/css', - }; - const s = http.createServer((req, res) => { - const parsedUrl = url.parse(req.url!); - const sanitizePath = path - .normalize(parsedUrl.pathname!) - .replace(/^(\.\.[\/\\])+/, ''); - let pathname = path.join(__dirname, sanitizePath); - try { - const data = fs.readFileSync(pathname); - const ext = path.parse(pathname).ext; - res.setHeader('Content-type', mimeType[ext] || 'text/plain'); - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Access-Control-Allow-Methods', 'GET'); - res.setHeader('Access-Control-Allow-Headers', 'Content-type'); - setTimeout(() => { - res.end(data); - // mock delay - }, 100); - } catch (error) { - res.end(); - } - }); - s.listen(3030).on('listening', () => { - resolve(s); - }); - }); - describe('record integration tests', function (this: ISuite) { this.timeout(10_000); @@ -84,7 +44,6 @@ describe('record integration tests', function (this: ISuite) { }; before(async () => { - this.server = await server(); this.browser = await launchPuppeteer(); const bundlePath = path.resolve(__dirname, '../dist/rrweb.min.js'); @@ -93,7 +52,6 @@ describe('record integration tests', function (this: ISuite) { after(async () => { await this.browser.close(); - this.server.close(); }); it('can record form interactions', async () => { @@ -409,51 +367,4 @@ describe('record integration tests', function (this: ISuite) { const snapshots = await page.evaluate('window.snapshots'); assertSnapshot(snapshots, __filename, 'log'); }); - - it('should nest record iframe', async () => { - const page: puppeteer.Page = await this.browser.newPage(); - await page.goto(`http://localhost:3030/html`); - await page.setContent(getHtml.call(this, 'main.html')); - - await page.waitFor(500); - const snapshots = await page.evaluate('window.snapshots'); - assertSnapshot(snapshots, __filename, 'iframe'); - }); - - it('should record shadow DOM', async () => { - const page: puppeteer.Page = await this.browser.newPage(); - await page.goto('about:blank'); - await page.setContent(getHtml.call(this, 'shadow-dom.html')); - - await page.evaluate(() => { - const sleep = (ms: number) => - new Promise((resolve) => setTimeout(resolve, ms)); - - const el = document.querySelector('.my-element') as HTMLDivElement; - const shadowRoot = el.shadowRoot as ShadowRoot; - shadowRoot.appendChild(document.createElement('p')); - sleep(1) - .then(() => { - shadowRoot.lastChild!.appendChild(document.createElement('p')); - return sleep(1); - }) - .then(() => { - const firstP = shadowRoot.querySelector('p') as HTMLParagraphElement; - shadowRoot.removeChild(firstP); - return sleep(1); - }) - .then(() => { - (shadowRoot.lastChild!.childNodes[0] as HTMLElement).innerText = 'hi'; - return sleep(1); - }) - .then(() => { - (shadowRoot.lastChild!.childNodes[0] as HTMLElement).innerText = - '123'; - }); - }); - await page.waitFor(50); - - const snapshots = await page.evaluate('window.snapshots'); - assertSnapshot(snapshots, __filename, 'shadow-dom'); - }); }); diff --git a/test/replayer.test.ts b/test/replayer.test.ts index e61c3d37..af7a3243 100644 --- a/test/replayer.test.ts +++ b/test/replayer.test.ts @@ -8,7 +8,7 @@ import { Suite } from 'mocha'; import { launchPuppeteer, sampleEvents as events, - sampleStyleSheetRemoveEvents as stylesheetRemoveEvents, + sampleStyleSheetRemoveEvents as stylesheetRemoveEvents } from './utils'; import styleSheetRuleEvents from './events/style-sheet-rule-events'; @@ -127,19 +127,17 @@ describe('replayer', function (this: ISuite) { `); const currentTime = await this.page.evaluate(` replayer.getCurrentTime(); - `); + `) const currentState = await this.page.evaluate(` replayer['service']['state']['value']; - `); - expect(actionLength).to.equal(0); + `) + expect(actionLength).to.equal(0) expect(currentTime).to.equal(2500); expect(currentState).to.equal('paused'); }); it('can fast forward past StyleSheetRule changes on virtual elements', async () => { - await this.page.evaluate( - `events = ${JSON.stringify(styleSheetRuleEvents)}`, - ); + await this.page.evaluate(`events = ${JSON.stringify(styleSheetRuleEvents)}`); const actionLength = await this.page.evaluate(` const { Replayer } = rrweb; const replayer = new Replayer(events); @@ -147,16 +145,12 @@ describe('replayer', function (this: ISuite) { replayer['timer']['actions'].length; `); expect(actionLength).to.equal( - styleSheetRuleEvents.filter( - (e) => e.timestamp - styleSheetRuleEvents[0].timestamp >= 1500, - ).length, + styleSheetRuleEvents.filter((e) => e.timestamp - styleSheetRuleEvents[0].timestamp >= 1500).length, ); }); it('can handle removing style elements', async () => { - await this.page.evaluate( - `events = ${JSON.stringify(stylesheetRemoveEvents)}`, - ); + await this.page.evaluate(`events = ${JSON.stringify(stylesheetRemoveEvents)}`); const actionLength = await this.page.evaluate(` const { Replayer } = rrweb; const replayer = new Replayer(events); @@ -164,9 +158,7 @@ describe('replayer', function (this: ISuite) { replayer['timer']['actions'].length; `); expect(actionLength).to.equal( - stylesheetRemoveEvents.filter( - (e) => e.timestamp - stylesheetRemoveEvents[0].timestamp >= 2500, - ).length, + stylesheetRemoveEvents.filter((e) => e.timestamp - stylesheetRemoveEvents[0].timestamp >= 2500).length, ); }); diff --git a/test/utils.ts b/test/utils.ts index ebf079f8..b83ee31e 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -61,7 +61,7 @@ function stringifySnapshots(snapshots: eventWithTime[]): string { s.data.href = 'about:blank'; } // FIXME: travis coordinates seems different with my laptop - const coordinatesReg = /(bottom|top|left|right|width|height): \d+(\.\d+)?px/g + const coordinatesReg = /(bottom|top|left|right)/; if ( s.type === EventType.IncrementalSnapshot && s.data.source === IncrementalSource.MouseInteraction @@ -78,7 +78,7 @@ function stringifySnapshots(snapshots: eventWithTime[]): string { 'style' in a.attributes && coordinatesReg.test(a.attributes.style!) ) { - a.attributes.style = a.attributes.style!.replace(coordinatesReg, '$1: Npx'); + delete a.attributes.style; } }); s.data.adds.forEach((add) => { @@ -88,7 +88,7 @@ function stringifySnapshots(snapshots: eventWithTime[]): string { typeof add.node.attributes.style === 'string' && coordinatesReg.test(add.node.attributes.style) ) { - add.node.attributes.style = add.node.attributes.style.replace(coordinatesReg, '$1: Npx'); + delete add.node.attributes.style; } }); } diff --git a/typings/record/iframe-manager.d.ts b/typings/record/iframe-manager.d.ts deleted file mode 100644 index 4300a7ab..00000000 --- a/typings/record/iframe-manager.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { serializedNodeWithId, INode } from 'rrweb-snapshot'; -import { mutationCallBack } from '../types'; -export declare class IframeManager { - private iframes; - private mutationCb; - private loadListener?; - constructor(options: { - mutationCb: mutationCallBack; - }); - addIframe(iframeEl: HTMLIFrameElement): void; - addLoadListener(cb: (iframeEl: HTMLIFrameElement) => unknown): void; - attachIframe(iframeEl: INode, childSn: serializedNodeWithId): void; -} diff --git a/typings/record/mutation.d.ts b/typings/record/mutation.d.ts index abd3aeb0..3584a0ff 100644 --- a/typings/record/mutation.d.ts +++ b/typings/record/mutation.d.ts @@ -1,9 +1,7 @@ import { MaskInputOptions, SlimDOMOptions } from '../snapshot'; import { mutationRecord, blockClass, mutationCallBack } from '../types'; -import { IframeManager } from './iframe-manager'; export default class MutationBuffer { private frozen; - private locked; private texts; private attributes; private removes; @@ -20,14 +18,10 @@ export default class MutationBuffer { private recordCanvas; private enableStrictPrivacy; private slimDOMOptions; - private doc; - private iframeManager; - init(cb: mutationCallBack, blockClass: blockClass, blockSelector: string | null, inlineStylesheet: boolean, maskInputOptions: MaskInputOptions, recordCanvas: boolean, slimDOMOptions: SlimDOMOptions, doc: Document, iframeManager: IframeManager, enableStrictPrivacy: boolean): void; + init(cb: mutationCallBack, blockClass: blockClass, blockSelector: string | null, inlineStylesheet: boolean, maskInputOptions: MaskInputOptions, recordCanvas: boolean, slimDOMOptions: SlimDOMOptions, enableStrictPrivacy: boolean): void; freeze(): void; unfreeze(): void; isFrozen(): boolean; - lock(): void; - unlock(): void; processMutations: (mutations: mutationRecord[]) => void; emit: () => void; private processMutation; diff --git a/typings/record/observer.d.ts b/typings/record/observer.d.ts index 60eb7178..99587378 100644 --- a/typings/record/observer.d.ts +++ b/typings/record/observer.d.ts @@ -1,5 +1,5 @@ import { observerParam, listenerHandler, hooksParam } from '../types'; import MutationBuffer from './mutation'; -export declare const mutationBuffers: MutationBuffer[]; +export declare const mutationBuffer: MutationBuffer; export declare const INPUT_TAGS: string[]; export declare function initObservers(o: observerParam, hooks?: hooksParam): listenerHandler; diff --git a/typings/replay/index.d.ts b/typings/replay/index.d.ts index e7fb59a1..696cadfd 100644 --- a/typings/replay/index.d.ts +++ b/typings/replay/index.d.ts @@ -20,7 +20,6 @@ export declare class Replayer { private fragmentParentMap; private elementStateMap; private imageMap; - private newDocumentQueue; constructor(events: Array, config?: Partial); on(event: string, handler: Handler): this; setConfig(config: Partial): void; @@ -40,9 +39,6 @@ export declare class Replayer { private getCastFn; private handleInactivity; private rebuildFullSnapshot; - private insertStyleRules; - private attachDocumentToIframe; - private collectIframeAndAttachDocument; private waitForStylesheetLoad; private preloadAllImages; private applyIncremental; diff --git a/typings/types.d.ts b/typings/types.d.ts index 0b44d0c8..4a0f4cc8 100644 --- a/typings/types.d.ts +++ b/typings/types.d.ts @@ -1,503 +1,433 @@ /// -import { - serializedNodeWithId, - idNodeMap, - INode, - MaskInputOptions, - SlimDOMOptions, -} from './snapshot'; +import { serializedNodeWithId, idNodeMap, INode, MaskInputOptions, SlimDOMOptions } from './snapshot'; import { PackFn, UnpackFn } from './packer/base'; import { FontFaceDescriptors } from 'css-font-loading-module'; -import { IframeManager } from './record/iframe-manager'; export declare enum EventType { - DomContentLoaded = 0, - Load = 1, - FullSnapshot = 2, - IncrementalSnapshot = 3, - Meta = 4, - Custom = 5, + DomContentLoaded = 0, + Load = 1, + FullSnapshot = 2, + IncrementalSnapshot = 3, + Meta = 4, + Custom = 5 } export declare type SessionInterval = { - startTime: number; - endTime: number; - duration: number; - active: boolean; + startTime: number; + endTime: number; + duration: number; + active: boolean; }; export declare type domContentLoadedEvent = { - type: EventType.DomContentLoaded; - data: {}; + type: EventType.DomContentLoaded; + data: {}; }; export declare type loadedEvent = { - type: EventType.Load; - data: {}; + type: EventType.Load; + data: {}; }; export declare type fullSnapshotEvent = { - type: EventType.FullSnapshot; - data: { - node: serializedNodeWithId; - initialOffset: { - top: number; - left: number; + type: EventType.FullSnapshot; + data: { + node: serializedNodeWithId; + initialOffset: { + top: number; + left: number; + }; }; - }; }; export declare type incrementalSnapshotEvent = { - type: EventType.IncrementalSnapshot; - data: incrementalData; + type: EventType.IncrementalSnapshot; + data: incrementalData; }; export declare type metaEvent = { - type: EventType.Meta; - data: { - href: string; - width: number; - height: number; - }; + type: EventType.Meta; + data: { + href: string; + width: number; + height: number; + }; }; export declare type logEvent = { - type: EventType.IncrementalSnapshot; - data: incrementalData; + type: EventType.IncrementalSnapshot; + data: incrementalData; }; export declare type customEvent = { - type: EventType.Custom; - data: { - tag: string; - payload: T; - }; + type: EventType.Custom; + data: { + tag: string; + payload: T; + }; }; export declare type styleSheetEvent = {}; export declare enum IncrementalSource { - Mutation = 0, - MouseMove = 1, - MouseInteraction = 2, - Scroll = 3, - ViewportResize = 4, - Input = 5, - TouchMove = 6, - MediaInteraction = 7, - StyleSheetRule = 8, - CanvasMutation = 9, - Font = 10, - Log = 11, + Mutation = 0, + MouseMove = 1, + MouseInteraction = 2, + Scroll = 3, + ViewportResize = 4, + Input = 5, + TouchMove = 6, + MediaInteraction = 7, + StyleSheetRule = 8, + CanvasMutation = 9, + Font = 10, + Log = 11 } export declare type mutationData = { - source: IncrementalSource.Mutation; + source: IncrementalSource.Mutation; } & mutationCallbackParam; export declare type mousemoveData = { - source: IncrementalSource.MouseMove | IncrementalSource.TouchMove; - positions: mousePosition[]; + source: IncrementalSource.MouseMove | IncrementalSource.TouchMove; + positions: mousePosition[]; }; export declare type mouseInteractionData = { - source: IncrementalSource.MouseInteraction; + source: IncrementalSource.MouseInteraction; } & mouseInteractionParam; export declare type scrollData = { - source: IncrementalSource.Scroll; + source: IncrementalSource.Scroll; } & scrollPosition; export declare type viewportResizeData = { - source: IncrementalSource.ViewportResize; -} & viewportResizeDimension; + source: IncrementalSource.ViewportResize; +} & viewportResizeDimention; export declare type inputData = { - source: IncrementalSource.Input; - id: number; + source: IncrementalSource.Input; + id: number; } & inputValue; export declare type mediaInteractionData = { - source: IncrementalSource.MediaInteraction; + source: IncrementalSource.MediaInteraction; } & mediaInteractionParam; export declare type styleSheetRuleData = { - source: IncrementalSource.StyleSheetRule; + source: IncrementalSource.StyleSheetRule; } & styleSheetRuleParam; export declare type canvasMutationData = { - source: IncrementalSource.CanvasMutation; + source: IncrementalSource.CanvasMutation; } & canvasMutationParam; export declare type fontData = { - source: IncrementalSource.Font; + source: IncrementalSource.Font; } & fontParam; export declare type logData = { - source: IncrementalSource.Log; + source: IncrementalSource.Log; } & LogParam; -export declare type incrementalData = - | mutationData - | mousemoveData - | mouseInteractionData - | scrollData - | viewportResizeData - | inputData - | mediaInteractionData - | styleSheetRuleData - | canvasMutationData - | fontData - | logData; -export declare type event = - | domContentLoadedEvent - | loadedEvent - | fullSnapshotEvent - | incrementalSnapshotEvent - | metaEvent - | logEvent - | customEvent; +export declare type incrementalData = mutationData | mousemoveData | mouseInteractionData | scrollData | viewportResizeData | inputData | mediaInteractionData | styleSheetRuleData | canvasMutationData | fontData | logData; +export declare type event = domContentLoadedEvent | loadedEvent | fullSnapshotEvent | incrementalSnapshotEvent | metaEvent | logEvent | customEvent; export declare type eventWithTime = event & { - timestamp: number; - delay?: number; + timestamp: number; + delay?: number; }; export declare type blockClass = string | RegExp; export declare type SamplingStrategy = Partial<{ - mousemove: boolean | number; - mousemoveCallback: number; - mouseInteraction: boolean | Record; - scroll: number; - input: 'all' | 'last'; + mousemove: boolean | number; + mouseInteraction: boolean | Record; + scroll: number; + input: 'all' | 'last'; }>; export declare type recordOptions = { - emit?: (e: T, isCheckout?: boolean) => void; - checkoutEveryNth?: number; - checkoutEveryNms?: number; - blockClass?: blockClass; - blockSelector?: string; - ignoreClass?: string; - maskAllInputs?: boolean; - maskInputOptions?: MaskInputOptions; - maskInputFn?: MaskInputFn; - slimDOMOptions?: SlimDOMOptions | 'all' | true; - inlineStylesheet?: boolean; - hooks?: hooksParam; - packFn?: PackFn; - sampling?: SamplingStrategy; - recordCanvas?: boolean; - collectFonts?: boolean; - mousemoveWait?: number; - recordLog?: boolean | LogRecordOptions; - debug?: boolean; - enableStrictPrivacy?: boolean; + emit?: (e: T, isCheckout?: boolean) => void; + checkoutEveryNth?: number; + checkoutEveryNms?: number; + blockClass?: blockClass; + blockSelector?: string; + ignoreClass?: string; + maskAllInputs?: boolean; + maskInputOptions?: MaskInputOptions; + maskInputFn?: MaskInputFn; + slimDOMOptions?: SlimDOMOptions | 'all' | true; + inlineStylesheet?: boolean; + hooks?: hooksParam; + packFn?: PackFn; + sampling?: SamplingStrategy; + recordCanvas?: boolean; + collectFonts?: boolean; + mousemoveWait?: number; + recordLog?: boolean | LogRecordOptions; + debug?: boolean; + enableStrictPrivacy?: boolean; }; export declare type observerParam = { - mutationCb: mutationCallBack; - mousemoveCb: mousemoveCallBack; - mouseInteractionCb: mouseInteractionCallBack; - scrollCb: scrollCallback; - viewportResizeCb: viewportResizeCallback; - inputCb: inputCallback; - mediaInteractionCb: mediaInteractionCallback; - blockClass: blockClass; - blockSelector: string | null; - ignoreClass: string; - maskInputOptions: MaskInputOptions; - maskInputFn?: MaskInputFn; - inlineStylesheet: boolean; - styleSheetRuleCb: styleSheetRuleCallback; - canvasMutationCb: canvasMutationCallback; - fontCb: fontCallback; - logCb: logCallback; - logOptions: LogRecordOptions; - sampling: SamplingStrategy; - recordCanvas: boolean; - collectFonts: boolean; - slimDOMOptions: SlimDOMOptions; - enableStrictPrivacy: boolean; - doc: Document; - iframeManager: IframeManager; + mutationCb: mutationCallBack; + mousemoveCb: mousemoveCallBack; + mouseInteractionCb: mouseInteractionCallBack; + scrollCb: scrollCallback; + viewportResizeCb: viewportResizeCallback; + inputCb: inputCallback; + mediaInteractionCb: mediaInteractionCallback; + blockClass: blockClass; + blockSelector: string | null; + ignoreClass: string; + maskInputOptions: MaskInputOptions; + maskInputFn?: MaskInputFn; + inlineStylesheet: boolean; + styleSheetRuleCb: styleSheetRuleCallback; + canvasMutationCb: canvasMutationCallback; + fontCb: fontCallback; + logCb: logCallback; + logOptions: LogRecordOptions; + sampling: SamplingStrategy; + recordCanvas: boolean; + collectFonts: boolean; + slimDOMOptions: SlimDOMOptions; + enableStrictPrivacy: boolean; }; export declare type hooksParam = { - mutation?: mutationCallBack; - mousemove?: mousemoveCallBack; - mouseInteraction?: mouseInteractionCallBack; - scroll?: scrollCallback; - viewportResize?: viewportResizeCallback; - input?: inputCallback; - mediaInteaction?: mediaInteractionCallback; - styleSheetRule?: styleSheetRuleCallback; - canvasMutation?: canvasMutationCallback; - font?: fontCallback; - log?: logCallback; + mutation?: mutationCallBack; + mousemove?: mousemoveCallBack; + mouseInteraction?: mouseInteractionCallBack; + scroll?: scrollCallback; + viewportResize?: viewportResizeCallback; + input?: inputCallback; + mediaInteaction?: mediaInteractionCallback; + styleSheetRule?: styleSheetRuleCallback; + canvasMutation?: canvasMutationCallback; + font?: fontCallback; + log?: logCallback; }; export declare type mutationRecord = { - type: string; - target: Node; - oldValue: string | null; - addedNodes: NodeList; - removedNodes: NodeList; - attributeName: string | null; + type: string; + target: Node; + oldValue: string | null; + addedNodes: NodeList; + removedNodes: NodeList; + attributeName: string | null; }; export declare type textCursor = { - node: Node; - value: string | null; + node: Node; + value: string | null; }; export declare type textMutation = { - id: number; - value: string | null; + id: number; + value: string | null; }; export declare type attributeCursor = { - node: Node; - attributes: { - [key: string]: string | null; - }; + node: Node; + attributes: { + [key: string]: string | null; + }; }; export declare type attributeMutation = { - id: number; - attributes: { - [key: string]: string | null; - }; + id: number; + attributes: { + [key: string]: string | null; + }; }; export declare type removedNodeMutation = { - parentId: number; - id: number; + parentId: number; + id: number; }; export declare type addedNodeMutation = { - parentId: number; - previousId?: number | null; - nextId: number | null; - node: serializedNodeWithId; + parentId: number; + previousId?: number | null; + nextId: number | null; + node: serializedNodeWithId; }; declare type mutationCallbackParam = { - texts: textMutation[]; - attributes: attributeMutation[]; - removes: removedNodeMutation[]; - adds: addedNodeMutation[]; + texts: textMutation[]; + attributes: attributeMutation[]; + removes: removedNodeMutation[]; + adds: addedNodeMutation[]; }; export declare type mutationCallBack = (m: mutationCallbackParam) => void; -export declare type mousemoveCallBack = ( - p: mousePosition[], - source: IncrementalSource.MouseMove | IncrementalSource.TouchMove, -) => void; +export declare type mousemoveCallBack = (p: mousePosition[], source: IncrementalSource.MouseMove | IncrementalSource.TouchMove) => void; export declare type mousePosition = { - x: number; - y: number; - id: number; - timeOffset: number; + x: number; + y: number; + id: number; + timeOffset: number; }; export declare enum MouseInteractions { - MouseUp = 0, - MouseDown = 1, - Click = 2, - ContextMenu = 3, - DblClick = 4, - Focus = 5, - Blur = 6, - TouchStart = 7, - TouchMove_Departed = 8, - TouchEnd = 9, + MouseUp = 0, + MouseDown = 1, + Click = 2, + ContextMenu = 3, + DblClick = 4, + Focus = 5, + Blur = 6, + TouchStart = 7, + TouchMove_Departed = 8, + TouchEnd = 9 } declare type mouseInteractionParam = { - type: MouseInteractions; - id: number; - x: number; - y: number; -}; -export declare type mouseInteractionCallBack = ( - d: mouseInteractionParam, -) => void; + type: MouseInteractions; + id: number; + x: number; + y: number; +}; +export declare type mouseInteractionCallBack = (d: mouseInteractionParam) => void; export declare type scrollPosition = { - id: number; - x: number; - y: number; + id: number; + x: number; + y: number; }; export declare type scrollCallback = (p: scrollPosition) => void; export declare type styleSheetAddRule = { - rule: string; - index?: number; + rule: string; + index?: number; }; export declare type styleSheetDeleteRule = { - index: number; + index: number; }; export declare type styleSheetRuleParam = { - id: number; - removes?: styleSheetDeleteRule[]; - adds?: styleSheetAddRule[]; + id: number; + removes?: styleSheetDeleteRule[]; + adds?: styleSheetAddRule[]; }; export declare type styleSheetRuleCallback = (s: styleSheetRuleParam) => void; export declare type canvasMutationCallback = (p: canvasMutationParam) => void; export declare type canvasMutationParam = { - id: number; - property: string; - args: Array; - setter?: true; + id: number; + property: string; + args: Array; + setter?: true; }; export declare type fontParam = { - family: string; - fontSource: string; - buffer: boolean; - descriptors?: FontFaceDescriptors; -}; -export declare type LogLevel = - | 'assert' - | 'clear' - | 'count' - | 'countReset' - | 'debug' - | 'dir' - | 'dirxml' - | 'error' - | 'group' - | 'groupCollapsed' - | 'groupEnd' - | 'info' - | 'log' - | 'table' - | 'time' - | 'timeEnd' - | 'timeLog' - | 'trace' - | 'warn'; + family: string; + fontSource: string; + buffer: boolean; + descriptors?: FontFaceDescriptors; +}; +export declare type LogLevel = 'assert' | 'clear' | 'count' | 'countReset' | 'debug' | 'dir' | 'dirxml' | 'error' | 'group' | 'groupCollapsed' | 'groupEnd' | 'info' | 'log' | 'table' | 'time' | 'timeEnd' | 'timeLog' | 'trace' | 'warn'; export declare type Logger = { - assert?: (value: any, message?: string, ...optionalParams: any[]) => void; - clear?: () => void; - count?: (label?: string) => void; - countReset?: (label?: string) => void; - debug?: (message?: any, ...optionalParams: any[]) => void; - dir?: (obj: any, options?: NodeJS.InspectOptions) => void; - dirxml?: (...data: any[]) => void; - error?: (message?: any, ...optionalParams: any[]) => void; - group?: (...label: any[]) => void; - groupCollapsed?: (label?: any[]) => void; - groupEnd?: () => void; - info?: (message?: any, ...optionalParams: any[]) => void; - log?: (message?: any, ...optionalParams: any[]) => void; - table?: (tabularData: any, properties?: ReadonlyArray) => void; - time?: (label?: string) => void; - timeEnd?: (label?: string) => void; - timeLog?: (label?: string, ...data: any[]) => void; - trace?: (message?: any, ...optionalParams: any[]) => void; - warn?: (message?: any, ...optionalParams: any[]) => void; -}; -export declare type ReplayLogger = Partial< - Record void> ->; + assert?: (value: any, message?: string, ...optionalParams: any[]) => void; + clear?: () => void; + count?: (label?: string) => void; + countReset?: (label?: string) => void; + debug?: (message?: any, ...optionalParams: any[]) => void; + dir?: (obj: any, options?: NodeJS.InspectOptions) => void; + dirxml?: (...data: any[]) => void; + error?: (message?: any, ...optionalParams: any[]) => void; + group?: (...label: any[]) => void; + groupCollapsed?: (label?: any[]) => void; + groupEnd?: () => void; + info?: (message?: any, ...optionalParams: any[]) => void; + log?: (message?: any, ...optionalParams: any[]) => void; + table?: (tabularData: any, properties?: ReadonlyArray) => void; + time?: (label?: string) => void; + timeEnd?: (label?: string) => void; + timeLog?: (label?: string, ...data: any[]) => void; + trace?: (message?: any, ...optionalParams: any[]) => void; + warn?: (message?: any, ...optionalParams: any[]) => void; +}; +export declare type ReplayLogger = Partial void>>; export declare type LogParam = { - level: LogLevel; - trace: Array; - payload: Array; + level: LogLevel; + trace: Array; + payload: Array; }; export declare type fontCallback = (p: fontParam) => void; export declare type logCallback = (p: LogParam) => void; -export declare type viewportResizeDimension = { - width: number; - height: number; +export declare type viewportResizeDimention = { + width: number; + height: number; }; -export declare type viewportResizeCallback = ( - d: viewportResizeDimension, -) => void; +export declare type viewportResizeCallback = (d: viewportResizeDimention) => void; export declare type inputValue = { - text: string; - isChecked: boolean; + text: string; + isChecked: boolean; }; -export declare type inputCallback = ( - v: inputValue & { +export declare type inputCallback = (v: inputValue & { id: number; - }, -) => void; +}) => void; export declare const enum MediaInteractions { - Play = 0, - Pause = 1, + Play = 0, + Pause = 1 } export declare type mediaInteractionParam = { - type: MediaInteractions; - id: number; -}; -export declare type mediaInteractionCallback = ( - p: mediaInteractionParam, -) => void; -export declare type DocumentDimension = { - x: number; - y: number; - relativeScale: number; - absoluteScale: number; + type: MediaInteractions; + id: number; }; +export declare type mediaInteractionCallback = (p: mediaInteractionParam) => void; export declare type Mirror = { - map: idNodeMap; - getId: (n: INode) => number; - getNode: (id: number) => INode | null; - removeNodeFromMap: (n: INode) => void; - has: (id: number) => boolean; + map: idNodeMap; + getId: (n: INode) => number; + getNode: (id: number) => INode | null; + removeNodeFromMap: (n: INode) => void; + has: (id: number) => boolean; }; export declare type throttleOptions = { - leading?: boolean; - trailing?: boolean; + leading?: boolean; + trailing?: boolean; }; export declare type listenerHandler = () => void; export declare type hookResetter = () => void; export declare type playerConfig = { - speed: number; - root: Element; - loadTimeout: number; - skipInactive: boolean; - showWarning: boolean; - showDebug: boolean; - blockClass: string; - liveMode: boolean; - insertStyleRules: string[]; - triggerFocus: boolean; - UNSAFE_replayCanvas: boolean; - pauseAnimation?: boolean; - mouseTail: - | boolean - | { + speed: number; + root: Element; + loadTimeout: number; + skipInactive: boolean; + showWarning: boolean; + showDebug: boolean; + blockClass: string; + liveMode: boolean; + insertStyleRules: string[]; + triggerFocus: boolean; + UNSAFE_replayCanvas: boolean; + pauseAnimation?: boolean; + mouseTail: boolean | { duration?: number; lineCap?: string; lineWidth?: number; strokeStyle?: string; - }; - unpackFn?: UnpackFn; - logConfig: LogReplayConfig; - inactiveThreshold: number; - inactiveSkipTime: number; - maxSkipSpeed: number; + }; + unpackFn?: UnpackFn; + logConfig: LogReplayConfig; + inactiveThreshold: number; + inactiveSkipTime: number; + maxSkipSpeed: number; }; export declare type LogReplayConfig = { - level?: Array | undefined; - replayLogger: ReplayLogger | undefined; + level?: Array | undefined; + replayLogger: ReplayLogger | undefined; }; export declare type playerMetaData = { - startTime: number; - endTime: number; - totalTime: number; + startTime: number; + endTime: number; + totalTime: number; }; export declare type missingNode = { - node: Node; - mutation: addedNodeMutation; + node: Node; + mutation: addedNodeMutation; }; export declare type missingNodeMap = { - [id: number]: missingNode; + [id: number]: missingNode; }; export declare type actionWithDelay = { - doAction: () => void; - delay: number; + doAction: () => void; + delay: number; }; export declare type Handler = (event?: unknown) => void; export declare type Emitter = { - on(type: string, handler: Handler): void; - emit(type: string, event?: unknown): void; - off(type: string, handler: Handler): void; + on(type: string, handler: Handler): void; + emit(type: string, event?: unknown): void; + off(type: string, handler: Handler): void; }; -export declare type Arguments = T extends (...payload: infer U) => unknown - ? U - : unknown; +export declare type Arguments = T extends (...payload: infer U) => unknown ? U : unknown; export declare enum ReplayerEvents { - Start = 'start', - Pause = 'pause', - Resume = 'resume', - Resize = 'resize', - Finish = 'finish', - FullsnapshotRebuilded = 'fullsnapshot-rebuilded', - LoadStylesheetStart = 'load-stylesheet-start', - LoadStylesheetEnd = 'load-stylesheet-end', - SkipStart = 'skip-start', - SkipEnd = 'skip-end', - MouseInteraction = 'mouse-interaction', - EventCast = 'event-cast', - CustomEvent = 'custom-event', - Flush = 'flush', - StateChange = 'state-change', + Start = "start", + Pause = "pause", + Resume = "resume", + Resize = "resize", + Finish = "finish", + FullsnapshotRebuilded = "fullsnapshot-rebuilded", + LoadStylesheetStart = "load-stylesheet-start", + LoadStylesheetEnd = "load-stylesheet-end", + SkipStart = "skip-start", + SkipEnd = "skip-end", + MouseInteraction = "mouse-interaction", + EventCast = "event-cast", + CustomEvent = "custom-event", + Flush = "flush", + StateChange = "state-change" } export declare type MaskInputFn = (text: string) => string; export declare type ElementState = { - scroll?: [number, number]; + scroll?: [number, number]; }; export declare type StringifyOptions = { - stringLengthLimit?: number; - numOfKeysLimit: number; + stringLengthLimit?: number; + numOfKeysLimit: number; }; export declare type LogRecordOptions = { - level?: Array | undefined; - lengthThreshold?: number; - stringifyOptions?: StringifyOptions; - logger?: Logger; + level?: Array | undefined; + lengthThreshold?: number; + stringifyOptions?: StringifyOptions; + logger?: Logger; }; export {}; diff --git a/typings/utils.d.ts b/typings/utils.d.ts index 1f6bca5a..3cf6fdc2 100644 --- a/typings/utils.d.ts +++ b/typings/utils.d.ts @@ -1,5 +1,5 @@ -import { Mirror, throttleOptions, listenerHandler, hookResetter, blockClass, eventWithTime, addedNodeMutation, removedNodeMutation, textMutation, attributeMutation, mutationData, scrollData, inputData, DocumentDimension } from './types'; -import { INode, serializedNodeWithId } from './snapshot'; +import { Mirror, throttleOptions, listenerHandler, hookResetter, blockClass, eventWithTime, addedNodeMutation, removedNodeMutation, textMutation, attributeMutation, mutationData, scrollData, inputData } from './types'; +import { INode } from './snapshot'; export declare function on(type: string, fn: EventListenerOrEventListenerObject, target?: Document | Window): listenerHandler; export declare const mirror: Mirror; export declare function throttle(func: (arg: T) => void, wait: number, options?: throttleOptions): (arg: T) => void; @@ -53,13 +53,4 @@ declare type ResolveTree = { }; export declare function queueToResolveTrees(queue: addedNodeMutation[]): ResolveTree[]; export declare function iterateResolveTree(tree: ResolveTree, cb: (mutation: addedNodeMutation) => unknown): void; -declare type HTMLIFrameINode = HTMLIFrameElement & { - __sn: serializedNodeWithId; -}; -export declare type AppendedIframe = { - mutationInQueue: addedNodeMutation; - builtNode: HTMLIFrameINode; -}; -export declare function isIframeINode(node: INode): node is HTMLIFrameINode; -export declare function getBaseDimension(node: Node, rootIframe: Node): DocumentDimension; export {}; diff --git a/yarn.lock b/yarn.lock index fcc9987a..6547317c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1792,11 +1792,6 @@ estree-walker@^0.6.0, estree-walker@^0.6.1: resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz" integrity sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w== -estree-walker@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" - integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== - esutils@^2.0.2: version "2.0.3" resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" @@ -2018,9 +2013,9 @@ fd-slicer@~1.1.0: pend "~1.2.0" fflate@^0.4.4: - version "0.4.4" - resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.4.4.tgz#b23c3f53a687bbce62a091af98f621ca7f68a191" - integrity sha512-BBKysCIvETp1l5wTUvjCR+tfFmlvSWtzNZe3SkQN1xDeTD9dscGypw5NZEZIkyPazKGOnpaKFlMwOmuTgApiJQ== + version "0.4.8" + resolved "https://registry.npmjs.org/fflate/-/fflate-0.4.8.tgz" + integrity sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA== figures@^2.0.0: version "2.0.0" @@ -2156,10 +2151,10 @@ fsevents@^1.2.7: bindings "^1.5.0" nan "^2.12.1" -fsevents@~2.1.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" - integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== +fsevents@~2.3.1: + version "2.3.2" + resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== function-bind@^1.1.1: version "1.1.1" @@ -3257,7 +3252,7 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -magic-string@^0.25.2, magic-string@^0.25.7: +magic-string@^0.25.2: version "0.25.7" resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz" integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA== @@ -4392,11 +4387,6 @@ preserve@^0.2.0: resolved "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz" integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= -prettier@2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5" - integrity sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q== - pretty-format@^23.6.0: version "23.6.0" resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-23.6.0.tgz" @@ -4770,14 +4760,6 @@ rollup-plugin-postcss@^3.1.1: safe-identifier "^0.4.1" style-inject "^0.3.0" -rollup-plugin-rename-node-modules@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/rollup-plugin-rename-node-modules/-/rollup-plugin-rename-node-modules-1.1.0.tgz#c73de5fed61b997857993813a7053285e2cca2dd" - integrity sha512-JpfsJ7NYI/4OdqWvZ/BY6fgjZb5j7sRFvHMv8EU0zrFiNUcW4ke9tw7WXImsHnjq7Bp3xv+UILRPpA7plOa38Q== - dependencies: - estree-walker "^2.0.1" - magic-string "^0.25.7" - rollup-plugin-terser@^5.3.0: version "5.3.1" resolved "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-5.3.1.tgz"