From 0333f38b452302b0546e2fee2c7b3843639dabbb Mon Sep 17 00:00:00 2001
From: Joris Machielse
Date: Fri, 2 Oct 2020 09:31:21 +0200
Subject: [PATCH 01/32] =?UTF-8?q?Register=20Enter=20event=20@=20porting=20?=
=?UTF-8?q?from=20@Juice10=E2=80=99s=20rrweb?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
source: @Juice10/record-once-rrweb/commit/d734cf95dbaf7442547
---
src/record/observer.ts | 12 +++++++++---
src/types.ts | 5 +++--
2 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/src/record/observer.ts b/src/record/observer.ts
index 792cd7ff7f..1e0e1afe1f 100644
--- a/src/record/observer.ts
+++ b/src/record/observer.ts
@@ -221,7 +221,7 @@ function initInputObserver(
maskInputOptions: MaskInputOptions,
sampling: SamplingStrategy,
): listenerHandler {
- function eventHandler(event: Event) {
+ function eventHandler(event: KeyboardEvent) { // was Event
const { target } = event;
if (
!target ||
@@ -231,6 +231,11 @@ function initInputObserver(
) {
return;
}
+
+ if (event.type === 'keyup' && event.key === 'Enter') {
+ return cbWithDedup(target, { key: 'Enter' });
+ }
+
const type: string | undefined = (target as HTMLInputElement).type;
if (
type === 'password' ||
@@ -272,7 +277,8 @@ function initInputObserver(
if (
!lastInputValue ||
lastInputValue.text !== v.text ||
- lastInputValue.isChecked !== v.isChecked
+ lastInputValue.isChecked !== v.isChecked ||
+ lastInputValue.key !== v.key
) {
lastInputValueMap.set(target, v);
const id = mirror.getId(target as INode);
@@ -304,7 +310,7 @@ function initInputObserver(
hookSetter(p[0], p[1], {
set() {
// mock to a normal event
- eventHandler({ target: this } as Event);
+ eventHandler({ target: this } as KeyboardEvent); // was Event
},
}),
),
diff --git a/src/types.ts b/src/types.ts
index c68069fa4c..1298c4bd94 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -356,8 +356,9 @@ export type viewportResizeDimention = {
export type viewportResizeCallback = (d: viewportResizeDimention) => void;
export type inputValue = {
- text: string;
- isChecked: boolean;
+ text?: string;
+ isChecked?: boolean;
+ key?: string;
};
export type inputCallback = (v: inputValue & { id: number }) => void;
From 425a04092d8cb036d83bd9e230be7ab8aebe6354 Mon Sep 17 00:00:00 2001
From: Joris Machielse
Date: Fri, 2 Oct 2020 09:39:22 +0200
Subject: [PATCH 02/32] @Juice10: Add a flag for rrweb generated events
Port of @Juice10/record-once-rrweb/commit/0aef9569a7c5eabe167a9abc8aecf8fd5987bf0a
---
src/record/observer.ts | 7 +++++--
src/types.ts | 1 +
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/record/observer.ts b/src/record/observer.ts
index 1e0e1afe1f..357aaf4b0c 100644
--- a/src/record/observer.ts
+++ b/src/record/observer.ts
@@ -223,6 +223,8 @@ function initInputObserver(
): listenerHandler {
function eventHandler(event: KeyboardEvent) { // was Event
const { target } = event;
+ const rrwebGenerated = !event.isTrusted;
+
if (
!target ||
!(target as Element).tagName ||
@@ -233,7 +235,7 @@ function initInputObserver(
}
if (event.type === 'keyup' && event.key === 'Enter') {
- return cbWithDedup(target, { key: 'Enter' });
+ return cbWithDedup(target, { key: 'Enter', rrwebGenerated });
}
const type: string | undefined = (target as HTMLInputElement).type;
@@ -255,7 +257,7 @@ function initInputObserver(
) {
text = '*'.repeat(text.length);
}
- cbWithDedup(target, { text, isChecked });
+ cbWithDedup(target, { text, isChecked, rrwebGenerated });
// if a radio was checked
// the other radios with the same name attribute will be unchecked.
const name: string | undefined = (target as HTMLInputElement).name;
@@ -267,6 +269,7 @@ function initInputObserver(
cbWithDedup(el, {
text: (el as HTMLInputElement).value,
isChecked: !isChecked,
+ rrwebGenerated: true,
});
}
});
diff --git a/src/types.ts b/src/types.ts
index 1298c4bd94..2501776b33 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -359,6 +359,7 @@ export type inputValue = {
text?: string;
isChecked?: boolean;
key?: string;
+ rrwebGenerated: boolean;
};
export type inputCallback = (v: inputValue & { id: number }) => void;
From 0cf62c08571b27513d46c114dd94eedc67bebcfe Mon Sep 17 00:00:00 2001
From: Joris Machielse
Date: Fri, 2 Oct 2020 11:53:09 +0200
Subject: [PATCH 03/32] Do not ignore password fields, but allow them to be
masked instead
---
guide.md | 2 +-
scripts/repl.ts | 6 ++++--
src/record/index.ts | 1 +
src/record/observer.ts | 1 -
4 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/guide.md b/guide.md
index 81e26058c1..2dead127c2 100644
--- a/guide.md
+++ b/guide.md
@@ -108,7 +108,7 @@ You may find some contents on the webpage which are not willing to be recorded,
- An element with the class name `.rr-block` will not be recorded. Instead, it will replay as a placeholder with the same dimension.
- An element with the class name `.rr-ignore` will not record its input events.
-- `input[type="password"]` will be ignored as default.
+- You’ll probably want to mask `input[type="password"]` by adding `maskInputOptions: {password: true}`
#### Checkout
diff --git a/scripts/repl.ts b/scripts/repl.ts
index 417552540a..bcf8013da6 100644
--- a/scripts/repl.ts
+++ b/scripts/repl.ts
@@ -96,7 +96,8 @@ function getCode(): string {
rrweb.record({
emit: event => window._replLog(event),
recordCanvas: true,
- collectFonts: true
+ collectFonts: true,
+ maskInputOptions: { password: true }
});
`);
page.on('framenavigated', async () => {
@@ -107,7 +108,8 @@ function getCode(): string {
rrweb.record({
emit: event => window._replLog(event),
recordCanvas: true,
- collectFonts: true
+ collectFonts: true,
+ maskInputOptions: { password: true }
});
`);
}
diff --git a/src/record/index.ts b/src/record/index.ts
index b5c508427a..5ea1b9c2d3 100644
--- a/src/record/index.ts
+++ b/src/record/index.ts
@@ -62,6 +62,7 @@ function record(
email: true,
month: true,
number: true,
+ password: true,
range: true,
search: true,
tel: true,
diff --git a/src/record/observer.ts b/src/record/observer.ts
index 357aaf4b0c..04604819e2 100644
--- a/src/record/observer.ts
+++ b/src/record/observer.ts
@@ -240,7 +240,6 @@ function initInputObserver(
const type: string | undefined = (target as HTMLInputElement).type;
if (
- type === 'password' ||
(target as HTMLElement).classList.contains(ignoreClass)
) {
return;
From 0159fa1c8377434c0e84a77a2898b71e10ac33c6 Mon Sep 17 00:00:00 2001
From: Joris Machielse
Date: Fri, 2 Oct 2020 12:11:39 +0200
Subject: [PATCH 04/32] Copied electron-inject.js from
@Juice10/record-once-rrweb
And configured some new rrweb options
---
src/electron-inject.js | 37 +++++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)
create mode 100644 src/electron-inject.js
diff --git a/src/electron-inject.js b/src/electron-inject.js
new file mode 100644
index 0000000000..8d02c6b077
--- /dev/null
+++ b/src/electron-inject.js
@@ -0,0 +1,37 @@
+/* eslint-disable import/no-extraneous-dependencies, import/no-unresolved,
+ no-underscore-dangle, no-console */
+
+const { ipcRenderer } = require('electron');
+
+process.once('loaded', () => {
+ console.log('loaded electron-inject.js');
+});
+
+const record = require('rrweb/record').default;
+
+window.__IS_RECORDING__ = true;
+
+record({
+ emit: (event) => {
+ console.log(event);
+
+ const message = {
+ event,
+ window: {
+ scrollX: window.scrollX,
+ scrollY: window.scrollY,
+ innerWidth: window.innerWidth,
+ innerHeight: window.innerHeight,
+ },
+ };
+ ipcRenderer.send('recordedEvent', JSON.stringify(message));
+ },
+ recordCanvas: true,
+ collectFonts: true,
+ maskInputOptions: {
+ password: true,
+ },
+ sampling: {
+ mousemove: false,
+ },
+});
\ No newline at end of file
From 92ca08b276d5968e20a83a64174cf99d44dd9b6b Mon Sep 17 00:00:00 2001
From: Joris Machielse
Date: Fri, 2 Oct 2020 12:31:33 +0200
Subject: [PATCH 05/32] Added build config from @Juice10/record-once-rrweb
---
.gitignore | 1 +
package.json | 19 ++++++++++--
webpack.config-inject.js | 62 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 79 insertions(+), 3 deletions(-)
create mode 100644 webpack.config-inject.js
diff --git a/.gitignore b/.gitignore
index 8b30d6c161..6604722a44 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@ package-lock.json
yarn.lock
build
dist
+dist-electron
es
lib
diff --git a/package.json b/package.json
index 467c4866c0..4384804b9c 100644
--- a/package.json
+++ b/package.json
@@ -7,8 +7,15 @@
"test:watch": "PUPPETEER_HEADLESS=true npm run test -- --watch --watch-extensions js,ts",
"repl": "npm run bundle:browser && cross-env TS_NODE_CACHE=false TS_NODE_FILES=true ts-node scripts/repl.ts",
"bundle:browser": "cross-env BROWSER_ONLY=true rollup --config",
- "bundle": "rollup --config",
- "typings": "tsc -d --declarationDir typings"
+ "bundle:inject": "npx webpack --config webpack.config-inject.js",
+ "bundle:default": "rollup --config",
+ "bundle": "run-s bundle:inject bundle:default",
+ "dev": "run-p dev:**",
+ "dev:default": "rollup --watch --config",
+ "dev:inject": "npx webpack --watch --config webpack.config-inject.js",
+ "typings": "tsc -d --declarationDir typings",
+ "start:client": "webpack-dev-server --config webpack.config.js",
+ "start": "babel-watch ./scrubber/server.js"
},
"repository": {
"type": "git",
@@ -24,6 +31,7 @@
"typings": "typings/entries/all.d.ts",
"files": [
"dist",
+ "dist-electron",
"lib",
"es",
"typings"
@@ -45,6 +53,7 @@
"inquirer": "^6.2.1",
"jest-snapshot": "^23.6.0",
"mocha": "^5.2.0",
+ "npm-run-all": "^4.1.5",
"puppeteer": "^1.11.0",
"rollup": "^2.3.3",
"rollup-plugin-commonjs": "^9.2.0",
@@ -55,7 +64,11 @@
"ts-node": "^7.0.1",
"tslib": "^1.9.3",
"tslint": "^4.5.1",
- "typescript": "^3.9.5"
+ "typescript": "^3.9.5",
+ "webpack-cli": "^3.3.12",
+ "webpack-dev-middleware": "^3.7.2",
+ "webpack-dev-server": "^3.11.0",
+ "webpack-hot-middleware": "^2.25.0"
},
"dependencies": {
"@types/css-font-loading-module": "0.0.4",
diff --git a/webpack.config-inject.js b/webpack.config-inject.js
new file mode 100644
index 0000000000..9013e3a017
--- /dev/null
+++ b/webpack.config-inject.js
@@ -0,0 +1,62 @@
+const path = require('path');
+
+module.exports = {
+ mode: 'development',
+ entry: {
+ app: ['./src/electron-inject'],
+ },
+ output: {
+ path: path.resolve(__dirname, 'dist-electron'),
+ filename: 'index.js',
+ },
+ target: 'electron-preload',
+ resolve: {
+ extensions: ['.tsx', '.ts', '.js', '.mjs'],
+
+ alias: {
+ 'rrweb/record$': path.resolve(__dirname, 'src/record/index.ts'),
+ rrweb$: path.resolve(__dirname, 'src/index.ts'),
+ },
+ },
+ module: {
+
+ rules: [
+ {
+ test: /\.tsx?$/,
+ use: 'ts-loader',
+ exclude: /node_modules/,
+ },
+ {
+ test: /\.css$/i,
+ use: ['style-loader', 'css-loader'],
+ },
+ {
+ test: /\.mjs$/,
+ include: /node_modules/,
+ type: 'javascript/auto',
+ },
+ {
+ test: /scrubber\/scripts\.js$/,
+ exclude: /(node_modules|bower_components)/,
+ use: [
+ {
+ loader: 'babel-loader',
+ options: {
+ presets: [
+ [
+ '@babel/preset-env',
+ {
+ modules: 'auto', // commonjs,amd,umd,systemjs,false
+ useBuiltIns: 'usage',
+ targets: '> 0.25%, not dead',
+ corejs: 3,
+ },
+ ],
+ ],
+ },
+ },
+ ],
+ },
+ ],
+ },
+};
\ No newline at end of file
From 2563ecdb7059b96eb2438d6de1ab60e0d0be7fbd Mon Sep 17 00:00:00 2001
From: Joris Machielse
Date: Fri, 2 Oct 2020 12:42:05 +0200
Subject: [PATCH 06/32] Correcting bundle:inject
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index 4384804b9c..479b48b043 100644
--- a/package.json
+++ b/package.json
@@ -7,7 +7,7 @@
"test:watch": "PUPPETEER_HEADLESS=true npm run test -- --watch --watch-extensions js,ts",
"repl": "npm run bundle:browser && cross-env TS_NODE_CACHE=false TS_NODE_FILES=true ts-node scripts/repl.ts",
"bundle:browser": "cross-env BROWSER_ONLY=true rollup --config",
- "bundle:inject": "npx webpack --config webpack.config-inject.js",
+ "bundle:inject": "npx webpack --config webpack.config-inject.js --mode production",
"bundle:default": "rollup --config",
"bundle": "run-s bundle:inject bundle:default",
"dev": "run-p dev:**",
From 943b18317c3b06c169c2ebf63e1b974818f4f66f Mon Sep 17 00:00:00 2001
From: Joris Machielse
Date: Fri, 2 Oct 2020 13:03:24 +0200
Subject: [PATCH 07/32] Correct dev dependencies
---
package.json | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/package.json b/package.json
index 479b48b043..e943f25699 100644
--- a/package.json
+++ b/package.json
@@ -43,17 +43,26 @@
},
"homepage": "https://github.com/rrweb-io/rrweb#readme",
"devDependencies": {
+ "@babel/core": "^7.11.6",
+ "@babel/preset-env": "^7.11.5",
"@types/chai": "^4.1.6",
"@types/inquirer": "0.0.43",
"@types/mocha": "^5.2.5",
"@types/node": "^10.11.7",
+ "@types/node-fetch": "^2.5.7",
"@types/puppeteer": "^1.11.1",
+ "babel-loader": "^8.1.0",
+ "babel-watch": "^7.0.0",
"chai": "^4.2.0",
+ "core-js": "^3.6.5",
"cross-env": "^5.2.0",
+ "css-loader": "^4.3.0",
"inquirer": "^6.2.1",
"jest-snapshot": "^23.6.0",
"mocha": "^5.2.0",
+ "node-fetch": "^2.6.1",
"npm-run-all": "^4.1.5",
+ "path": "^0.12.7",
"puppeteer": "^1.11.0",
"rollup": "^2.3.3",
"rollup-plugin-commonjs": "^9.2.0",
@@ -61,10 +70,13 @@
"rollup-plugin-postcss": "^3.1.1",
"rollup-plugin-terser": "^5.3.0",
"rollup-plugin-typescript": "^1.0.0",
+ "style-loader": "^1.2.1",
+ "ts-loader": "^8.0.4",
"ts-node": "^7.0.1",
"tslib": "^1.9.3",
"tslint": "^4.5.1",
"typescript": "^3.9.5",
+ "webpack": "^4.44.2",
"webpack-cli": "^3.3.12",
"webpack-dev-middleware": "^3.7.2",
"webpack-dev-server": "^3.11.0",
From 27fbb31eef3c6478fae07e89f01ad6bc9af9c50c Mon Sep 17 00:00:00 2001
From: Joris Machielse
Date: Fri, 2 Oct 2020 13:04:10 +0200
Subject: [PATCH 08/32] Copied checks from
@Juice10/record-once-rrweb/commit/903ab8d883593b5167f052ff1a74031f6a7491c8
---
src/replay/index.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/replay/index.ts b/src/replay/index.ts
index 4a547f9b4d..6386adfdf6 100644
--- a/src/replay/index.ts
+++ b/src/replay/index.ts
@@ -1058,8 +1058,8 @@ export class Replayer {
return this.debugNodeNotFound(d, d.id);
}
try {
- ((target as Node) as HTMLInputElement).checked = d.isChecked;
- ((target as Node) as HTMLInputElement).value = d.text;
+ if (d.isChecked) ((target as Node) as HTMLInputElement).checked = d.isChecked;
+ if (d.text) ((target as Node) as HTMLInputElement).value = d.text;
} catch (error) {
// for safe
}
From f569556f2dbeed89e346ea90826ca1f8404df395 Mon Sep 17 00:00:00 2001
From: Joris Machielse
Date: Fri, 2 Oct 2020 13:36:23 +0200
Subject: [PATCH 09/32] =?UTF-8?q?Attempting=20a=20postinstall=20hook?=
=?UTF-8?q?=E2=80=A6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
package.json | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/package.json b/package.json
index e943f25699..f1c3463e71 100644
--- a/package.json
+++ b/package.json
@@ -15,7 +15,8 @@
"dev:inject": "npx webpack --watch --config webpack.config-inject.js",
"typings": "tsc -d --declarationDir typings",
"start:client": "webpack-dev-server --config webpack.config.js",
- "start": "babel-watch ./scrubber/server.js"
+ "start": "babel-watch ./scrubber/server.js",
+ "postinstall": "npm run bundle; npm run typings"
},
"repository": {
"type": "git",
From c210d265210274e6b21e0a75f18ab5642de34489 Mon Sep 17 00:00:00 2001
From: Joris Machielse
Date: Fri, 2 Oct 2020 13:40:27 +0200
Subject: [PATCH 10/32] Do not run typings post install
---
package.json | 2 +-
typings/types.d.ts | 6 ++++--
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/package.json b/package.json
index f1c3463e71..d06ac66502 100644
--- a/package.json
+++ b/package.json
@@ -16,7 +16,7 @@
"typings": "tsc -d --declarationDir typings",
"start:client": "webpack-dev-server --config webpack.config.js",
"start": "babel-watch ./scrubber/server.js",
- "postinstall": "npm run bundle; npm run typings"
+ "postinstall": "npm run bundle"
},
"repository": {
"type": "git",
diff --git a/typings/types.d.ts b/typings/types.d.ts
index cdb25b0165..3902162e1f 100644
--- a/typings/types.d.ts
+++ b/typings/types.d.ts
@@ -262,8 +262,10 @@ export declare type viewportResizeDimention = {
};
export declare type viewportResizeCallback = (d: viewportResizeDimention) => void;
export declare type inputValue = {
- text: string;
- isChecked: boolean;
+ text?: string;
+ isChecked?: boolean;
+ key?: string;
+ rrwebGenerated: boolean;
};
export declare type inputCallback = (v: inputValue & {
id: number;
From 2831dcfd08f1786009eb50325f72be5da2c51434 Mon Sep 17 00:00:00 2001
From: Joris Machielse
Date: Fri, 2 Oct 2020 13:41:21 +0200
Subject: [PATCH 11/32] Hopefully this does work
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index d06ac66502..4cc614107b 100644
--- a/package.json
+++ b/package.json
@@ -16,7 +16,7 @@
"typings": "tsc -d --declarationDir typings",
"start:client": "webpack-dev-server --config webpack.config.js",
"start": "babel-watch ./scrubber/server.js",
- "postinstall": "npm run bundle"
+ "postinstall": "npm run bundle:inject bundle:default"
},
"repository": {
"type": "git",
From 5d9eeea83d324678143bd320f604f4c2b467d289 Mon Sep 17 00:00:00 2001
From: Joris Machielse
Date: Wed, 20 Jan 2021 13:40:19 +0100
Subject: [PATCH 12/32] Removed electron injection
---
.gitignore | 1 -
package.json | 1 -
src/electron-inject.js | 37 ------------------------
webpack.config-inject.js | 62 ----------------------------------------
4 files changed, 101 deletions(-)
delete mode 100644 src/electron-inject.js
delete mode 100644 webpack.config-inject.js
diff --git a/.gitignore b/.gitignore
index 6604722a44..8b30d6c161 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,7 +4,6 @@ package-lock.json
yarn.lock
build
dist
-dist-electron
es
lib
diff --git a/package.json b/package.json
index 4cc614107b..932e465408 100644
--- a/package.json
+++ b/package.json
@@ -32,7 +32,6 @@
"typings": "typings/entries/all.d.ts",
"files": [
"dist",
- "dist-electron",
"lib",
"es",
"typings"
diff --git a/src/electron-inject.js b/src/electron-inject.js
deleted file mode 100644
index 8d02c6b077..0000000000
--- a/src/electron-inject.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* eslint-disable import/no-extraneous-dependencies, import/no-unresolved,
- no-underscore-dangle, no-console */
-
-const { ipcRenderer } = require('electron');
-
-process.once('loaded', () => {
- console.log('loaded electron-inject.js');
-});
-
-const record = require('rrweb/record').default;
-
-window.__IS_RECORDING__ = true;
-
-record({
- emit: (event) => {
- console.log(event);
-
- const message = {
- event,
- window: {
- scrollX: window.scrollX,
- scrollY: window.scrollY,
- innerWidth: window.innerWidth,
- innerHeight: window.innerHeight,
- },
- };
- ipcRenderer.send('recordedEvent', JSON.stringify(message));
- },
- recordCanvas: true,
- collectFonts: true,
- maskInputOptions: {
- password: true,
- },
- sampling: {
- mousemove: false,
- },
-});
\ No newline at end of file
diff --git a/webpack.config-inject.js b/webpack.config-inject.js
deleted file mode 100644
index 9013e3a017..0000000000
--- a/webpack.config-inject.js
+++ /dev/null
@@ -1,62 +0,0 @@
-const path = require('path');
-
-module.exports = {
- mode: 'development',
- entry: {
- app: ['./src/electron-inject'],
- },
- output: {
- path: path.resolve(__dirname, 'dist-electron'),
- filename: 'index.js',
- },
- target: 'electron-preload',
- resolve: {
- extensions: ['.tsx', '.ts', '.js', '.mjs'],
-
- alias: {
- 'rrweb/record$': path.resolve(__dirname, 'src/record/index.ts'),
- rrweb$: path.resolve(__dirname, 'src/index.ts'),
- },
- },
- module: {
-
- rules: [
- {
- test: /\.tsx?$/,
- use: 'ts-loader',
- exclude: /node_modules/,
- },
- {
- test: /\.css$/i,
- use: ['style-loader', 'css-loader'],
- },
- {
- test: /\.mjs$/,
- include: /node_modules/,
- type: 'javascript/auto',
- },
- {
- test: /scrubber\/scripts\.js$/,
- exclude: /(node_modules|bower_components)/,
- use: [
- {
- loader: 'babel-loader',
- options: {
- presets: [
- [
- '@babel/preset-env',
- {
- modules: 'auto', // commonjs,amd,umd,systemjs,false
- useBuiltIns: 'usage',
- targets: '> 0.25%, not dead',
- corejs: 3,
- },
- ],
- ],
- },
- },
- ],
- },
- ],
- },
-};
\ No newline at end of file
From 9e4c36f6aed4152fe07b36fec73d3b21d322e489 Mon Sep 17 00:00:00 2001
From: Justin Halsall
Date: Thu, 18 Feb 2021 12:10:54 +0100
Subject: [PATCH 13/32] Revert "Added build config from
@Juice10/record-once-rrweb"
This reverts commit 92ca08b276d5968e20a83a64174cf99d44dd9b6b.
---
package.json | 19 +++----------------
1 file changed, 3 insertions(+), 16 deletions(-)
diff --git a/package.json b/package.json
index de76f52e08..22a8d15b18 100644
--- a/package.json
+++ b/package.json
@@ -7,16 +7,8 @@
"test:watch": "PUPPETEER_HEADLESS=true npm run test -- --watch --watch-extensions js,ts",
"repl": "npm run bundle:browser && cross-env TS_NODE_CACHE=false TS_NODE_FILES=true ts-node scripts/repl.ts",
"bundle:browser": "cross-env BROWSER_ONLY=true rollup --config",
- "bundle:inject": "npx webpack --config webpack.config-inject.js --mode production",
- "bundle:default": "rollup --config",
- "bundle": "run-s bundle:inject bundle:default",
- "dev": "run-p dev:**",
- "dev:default": "rollup --watch --config",
- "dev:inject": "npx webpack --watch --config webpack.config-inject.js",
- "typings": "tsc -d --declarationDir typings",
- "start:client": "webpack-dev-server --config webpack.config.js",
- "start": "babel-watch ./scrubber/server.js",
- "postinstall": "npm run bundle:inject bundle:default"
+ "bundle": "rollup --config",
+ "typings": "tsc -d --declarationDir typings"
},
"repository": {
"type": "git",
@@ -73,12 +65,7 @@
"ts-node": "^7.0.1",
"tslib": "^1.9.3",
"tslint": "^4.5.1",
- "typescript": "^3.9.5",
- "webpack": "^4.44.2",
- "webpack-cli": "^3.3.12",
- "webpack-dev-middleware": "^3.7.2",
- "webpack-dev-server": "^3.11.0",
- "webpack-hot-middleware": "^2.25.0"
+ "typescript": "^3.9.5"
},
"dependencies": {
"@types/css-font-loading-module": "0.0.4",
From 7c269d75861ab8d46a392df0fc414bbc8ab6f82e Mon Sep 17 00:00:00 2001
From: Justin Halsall
Date: Thu, 18 Feb 2021 13:24:59 +0100
Subject: [PATCH 14/32] add ability to mask passwords
---
guide.md | 40 +-
guide.zh_CN.md | 40 +-
src/record/index.ts | 3 +-
src/record/observer.ts | 5 +-
test/__snapshots__/integration.test.ts.snap | 879 +++++++++-----------
test/html/form.html | 3 +
test/html/ignore.html | 1 -
test/integration.test.ts | 4 +-
8 files changed, 441 insertions(+), 534 deletions(-)
diff --git a/guide.md b/guide.md
index 3912210123..4018117c96 100644
--- a/guide.md
+++ b/guide.md
@@ -135,25 +135,25 @@ setInterval(save, 10 * 1000);
The parameter of `rrweb.record` accepts the following options.
-| key | default | description |
-| ---------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| emit | required | the callback function to get emitted events |
-| checkoutEveryNth | - | take a full snapshot after every N events
refer to the [checkout](#checkout) chapter |
-| 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) |
-| sampling | - | refer to the [storage optimization recipe](./docs/recipes/optimize-storage.md) |
-| recordCanvas | false | whether to record the canvas element |
-| collectFonts | false | whether to collect fonts in the website |
-| recordLog | false | whether to record console output, refer to the [console recipe](./docs/recipes/console.md) |
+| key | default | description |
+| ---------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| emit | required | the callback function to get emitted events |
+| checkoutEveryNth | - | take a full snapshot after every N events
refer to the [checkout](#checkout) chapter |
+| 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 | { password: true } | 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) |
+| sampling | - | refer to the [storage optimization recipe](./docs/recipes/optimize-storage.md) |
+| recordCanvas | false | whether to record the canvas element |
+| collectFonts | false | whether to collect fonts in the website |
+| recordLog | false | whether to record console output, refer to the [console recipe](./docs/recipes/console.md) |
#### Privacy
@@ -161,8 +161,8 @@ You may find some contents on the webpage which are not willing to be recorded,
- An element with the class name `.rr-block` will not be recorded. Instead, it will replay as a placeholder with the same dimension.
- An element with the class name `.rr-ignore` will not record its input events.
-- `input[type="password"]` will be ignored as default.
- Mask options to mask the content in input elements.
+- `input[type="password"]` will be masked as default.
#### Checkout
diff --git a/guide.zh_CN.md b/guide.zh_CN.md
index 4280a58da3..967d2ab230 100644
--- a/guide.zh_CN.md
+++ b/guide.zh_CN.md
@@ -131,25 +131,25 @@ setInterval(save, 10 * 1000);
`rrweb.record(config)` 的 config 部分接受以下参数
-| key | 默认值 | 功能 |
-| ---------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
-| emit | 必填 | 获取当前录制的数据 |
-| 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) |
+| key | 默认值 | 功能 |
+| ---------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| emit | 必填 | 获取当前录制的数据 |
+| checkoutEveryNth | - | 每 N 次事件重新制作一次全量快照
详见[“重新制作快照”](#重新制作快照)章节 |
+| checkoutEveryNms | - | 每 N 毫秒重新制作一次全量快照
详见[“重新制作快照”](#重新制作快照)章节 |
+| blockClass | 'rr-block' | 字符串或正则表达式,可用于自定义屏蔽元素的类名,详见[“隐私”](#隐私)章节 |
+| blockSelector | null | 字符串或正则表达式,可用于自定义屏蔽元素的选择器,详见[“隐私”](#隐私)章节 |
+| ignoreClass | 'rr-ignore' | 字符串或正则表达式,可用于自定义忽略元素的类名,详见[“隐私”](#隐私)章节 |
+| maskAllInputs | false | 将所有输入内容记录为 \* |
+| maskInputOptions | { password: true } | 选择将特定类型的输入框内容记录为 \*
类型详见[列表](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) |
#### 隐私
@@ -157,8 +157,8 @@ setInterval(save, 10 * 1000);
- 在 HTML 元素中添加类名 `.rr-block` 将会避免该元素及其子元素被录制,回放时取而代之的是一个同等宽高的占位元素。
- 在 HTML 元素中添加类名 `.rr-ignore` 将会避免录制该元素的输入事件。
-- `input[type="password"]` 类型的密码输入框默认不会录制输入事件。
- 配置中还有更为丰富的隐私保护选项。
+- `input[type="password"]` 类型的密码输入框默认不会录制输入事件。
#### 重新制作快照
diff --git a/src/record/index.ts b/src/record/index.ts
index 70333c0747..03c041914d 100644
--- a/src/record/index.ts
+++ b/src/record/index.ts
@@ -78,10 +78,11 @@ function record(
week: true,
textarea: true,
select: true,
+ password: true,
}
: _maskInputOptions !== undefined
? _maskInputOptions
- : {};
+ : { password: true };
const slimDOMOptions: SlimDOMOptions =
_slimDOMOptions === true || _slimDOMOptions === 'all'
diff --git a/src/record/observer.ts b/src/record/observer.ts
index d71a8b0fd1..26e429e5c6 100644
--- a/src/record/observer.ts
+++ b/src/record/observer.ts
@@ -298,10 +298,7 @@ function initInputObserver(
return;
}
const type: string | undefined = (target as HTMLInputElement).type;
- if (
- type === 'password' ||
- (target as HTMLElement).classList.contains(ignoreClass)
- ) {
+ if ((target as HTMLElement).classList.contains(ignoreClass)) {
return;
}
let text = (target as HTMLInputElement).value;
diff --git a/test/__snapshots__/integration.test.ts.snap b/test/__snapshots__/integration.test.ts.snap
index f205fe9562..391cdceef8 100644
--- a/test/__snapshots__/integration.test.ts.snap
+++ b/test/__snapshots__/integration.test.ts.snap
@@ -1229,8 +1229,42 @@ exports[`form 1`] = `
},
{
\\"type\\": 3,
- \\"textContent\\": \\"\\\\n \\",
+ \\"textContent\\": \\"\\\\n \\",
\\"id\\": 51
+ },
+ {
+ \\"type\\": 2,
+ \\"tagName\\": \\"label\\",
+ \\"attributes\\": {
+ \\"for\\": \\"password\\"
+ },
+ \\"childNodes\\": [
+ {
+ \\"type\\": 3,
+ \\"textContent\\": \\"\\\\n \\",
+ \\"id\\": 53
+ },
+ {
+ \\"type\\": 2,
+ \\"tagName\\": \\"input\\",
+ \\"attributes\\": {
+ \\"type\\": \\"password\\"
+ },
+ \\"childNodes\\": [],
+ \\"id\\": 54
+ },
+ {
+ \\"type\\": 3,
+ \\"textContent\\": \\"\\\\n \\",
+ \\"id\\": 55
+ }
+ ],
+ \\"id\\": 52
+ },
+ {
+ \\"type\\": 3,
+ \\"textContent\\": \\"\\\\n \\",
+ \\"id\\": 56
}
],
\\"id\\": 18
@@ -1238,7 +1272,7 @@ exports[`form 1`] = `
{
\\"type\\": 3,
\\"textContent\\": \\"\\\\n\\\\n \\",
- \\"id\\": 52
+ \\"id\\": 57
},
{
\\"type\\": 2,
@@ -1248,15 +1282,15 @@ exports[`form 1`] = `
{
\\"type\\": 3,
\\"textContent\\": \\"SCRIPT_PLACEHOLDER\\",
- \\"id\\": 54
+ \\"id\\": 59
}
],
- \\"id\\": 53
+ \\"id\\": 58
},
{
\\"type\\": 3,
\\"textContent\\": \\"\\\\n \\\\n \\\\n\\\\n\\\\n\\",
- \\"id\\": 55
+ \\"id\\": 60
}
],
\\"id\\": 16
@@ -2571,7 +2605,7 @@ exports[`ignore 1`] = `
\\"type\\": 2,
\\"tagName\\": \\"label\\",
\\"attributes\\": {
- \\"for\\": \\"password\\"
+ \\"for\\": \\"ignore text\\"
},
\\"childNodes\\": [
{
@@ -2583,7 +2617,8 @@ exports[`ignore 1`] = `
\\"type\\": 2,
\\"tagName\\": \\"input\\",
\\"attributes\\": {
- \\"type\\": \\"password\\"
+ \\"type\\": \\"text\\",
+ \\"class\\": \\"rr-ignore\\"
},
\\"childNodes\\": [],
\\"id\\": 22
@@ -2596,45 +2631,10 @@ exports[`ignore 1`] = `
],
\\"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\\": 24
}
],
\\"id\\": 18
@@ -2642,7 +2642,7 @@ exports[`ignore 1`] = `
{
\\"type\\": 3,
\\"textContent\\": \\"\\\\n \\\\n \\",
- \\"id\\": 30
+ \\"id\\": 25
},
{
\\"type\\": 2,
@@ -2652,15 +2652,15 @@ exports[`ignore 1`] = `
{
\\"type\\": 3,
\\"textContent\\": \\"SCRIPT_PLACEHOLDER\\",
- \\"id\\": 32
+ \\"id\\": 27
}
],
- \\"id\\": 31
+ \\"id\\": 26
},
{
\\"type\\": 3,
\\"textContent\\": \\"\\\\n \\\\n \\\\n\\\\n\\",
- \\"id\\": 33
+ \\"id\\": 28
}
],
\\"id\\": 16
@@ -2684,27 +2684,11 @@ exports[`ignore 1`] = `
\\"type\\": 5,
\\"id\\": 22
}
- },
- {
- \\"type\\": 3,
- \\"data\\": {
- \\"source\\": 2,
- \\"type\\": 6,
- \\"id\\": 22
- }
- },
- {
- \\"type\\": 3,
- \\"data\\": {
- \\"source\\": 2,
- \\"type\\": 5,
- \\"id\\": 27
- }
}
]"
`;
-exports[`log`] = `
+exports[`log 1`] = `
"[
{
\\"type\\": 0,
@@ -2870,9 +2854,13 @@ exports[`log`] = `
\\"data\\": {
\\"source\\": 11,
\\"level\\": \\"assert\\",
+ \\"trace\\": [
+ \\"__puppeteer_evalu\\",
+ \\"ion_script__:2:37\\"
+ ],
\\"payload\\": [
\\"true\\",
- \\"\\"assert\\"\\"
+ \\"\\\\\\"assert\\\\\\"\\"
]
}
},
@@ -2881,8 +2869,12 @@ exports[`log`] = `
\\"data\\": {
\\"source\\": 11,
\\"level\\": \\"count\\",
+ \\"trace\\": [
+ \\"__puppeteer_evalu\\",
+ \\"ion_script__:3:37\\"
+ ],
\\"payload\\": [
- \\"\\"count\\"\\"
+ \\"\\\\\\"count\\\\\\"\\"
]
}
},
@@ -2891,8 +2883,12 @@ exports[`log`] = `
\\"data\\": {
\\"source\\": 11,
\\"level\\": \\"countReset\\",
+ \\"trace\\": [
+ \\"__puppeteer_evalu\\",
+ \\"ion_script__:4:37\\"
+ ],
\\"payload\\": [
- \\"\\"count\\"\\"
+ \\"\\\\\\"count\\\\\\"\\"
]
}
},
@@ -2901,8 +2897,12 @@ exports[`log`] = `
\\"data\\": {
\\"source\\": 11,
\\"level\\": \\"debug\\",
+ \\"trace\\": [
+ \\"__puppeteer_evalu\\",
+ \\"ion_script__:5:37\\"
+ ],
\\"payload\\": [
- \\"\\"debug\\"\\"
+ \\"\\\\\\"debug\\\\\\"\\"
]
}
},
@@ -2911,8 +2911,12 @@ exports[`log`] = `
\\"data\\": {
\\"source\\": 11,
\\"level\\": \\"dir\\",
+ \\"trace\\": [
+ \\"__puppeteer_evalu\\",
+ \\"ion_script__:6:37\\"
+ ],
\\"payload\\": [
- \\"\\"dir\\"\\"
+ \\"\\\\\\"dir\\\\\\"\\"
]
}
},
@@ -2921,8 +2925,12 @@ exports[`log`] = `
\\"data\\": {
\\"source\\": 11,
\\"level\\": \\"dirxml\\",
+ \\"trace\\": [
+ \\"__puppeteer_evalu\\",
+ \\"ion_script__:7:37\\"
+ ],
\\"payload\\": [
- \\"\\"dirxml\\"\\"
+ \\"\\\\\\"dirxml\\\\\\"\\"
]
}
},
@@ -2931,6 +2939,10 @@ exports[`log`] = `
\\"data\\": {
\\"source\\": 11,
\\"level\\": \\"group\\",
+ \\"trace\\": [
+ \\"__puppeteer_evalu\\",
+ \\"ion_script__:8:37\\"
+ ],
\\"payload\\": []
}
},
@@ -2939,6 +2951,10 @@ exports[`log`] = `
\\"data\\": {
\\"source\\": 11,
\\"level\\": \\"groupCollapsed\\",
+ \\"trace\\": [
+ \\"__puppeteer_evalu\\",
+ \\"ion_script__:9:37\\"
+ ],
\\"payload\\": []
}
},
@@ -2947,8 +2963,12 @@ exports[`log`] = `
\\"data\\": {
\\"source\\": 11,
\\"level\\": \\"info\\",
+ \\"trace\\": [
+ \\"__puppeteer_evalu\\",
+ \\"ion_script__:10:37\\"
+ ],
\\"payload\\": [
- \\"\\"info\\"\\"
+ \\"\\\\\\"info\\\\\\"\\"
]
}
},
@@ -2957,8 +2977,12 @@ exports[`log`] = `
\\"data\\": {
\\"source\\": 11,
\\"level\\": \\"log\\",
+ \\"trace\\": [
+ \\"__puppeteer_evalu\\",
+ \\"ion_script__:11:37\\"
+ ],
\\"payload\\": [
- \\"\\"log\\"\\"
+ \\"\\\\\\"log\\\\\\"\\"
]
}
},
@@ -2967,8 +2991,12 @@ exports[`log`] = `
\\"data\\": {
\\"source\\": 11,
\\"level\\": \\"table\\",
+ \\"trace\\": [
+ \\"__puppeteer_evalu\\",
+ \\"ion_script__:12:37\\"
+ ],
\\"payload\\": [
- \\"\\"table\\"\\"
+ \\"\\\\\\"table\\\\\\"\\"
]
}
},
@@ -2977,6 +3005,10 @@ exports[`log`] = `
\\"data\\": {
\\"source\\": 11,
\\"level\\": \\"time\\",
+ \\"trace\\": [
+ \\"__puppeteer_evalu\\",
+ \\"ion_script__:13:37\\"
+ ],
\\"payload\\": []
}
},
@@ -2985,6 +3017,10 @@ exports[`log`] = `
\\"data\\": {
\\"source\\": 11,
\\"level\\": \\"timeEnd\\",
+ \\"trace\\": [
+ \\"__puppeteer_evalu\\",
+ \\"ion_script__:14:37\\"
+ ],
\\"payload\\": []
}
},
@@ -2993,6 +3029,10 @@ exports[`log`] = `
\\"data\\": {
\\"source\\": 11,
\\"level\\": \\"timeLog\\",
+ \\"trace\\": [
+ \\"__puppeteer_evalu\\",
+ \\"ion_script__:15:37\\"
+ ],
\\"payload\\": []
}
},
@@ -3001,8 +3041,12 @@ exports[`log`] = `
\\"data\\": {
\\"source\\": 11,
\\"level\\": \\"trace\\",
+ \\"trace\\": [
+ \\"__puppeteer_evalu\\",
+ \\"ion_script__:16:37\\"
+ ],
\\"payload\\": [
- \\"\\"trace\\"\\"
+ \\"\\\\\\"trace\\\\\\"\\"
]
}
},
@@ -3011,8 +3055,12 @@ exports[`log`] = `
\\"data\\": {
\\"source\\": 11,
\\"level\\": \\"warn\\",
+ \\"trace\\": [
+ \\"__puppeteer_evalu\\",
+ \\"ion_script__:17:37\\"
+ ],
\\"payload\\": [
- \\"\\"warn\\"\\"
+ \\"\\\\\\"warn\\\\\\"\\"
]
}
},
@@ -3021,13 +3069,17 @@ exports[`log`] = `
\\"data\\": {
\\"source\\": 11,
\\"level\\": \\"clear\\",
+ \\"trace\\": [
+ \\"__puppeteer_evalu\\",
+ \\"ion_script__:18:37\\"
+ ],
\\"payload\\": []
}
}
]"
`;
-exports[`log 1`] = `
+exports[`mask 1`] = `
"[
{
\\"type\\": 0,
@@ -3072,7 +3124,7 @@ exports[`log 1`] = `
\\"childNodes\\": [
{
\\"type\\": 3,
- \\"textContent\\": \\"\\\\n \\",
+ \\"textContent\\": \\"\\\\n \\",
\\"id\\": 5
},
{
@@ -3086,7 +3138,7 @@ exports[`log 1`] = `
},
{
\\"type\\": 3,
- \\"textContent\\": \\"\\\\n \\",
+ \\"textContent\\": \\"\\\\n \\",
\\"id\\": 7
},
{
@@ -3101,7 +3153,7 @@ exports[`log 1`] = `
},
{
\\"type\\": 3,
- \\"textContent\\": \\"\\\\n \\",
+ \\"textContent\\": \\"\\\\n \\",
\\"id\\": 9
},
{
@@ -3116,7 +3168,7 @@ exports[`log 1`] = `
},
{
\\"type\\": 3,
- \\"textContent\\": \\"\\\\n \\",
+ \\"textContent\\": \\"\\\\n \\",
\\"id\\": 11
},
{
@@ -3126,7 +3178,7 @@ exports[`log 1`] = `
\\"childNodes\\": [
{
\\"type\\": 3,
- \\"textContent\\": \\"Log record\\",
+ \\"textContent\\": \\"form fields\\",
\\"id\\": 13
}
],
@@ -3134,7 +3186,7 @@ exports[`log 1`] = `
},
{
\\"type\\": 3,
- \\"textContent\\": \\"\\\\n \\",
+ \\"textContent\\": \\"\\\\n\\",
\\"id\\": 14
}
],
@@ -3142,7 +3194,7 @@ exports[`log 1`] = `
},
{
\\"type\\": 3,
- \\"textContent\\": \\"\\\\n \\",
+ \\"textContent\\": \\"\\\\n\\\\n\\",
\\"id\\": 15
},
{
@@ -3152,408 +3204,17 @@ exports[`log 1`] = `
\\"childNodes\\": [
{
\\"type\\": 3,
- \\"textContent\\": \\"\\\\n \\",
+ \\"textContent\\": \\"\\\\n \\",
\\"id\\": 17
},
{
\\"type\\": 2,
- \\"tagName\\": \\"script\\",
+ \\"tagName\\": \\"form\\",
\\"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
- }
- }
- },
- {
- \\"type\\": 3,
- \\"data\\": {
- \\"source\\": 11,
- \\"level\\": \\"assert\\",
- \\"trace\\": [
- \\"__puppeteer_evalu\\",
- \\"ion_script__:2:37\\"
- ],
- \\"payload\\": [
- \\"true\\",
- \\"\\\\\\"assert\\\\\\"\\"
- ]
- }
- },
- {
- \\"type\\": 3,
- \\"data\\": {
- \\"source\\": 11,
- \\"level\\": \\"count\\",
- \\"trace\\": [
- \\"__puppeteer_evalu\\",
- \\"ion_script__:3:37\\"
- ],
- \\"payload\\": [
- \\"\\\\\\"count\\\\\\"\\"
- ]
- }
- },
- {
- \\"type\\": 3,
- \\"data\\": {
- \\"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[`mask 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\\": 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\\": \\"form fields\\",
- \\"id\\": 13
- }
- ],
- \\"id\\": 12
- },
- {
- \\"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
- },
- {
- \\"type\\": 2,
- \\"tagName\\": \\"form\\",
- \\"attributes\\": {},
- \\"childNodes\\": [
- {
- \\"type\\": 3,
- \\"textContent\\": \\"\\\\n \\",
+ \\"textContent\\": \\"\\\\n \\",
\\"id\\": 19
},
{
@@ -3775,8 +3436,42 @@ exports[`mask 1`] = `
},
{
\\"type\\": 3,
- \\"textContent\\": \\"\\\\n \\",
+ \\"textContent\\": \\"\\\\n \\",
\\"id\\": 51
+ },
+ {
+ \\"type\\": 2,
+ \\"tagName\\": \\"label\\",
+ \\"attributes\\": {
+ \\"for\\": \\"password\\"
+ },
+ \\"childNodes\\": [
+ {
+ \\"type\\": 3,
+ \\"textContent\\": \\"\\\\n \\",
+ \\"id\\": 53
+ },
+ {
+ \\"type\\": 2,
+ \\"tagName\\": \\"input\\",
+ \\"attributes\\": {
+ \\"type\\": \\"password\\"
+ },
+ \\"childNodes\\": [],
+ \\"id\\": 54
+ },
+ {
+ \\"type\\": 3,
+ \\"textContent\\": \\"\\\\n \\",
+ \\"id\\": 55
+ }
+ ],
+ \\"id\\": 52
+ },
+ {
+ \\"type\\": 3,
+ \\"textContent\\": \\"\\\\n \\",
+ \\"id\\": 56
}
],
\\"id\\": 18
@@ -3784,7 +3479,7 @@ exports[`mask 1`] = `
{
\\"type\\": 3,
\\"textContent\\": \\"\\\\n\\\\n \\",
- \\"id\\": 52
+ \\"id\\": 57
},
{
\\"type\\": 2,
@@ -3794,15 +3489,15 @@ exports[`mask 1`] = `
{
\\"type\\": 3,
\\"textContent\\": \\"SCRIPT_PLACEHOLDER\\",
- \\"id\\": 54
+ \\"id\\": 59
}
],
- \\"id\\": 53
+ \\"id\\": 58
},
{
\\"type\\": 3,
\\"textContent\\": \\"\\\\n \\\\n \\\\n\\\\n\\\\n\\",
- \\"id\\": 55
+ \\"id\\": 60
}
],
\\"id\\": 16
@@ -3969,6 +3664,94 @@ exports[`mask 1`] = `
\\"id\\": 32
}
},
+ {
+ \\"type\\": 3,
+ \\"data\\": {
+ \\"source\\": 2,
+ \\"type\\": 5,
+ \\"id\\": 54
+ }
+ },
+ {
+ \\"type\\": 3,
+ \\"data\\": {
+ \\"source\\": 5,
+ \\"text\\": \\"*\\",
+ \\"isChecked\\": false,
+ \\"id\\": 54
+ }
+ },
+ {
+ \\"type\\": 3,
+ \\"data\\": {
+ \\"source\\": 5,
+ \\"text\\": \\"**\\",
+ \\"isChecked\\": false,
+ \\"id\\": 54
+ }
+ },
+ {
+ \\"type\\": 3,
+ \\"data\\": {
+ \\"source\\": 5,
+ \\"text\\": \\"***\\",
+ \\"isChecked\\": false,
+ \\"id\\": 54
+ }
+ },
+ {
+ \\"type\\": 3,
+ \\"data\\": {
+ \\"source\\": 5,
+ \\"text\\": \\"****\\",
+ \\"isChecked\\": false,
+ \\"id\\": 54
+ }
+ },
+ {
+ \\"type\\": 3,
+ \\"data\\": {
+ \\"source\\": 5,
+ \\"text\\": \\"*****\\",
+ \\"isChecked\\": false,
+ \\"id\\": 54
+ }
+ },
+ {
+ \\"type\\": 3,
+ \\"data\\": {
+ \\"source\\": 5,
+ \\"text\\": \\"******\\",
+ \\"isChecked\\": false,
+ \\"id\\": 54
+ }
+ },
+ {
+ \\"type\\": 3,
+ \\"data\\": {
+ \\"source\\": 5,
+ \\"text\\": \\"*******\\",
+ \\"isChecked\\": false,
+ \\"id\\": 54
+ }
+ },
+ {
+ \\"type\\": 3,
+ \\"data\\": {
+ \\"source\\": 5,
+ \\"text\\": \\"********\\",
+ \\"isChecked\\": false,
+ \\"id\\": 54
+ }
+ },
+ {
+ \\"type\\": 3,
+ \\"data\\": {
+ \\"source\\": 2,
+ \\"type\\": 6,
+ \\"id\\": 54
+ }
+ },
{
\\"type\\": 3,
\\"data\\": {
@@ -4463,8 +4246,42 @@ exports[`maskInputOptions 1`] = `
},
{
\\"type\\": 3,
- \\"textContent\\": \\"\\\\n \\",
+ \\"textContent\\": \\"\\\\n \\",
\\"id\\": 51
+ },
+ {
+ \\"type\\": 2,
+ \\"tagName\\": \\"label\\",
+ \\"attributes\\": {
+ \\"for\\": \\"password\\"
+ },
+ \\"childNodes\\": [
+ {
+ \\"type\\": 3,
+ \\"textContent\\": \\"\\\\n \\",
+ \\"id\\": 53
+ },
+ {
+ \\"type\\": 2,
+ \\"tagName\\": \\"input\\",
+ \\"attributes\\": {
+ \\"type\\": \\"password\\"
+ },
+ \\"childNodes\\": [],
+ \\"id\\": 54
+ },
+ {
+ \\"type\\": 3,
+ \\"textContent\\": \\"\\\\n \\",
+ \\"id\\": 55
+ }
+ ],
+ \\"id\\": 52
+ },
+ {
+ \\"type\\": 3,
+ \\"textContent\\": \\"\\\\n \\",
+ \\"id\\": 56
}
],
\\"id\\": 18
@@ -4472,7 +4289,7 @@ exports[`maskInputOptions 1`] = `
{
\\"type\\": 3,
\\"textContent\\": \\"\\\\n\\\\n \\",
- \\"id\\": 52
+ \\"id\\": 57
},
{
\\"type\\": 2,
@@ -4482,15 +4299,15 @@ exports[`maskInputOptions 1`] = `
{
\\"type\\": 3,
\\"textContent\\": \\"SCRIPT_PLACEHOLDER\\",
- \\"id\\": 54
+ \\"id\\": 59
}
],
- \\"id\\": 53
+ \\"id\\": 58
},
{
\\"type\\": 3,
\\"textContent\\": \\"\\\\n \\\\n \\\\n\\\\n\\\\n\\",
- \\"id\\": 55
+ \\"id\\": 60
}
],
\\"id\\": 16
@@ -4782,6 +4599,94 @@ exports[`maskInputOptions 1`] = `
\\"id\\": 37
}
},
+ {
+ \\"type\\": 3,
+ \\"data\\": {
+ \\"source\\": 2,
+ \\"type\\": 6,
+ \\"id\\": 37
+ }
+ },
+ {
+ \\"type\\": 3,
+ \\"data\\": {
+ \\"source\\": 2,
+ \\"type\\": 5,
+ \\"id\\": 54
+ }
+ },
+ {
+ \\"type\\": 3,
+ \\"data\\": {
+ \\"source\\": 5,
+ \\"text\\": \\"*\\",
+ \\"isChecked\\": false,
+ \\"id\\": 54
+ }
+ },
+ {
+ \\"type\\": 3,
+ \\"data\\": {
+ \\"source\\": 5,
+ \\"text\\": \\"**\\",
+ \\"isChecked\\": false,
+ \\"id\\": 54
+ }
+ },
+ {
+ \\"type\\": 3,
+ \\"data\\": {
+ \\"source\\": 5,
+ \\"text\\": \\"***\\",
+ \\"isChecked\\": false,
+ \\"id\\": 54
+ }
+ },
+ {
+ \\"type\\": 3,
+ \\"data\\": {
+ \\"source\\": 5,
+ \\"text\\": \\"****\\",
+ \\"isChecked\\": false,
+ \\"id\\": 54
+ }
+ },
+ {
+ \\"type\\": 3,
+ \\"data\\": {
+ \\"source\\": 5,
+ \\"text\\": \\"*****\\",
+ \\"isChecked\\": false,
+ \\"id\\": 54
+ }
+ },
+ {
+ \\"type\\": 3,
+ \\"data\\": {
+ \\"source\\": 5,
+ \\"text\\": \\"******\\",
+ \\"isChecked\\": false,
+ \\"id\\": 54
+ }
+ },
+ {
+ \\"type\\": 3,
+ \\"data\\": {
+ \\"source\\": 5,
+ \\"text\\": \\"*******\\",
+ \\"isChecked\\": false,
+ \\"id\\": 54
+ }
+ },
+ {
+ \\"type\\": 3,
+ \\"data\\": {
+ \\"source\\": 5,
+ \\"text\\": \\"********\\",
+ \\"isChecked\\": false,
+ \\"id\\": 54
+ }
+ },
{
\\"type\\": 3,
\\"data\\": {
diff --git a/test/html/form.html b/test/html/form.html
index 14120fd30e..9d4a0c7116 100644
--- a/test/html/form.html
+++ b/test/html/form.html
@@ -28,6 +28,9 @@
+