Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add mask attribute function #25

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions packages/rrweb-snapshot/src/snapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
KeepIframeSrcFn,
ICanvas,
DialogAttributes,
MaskAttributeFn,
} from './types';
import { NodeType } from '@posthog-internal/rrweb-types';
import type {
Expand Down Expand Up @@ -166,7 +167,7 @@
} else if (customHref.startsWith('blob:') || customHref.startsWith('data:')) {
return customHref;
}
// note: using `new URL` is slower. See #1434 or https://jsbench.me/uqlud17rxo/1

Check warning

Code scanning / CodeQL

DOM text reinterpreted as HTML Medium

DOM text
is reinterpreted as HTML without escaping meta-characters.
a.setAttribute('href', customHref);
return a.href;
}
Expand Down Expand Up @@ -283,7 +284,7 @@
// should warn? maybe a text node isn't attached to a parent node yet?
return false;
} else {
el = dom.parentElement(node)!;

Check warning on line 287 in packages/rrweb-snapshot/src/snapshot.ts

View workflow job for this annotation

GitHub Actions / ESLint Check and Report Upload

Forbidden non-null assertion
}
try {
if (typeof maskTextClass === 'string') {
Expand Down Expand Up @@ -399,6 +400,7 @@
maskInputOptions: MaskInputOptions;
maskTextFn: MaskTextFn | undefined;
maskInputFn: MaskInputFn | undefined;
maskAttributeFn: MaskAttributeFn | undefined;
dataURLOptions?: DataURLOptions;
inlineImages: boolean;
recordCanvas: boolean;
Expand All @@ -420,6 +422,7 @@
maskInputOptions = {},
maskTextFn,
maskInputFn,
maskAttributeFn,
dataURLOptions = {},
inlineImages,
recordCanvas,
Expand Down Expand Up @@ -465,6 +468,7 @@
keepIframeSrcFn,
newlyAddedElement,
rootId,
maskAttributeFn,
});
case n.TEXT_NODE:
return serializeTextNode(n as Text, {
Expand Down Expand Up @@ -574,6 +578,7 @@
*/
newlyAddedElement?: boolean;
rootId: number | undefined;
maskAttributeFn: MaskAttributeFn | undefined;
},
): serializedNode | false {
const {
Expand All @@ -589,6 +594,8 @@
keepIframeSrcFn,
newlyAddedElement = false,
rootId,
// by default, we can just pass the attribute through
maskAttributeFn = (_name, value, _element) => value,

Check warning on line 598 in packages/rrweb-snapshot/src/snapshot.ts

View workflow job for this annotation

GitHub Actions / ESLint Check and Report Upload

'_element' is defined but never used
} = options;
const needBlock = _isBlockedElement(n, blockClass, blockSelector);
const tagName = getValidTagName(n);
Expand All @@ -597,11 +604,10 @@
for (let i = 0; i < len; i++) {
const attr = n.attributes[i];
if (!ignoreAttribute(tagName, attr.name, attr.value)) {
attributes[attr.name] = transformAttribute(
doc,
tagName,
toLowerCase(attr.name),
attr.value,
attributes[attr.name] = maskAttributeFn(
attr.name,
transformAttribute(doc, tagName, toLowerCase(attr.name), attr.value),
n,
);
}
}
Expand Down Expand Up @@ -734,10 +740,10 @@
const recordInlineImage = () => {
image.removeEventListener('load', recordInlineImage);
try {
canvasService!.width = image.naturalWidth;

Check warning on line 743 in packages/rrweb-snapshot/src/snapshot.ts

View workflow job for this annotation

GitHub Actions / ESLint Check and Report Upload

Forbidden non-null assertion
canvasService!.height = image.naturalHeight;

Check warning on line 744 in packages/rrweb-snapshot/src/snapshot.ts

View workflow job for this annotation

GitHub Actions / ESLint Check and Report Upload

Forbidden non-null assertion
canvasCtx!.drawImage(image, 0, 0);

Check warning on line 745 in packages/rrweb-snapshot/src/snapshot.ts

View workflow job for this annotation

GitHub Actions / ESLint Check and Report Upload

Forbidden non-null assertion
attributes.rr_dataURL = canvasService!.toDataURL(

Check warning on line 746 in packages/rrweb-snapshot/src/snapshot.ts

View workflow job for this annotation

GitHub Actions / ESLint Check and Report Upload

Forbidden non-null assertion
dataURLOptions.type,
dataURLOptions.quality,
);
Expand Down Expand Up @@ -963,6 +969,7 @@
) => unknown;
stylesheetLoadTimeout?: number;
cssCaptured?: boolean;
maskAttributeFn?: MaskAttributeFn;
},
): serializedNodeWithId | null {
const {
Expand All @@ -989,6 +996,7 @@
keepIframeSrcFn = () => false,
newlyAddedElement = false,
cssCaptured = false,
maskAttributeFn,
} = options;
let { needsMask } = options;
let { preserveWhiteSpace = true } = options;
Expand Down Expand Up @@ -1020,6 +1028,7 @@
keepIframeSrcFn,
newlyAddedElement,
cssCaptured,
maskAttributeFn,
});
if (!_serializedNode) {
// TODO: dev only
Expand Down Expand Up @@ -1100,6 +1109,7 @@
stylesheetLoadTimeout,
keepIframeSrcFn,
cssCaptured: false,
maskAttributeFn,
};

if (
Expand Down Expand Up @@ -1256,6 +1266,7 @@
maskAllInputs?: boolean | MaskInputOptions;
maskTextFn?: MaskTextFn;
maskInputFn?: MaskInputFn;
maskAttributeFn?: MaskAttributeFn;
slimDOM?: 'all' | boolean | SlimDOMOptions;
dataURLOptions?: DataURLOptions;
inlineImages?: boolean;
Expand Down Expand Up @@ -1287,6 +1298,7 @@
maskAllInputs = false,
maskTextFn,
maskInputFn,
maskAttributeFn,
slimDOM = false,
dataURLOptions,
preserveWhiteSpace,
Expand Down Expand Up @@ -1352,6 +1364,7 @@
maskInputOptions,
maskTextFn,
maskInputFn,
maskAttributeFn,
slimDOMOptions,
dataURLOptions,
inlineImages,
Expand Down
5 changes: 5 additions & 0 deletions packages/rrweb-snapshot/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ export type SlimDOMOptions = Partial<{

export type MaskTextFn = (text: string, element: HTMLElement | null) => string;
export type MaskInputFn = (text: string, element: HTMLElement) => string;
export type MaskAttributeFn = (
name: string,
value: string | null,
element: HTMLElement,
) => string | null;

export type KeepIframeSrcFn = (src: string) => boolean;

Expand Down
10 changes: 5 additions & 5 deletions packages/rrweb-snapshot/test/css.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import { splitCssText, stringifyStylesheet } from './../src/utils';
import { applyCssSplits } from './../src/rebuild';
import * as fs from 'fs';
import * as path from 'path';
import type {
serializedElementNodeWithId,
BuildCache,
import {
textNode,
} from '../src/types';
import { NodeType } from '@posthog-internal/rrweb-types';
NodeType,
serializedElementNodeWithId,
} from '@posthog-internal/rrweb-types';
import { Window } from 'happy-dom';
import { BuildCache } from '../src';

describe('css parser', () => {
function parse(plugin: AcceptedPlugin, input: string): string {
Expand Down
Loading
Loading