summaryrefslogtreecommitdiffstats
path: root/remote/test/puppeteer/packages/puppeteer-core/src/common/bidi/JSHandle.ts
diff options
context:
space:
mode:
Diffstat (limited to 'remote/test/puppeteer/packages/puppeteer-core/src/common/bidi/JSHandle.ts')
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/common/bidi/JSHandle.ts159
1 files changed, 159 insertions, 0 deletions
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/common/bidi/JSHandle.ts b/remote/test/puppeteer/packages/puppeteer-core/src/common/bidi/JSHandle.ts
new file mode 100644
index 0000000000..2cd2876622
--- /dev/null
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/common/bidi/JSHandle.ts
@@ -0,0 +1,159 @@
+/**
+ * Copyright 2023 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import * as Bidi from 'chromium-bidi/lib/cjs/protocol/protocol.js';
+
+import {ElementHandle} from '../../api/ElementHandle.js';
+import {JSHandle as BaseJSHandle} from '../../api/JSHandle.js';
+import {EvaluateFuncWith, HandleFor, HandleOr} from '../../common/types.js';
+
+import {Connection} from './Connection.js';
+import {Context} from './Context.js';
+import {BidiSerializer} from './Serializer.js';
+import {releaseReference} from './utils.js';
+
+export class JSHandle<T = unknown> extends BaseJSHandle<T> {
+ #disposed = false;
+ #context;
+ #remoteValue;
+
+ constructor(context: Context, remoteValue: Bidi.CommonDataTypes.RemoteValue) {
+ super();
+ this.#context = context;
+ this.#remoteValue = remoteValue;
+ }
+
+ context(): Context {
+ return this.#context;
+ }
+
+ get connection(): Connection {
+ return this.#context.connection;
+ }
+
+ override get disposed(): boolean {
+ return this.#disposed;
+ }
+
+ override async evaluate<
+ Params extends unknown[],
+ Func extends EvaluateFuncWith<T, Params> = EvaluateFuncWith<T, Params>
+ >(
+ pageFunction: Func | string,
+ ...args: Params
+ ): Promise<Awaited<ReturnType<Func>>> {
+ return await this.context().evaluate(pageFunction, this, ...args);
+ }
+
+ override async evaluateHandle<
+ Params extends unknown[],
+ Func extends EvaluateFuncWith<T, Params> = EvaluateFuncWith<T, Params>
+ >(
+ pageFunction: Func | string,
+ ...args: Params
+ ): Promise<HandleFor<Awaited<ReturnType<Func>>>> {
+ return await this.context().evaluateHandle(pageFunction, this, ...args);
+ }
+
+ override async getProperty<K extends keyof T>(
+ propertyName: HandleOr<K>
+ ): Promise<HandleFor<T[K]>>;
+ override async getProperty(propertyName: string): Promise<HandleFor<unknown>>;
+ override async getProperty<K extends keyof T>(
+ propertyName: HandleOr<K>
+ ): Promise<HandleFor<T[K]>> {
+ return await this.evaluateHandle((object, propertyName) => {
+ return object[propertyName as K];
+ }, propertyName);
+ }
+
+ override async getProperties(): Promise<Map<string, BaseJSHandle>> {
+ // TODO(lightning00blade): Either include return of depth Handles in RemoteValue
+ // or new BiDi command that returns array of remote value
+ const keys = await this.evaluate(object => {
+ return Object.getOwnPropertyNames(object);
+ });
+ const map: Map<string, BaseJSHandle> = new Map();
+ const results = await Promise.all(
+ keys.map(key => {
+ return this.getProperty(key);
+ })
+ );
+
+ for (const [key, value] of Object.entries(keys)) {
+ const handle = results[key as any];
+ if (handle) {
+ map.set(value, handle);
+ }
+ }
+
+ return map;
+ }
+
+ override async jsonValue(): Promise<T> {
+ const value = BidiSerializer.deserialize(this.#remoteValue);
+
+ if (this.#remoteValue.type !== 'undefined' && value === undefined) {
+ throw new Error('Could not serialize referenced object');
+ }
+ return value;
+ }
+
+ override asElement(): ElementHandle<Node> | null {
+ return null;
+ }
+
+ override async dispose(): Promise<void> {
+ if (this.#disposed) {
+ return;
+ }
+ this.#disposed = true;
+ if ('handle' in this.#remoteValue) {
+ await releaseReference(this.#context, this.#remoteValue);
+ }
+ }
+
+ get isPrimitiveValue(): boolean {
+ switch (this.#remoteValue.type) {
+ case 'string':
+ case 'number':
+ case 'bigint':
+ case 'boolean':
+ case 'undefined':
+ case 'null':
+ return true;
+
+ default:
+ return false;
+ }
+ }
+
+ override toString(): string {
+ if (this.isPrimitiveValue) {
+ return 'JSHandle:' + BidiSerializer.deserialize(this.#remoteValue);
+ }
+
+ return 'JSHandle@' + this.#remoteValue.type;
+ }
+
+ override get id(): string | undefined {
+ return 'handle' in this.#remoteValue ? this.#remoteValue.handle : undefined;
+ }
+
+ remoteValue(): Bidi.CommonDataTypes.RemoteValue {
+ return this.#remoteValue;
+ }
+}