Remove INode (node.__sn) and use Mirror as source of truth (#868)
* Move ids to weakmap * Fix typo * Move from INode to storing serialized data in mirror * Update packages/rrweb-snapshot/src/rebuild.ts Co-authored-by: Yun Feng <yun.feng@anu.edu.au> * Remove unnessisary `as Node` typecastings Fixes: https://github.com/rrweb-io/rrweb/pull/868#discussion_r842240758 * Remove unnessisary `as unknown as ...` * Remove unnessisary `as unknown as ...` * Reset mirror when recording starts Solves: https://github.com/rrweb-io/rrweb/pull/868#discussion_r842249599 * API has changed for snapshot, change test to reflect that * Allow for es5 compatibility * Remove unnessisary as unknown as ... and change test to reflect the API change * Refactor mirror to remove `nodeIdMap` Fixes: https://github.com/rrweb-io/rrweb/pull/868#discussion_r842732696 Co-authored-by: Yun Feng <yun.feng@anu.edu.au>
This commit is contained in:
@@ -1,6 +1,12 @@
|
||||
import { INode, MaskInputFn, MaskInputOptions } from './types';
|
||||
import {
|
||||
idNodeMap,
|
||||
MaskInputFn,
|
||||
MaskInputOptions,
|
||||
nodeMetaMap,
|
||||
serializedNodeWithId,
|
||||
} from './types';
|
||||
|
||||
export function isElement(n: Node | INode): n is Element {
|
||||
export function isElement(n: Node): n is Element {
|
||||
return n.nodeType === n.ELEMENT_NODE;
|
||||
}
|
||||
|
||||
@@ -9,6 +15,69 @@ export function isShadowRoot(n: Node): n is ShadowRoot {
|
||||
return Boolean(host && host.shadowRoot && host.shadowRoot === n);
|
||||
}
|
||||
|
||||
export class Mirror {
|
||||
private idNodeMap: idNodeMap = new Map();
|
||||
private nodeMetaMap: nodeMetaMap = new WeakMap();
|
||||
|
||||
getId(n: Node | undefined | null): number {
|
||||
if (!n) return -1;
|
||||
|
||||
const id = this.getMeta(n)?.id;
|
||||
|
||||
// if n is not a serialized Node, use -1 as its id.
|
||||
return id ?? -1;
|
||||
}
|
||||
|
||||
getNode(id: number): Node | null {
|
||||
return this.idNodeMap.get(id) || null;
|
||||
}
|
||||
|
||||
getIds(): number[] {
|
||||
return Array.from(this.idNodeMap.keys());
|
||||
}
|
||||
|
||||
getMeta(n: Node): serializedNodeWithId | null {
|
||||
return this.nodeMetaMap.get(n) || null;
|
||||
}
|
||||
|
||||
// removes the node from idNodeMap
|
||||
// doesn't remove the node from nodeMetaMap
|
||||
removeNodeFromMap(n: Node) {
|
||||
const id = this.getId(n);
|
||||
this.idNodeMap.delete(id);
|
||||
|
||||
if (n.childNodes) {
|
||||
n.childNodes.forEach((childNode) => this.removeNodeFromMap(childNode));
|
||||
}
|
||||
}
|
||||
has(id: number): boolean {
|
||||
return this.idNodeMap.has(id);
|
||||
}
|
||||
|
||||
hasNode(node: Node): boolean {
|
||||
return this.nodeMetaMap.has(node);
|
||||
}
|
||||
|
||||
add(n: Node, meta: serializedNodeWithId) {
|
||||
const id = meta.id;
|
||||
this.idNodeMap.set(id, n);
|
||||
this.nodeMetaMap.set(n, meta);
|
||||
}
|
||||
|
||||
replace(id: number, n: Node) {
|
||||
this.idNodeMap.set(id, n);
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.idNodeMap = new Map();
|
||||
this.nodeMetaMap = new WeakMap();
|
||||
}
|
||||
}
|
||||
|
||||
export function createMirror(): Mirror {
|
||||
return new Mirror();
|
||||
}
|
||||
|
||||
export function maskInputValue({
|
||||
maskInputOptions,
|
||||
tagName,
|
||||
|
||||
Reference in New Issue
Block a user