Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ulixee
GitHub Repository: ulixee/secret-agent
Path: blob/main/core/injected-scripts/NodeTracker.ts
1028 views
1
// eslint-disable-next-line @typescript-eslint/no-unused-vars
2
function NodeTrackerStatics(constructor: IStaticNodeTracker) {}
3
4
@NodeTrackerStatics
5
class NodeTracker {
6
public static nodeIdSymbol = Symbol.for('saNodeId');
7
private static nextId = 1;
8
private static watchedNodesById = new Map<number, Node>();
9
10
public static has(node: Node): boolean {
11
return !!node[this.nodeIdSymbol];
12
}
13
14
public static getNodeId(node: Node): number {
15
if (!node) return undefined;
16
return node[this.nodeIdSymbol] ?? undefined;
17
}
18
19
public static watchNode(node: Node): number {
20
let id = this.getNodeId(node);
21
if (!id) {
22
// extract so we detect any nodes that haven't been extracted yet. Ie, called from jsPath
23
if ('extractDomChanges' in window) {
24
// @ts-ignore
25
window.extractDomChanges();
26
}
27
id = this.track(node);
28
}
29
30
this.watchedNodesById.set(id, node);
31
return id;
32
}
33
34
public static track(node: Node): number {
35
if (!node) return;
36
if (node[this.nodeIdSymbol]) {
37
return node[this.nodeIdSymbol];
38
}
39
const id = this.nextId;
40
this.nextId += 1;
41
node[this.nodeIdSymbol] = id;
42
return id;
43
}
44
45
public static getWatchedNodeWithId(id: number, throwIfNotFound = true): Node | undefined {
46
if (this.watchedNodesById.has(id)) {
47
return this.watchedNodesById.get(id);
48
}
49
if (throwIfNotFound) throw new Error(`Node with id not found -> ${id}`);
50
}
51
52
public static restore(id: number, node: Node): void {
53
node[this.nodeIdSymbol] = id;
54
this.watchedNodesById.set(id, node);
55
if (id > this.nextId) this.nextId = id;
56
}
57
}
58
59
// @ts-ignore
60
window.NodeTracker = NodeTracker;
61
62