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
This commit is contained in:
Billy Vong
2026-04-01 12:00:00 +08:00
committed by GitHub
parent b4288791bd
commit d4ce14af98
8 changed files with 25 additions and 2 deletions

View File

@@ -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.

View File

@@ -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 | | 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 | | 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 | | 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 | | 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 | | 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 | | maskTextSelector | null | Use a string to configure which selector should be masked, refer to the [privacy](#privacy) chapter |

View File

@@ -64,6 +64,7 @@ function record<T = eventWithTime>(
blockClass = 'rr-block', blockClass = 'rr-block',
blockSelector = null, blockSelector = null,
ignoreClass = 'rr-ignore', ignoreClass = 'rr-ignore',
ignoreSelector = null,
maskTextClass = 'rr-mask', maskTextClass = 'rr-mask',
maskTextSelector = null, maskTextSelector = null,
inlineStylesheet = true, inlineStylesheet = true,
@@ -522,6 +523,7 @@ function record<T = eventWithTime>(
}, },
blockClass, blockClass,
ignoreClass, ignoreClass,
ignoreSelector,
maskTextClass, maskTextClass,
maskTextSelector, maskTextSelector,
maskInputOptions, maskInputOptions,

View File

@@ -423,6 +423,7 @@ function initInputObserver({
blockClass, blockClass,
blockSelector, blockSelector,
ignoreClass, ignoreClass,
ignoreSelector,
maskInputOptions, maskInputOptions,
maskInputFn, maskInputFn,
sampling, sampling,
@@ -449,7 +450,10 @@ function initInputObserver({
return; return;
} }
if (target.classList.contains(ignoreClass)) { if (
target.classList.contains(ignoreClass) ||
(ignoreSelector && target.matches(ignoreSelector))
) {
return; return;
} }
let text = (target as HTMLInputElement).value; let text = (target as HTMLInputElement).value;

View File

@@ -46,6 +46,7 @@ export type recordOptions<T> = {
blockClass?: blockClass; blockClass?: blockClass;
blockSelector?: string; blockSelector?: string;
ignoreClass?: string; ignoreClass?: string;
ignoreSelector?: string;
maskTextClass?: maskTextClass; maskTextClass?: maskTextClass;
maskTextSelector?: string; maskTextSelector?: string;
maskAllInputs?: boolean; maskAllInputs?: boolean;
@@ -84,6 +85,7 @@ export type observerParam = {
blockClass: blockClass; blockClass: blockClass;
blockSelector: string | null; blockSelector: string | null;
ignoreClass: string; ignoreClass: string;
ignoreSelector: string | null;
maskTextClass: maskTextClass; maskTextClass: maskTextClass;
maskTextSelector: string | null; maskTextSelector: string | null;
maskInputOptions: MaskInputOptions; maskInputOptions: MaskInputOptions;

View File

@@ -10,6 +10,7 @@
<body> <body>
<form> <form>
<label for="ignore text"> <input type="text" class="rr-ignore" /> </label> <label for="ignore text"> <input type="text" class="rr-ignore" /> </label>
<label for="ignore selector"> <input type="text" data-rr-ignore /> </label>
</form> </form>
</body> </body>
</html> </html>

View File

@@ -298,9 +298,14 @@ describe('record integration tests', function (this: ISuite) {
it('should not record input events on ignored elements', async () => { it('should not record input events on ignored elements', async () => {
const page: puppeteer.Page = await browser.newPage(); const page: puppeteer.Page = await browser.newPage();
await page.goto('about:blank'); 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('.rr-ignore', 'secret');
await page.type('[data-rr-ignore]', 'secret');
const snapshots = (await page.evaluate( const snapshots = (await page.evaluate(
'window.snapshots', 'window.snapshots',

View File

@@ -597,6 +597,7 @@ export function generateRecordSnippet(options: recordOptions<eventWithTime>) {
emit: event => { emit: event => {
window.snapshots.push(event); window.snapshots.push(event);
}, },
ignoreSelector: ${options.ignoreSelector},
maskTextSelector: ${JSON.stringify(options.maskTextSelector)}, maskTextSelector: ${JSON.stringify(options.maskTextSelector)},
maskAllInputs: ${options.maskAllInputs}, maskAllInputs: ${options.maskAllInputs},
maskInputOptions: ${JSON.stringify(options.maskAllInputs)}, maskInputOptions: ${JSON.stringify(options.maskAllInputs)},