Merge pull request #524 from openreplay/hide-containers-rule
feat(ui): add option to mask entire HTML/SVG containers and their children tree
This commit is contained in:
commit
e56fee3134
2 changed files with 37 additions and 11 deletions
|
|
@ -1,5 +1,5 @@
|
|||
import {
|
||||
RemoveNodeAttribute,
|
||||
import {
|
||||
RemoveNodeAttribute,
|
||||
SetNodeAttribute,
|
||||
SetNodeAttributeURLBased,
|
||||
SetCSSDataURLBased,
|
||||
|
|
@ -220,9 +220,10 @@ export default abstract class Observer {
|
|||
}
|
||||
const parent = node.parentNode;
|
||||
let parentID: number | undefined;
|
||||
|
||||
// Disable parent check for the upper context HTMLHtmlElement, because it is root there... (before)
|
||||
// TODO: get rid of "special" cases (there is an issue with CreateDocument altered behaviour though)
|
||||
// TODO: Clean the logic (though now it workd fine)
|
||||
// TODO: Clean the logic (though now it workd fine)
|
||||
if (!isInstance(node, HTMLHtmlElement) || !this.isTopContext) {
|
||||
if (parent === null) {
|
||||
this.unbindNode(node);
|
||||
|
|
@ -238,6 +239,9 @@ export default abstract class Observer {
|
|||
return false;
|
||||
}
|
||||
this.app.sanitizer.handleNode(id, parentID, node);
|
||||
if (this.app.sanitizer.isMaskedContainer(parentID)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
let sibling = node.previousSibling;
|
||||
while (sibling !== null) {
|
||||
|
|
@ -259,20 +263,29 @@ export default abstract class Observer {
|
|||
}
|
||||
if (isNew === true) {
|
||||
if (isInstance(node, Element)) {
|
||||
let el: Element = node
|
||||
if (parentID !== undefined) {
|
||||
this.app.send(new
|
||||
if (this.app.sanitizer.isMaskedContainer(id)) {
|
||||
const width = el.clientWidth;
|
||||
const height = el.clientHeight;
|
||||
el = node.cloneNode() as Element;
|
||||
(el as HTMLElement | SVGElement).style.width = width + 'px';
|
||||
(el as HTMLElement | SVGElement).style.height = height + 'px';
|
||||
}
|
||||
|
||||
this.app.send(new
|
||||
CreateElementNode(
|
||||
id,
|
||||
parentID,
|
||||
index,
|
||||
node.tagName,
|
||||
el.tagName,
|
||||
isSVGElement(node),
|
||||
),
|
||||
);
|
||||
}
|
||||
for (let i = 0; i < node.attributes.length; i++) {
|
||||
const attr = node.attributes[i];
|
||||
this.sendNodeAttribute(id, node, attr.nodeName, attr.value);
|
||||
for (let i = 0; i < el.attributes.length; i++) {
|
||||
const attr = el.attributes[i];
|
||||
this.sendNodeAttribute(id, el, attr.nodeName, attr.value);
|
||||
}
|
||||
} else if (isInstance(node, Text)) {
|
||||
// for text node id != 0, hence parentID !== undefined and parent is Element
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ export interface Options {
|
|||
|
||||
export default class Sanitizer {
|
||||
private readonly masked: Set<number> = new Set();
|
||||
private readonly maskedContainers: Set<number> = new Set();
|
||||
private readonly options: Options;
|
||||
|
||||
constructor(private readonly app: App, options: Partial<Options>) {
|
||||
|
|
@ -21,10 +22,18 @@ export default class Sanitizer {
|
|||
handleNode(id: number, parentID: number, node: Node) {
|
||||
if (
|
||||
this.masked.has(parentID) ||
|
||||
(isElementNode(node) && hasOpenreplayAttribute(node, 'masked'))
|
||||
(isElementNode(node) &&
|
||||
hasOpenreplayAttribute(node, 'masked'))
|
||||
) {
|
||||
this.masked.add(id);
|
||||
}
|
||||
if (
|
||||
this.maskedContainers.has(parentID) ||
|
||||
(isElementNode(node) &&
|
||||
hasOpenreplayAttribute(node, 'htmlmasked'))
|
||||
) {
|
||||
this.maskedContainers.add(id);
|
||||
}
|
||||
}
|
||||
|
||||
sanitize(id: number, data: string): string {
|
||||
|
|
@ -34,7 +43,7 @@ export default class Sanitizer {
|
|||
/[^\f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]/g,
|
||||
'█',
|
||||
);
|
||||
}
|
||||
}
|
||||
if (this.options.obscureTextNumbers) {
|
||||
data = data.replace(/\d/g, '0');
|
||||
}
|
||||
|
|
@ -51,6 +60,9 @@ export default class Sanitizer {
|
|||
isMasked(id: number): boolean {
|
||||
return this.masked.has(id);
|
||||
}
|
||||
isMaskedContainer(id: number) {
|
||||
return this.maskedContainers.has(id);
|
||||
}
|
||||
|
||||
getInnerTextSecure(el: HTMLElement): string {
|
||||
const id = this.app.nodes.getID(el)
|
||||
|
|
@ -61,6 +73,7 @@ export default class Sanitizer {
|
|||
|
||||
clear(): void {
|
||||
this.masked.clear();
|
||||
this.maskedContainers.clear();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue