From 36da39db366a9f80c28549771ed331090a1c6647 Mon Sep 17 00:00:00 2001 From: Billy Vong Date: Fri, 4 Aug 2023 04:30:03 -0400 Subject: [PATCH] feat: Add `ignoreSelector` option (#1262) * feat: Add `ignoreSelector` option Similar to `ignoreClass`, but accepts a CSS selector so that you can use any CSS selector. * Apply formatting changes * Create clean-shrimps-lay.md * Apply formatting changes --- .changeset/clean-shrimps-lay.md | 7 +++++++ guide.md | 1 + packages/rrweb/src/record/index.ts | 2 ++ packages/rrweb/src/record/observer.ts | 6 +++++- packages/rrweb/src/types.ts | 2 ++ packages/rrweb/test/html/ignore.html | 1 + packages/rrweb/test/integration.test.ts | 7 ++++++- packages/rrweb/test/utils.ts | 1 + 8 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 .changeset/clean-shrimps-lay.md diff --git a/.changeset/clean-shrimps-lay.md b/.changeset/clean-shrimps-lay.md new file mode 100644 index 0000000000..01c2d6b73b --- /dev/null +++ b/.changeset/clean-shrimps-lay.md @@ -0,0 +1,7 @@ +--- +'rrweb': patch +--- + +feat: Add `ignoreSelector` option + +Similar to ignoreClass, but accepts a CSS selector so that you can use any CSS selector. diff --git a/guide.md b/guide.md index e2dbf0d23f..d7807bf00d 100644 --- a/guide.md +++ b/guide.md @@ -143,6 +143,7 @@ The parameter of `rrweb.record` accepts the following options. | blockClass | 'rr-block' | Use a string or RegExp to configure which elements should be blocked, refer to the [privacy](#privacy) chapter | | blockSelector | null | Use a string to configure which selector 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 | +| ignoreSelector | null | Use a string to configure which selector should be ignored, refer to the [privacy](#privacy) chapter | | ignoreCSSAttributes | null | array of CSS attributes that should be ignored | | maskTextClass | 'rr-mask' | Use a string or RegExp to configure which elements should be masked, refer to the [privacy](#privacy) chapter | | maskTextSelector | null | Use a string to configure which selector should be masked, refer to the [privacy](#privacy) chapter | diff --git a/packages/rrweb/src/record/index.ts b/packages/rrweb/src/record/index.ts index 563942312f..1c2141bfef 100644 --- a/packages/rrweb/src/record/index.ts +++ b/packages/rrweb/src/record/index.ts @@ -64,6 +64,7 @@ function record( blockClass = 'rr-block', blockSelector = null, ignoreClass = 'rr-ignore', + ignoreSelector = null, maskTextClass = 'rr-mask', maskTextSelector = null, inlineStylesheet = true, @@ -522,6 +523,7 @@ function record( }, blockClass, ignoreClass, + ignoreSelector, maskTextClass, maskTextSelector, maskInputOptions, diff --git a/packages/rrweb/src/record/observer.ts b/packages/rrweb/src/record/observer.ts index 9a02c4adcc..428cce1a4e 100644 --- a/packages/rrweb/src/record/observer.ts +++ b/packages/rrweb/src/record/observer.ts @@ -423,6 +423,7 @@ function initInputObserver({ blockClass, blockSelector, ignoreClass, + ignoreSelector, maskInputOptions, maskInputFn, sampling, @@ -449,7 +450,10 @@ function initInputObserver({ return; } - if (target.classList.contains(ignoreClass)) { + if ( + target.classList.contains(ignoreClass) || + (ignoreSelector && target.matches(ignoreSelector)) + ) { return; } let text = (target as HTMLInputElement).value; diff --git a/packages/rrweb/src/types.ts b/packages/rrweb/src/types.ts index dd9a516709..17ed750e68 100644 --- a/packages/rrweb/src/types.ts +++ b/packages/rrweb/src/types.ts @@ -46,6 +46,7 @@ export type recordOptions = { blockClass?: blockClass; blockSelector?: string; ignoreClass?: string; + ignoreSelector?: string; maskTextClass?: maskTextClass; maskTextSelector?: string; maskAllInputs?: boolean; @@ -84,6 +85,7 @@ export type observerParam = { blockClass: blockClass; blockSelector: string | null; ignoreClass: string; + ignoreSelector: string | null; maskTextClass: maskTextClass; maskTextSelector: string | null; maskInputOptions: MaskInputOptions; diff --git a/packages/rrweb/test/html/ignore.html b/packages/rrweb/test/html/ignore.html index f46c2efd00..2575bc20b0 100644 --- a/packages/rrweb/test/html/ignore.html +++ b/packages/rrweb/test/html/ignore.html @@ -10,6 +10,7 @@
+
diff --git a/packages/rrweb/test/integration.test.ts b/packages/rrweb/test/integration.test.ts index b61f76ece5..8496304d8d 100644 --- a/packages/rrweb/test/integration.test.ts +++ b/packages/rrweb/test/integration.test.ts @@ -298,9 +298,14 @@ describe('record integration tests', function (this: ISuite) { it('should not record input events on ignored elements', async () => { const page: puppeteer.Page = await browser.newPage(); await page.goto('about:blank'); - await page.setContent(getHtml.call(this, 'ignore.html')); + await page.setContent( + getHtml.call(this, 'ignore.html', { + ignoreSelector: '[data-rr-ignore]', + }), + ); await page.type('.rr-ignore', 'secret'); + await page.type('[data-rr-ignore]', 'secret'); const snapshots = (await page.evaluate( 'window.snapshots', diff --git a/packages/rrweb/test/utils.ts b/packages/rrweb/test/utils.ts index 0d1e6400c6..fb769135af 100644 --- a/packages/rrweb/test/utils.ts +++ b/packages/rrweb/test/utils.ts @@ -597,6 +597,7 @@ export function generateRecordSnippet(options: recordOptions) { emit: event => { window.snapshots.push(event); }, + ignoreSelector: ${options.ignoreSelector}, maskTextSelector: ${JSON.stringify(options.maskTextSelector)}, maskAllInputs: ${options.maskAllInputs}, maskInputOptions: ${JSON.stringify(options.maskAllInputs)},