tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

JSHandle.ts (3343B)


      1 /**
      2 * @license
      3 * Copyright 2019 Google Inc.
      4 * SPDX-License-Identifier: Apache-2.0
      5 */
      6 
      7 import type {Protocol} from 'devtools-protocol';
      8 
      9 import type {CDPSession} from '../api/CDPSession.js';
     10 import {JSHandle} from '../api/JSHandle.js';
     11 import {debugError} from '../common/util.js';
     12 
     13 import type {CdpElementHandle} from './ElementHandle.js';
     14 import type {IsolatedWorld} from './IsolatedWorld.js';
     15 import {valueFromRemoteObject} from './utils.js';
     16 
     17 /**
     18 * @internal
     19 */
     20 export class CdpJSHandle<T = unknown> extends JSHandle<T> {
     21  #disposed = false;
     22  readonly #remoteObject: Protocol.Runtime.RemoteObject;
     23  readonly #world: IsolatedWorld;
     24 
     25  constructor(
     26    world: IsolatedWorld,
     27    remoteObject: Protocol.Runtime.RemoteObject,
     28  ) {
     29    super();
     30    this.#world = world;
     31    this.#remoteObject = remoteObject;
     32  }
     33 
     34  override get disposed(): boolean {
     35    return this.#disposed;
     36  }
     37 
     38  override get realm(): IsolatedWorld {
     39    return this.#world;
     40  }
     41 
     42  get client(): CDPSession {
     43    return this.realm.environment.client;
     44  }
     45 
     46  override async jsonValue(): Promise<T> {
     47    if (!this.#remoteObject.objectId) {
     48      return valueFromRemoteObject(this.#remoteObject);
     49    }
     50    const value = await this.evaluate(object => {
     51      return object;
     52    });
     53    if (value === undefined) {
     54      throw new Error('Could not serialize referenced object');
     55    }
     56    return value;
     57  }
     58 
     59  /**
     60   * Either `null` or the handle itself if the handle is an
     61   * instance of {@link ElementHandle}.
     62   */
     63  override asElement(): CdpElementHandle<Node> | null {
     64    return null;
     65  }
     66 
     67  override async dispose(): Promise<void> {
     68    if (this.#disposed) {
     69      return;
     70    }
     71    this.#disposed = true;
     72    await releaseObject(this.client, this.#remoteObject);
     73  }
     74 
     75  override toString(): string {
     76    if (!this.#remoteObject.objectId) {
     77      return 'JSHandle:' + valueFromRemoteObject(this.#remoteObject);
     78    }
     79    const type = this.#remoteObject.subtype || this.#remoteObject.type;
     80    return 'JSHandle@' + type;
     81  }
     82 
     83  override get id(): string | undefined {
     84    return this.#remoteObject.objectId;
     85  }
     86 
     87  override remoteObject(): Protocol.Runtime.RemoteObject {
     88    return this.#remoteObject;
     89  }
     90 
     91  override async getProperties(): Promise<Map<string, JSHandle<unknown>>> {
     92    // We use Runtime.getProperties rather than iterative version for
     93    // improved performance as it allows getting everything at once.
     94    const response = await this.client.send('Runtime.getProperties', {
     95      objectId: this.#remoteObject.objectId!,
     96      ownProperties: true,
     97    });
     98    const result = new Map<string, JSHandle>();
     99    for (const property of response.result) {
    100      if (!property.enumerable || !property.value) {
    101        continue;
    102      }
    103      result.set(property.name, this.#world.createCdpHandle(property.value));
    104    }
    105    return result;
    106  }
    107 }
    108 
    109 /**
    110 * @internal
    111 */
    112 export async function releaseObject(
    113  client: CDPSession,
    114  remoteObject: Protocol.Runtime.RemoteObject,
    115 ): Promise<void> {
    116  if (!remoteObject.objectId) {
    117    return;
    118  }
    119  await client
    120    .send('Runtime.releaseObject', {objectId: remoteObject.objectId})
    121    .catch(error => {
    122      // Exceptions might happen in case of a page been navigated or closed.
    123      // Swallow these since they are harmless and we don't leak anything in this case.
    124      debugError(error);
    125    });
    126 }