diff --git a/guide.zh_CN.md b/guide.zh_CN.md
index ab3fd668..43edece2 100644
--- a/guide.zh_CN.md
+++ b/guide.zh_CN.md
@@ -131,29 +131,30 @@ setInterval(save, 10 * 1000);
`rrweb.record(config)` 的 config 部分接受以下参数
-| key | 默认值 | 功能 |
-| -------------------- | ------------------ | ------------------------------------------------------------ |
-| emit | 必填 | 获取当前录制的数据 |
-| checkoutEveryNth | - | 每 N 次事件重新制作一次全量快照
详见[“重新制作快照”](#重新制作快照)章节 |
-| checkoutEveryNms | - | 每 N 毫秒重新制作一次全量快照
详见[“重新制作快照”](#重新制作快照)章节 |
-| blockClass | 'rr-block' | 字符串或正则表达式,可用于自定义屏蔽元素的类名,详见[“隐私”](#隐私)章节 |
-| blockSelector | null | 所有 element.matches(blockSelector)为 true 的元素都不会被录制,回放时取而代之的是一个同等宽高的占位元素 |
-| ignoreClass | 'rr-ignore' | 字符串或正则表达式,可用于自定义忽略元素的类名,详见[“隐私”](#隐私)章节 |
-| maskTextClass | 'rr-mask' | 字符串或正则表达式,可用于自定义忽略元素 text 内容的类名,详见[“隐私”](#隐私)章节 |
-| maskTextSelector | null | 所有 element.matches(maskTextSelector)为 true 的元素及其子元素的 text 内容将会被屏蔽 |
-| maskAllInputs | false | 将所有输入内容记录为 \* |
+| key | 默认值 | 功能 |
+| -------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| emit | 必填 | 获取当前录制的数据 |
+| checkoutEveryNth | - | 每 N 次事件重新制作一次全量快照
详见[“重新制作快照”](#重新制作快照)章节 |
+| checkoutEveryNms | - | 每 N 毫秒重新制作一次全量快照
详见[“重新制作快照”](#重新制作快照)章节 |
+| blockClass | 'rr-block' | 字符串或正则表达式,可用于自定义屏蔽元素的类名,详见[“隐私”](#隐私)章节 |
+| blockSelector | null | 所有 element.matches(blockSelector)为 true 的元素都不会被录制,回放时取而代之的是一个同等宽高的占位元素 |
+| ignoreClass | 'rr-ignore' | 字符串或正则表达式,可用于自定义忽略元素的类名,详见[“隐私”](#隐私)章节 |
+| maskTextClass | 'rr-mask' | 字符串或正则表达式,可用于自定义忽略元素 text 内容的类名,详见[“隐私”](#隐私)章节 |
+| maskTextSelector | null | 所有 element.matches(maskTextSelector)为 true 的元素及其子元素的 text 内容将会被屏蔽 |
+| maskAllInputs | false | 将所有输入内容记录为 \* |
| maskInputOptions | { password: true } | 选择将特定类型的输入框内容记录为 \*
类型详见[列表](https://github.com/rrweb-io/rrweb/blob/588164aa12f1d94576f89ae0210b98f6e971c895/packages/rrweb-snapshot/src/types.ts#L77-L95) |
-| maskInputFn | - | 自定义特定类型的输入框内容记录逻辑 |
-| maskTextFn | - | 自定义文字内容的记录逻辑 |
-| slimDOMOptions | {} | 去除 DOM 中不必要的部分
类型详见[列表](https://github.com/rrweb-io/rrweb/blob/588164aa12f1d94576f89ae0210b98f6e971c895/packages/rrweb-snapshot/src/types.ts#L97-L108) |
-| 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 | 是否记录页面中的字体文件 |
-| userTriggeredOnInput | false | [什么是 `userTriggered`](https://github.com/rrweb-io/rrweb/pull/495) |
-| plugins | [] | 加载插件以获得额外的录制功能. [什么是插件?](./docs/recipes/plugin.zh_CN.md) |
+| maskInputFn | - | 自定义特定类型的输入框内容记录逻辑 |
+| maskTextFn | - | 自定义文字内容的记录逻辑 |
+| slimDOMOptions | {} | 去除 DOM 中不必要的部分
类型详见[列表](https://github.com/rrweb-io/rrweb/blob/588164aa12f1d94576f89ae0210b98f6e971c895/packages/rrweb-snapshot/src/types.ts#L97-L108) |
+| 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 内容 |
+| inlineImages | false | 是否将图片内容记内联录制 |
+| collectFonts | false | 是否记录页面中的字体文件 |
+| userTriggeredOnInput | false | [什么是 `userTriggered`](https://github.com/rrweb-io/rrweb/pull/495) |
+| plugins | [] | 加载插件以获得额外的录制功能. [什么是插件?](./docs/recipes/plugin.zh_CN.md) |
#### 隐私
@@ -281,23 +282,23 @@ replayer.pause(5000);
可以通过 `new rrweb.Replayer(events, options)` 的方式向 rrweb 传递回放时的配置参数,具体配置如下:
-| key | 默认值 | 功能 |
-| ------------------- | ------------- | ------------------------------------------------------------ |
-| speed | 1 | 回放倍速 |
-| root | document.body | 回放时使用的 HTML 元素 |
-| loadTimeout | 0 | 加载异步样式表的超时时长 |
-| skipInactive | false | 是否快速跳过无用户操作的阶段 |
-| showWarning | true | 是否在回放过程中打印警告信息 |
-| showDebug | false | 是否在回放过程中打印 debug 信息 |
-| blockClass | 'rr-block' | 需要在回放时展示为隐藏区域的元素类名 |
-| liveMode | false | 是否开启直播模式 |
-| insertStyleRules | [] | 可以传入多个 CSS rule string,用于自定义回放时 iframe 内的样式 |
-| triggerFocus | true | 回放时是否回放 focus 交互 |
-| UNSAFE_replayCanvas | false | 回放时是否回放 canvas 内容,**开启后将会关闭沙盒策略,导致一定风险** |
+| key | 默认值 | 功能 |
+| ------------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| speed | 1 | 回放倍速 |
+| root | document.body | 回放时使用的 HTML 元素 |
+| loadTimeout | 0 | 加载异步样式表的超时时长 |
+| skipInactive | false | 是否快速跳过无用户操作的阶段 |
+| showWarning | true | 是否在回放过程中打印警告信息 |
+| showDebug | false | 是否在回放过程中打印 debug 信息 |
+| blockClass | 'rr-block' | 需要在回放时展示为隐藏区域的元素类名 |
+| liveMode | false | 是否开启直播模式 |
+| 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) |
-| plugins | [] | 加载插件以获得额外的回放功能. [什么是插件?](./docs/recipes/plugin.zh_CN.md) |
+| unpackFn | - | 数据解压缩函数,详见[优化存储策略](./docs/recipes/optimize-storage.zh_CN.md) |
+| logConfig | - | console logger 数据播放设置,详见[console 录制和播放](./docs/recipes/console.zh_CN.md) |
+| plugins | [] | 加载插件以获得额外的回放功能. [什么是插件?](./docs/recipes/plugin.zh_CN.md) |
#### 使用 rrweb-player
diff --git a/packages/rrweb/src/record/index.ts b/packages/rrweb/src/record/index.ts
index 5930913a..e9189c16 100644
--- a/packages/rrweb/src/record/index.ts
+++ b/packages/rrweb/src/record/index.ts
@@ -59,6 +59,7 @@ function record(
recordCanvas = false,
userTriggeredOnInput = false,
collectFonts = false,
+ inlineImages = false,
plugins,
keepIframeSrcFn = () => false,
} = options;
@@ -197,6 +198,7 @@ function record(
maskTextFn,
maskInputFn,
recordCanvas,
+ inlineImages,
sampling,
slimDOMOptions,
iframeManager,
@@ -228,6 +230,7 @@ function record(
maskTextFn,
slimDOM: slimDOMOptions,
recordCanvas,
+ inlineImages,
onSerialize: (n) => {
if (isIframeINode(n)) {
iframeManager.addIframe(n);
@@ -390,6 +393,7 @@ function record(
inlineStylesheet,
sampling,
recordCanvas,
+ inlineImages,
userTriggeredOnInput,
collectFonts,
doc,
diff --git a/packages/rrweb/src/record/mutation.ts b/packages/rrweb/src/record/mutation.ts
index 924c58cd..275843fb 100644
--- a/packages/rrweb/src/record/mutation.ts
+++ b/packages/rrweb/src/record/mutation.ts
@@ -172,6 +172,7 @@ export default class MutationBuffer {
private maskTextFn: MaskTextFn | undefined;
private maskInputFn: MaskInputFn | undefined;
private recordCanvas: boolean;
+ private inlineImages: boolean;
private slimDOMOptions: SlimDOMOptions;
private doc: Document;
@@ -190,6 +191,7 @@ export default class MutationBuffer {
maskTextFn: MaskTextFn | undefined,
maskInputFn: MaskInputFn | undefined,
recordCanvas: boolean,
+ inlineImages: boolean,
slimDOMOptions: SlimDOMOptions,
doc: Document,
mirror: Mirror,
@@ -205,6 +207,7 @@ export default class MutationBuffer {
this.maskTextFn = maskTextFn;
this.maskInputFn = maskInputFn;
this.recordCanvas = recordCanvas;
+ this.inlineImages = inlineImages;
this.slimDOMOptions = slimDOMOptions;
this.emissionCallback = cb;
this.doc = doc;
@@ -296,6 +299,7 @@ export default class MutationBuffer {
maskInputFn: this.maskInputFn,
slimDOMOptions: this.slimDOMOptions,
recordCanvas: this.recordCanvas,
+ inlineImages: this.inlineImages,
onSerialize: (currentN) => {
if (isIframeINode(currentN)) {
this.iframeManager.addIframe(currentN);
@@ -504,7 +508,8 @@ export default class MutationBuffer {
}
}
for (const pname of Array.from(old.style)) {
- if (target.style.getPropertyValue(pname) === '') { // "if not set, returns the empty string"
+ if (target.style.getPropertyValue(pname) === '') {
+ // "if not set, returns the empty string"
styleObj[pname] = false; // delete
}
}
diff --git a/packages/rrweb/src/record/observer.ts b/packages/rrweb/src/record/observer.ts
index d59e57d4..b01ef49e 100644
--- a/packages/rrweb/src/record/observer.ts
+++ b/packages/rrweb/src/record/observer.ts
@@ -97,6 +97,7 @@ export function initMutationObserver(
maskTextFn: MaskTextFn | undefined,
maskInputFn: MaskInputFn | undefined,
recordCanvas: boolean,
+ inlineImages: boolean,
slimDOMOptions: SlimDOMOptions,
mirror: Mirror,
iframeManager: IframeManager,
@@ -117,6 +118,7 @@ export function initMutationObserver(
maskTextFn,
maskInputFn,
recordCanvas,
+ inlineImages,
slimDOMOptions,
doc,
mirror,
@@ -951,6 +953,7 @@ export function initObservers(
o.maskTextFn,
o.maskInputFn,
o.recordCanvas,
+ o.inlineImages,
o.slimDOMOptions,
o.mirror,
o.iframeManager,
diff --git a/packages/rrweb/src/record/shadow-dom-manager.ts b/packages/rrweb/src/record/shadow-dom-manager.ts
index e068bb64..6f2ed26a 100644
--- a/packages/rrweb/src/record/shadow-dom-manager.ts
+++ b/packages/rrweb/src/record/shadow-dom-manager.ts
@@ -25,6 +25,7 @@ type BypassOptions = {
maskTextFn: MaskTextFn | undefined;
maskInputFn: MaskInputFn | undefined;
recordCanvas: boolean;
+ inlineImages: boolean;
sampling: SamplingStrategy;
slimDOMOptions: SlimDOMOptions;
iframeManager: IframeManager;
@@ -61,6 +62,7 @@ export class ShadowDomManager {
this.bypassOptions.maskTextFn,
this.bypassOptions.maskInputFn,
this.bypassOptions.recordCanvas,
+ this.bypassOptions.inlineImages,
this.bypassOptions.slimDOMOptions,
this.mirror,
this.bypassOptions.iframeManager,
diff --git a/packages/rrweb/src/types.ts b/packages/rrweb/src/types.ts
index da904dee..a84a29ed 100644
--- a/packages/rrweb/src/types.ts
+++ b/packages/rrweb/src/types.ts
@@ -230,6 +230,7 @@ export type recordOptions = {
recordCanvas?: boolean;
userTriggeredOnInput?: boolean;
collectFonts?: boolean;
+ inlineImages?: boolean;
plugins?: RecordPlugin[];
// departed, please use sampling options
mousemoveWait?: number;
@@ -259,6 +260,7 @@ export type observerParam = {
fontCb: fontCallback;
sampling: SamplingStrategy;
recordCanvas: boolean;
+ inlineImages: boolean;
userTriggeredOnInput: boolean;
collectFonts: boolean;
slimDOMOptions: SlimDOMOptions;
diff --git a/packages/rrweb/typings/record/mutation.d.ts b/packages/rrweb/typings/record/mutation.d.ts
index b67548e3..e47b1197 100644
--- a/packages/rrweb/typings/record/mutation.d.ts
+++ b/packages/rrweb/typings/record/mutation.d.ts
@@ -23,12 +23,13 @@ export default class MutationBuffer {
private maskTextFn;
private maskInputFn;
private recordCanvas;
+ private inlineImages;
private slimDOMOptions;
private doc;
private mirror;
private iframeManager;
private shadowDomManager;
- init(cb: mutationCallBack, blockClass: blockClass, blockSelector: string | null, maskTextClass: maskTextClass, maskTextSelector: string | null, inlineStylesheet: boolean, maskInputOptions: MaskInputOptions, maskTextFn: MaskTextFn | undefined, maskInputFn: MaskInputFn | undefined, recordCanvas: boolean, slimDOMOptions: SlimDOMOptions, doc: Document, mirror: Mirror, iframeManager: IframeManager, shadowDomManager: ShadowDomManager): void;
+ init(cb: mutationCallBack, blockClass: blockClass, blockSelector: string | null, maskTextClass: maskTextClass, maskTextSelector: string | null, inlineStylesheet: boolean, maskInputOptions: MaskInputOptions, maskTextFn: MaskTextFn | undefined, maskInputFn: MaskInputFn | undefined, recordCanvas: boolean, inlineImages: boolean, slimDOMOptions: SlimDOMOptions, doc: Document, mirror: Mirror, iframeManager: IframeManager, shadowDomManager: ShadowDomManager): void;
freeze(): void;
unfreeze(): void;
isFrozen(): boolean;
diff --git a/packages/rrweb/typings/record/observer.d.ts b/packages/rrweb/typings/record/observer.d.ts
index ffca5918..58965d55 100644
--- a/packages/rrweb/typings/record/observer.d.ts
+++ b/packages/rrweb/typings/record/observer.d.ts
@@ -4,7 +4,7 @@ import MutationBuffer from './mutation';
import { IframeManager } from './iframe-manager';
import { ShadowDomManager } from './shadow-dom-manager';
export declare const mutationBuffers: MutationBuffer[];
-export declare function initMutationObserver(cb: mutationCallBack, doc: Document, blockClass: blockClass, blockSelector: string | null, maskTextClass: maskTextClass, maskTextSelector: string | null, inlineStylesheet: boolean, maskInputOptions: MaskInputOptions, maskTextFn: MaskTextFn | undefined, maskInputFn: MaskInputFn | undefined, recordCanvas: boolean, slimDOMOptions: SlimDOMOptions, mirror: Mirror, iframeManager: IframeManager, shadowDomManager: ShadowDomManager, rootEl: Node): MutationObserver;
+export declare function initMutationObserver(cb: mutationCallBack, doc: Document, blockClass: blockClass, blockSelector: string | null, maskTextClass: maskTextClass, maskTextSelector: string | null, inlineStylesheet: boolean, maskInputOptions: MaskInputOptions, maskTextFn: MaskTextFn | undefined, maskInputFn: MaskInputFn | undefined, recordCanvas: boolean, inlineImages: boolean, slimDOMOptions: SlimDOMOptions, mirror: Mirror, iframeManager: IframeManager, shadowDomManager: ShadowDomManager, rootEl: Node): MutationObserver;
export declare function initScrollObserver(cb: scrollCallback, doc: Document, mirror: Mirror, blockClass: blockClass, sampling: SamplingStrategy): listenerHandler;
export declare const INPUT_TAGS: string[];
export declare function initObservers(o: observerParam, hooks?: hooksParam): listenerHandler;
diff --git a/packages/rrweb/typings/record/shadow-dom-manager.d.ts b/packages/rrweb/typings/record/shadow-dom-manager.d.ts
index c3bbaef7..d31d5727 100644
--- a/packages/rrweb/typings/record/shadow-dom-manager.d.ts
+++ b/packages/rrweb/typings/record/shadow-dom-manager.d.ts
@@ -11,6 +11,7 @@ declare type BypassOptions = {
maskTextFn: MaskTextFn | undefined;
maskInputFn: MaskInputFn | undefined;
recordCanvas: boolean;
+ inlineImages: boolean;
sampling: SamplingStrategy;
slimDOMOptions: SlimDOMOptions;
iframeManager: IframeManager;
diff --git a/packages/rrweb/typings/types.d.ts b/packages/rrweb/typings/types.d.ts
index 7d9c0494..ce27ce41 100644
--- a/packages/rrweb/typings/types.d.ts
+++ b/packages/rrweb/typings/types.d.ts
@@ -122,6 +122,7 @@ export declare type SamplingStrategy = Partial<{
mousemoveCallback: number;
mouseInteraction: boolean | Record;
scroll: number;
+ media: number;
input: 'all' | 'last';
}>;
export declare type RecordPlugin = {
@@ -150,6 +151,7 @@ export declare type recordOptions = {
recordCanvas?: boolean;
userTriggeredOnInput?: boolean;
collectFonts?: boolean;
+ inlineImages?: boolean;
plugins?: RecordPlugin[];
mousemoveWait?: number;
keepIframeSrcFn?: KeepIframeSrcFn;
@@ -177,6 +179,7 @@ export declare type observerParam = {
fontCb: fontCallback;
sampling: SamplingStrategy;
recordCanvas: boolean;
+ inlineImages: boolean;
userTriggeredOnInput: boolean;
collectFonts: boolean;
slimDOMOptions: SlimDOMOptions;
@@ -349,12 +352,15 @@ export declare type inputCallback = (v: inputValue & {
export declare const enum MediaInteractions {
Play = 0,
Pause = 1,
- Seeked = 2
+ Seeked = 2,
+ VolumeChange = 3
}
export declare type mediaInteractionParam = {
type: MediaInteractions;
id: number;
currentTime?: number;
+ volume?: number;
+ muted?: boolean;
};
export declare type mediaInteractionCallback = (p: mediaInteractionParam) => void;
export declare type DocumentDimension = {