Skip to content

Commit

Permalink
Update rrweb (#35)
Browse files Browse the repository at this point in the history
* fix: sometimes currentTime is smaller than the totalTime when player is finished (#445)

plus: fix the problem that sometimes return value of getCurrentTime() is negative

* Fix broken link to design docs

* Update to fflate (#448)

* Update to fflate

* Update docs, bundler config

* Scroll replayer iframe on firstFullsnapshot (#451)

* upgrade snapshot

* Release 0.9.12

* Protect against generation of no-change viewport resize events. (#454)

I noticed 8 or 10 of these events being generated in a multi-tab browsing session on Chrome 87.0 on Win10.  I'm speculating they were generated as a side effect of changing tabs but I can't recreate

* fix #452 check isBlocked on add mutation's target

* Release 0.9.13

* let mouse tail duration respect timer speed

* clean addList when meet a corner case

* fix #460 ignore added node that are not in document anymore

* upgrade 0.9.14

* Release 0.9.14

* Tweaks to timings to get tests passing on my dev laptop (#466)

* Tweaks to timings to get tests passing on my dev laptop - hopefully this makes tests more deterministic

* Okay understand what's going on now that the test has run in the travis environment

* fix #469 try to get original MutationObserver
We found Angular's zone module will patch MutationObserver which
make the browser hang in some scenarios.
Reference: angular/angular#26948

* Discovered that the common case of mouse movement or scrolling happening during `takeFullSnapshot` was causing mutations to be immediately emitted, contrary to the goal of rrweb-io/rrweb#385 (#470)

* Don't remove the style attributes altogether from tests; they are an important part of the mutations (#468)

These were removed in rrweb-io/rrweb@8ed1c99 in order to smooth over differences in test environments
so have maintained that by converting pixel values to 'Npx' (could also try rounding, but didn't attempt that)

* read __rrMutationObserver from window

* update guide (#483)

* Fix RangeError: Maximum call stack size exceeded (#479)

Saw this line cause issues in production, causing the following error:

```
RangeError Maximum call stack size exceeded
```

I believe this is caused by javascript engine max argument length - see note from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply#using_apply_and_built-in_functions

> The consequences of applying a function with too many arguments (that is, more than tens of thousands of arguments) varies across engines. (The JavaScriptCore engine has hard-coded argument limit of 65536.

* Impl record iframe (#481)

* Impl record iframe

* iframe observe

* temp: add bundle file to git

* update bundle

* update with pick

* update bundle

* fix fragment map remove

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

set pauseAnimation to true by default

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

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

* refactor: the bugfix code

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

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

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

* pick fixes

* revert ignore file

* re-impl iframe record

* re-impl iframe replay

* code housekeeping

* move multi layer dimension calculation to replay side

* update test cases

* teardown test server

* upgrade rrweb-snapshot with iframe load timeout

Co-authored-by: Lucky Feng <[email protected]>

* remove debugging warning (#486)

I can't see a reason for the warning here so believe it's a debugging statement that crept in?

* Add prettier as a dependency (#487)

* start impl rrdom

* upgrade rrweb-snapshot to 1.0.7

* Adding prepare npm statement (#490)

* added prepare statement

* using master rrweb snapshot

Co-authored-by: filip slatinac <[email protected]>

* Added mousemoveCallback threshold option to sampling config. (#492)

* Added mousemoveCallback threshold option to sampling config.

* Added mousemoveCallback to definitions file.

* Add yarn support for installing unreleased rrweb as a dependency  (#497)

* Use prepack instead of prepare for yarn support

* add prepare and prepack

for yarn v1 & v2 compatibility

* Create .npmignore

* update guide

* close #501 do not count attach iframe event in checkout

* close #491 check whether link node is head

* update test snapshot

* fix lint errors

* add hiring link

* impl #507 export takeFullSnapshot as a public API

* Update observer.md (#504)

Fixed some grammatical errors

* add an experiment config to set max speed in fast forward

* Handle event undefined in initMoveObserver (#515)

* fix: errors of replaying iframe records (#520)

* fix: errors of replaying iframe records

error1:
HierarchyRequestError: Failed to execute 'appendChild' on 'Node': Nodes of type '#document' may not be inserted inside nodes of type '#document-fragment'.
code: parent.appendChild(target)

error2:
Uncaught DOMException: Failed to execute 'appendChild' on 'Node': Only one element on document allowed.
code: parent.appendChild(target);

* improve the comment for bugfix

* rename node_modules in es bundle to ext

* fix: inaccurate mouse position (#522)

1. Position of mouse was inaccurate when replaying and this PR will fix it.
2. Fix the bug that if one nested iframe has a scale transform and the position of mouse was inaccurate as well.

* impl shadow DOM manager
part of #38
1. observe DOM mutations in shadow DOM
2. rebuild DOM mutations in shadow DOM

* Fix docs to point to correct event format (#523)

* Fix docs to point to correct event attribute

* Update customize-replayer.zh_CN.md

* correct event object in guide

* Update guide.zh_CN.md

* Update snapshot to Release 1.1.1

Co-authored-by: Lucky Feng <[email protected]>
Co-authored-by: Fanis Katsimpas <[email protected]>
Co-authored-by: Lucky Feng <[email protected]>
Co-authored-by: 101arrowz <[email protected]>
Co-authored-by: Jarosław Salwa <[email protected]>
Co-authored-by: Yanzhen Yu <[email protected]>
Co-authored-by: Eoghan Murray <[email protected]>
Co-authored-by: zzq0826 <[email protected]>
Co-authored-by: Karl-Aksel Puulmann <[email protected]>
Co-authored-by: Moji Izadmehr <[email protected]>
Co-authored-by: Filip Slatinac <[email protected]>
Co-authored-by: filip slatinac <[email protected]>
Co-authored-by: Province Innovation <[email protected]>
Co-authored-by: Justin Halsall <[email protected]>
Co-authored-by: Season <[email protected]>
Co-authored-by: arshabh-copods <[email protected]>
Co-authored-by: Yakko Majuri <[email protected]>
  • Loading branch information
18 people authored Apr 6, 2021
1 parent c5046d0 commit 5dc4ca2
Show file tree
Hide file tree
Showing 47 changed files with 3,406 additions and 896 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ es
lib

temp

*.log
8 changes: 7 additions & 1 deletion .npmignore
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
!**/node_modules
.vscode
.idea
node_modules
package-lock.json
yarn.lock
temp
*.log
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

# 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)
Expand Down
2 changes: 2 additions & 0 deletions README.zh_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

# 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)
Expand Down
2 changes: 1 addition & 1 deletion docs/observer.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 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.
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.

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:

Expand Down
6 changes: 3 additions & 3 deletions docs/recipes/customize-replayer.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.detail.payload);
console.log(event.payload);
});

// get current state
rrwebPlayer.addEventListener('ui-update-player-state', (event) => {
console.log(event.detail.payload);
console.log(event.payload);
});

// get current progress
rrwebPlayer.addEventListener('ui-update-progress', (event) => {
console.log(event.detail.payload);
console.log(event.payload);
});
```

Expand Down
6 changes: 3 additions & 3 deletions docs/recipes/customize-replayer.zh_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,17 @@ rrwebPlayer.goto(3000);
```js
// 当前播放时间
rrwebPlayer.addEventListener('ui-update-current-time', (event) => {
console.log(event.detail.payload);
console.log(event.payload);
});

// 当前播放状态
rrwebPlayer.addEventListener('ui-update-player-state', (event) => {
console.log(event.detail.payload);
console.log(event.payload);
});

// 当前播放进度
rrwebPlayer.addEventListener('ui-update-progress', (event) => {
console.log(event.detail.payload);
console.log(event.payload);
});
```

Expand Down
13 changes: 8 additions & 5 deletions guide.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Guide

[中文指南](./guide.md)
[中文指南](./guide.zh_CN.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.
Expand Down Expand Up @@ -142,8 +142,11 @@ The parameter of `rrweb.record` accepts the following options.
| checkoutEveryNms | - | take a full snapshot after every N ms<br />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 \*<br />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 <br />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<br />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) |
Expand Down Expand Up @@ -287,7 +290,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 |
| inertStyleRules | [] | accepts multiple CSS rule string, which will be injected into the replay iframe |
| insertStyleRules | [] | 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) |
Expand Down Expand Up @@ -375,9 +378,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 | { detail: { payload } } |
| ui-update-player-state | current player state has changed | { detail: { payload } } |
| ui-update-progress | current progress has changed | { detail: { payload } } |
| 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 } |

## REPL tool

Expand Down
15 changes: 9 additions & 6 deletions guide.zh_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,16 +137,19 @@ setInterval(save, 10 * 1000);
| checkoutEveryNth | - | 每 N 次事件重新制作一次全量快照<br />详见[“重新制作快照”](#重新制作快照)章节 |
| checkoutEveryNms | - | 每 N 毫秒重新制作一次全量快照<br />详见[“重新制作快照”](#重新制作快照)章节 |
| blockClass | 'rr-block' | 字符串或正则表达式,可用于自定义屏蔽元素的类名,详见[“隐私”](#隐私)章节 |
| blockSelector | null | 字符串或正则表达式,可用于自定义屏蔽元素的选择器,详见[“隐私”](#隐私)章节 |
| ignoreClass | 'rr-ignore' | 字符串或正则表达式,可用于自定义忽略元素的类名,详见[“隐私”](#隐私)章节 |
| maskAllInputs | false | 将所有输入内容记录为 \* |
| maskInputOptions | {} | 选择将特定类型的输入框内容记录为 \*<br />类型详见[列表](https://github.com/rrweb-io/rrweb-snapshot/blob/6728d12b3cddd96951c86d948578f99ada5749ff/src/types.ts#L72) |
| maskInputFn | - | 自定义特定类型的输入框内容记录逻辑 |
| slimDOMOptions | {} | 去除 DOM 中不必要的部分 <br />类型详见[列表](https://github.com/rrweb-io/rrweb-snapshot/blob/6728d12b3cddd96951c86d948578f99ada5749ff/src/types.ts#L91) |
| inlineStylesheet | true | 是否将样式表内联 |
| hooks | {} | 各类事件的回调<br />类型详见[列表](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) |

#### 隐私

Expand Down Expand Up @@ -283,12 +286,12 @@ replayer.pause(5000);
| showDebug | false | 是否在回放过程中打印 debug 信息 |
| blockClass | 'rr-block' | 需要在回放时展示为隐藏区域的元素类名 |
| liveMode | false | 是否开启直播模式 |
| inertStyleRules | [] | 可以传入多个 CSS rule string,用于自定义回放时 iframe 内的样式 |
| insertStyleRules | [] | 可以传入多个 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

Expand Down Expand Up @@ -373,9 +376,9 @@ replayer.on(EVENT_NAME, (payload) => {

| 事件类型 | 描述 ||
| ---------------------- | -------------- | ----------------------- |
| ui-update-current-time | 当前回放时间点 | { detail: { payload } } |
| ui-update-player-state | 当前回放状态 | { detail: { payload } } |
| ui-update-progress | 当前回放百分比 | { detail: { payload } } |
| ui-update-current-time | 当前回放时间点 | { payload } |
| ui-update-player-state | 当前回放状态 | { payload } |
| ui-update-progress | 当前回放百分比 | { payload } |

## REPL 工具

Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@highlight-run/rrweb",
"version": "0.10.4",
"version": "0.10.5",
"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",
Expand Down Expand Up @@ -44,11 +44,13 @@
"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",
Expand Down
2 changes: 2 additions & 0 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ 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) {
Expand Down Expand Up @@ -137,6 +138,7 @@ for (const c of baseConfigs) {
{
format: 'esm',
dir: 'es/rrweb',
plugins: [renameNodeModules('ext')],
},
],
});
Expand Down
8 changes: 6 additions & 2 deletions scripts/repl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,11 @@ function getCode(): string {
width: 1600,
height: 900,
},
args: ['--start-maximized', '--ignore-certificate-errors'],
args: [
'--start-maximized',
'--ignore-certificate-errors',
'--no-sandbox',
],
});
const page = await browser.newPage();
await page.goto(url, {
Expand Down Expand Up @@ -128,7 +132,7 @@ function getCode(): string {
width: 1600,
height: 900,
},
args: ['--start-maximized'],
args: ['--start-maximized', '--no-sandbox'],
});
const page = await browser.newPage();
await page.goto('about:blank');
Expand Down
37 changes: 37 additions & 0 deletions src/record/iframe-manager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { serializedNodeWithId, INode } from '../snapshot';
import { mutationCallBack } from '../types';

export class IframeManager {
private iframes: WeakMap<HTMLIFrameElement, true> = 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);
}
}
Loading

0 comments on commit 5dc4ca2

Please sign in to comment.