Skip to content

Commit f1b5cb2

Browse files
YunFeng0817Mark-Fenng
and
Mark-Fenng
authored
CI: add a prettier GitHub action to format code automatically (#988)
* CI: add a prettier GitHub action to format code automatically * improve GitHub Action config and format some files * Apply formatting changes * CI: make the prettier action a standalone action * Apply formatting changes * CI: add push as new trigger event Co-authored-by: Mark-Fenng <[email protected]>
1 parent 5ba933c commit f1b5cb2

22 files changed

+109
-54
lines changed

.github/workflows/eslint.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: Eslint Check
22

3-
on: [pull_request]
3+
on: [pull_request, push]
44

55
jobs:
66
eslint_check_upload:

.github/workflows/prettier.yml

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: Prettier
2+
3+
on: [pull_request, push]
4+
5+
jobs:
6+
prettier:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- name: Checkout
10+
uses: actions/checkout@v3
11+
with:
12+
ref: ${{ github.head_ref }}
13+
- name: Setup Node
14+
uses: actions/setup-node@v3
15+
with:
16+
node-version: 16
17+
cache: 'yarn'
18+
- name: Install Dependencies
19+
run: yarn
20+
- name: Prettify code
21+
run: yarn prettier --write '**/*.{ts,md}'
22+
- name: Commit changes
23+
uses: stefanzweifel/git-auto-commit-action@v4
24+
with:
25+
commit_message: Apply formatting changes
26+
branch: ${{ github.head_ref }}

.release-it.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@
1212
"release": true,
1313
"releaseName": "Release ${version}"
1414
}
15-
}
15+
}

CODE_OF_CONDUCT.md

+11-11
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,23 @@ diverse, inclusive, and healthy community.
1717
Examples of behavior that contributes to a positive environment for our
1818
community include:
1919

20-
* Demonstrating empathy and kindness toward other people
21-
* Being respectful of differing opinions, viewpoints, and experiences
22-
* Giving and gracefully accepting constructive feedback
23-
* Accepting responsibility and apologizing to those affected by our mistakes,
20+
- Demonstrating empathy and kindness toward other people
21+
- Being respectful of differing opinions, viewpoints, and experiences
22+
- Giving and gracefully accepting constructive feedback
23+
- Accepting responsibility and apologizing to those affected by our mistakes,
2424
and learning from the experience
25-
* Focusing on what is best not just for us as individuals, but for the
25+
- Focusing on what is best not just for us as individuals, but for the
2626
overall community
2727

2828
Examples of unacceptable behavior include:
2929

30-
* The use of sexualized language or imagery, and sexual attention or
30+
- The use of sexualized language or imagery, and sexual attention or
3131
advances of any kind
32-
* Trolling, insulting or derogatory comments, and personal or political attacks
33-
* Public or private harassment
34-
* Publishing others' private information, such as a physical or email
32+
- Trolling, insulting or derogatory comments, and personal or political attacks
33+
- Public or private harassment
34+
- Publishing others' private information, such as a physical or email
3535
address, without their explicit permission
36-
* Other conduct which could reasonably be considered inappropriate in a
36+
- Other conduct which could reasonably be considered inappropriate in a
3737
professional setting
3838

3939
## Enforcement Responsibilities
@@ -106,7 +106,7 @@ Violating these terms may lead to a permanent ban.
106106
### 4. Permanent Ban
107107

108108
**Community Impact**: Demonstrating a pattern of violation of community
109-
standards, including sustained inappropriate behavior, harassment of an
109+
standards, including sustained inappropriate behavior, harassment of an
110110
individual, or aggression toward or disparagement of classes of individuals.
111111

112112
**Consequence**: A permanent ban from any sort of public interaction within

CONTRIBUTING.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,30 @@
11
# Contributing to rrweb
2+
23
We want to make contributing to this project as easy and transparent as
34
possible.
45

56
## Our Development Process
7+
68
The majority of development on rrweb will occur through GitHub. Accordingly,
79
the process for contributing will follow standard GitHub protocol.
810

911
## Pull Requests
12+
1013
We actively welcome your pull requests.
14+
1115
1. Fork the repo and create your branch from `master`.
1216
2. If you've added code that should be tested, add tests
1317
3. If you've changed APIs, update the documentation.
1418
4. Ensure the test suite passes.
1519
5. Make sure your code lints and typechecks.
1620

1721
## Issues
22+
1823
We use GitHub issues to track public bugs. Please ensure your description is
1924
clear and has sufficient instructions to be able to reproduce the issue.
2025

2126
## License
27+
2228
rrweb is [MIT licensed](https://github.com/rrweb-io/rrweb/blob/master/LICENSE).
2329

2430
By contributing to rrweb, you agree that your contributions will be licensed

docs/observer.zh_CN.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ body
5757

5858
[序列化设计](./serialization.zh_CN.md)中已经介绍了我们需要维护一个 `id -> Node` 的映射,因此当出现新增节点时,我们需要将新节点序列化并加入映射中。但由于我们为了去重新增节点,选择在所有 mutation 记录遍历完毕之后才进行序列化,在以下示例中就会出现问题:
5959

60-
1. mutation 记录1,新增节点 n1。我们暂不处理,等待最终去重后序列化。
61-
2. mutation 记录2,n1 新增属性 a1。我们试图将它记录成一次增量快照,但会发现无法从映射中找到 n1 对应的 id,因为此时它还未被序列化。
60+
1. mutation 记录 1,新增节点 n1。我们暂不处理,等待最终去重后序列化。
61+
2. mutation 记录 2,n1 新增属性 a1。我们试图将它记录成一次增量快照,但会发现无法从映射中找到 n1 对应的 id,因为此时它还未被序列化。
6262

6363
由此可见,由于我们对新增节点进行了延迟序列化的处理,所有 mutation 记录也都需要先收集,再新增节点去重并序列化之后再做处理。
6464

@@ -119,4 +119,4 @@ function hookSetter<T>(
119119
}
120120
```
121121

122-
注意为了避免我们在 setter 中的逻辑阻塞被录制页面的正常交互,我们应该把逻辑放入 event loop 中异步执行。
122+
注意为了避免我们在 setter 中的逻辑阻塞被录制页面的正常交互,我们应该把逻辑放入 event loop 中异步执行。

docs/recipes/record-and-replay.zh_CN.md

+3-4
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
const stopFn = rrweb.record({
99
emit(event) {
1010
// 保存获取到的 event 数据
11-
}
12-
})
11+
},
12+
});
1313
```
1414

1515
你可以使用任何方式保存录制的数据,例如通过网络请求将数据传入至后端持久化保存,但请确保:
@@ -22,9 +22,8 @@ const stopFn = rrweb.record({
2222
回放时只需要获取一段录制数据,并传入 rrweb 提供的 Replayer:
2323

2424
```js
25-
const events = GET_YOUR_EVENTS
25+
const events = GET_YOUR_EVENTS;
2626

2727
const replayer = new rrweb.Replayer(events);
2828
replayer.play();
2929
```
30-

docs/replay.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
# Replay
2+
23
A design principle of rrweb is to process as little as possible on the recording side, minimizing the impact on the recorded page. This means we need to do some special processing on the replay side.
34

45
## High precision timer
6+
57
During replay, we will get the complete snapshot chain at one time. If all the snapshots are executed in sequence, we can directly get the last state of the recorded page, but what we need is to synchronously initialize the first full snapshot, and then apply the remaining incremental snapshots asynchronously. Using a time interval we replay each incremental snapshot one after the other, which requires a high-precision timer.
68

79
The reason why **high precision** is emphasized is because the native `setTimeout` does not guarantee accurate execution after the set delay time, for example, when the main thread is blocked.
@@ -11,6 +13,7 @@ For our replay function, this imprecise delay is unacceptable and can lead to va
1113
At the same time, the custom timer is also the basis for our "fast forward" function.
1214

1315
## Completing missing nodes
16+
1417
The delay serialization strategy when rrweb uses MutationObserver is mentioned in the [incremental snapshot design](./observer.md), which may result in the following scenarios where we cannot record a full incremental snapshot:
1518

1619
```
@@ -29,6 +32,7 @@ During replay, when we process the incremental snapshot of the new `foo`, we kno
2932
After processing the incremental snapshot of the new n1, we normally process and insert `bar`. After the replay is completed, we check whether the neighbor node id of `foo` points to a node which is in the missing node pool. If it matches, then it will be removed from the pool and be inserted into the DOM tree.
3033

3134
## Simulation Hover
35+
3236
CSS styles for the `:hover` selector are present in many web pages, but we can't trigger the hover state via JavaScript. So when playing back we need to simulate the hover state to make the style display correctly.
3337

3438
The specific method includes two parts:
@@ -37,6 +41,7 @@ The specific method includes two parts:
3741
2. When playing back the mouse up mouse interaction event, add the `.:hover` class name to the event target and all its ancestors, and remove it when the mouse moves away again.
3842

3943
## Play from any point in time
44+
4045
In addition to the basic replay features, we also want players like `rrweb-player` to provide similar functionality to video players, such as dragging and dropping to the progress bar to any point in time.
4146

4247
In actual implementation, we pass a start time to the method. We can then divide the snapshot chain into two parts: The parts before and the part after the start time. Then, the snapshot chain before the start time is executed synchronously, and then the snapshot chain after the starting times uses the normal asynchronous execution. This way we can achieve starting replay from any point in time.

docs/sandbox.md

+3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ In the [serialization design](./serialization.md) we mentioned the "de-scripting
55
There are many kinds of scripting behaviors. A filtering approach to getting rid of these scripts will never be a complete solution, and once a script slips through and is executed, it may cause irreversible unintended consequences. So we use the iframe sandbox feature provided by HTML for browser-level restrictions.
66

77
## iframe sandbox
8+
89
We reconstruct the recorded DOM in an `iframe` element when we rebuild the snapshot. By setting its `sandbox` attribute, we can disable the following behavior:
910

1011
- Form submission
@@ -14,13 +15,15 @@ We reconstruct the recorded DOM in an `iframe` element when we rebuild the snaps
1415
This is in line with our expectations, especially when dealing with JS scripts is safer and more reliable than implementing this security ourselves.
1516

1617
## Avoid link jumps
18+
1719
When you click the a element link, the default event is to jump to the URL corresponding to its href attribute. During replay, we will ensure visually correct replay by rebuilding the page DOM after the jump, and the original jump should be prohibited.
1820

1921
Usually we will capture all an elements click events through the event handler proxy and disable the default event via `event.preventDefault()`. But when we put the replay page in the sandbox, all the event handlers will not be executed, and we will not be able to implement the event delegation.
2022

2123
When replaying interactive events, note that replaying the JS `click` event is not nessecary because click events do not have any impact when JS is disabled. However, in order to optimize the replay effect, we can add special animation effects to visualize elements being clicked with the mouse, to clearly show the viewer that a click has occurred.
2224

2325
## iframe style settings
26+
2427
Since we're rebuilding the DOM in an iframe, we can't affect the elements in the iframe through the CSS stylesheet of the parent page. But if JS scripts are not allowed to execute, the `noscript` tag will be displayed, and we want to hide it. So we need to dynamically add styles to the iframe. The sample code is as follows:
2528

2629
```typescript

docs/sandbox.zh_CN.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,4 @@ for (let idx = 0; idx < injectStyleRules.length; idx++) {
4242
}
4343
```
4444

45-
需要注意的是这个插入的 style 元素在被录制页面中并不存在,所以我们不能将其序列化,否则 `id -> Node` 的映射将出现错误。
45+
需要注意的是这个插入的 style 元素在被录制页面中并不存在,所以我们不能将其序列化,否则 `id -> Node` 的映射将出现错误。

docs/serialization.md

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# Serialization
2+
23
If you only need to record and replay changes within the browser locally, then we can simply save the current view by deep copying the DOM object. For example, the following code implementation (simplified example with jQuery, saves only the body part):
34

45
```javascript
@@ -18,6 +19,7 @@ We do not use an existing open source solutions such as [parse5](https://github.
1819
2. This part of the code needs to run on the recorded page, and we want to control the amount of code as much as possible, only retaining the necessary functions.
1920

2021
## Special handling in serialization
22+
2123
The reason why our serialization method is non-standard is because we still need to do the following parts:
2224

2325
1. Output needs to be descriptive. All JavaScript in the original recorded page should not be executed on replay. In rrweb we do this by replacing `script` tags with placeholder `noscript` tags in snapshots. The content inside the script is no longer important. We instead record any changes to the DOM that scripts cause, and we ​​do not need to fully record large amounts of script content that may be present on the original web page.
@@ -26,15 +28,15 @@ The reason why our serialization method is non-standard is because we still need
2628
4. We want to record the contents of the CSS style sheet. If the recorded page links to external style sheets, we can get its parsed CSS rules from the browser, generate an inline style sheet containing all these rules. This way stylesheets that are not always accessible (for example, because they are located on an intranet or localhost) are included in the recording and can be replayed correctly.
2729

2830
## Uniquely identifies
31+
2932
At the same time, our serialization should also include both full and incremental types. Full serialization can transform a DOM tree into a corresponding tree data structure.
3033

3134
For example, the following DOM tree:
3235

3336
```html
3437
<html>
3538
<body>
36-
<header>
37-
</header>
39+
<header></header>
3840
</body>
3941
</html>
4042
```
@@ -98,12 +100,12 @@ There are two things to note in this serialization result:
98100

99101
Imagine if we recorded the click of a button on the same page and played it back, we can record the operation in the following format (that is what we call an incremental snapshot):
100102

101-
```javascript
103+
```typescript
102104
type clickSnapshot = {
103105
source: 'MouseInteraction';
104106
type: 'Click';
105107
node: HTMLButtonElement;
106-
}
108+
};
107109
```
108110

109111
The operation can be executed again by `snapshot.node.click()`.
@@ -119,5 +121,5 @@ type clickSnapshot = {
119121
source: 'MouseInteraction';
120122
type: 'Click';
121123
id: Number;
122-
}
124+
};
123125
```

docs/serialization.zh_CN.md

+5-7
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ $('body').replaceWith(snapshot);
2222

2323
1. 去脚本化。被录制页面中的所有 JavaScript 都不应该被执行,例如我们会在重建快照时将 `script` 标签改为 `noscript` 标签,此时 script 内部的内容就不再重要,录制时可以简单记录一个标记值而不需要将可能存在的大量脚本内容全部记录。
2424
2. 记录没有反映在 HTML 中的视图状态。例如 `<input type="text" />` 输入后的值不会反映在其 HTML 中,而是通过 `value` 属性记录,我们在序列化时就需要读出该值并且以属性的形式回放成 `<input type="text" value="recordValue" />`
25-
3. 相对路径转换为绝对路径。回放时我们会将被录制的页面放置在一个 `<iframe>` 中,此时的页面 URL为重放页面的地址,如果被录制页面中有一些相对路径就会产生错误,所以在录制时就要将相对路径进行转换,同样的 CSS 样式表中的相对路径也需要转换。
25+
3. 相对路径转换为绝对路径。回放时我们会将被录制的页面放置在一个 `<iframe>` 中,此时的页面 URL 为重放页面的地址,如果被录制页面中有一些相对路径就会产生错误,所以在录制时就要将相对路径进行转换,同样的 CSS 样式表中的相对路径也需要转换。
2626
4. 尽量记录 CSS 样式表的内容。如果被录制页面加载了一些同源的 样式表,我们则可以获取到解析好的 CSS rules,录制时将能获取到的样式都 inline 化,这样可以让一些内网环境(如 localhost)的录制也有比较好的效果。
2727

2828
## 唯一标识
@@ -34,8 +34,7 @@ $('body').replaceWith(snapshot);
3434
```html
3535
<html>
3636
<body>
37-
<header>
38-
</header>
37+
<header></header>
3938
</body>
4039
</html>
4140
```
@@ -99,12 +98,12 @@ $('body').replaceWith(snapshot);
9998

10099
想象一下如果我们在同页面中记录一次点击按钮的操作并回放,我们可以用以下格式记录该操作(也就是我们所说的一次增量快照):
101100

102-
```javascript
101+
```typescript
103102
type clickSnapshot = {
104103
source: 'MouseInteraction';
105104
type: 'Click';
106105
node: HTMLButtonElement;
107-
}
106+
};
108107
```
109108

110109
再通过 `snapshot.node.click()` 就能将操作再执行一次。
@@ -120,6 +119,5 @@ type clickSnapshot = {
120119
source: 'MouseInteraction';
121120
type: 'Click';
122121
id: Number;
123-
}
122+
};
124123
```
125-

guide.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ The parameter of `rrweb.record` accepts the following options.
143143
| blockClass | 'rr-block' | Use a string or RegExp to configure which elements should be blocked, refer to the [privacy](#privacy) chapter |
144144
| blockSelector | null | Use a string to configure which selector should be blocked, refer to the [privacy](#privacy) chapter |
145145
| ignoreClass | 'rr-ignore' | Use a string or RegExp to configure which elements should be ignored, refer to the [privacy](#privacy) chapter |
146-
| ignoreCSSAttributes | null | array of CSS attributes that should be ignored |
146+
| ignoreCSSAttributes | null | array of CSS attributes that should be ignored |
147147
| maskTextClass | 'rr-mask' | Use a string or RegExp to configure which elements should be masked, refer to the [privacy](#privacy) chapter |
148148
| maskTextSelector | null | Use a string to configure which selector should be masked, refer to the [privacy](#privacy) chapter |
149149
| maskAllInputs | false | mask all input content as \* |

packages/rrweb-player/README.md

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
*Psst — looking for a shareable component template? Go here --> [sveltejs/component-template](https://github.com/sveltejs/component-template)*
1+
_Psst — looking for a shareable component template? Go here --> [sveltejs/component-template](https://github.com/sveltejs/component-template)_
22

3-
*Looking for a Vue.js version? Go here --> [@preflight-hq/rrweb-player-vue](https://github.com/Preflight-HQ/rrweb-player-vue)*
3+
_Looking for a Vue.js version? Go here --> [@preflight-hq/rrweb-player-vue](https://github.com/Preflight-HQ/rrweb-player-vue)_
44

55
---
66

@@ -17,8 +17,7 @@ degit sveltejs/template svelte-app
1717
cd svelte-app
1818
```
1919

20-
*Note that you will need to have [Node.js](https://nodejs.org) installed.*
21-
20+
_Note that you will need to have [Node.js](https://nodejs.org) installed._
2221

2322
## Get started
2423

@@ -37,7 +36,6 @@ npm run dev
3736

3837
Navigate to [localhost:5000](http://localhost:5000). You should see your app running. Edit a component file in `src`, save it, and reload the page to see your changes.
3938

40-
4139
## Deploying to the web
4240

4341
### With [now](https://zeit.co/now)

packages/rrweb/.release-it.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@
99
"github": {
1010
"release": true
1111
}
12-
}
12+
}

packages/rrweb/src/record/mutation.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,8 @@ export default class MutationBuffer {
554554
/**
555555
* Parent is blocked, ignore all child mutations
556556
*/
557-
if (isBlocked(m.target, this.blockClass, this.blockSelector, true)) return;
557+
if (isBlocked(m.target, this.blockClass, this.blockSelector, true))
558+
return;
558559

559560
m.addedNodes.forEach((n) => this.genAdds(n, m.target));
560561
m.removedNodes.forEach((n) => {

0 commit comments

Comments
 (0)