1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 | import type Protocol from 'devtools-protocol';
|
8 |
|
9 | import type {EvaluateFuncWith, HandleFor, HandleOr} from '../common/types.js';
|
10 | import {debugError, withSourcePuppeteerURLIfNone} from '../common/util.js';
|
11 | import {moveable, throwIfDisposed} from '../util/decorators.js';
|
12 | import {disposeSymbol, asyncDisposeSymbol} from '../util/disposable.js';
|
13 |
|
14 | import type {ElementHandle} from './ElementHandle.js';
|
15 | import type {Realm} from './Realm.js';
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 | @moveable
|
39 | export abstract class JSHandle<T = unknown> {
|
40 | declare move: () => this;
|
41 |
|
42 | |
43 |
|
44 |
|
45 | declare _?: T;
|
46 |
|
47 | |
48 |
|
49 |
|
50 | constructor() {}
|
51 |
|
52 | |
53 |
|
54 |
|
55 | abstract get realm(): Realm;
|
56 |
|
57 | |
58 |
|
59 |
|
60 | abstract get disposed(): boolean;
|
61 |
|
62 | |
63 |
|
64 |
|
65 | async evaluate<
|
66 | Params extends unknown[],
|
67 | Func extends EvaluateFuncWith<T, Params> = EvaluateFuncWith<T, Params>,
|
68 | >(
|
69 | pageFunction: Func | string,
|
70 | ...args: Params
|
71 | ): Promise<Awaited<ReturnType<Func>>> {
|
72 | pageFunction = withSourcePuppeteerURLIfNone(
|
73 | this.evaluate.name,
|
74 | pageFunction,
|
75 | );
|
76 | return await this.realm.evaluate(pageFunction, this, ...args);
|
77 | }
|
78 |
|
79 | |
80 |
|
81 |
|
82 |
|
83 | async evaluateHandle<
|
84 | Params extends unknown[],
|
85 | Func extends EvaluateFuncWith<T, Params> = EvaluateFuncWith<T, Params>,
|
86 | >(
|
87 | pageFunction: Func | string,
|
88 | ...args: Params
|
89 | ): Promise<HandleFor<Awaited<ReturnType<Func>>>> {
|
90 | pageFunction = withSourcePuppeteerURLIfNone(
|
91 | this.evaluateHandle.name,
|
92 | pageFunction,
|
93 | );
|
94 | return await this.realm.evaluateHandle(pageFunction, this, ...args);
|
95 | }
|
96 |
|
97 | |
98 |
|
99 |
|
100 | getProperty<K extends keyof T>(
|
101 | propertyName: HandleOr<K>,
|
102 | ): Promise<HandleFor<T[K]>>;
|
103 | getProperty(propertyName: string): Promise<JSHandle<unknown>>;
|
104 |
|
105 | |
106 |
|
107 |
|
108 | @throwIfDisposed()
|
109 | async getProperty<K extends keyof T>(
|
110 | propertyName: HandleOr<K>,
|
111 | ): Promise<HandleFor<T[K]>> {
|
112 | return await this.evaluateHandle((object, propertyName) => {
|
113 | return object[propertyName as K];
|
114 | }, propertyName);
|
115 | }
|
116 |
|
117 | |
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 |
|
124 |
|
125 |
|
126 |
|
127 |
|
128 |
|
129 |
|
130 |
|
131 |
|
132 |
|
133 |
|
134 |
|
135 | @throwIfDisposed()
|
136 | async getProperties(): Promise<Map<string, JSHandle>> {
|
137 | const propertyNames = await this.evaluate(object => {
|
138 | const enumerableProperties = [];
|
139 | const descriptors = Object.getOwnPropertyDescriptors(object);
|
140 | for (const propertyName in descriptors) {
|
141 | if (descriptors[propertyName]?.enumerable) {
|
142 | enumerableProperties.push(propertyName);
|
143 | }
|
144 | }
|
145 | return enumerableProperties;
|
146 | });
|
147 | const map = new Map<string, JSHandle>();
|
148 | const results = await Promise.all(
|
149 | propertyNames.map(key => {
|
150 | return this.getProperty(key);
|
151 | }),
|
152 | );
|
153 | for (const [key, value] of Object.entries(propertyNames)) {
|
154 | using handle = results[key as any];
|
155 | if (handle) {
|
156 | map.set(value, handle.move());
|
157 | }
|
158 | }
|
159 | return map;
|
160 | }
|
161 |
|
162 | |
163 |
|
164 |
|
165 |
|
166 |
|
167 |
|
168 |
|
169 |
|
170 | abstract jsonValue(): Promise<T>;
|
171 |
|
172 | |
173 |
|
174 |
|
175 |
|
176 | abstract asElement(): ElementHandle<Node> | null;
|
177 |
|
178 | |
179 |
|
180 |
|
181 | abstract dispose(): Promise<void>;
|
182 |
|
183 | |
184 |
|
185 |
|
186 |
|
187 |
|
188 |
|
189 | abstract toString(): string;
|
190 |
|
191 | |
192 |
|
193 |
|
194 | abstract get id(): string | undefined;
|
195 |
|
196 | |
197 |
|
198 |
|
199 |
|
200 |
|
201 | abstract remoteObject(): Protocol.Runtime.RemoteObject;
|
202 |
|
203 |
|
204 | [disposeSymbol](): void {
|
205 | return void this.dispose().catch(debugError);
|
206 | }
|
207 |
|
208 |
|
209 | [asyncDisposeSymbol](): Promise<void> {
|
210 | return this.dispose();
|
211 | }
|
212 | }
|