tor-browser

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

inspected-window-command.js (5167B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 "use strict";
      6 
      7 const {
      8  getAdHocFrontOrPrimitiveGrip,
      9  // eslint-disable-next-line mozilla/reject-some-requires
     10 } = require("resource://devtools/client/fronts/object.js");
     11 
     12 /**
     13 * For now, this class is mostly a wrapper around webExtInspectedWindow actor.
     14 */
     15 class InspectedWindowCommand {
     16  constructor({ commands }) {
     17    this.commands = commands;
     18  }
     19 
     20  /**
     21   * Return a promise that resolves to the related target actor's front.
     22   * The Web Extension inspected window actor.
     23   *
     24   * @return {Promise<WebExtensionInspectedWindowFront>}
     25   */
     26  getFront() {
     27    return this.commands.targetCommand.targetFront.getFront(
     28      "webExtensionInspectedWindow"
     29    );
     30  }
     31 
     32  /**
     33   * Evaluate the provided javascript code in a target window.
     34   *
     35   * @param {object} webExtensionCallerInfo - The addonId and the url (the addon base url
     36   *        or the url of the actual caller filename and lineNumber) used to log useful
     37   *        debugging information in the produced error logs and eval stack trace.
     38   * @param {string} expression - The expression to evaluate.
     39   * @param {object} options - An option object. Check the actor method definition to see
     40   *        what properties it can hold (minus the `consoleFront` property which is defined
     41   *        below).
     42   * @param {WebConsoleFront} options.consoleFront - An optional webconsole front. When
     43   *         set, the result will be either a primitive, a LongStringFront or an
     44   *         ObjectFront, and the WebConsoleActor corresponding to the console front will
     45   *         be used to generate those, which is needed if we want to handle ObjectFronts
     46   *         on the client.
     47   */
     48  async eval(webExtensionCallerInfo, expression, options = {}) {
     49    const { consoleFront } = options;
     50 
     51    if (consoleFront) {
     52      options.evalResultAsGrip = true;
     53      options.toolboxConsoleActorID = consoleFront.actor;
     54      delete options.consoleFront;
     55    }
     56 
     57    const front = await this.getFront();
     58    const response = await front.eval(
     59      webExtensionCallerInfo,
     60      expression,
     61      options
     62    );
     63 
     64    // If no consoleFront was provided, we can directly return the response.
     65    if (!consoleFront) {
     66      return response;
     67    }
     68 
     69    if (
     70      !response.hasOwnProperty("exceptionInfo") &&
     71      !response.hasOwnProperty("valueGrip")
     72    ) {
     73      throw new Error(
     74        "Response does not have `exceptionInfo` or `valueGrip` property"
     75      );
     76    }
     77 
     78    if (response.exceptionInfo) {
     79      console.error(
     80        response.exceptionInfo.description,
     81        ...(response.exceptionInfo.details || [])
     82      );
     83      return response;
     84    }
     85 
     86    // On the server, the valueGrip is created from the toolbox webconsole actor.
     87    // If we want since the ObjectFront connection is inherited from the parent front, we
     88    // need to set the console front as the parent front.
     89    return getAdHocFrontOrPrimitiveGrip(
     90      response.valueGrip,
     91      consoleFront || this
     92    );
     93  }
     94 
     95  /**
     96   * Reload the target tab, optionally bypass cache, customize the userAgent and/or
     97   * inject a script in targeted document or any of its sub-frame.
     98   *
     99   * @param {WebExtensionCallerInfo} callerInfo
    100   *   the addonId and the url (the addon base url or the url of the actual caller
    101   *   filename and lineNumber) used to log useful debugging information in the
    102   *   produced error logs and eval stack trace.
    103   * @param {object} options
    104   * @param {boolean|undefined} options.ignoreCache
    105   *        Enable/disable the cache bypass headers.
    106   * @param {string|undefined} options.injectedScript
    107   *        Evaluate the provided javascript code in the top level and every sub-frame
    108   *        created during the page reload, before any other script in the page has been
    109   *        executed.
    110   * @param {string|undefined} options.userAgent
    111   *        Customize the userAgent during the page reload.
    112   * @returns {Promise} A promise that resolves once the page is done loading when userAgent
    113   *          or injectedScript option are passed. If those options are not provided, the
    114   *          Promise will resolve after the reload was initiated.
    115   */
    116  async reload(callerInfo, options = {}) {
    117    if (this._reloadPending) {
    118      return null;
    119    }
    120 
    121    this._reloadPending = true;
    122 
    123    try {
    124      // We always want to update the target configuration to set the user agent if one is
    125      // passed, or to reset a potential existing override if userAgent isn't defined.
    126      await this.commands.targetConfigurationCommand.updateConfiguration({
    127        customUserAgent: options.userAgent,
    128      });
    129 
    130      const front = await this.getFront();
    131      const result = await front.reload(callerInfo, options);
    132      this._reloadPending = false;
    133 
    134      return result;
    135    } catch (e) {
    136      this._reloadPending = false;
    137      console.error(e);
    138      return Promise.reject({
    139        message: "An unexpected error occurred",
    140      });
    141    }
    142  }
    143 }
    144 
    145 module.exports = InspectedWindowCommand;