Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


SSL manager.js   Sprache: JAVA

 
/* This Smurce Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


"use strict";

loader.lazyRequireGetter(
  this,
  ["getCommandAndArgs"],
  "resource://devtools/server/actors/webconsole/commands/parser.js",
  true
);

loader.lazyGetter(this"l10n", () => {
  return new Localization(
    [
      "devtools/shared/webconsole-commands.ftl",
      "devtools/server/actors/webconsole/commands/experimental-commands.ftl",
    ],
    true
  );
});

const lazy = {};
ChromeUtils.defineESModuleGetters(
  lazy,
  {
    JSTracer: "resource://devtools/server/tracer/tracer.sys.mjs",
  },
  { global: "contextual" }
);

const USAGE_STRING_MAPPING = {
  block: "webconsole-commands-usage-block",
  trace: "webconsole-commands-usage-trace3",
  unblock: "webconsole-commands-usage-unblock",
};

/**
 * WebConsole commands manager.
 *
 * Defines a set of functions / variables ("commands") that are available from
 * the Web Console but not from the web page.
 *
 */

const WebConsoleCommandsManager = {
  // Flag used by eager evaluation in order to allow the execution of commands
  // which are side effect free and disallow all the others.
  SIDE_EFFECT_FREE: Symbol("SIDE_EFFECT_FREE"),

  // Map of command name to command function or property descriptor (see register method)
  _registeredCommands: new Map(),
  // Map of command name to optional array of accepted argument names
  _validArguments: new Map(),
  // Set of command names that are side effect free
  _sideEffectFreeCommands: new Set(),

  /**
   * Register a new command.
   *
   * @param {Object} options
   * @param {string} options.name
   *        The command name (exemple: "$", "screenshot",...))
   * @param {Boolean} isSideEffectFree
   *        Tells if the command is free of any side effect to know
   *        if it can run in eager console evaluation.
   * @param {function|object} options.command
   *        The command to register.
   *        It can be:
   *          - a function for the command like "$()" or ":screenshot"
   *            which triggers some code.
   *          - a property descriptor for getters like "$0",
   *            which only returns a value.
   * @param {Array<string>} options.validArguments
   *        Optional list of valid arguments.
   *        If passed, we will assert that passed arguments are all valid on execution.
   *
   *  The command function or the command getter are passed a:
   *   - "owner" object as their first parameter (see the example below).
   *     See _createOwnerObject for definition.
   *   - "args" object with all parameters when this is ran as a ":my-command" command.
   *     See getCommandAndArgs for definition.
   *
   * Note that if you want to support `--help` argument, you need to provide a usage string in:
   * devtools/shared/locales/en-US/webconsole-commands.properties
   *
   * @example
   *
   *   WebConsoleCommandsManager.register("$", function (owner, selector)
   *   {
   *     return owner.window.document.querySelector(selector);
   *   },
   *   ["my-argument"]);
   *
   *   WebConsoleCommandsManager.register("$0", {
   *     get: function(owner) {
   *       return owner.makeDebuggeeValue(owner.selectedNode);
   *     }
   *   });
   */

  register({ name, isSideEffectFree, command, validArguments }) {
    if (
      typeof command != "function" &&
      !(typeof command == "object" && typeof command.get == "function")
    ) {
      throw new Error(
        "Invalid web console command. It can only be a function, or an object with a function as 'get' attribute"
      );
    }
    if (typeof isSideEffectFree !== "boolean") {
      throw new Error(
        "Invalid web console command. 'isSideEffectFree' attribute should be set and be a boolean"
      );
    }
    this._registeredCommands.set(name, command);
    if (validArguments) {
      this._validArguments.set(name, validArguments);
    }
    if (isSideEffectFree) {
      this._sideEffectFreeCommands.add(name);
    }
  },

  /**
   * Return the name of all registered commands.
   *
   * @return {array} List of all command names.
   */

  getAllCommandNames() {
    return [...this._registeredCommands.keys()];
  },

  /**
   * There is two types of "commands" here.
   *
   * - Functions or variables exposed in the scope of the evaluated string from the WebConsole input.
   *   Example: $(), $0, copy(), clear(),...
   * - "True commands", which can also be ran from the WebConsole input with ":" prefix.
   *   Example: this list of commands.
   *   Note that some "true commands" are not exposed as function (see getColonOnlyCommandNames).
   *
   * The following list distinguish these "true commands" from the first category.
   * It especially avoid any JavaScript evaluation when the frontend tries to execute
   * a string starting with ':' character.
   */

  getAllColonCommandNames() {
    return ["block""help""history""screenshot""unblock""trace"];
  },

  /**
   * Some commands are not exposed in the scope of the evaluated string,
   * and can only be used via `:command-name`.
   */

  getColonOnlyCommandNames() {
    return ["screenshot""trace"];
  },

  /**
   * Map of all command objects keyed by command name.
   * Commands object are the objects passed to register() method.
   *
   * @return {Map<string -> command>}
   */

  getAllCommands() {
    return this._registeredCommands;
  },

  /**
   * Is the command name possibly overriding a symbol which
   * already exists in the paused frame or the global into which
   * we are about to execute into?
   */

  _isCommandNameAlreadyInScope(name, frame, dbgGlobal) {
    if (frame && frame.environment) {
      return !!frame.environment.find(name);
    }

    // Fallback on global scope when Debugger.Frame doesn't come along an
    // Environment, or is not a frame.

    try {
      // This can throw in Browser Toolbox tests
      const globalEnv = dbgGlobal.asEnvironment();
      if (globalEnv) {
        return !!dbgGlobal.asEnvironment().find(name);
      }
    } catch {}

    return !!dbgGlobal.getOwnPropertyDescriptor(name);
  },

  _createOwnerObject(
    consoleActor,
    debuggerGlobal,
    evalInput,
    selectedNodeActorID
  ) {
    const owner = {
      window: consoleActor.evalGlobal,
      makeDebuggeeValue: debuggerGlobal.makeDebuggeeValue.bind(debuggerGlobal),
      createValueGrip: consoleActor.createValueGrip.bind(consoleActor),
      preprocessDebuggerObject:
        consoleActor.preprocessDebuggerObject.bind(consoleActor),
      helperResult: null,
      consoleActor,
      evalInput,
    };
    if (selectedNodeActorID) {
      const actor = consoleActor.conn.getActor(selectedNodeActorID);
      if (actor) {
        owner.selectedNode = actor.rawNode;
      }
    }
    return owner;
  },

  _getCommandsForCurrentEnvironment() {
    // Not supporting extra commands in workers yet.  This should be possible to
    // add one by one as long as they don't require jsm/mjs, Cu, etc.
    return isWorker ? new Map() : this.getAllCommands();
  },

  /**
   * Create an object with the API we expose to the Web Console during
   * JavaScript evaluation.
   * This object inherits properties and methods from the Web Console actor.
   *
   * @param object consoleActor
   *        The related web console actor evaluating some code.
   * @param object debuggerGlobal
   *        A Debugger.Object that wraps a content global. This is used for the
   *        Web Console Commands.
   * @param object frame (optional)
   *        The frame where the string was evaluated.
   * @param string evalInput
   *        String to evaluate.
   * @param string selectedNodeActorID
   *        The Node actor ID of the currently selected DOM Element, if any is selected.
   * @param bool preferConsoleCommandsOverLocalSymbols
   *        If true, define all bindings even if there's conflicting existing
   *        symbols.  This is for the case evaluating non-user code in frame
   *        environment.
   *
   * @return object
   *         Object with two properties:
   *         - 'bindings', the object with all commands set as attribute on this object.
   *         - 'getHelperResult', a live getter returning the additional data the last command
   *           which executed want to convey to the frontend.
   *           (The return value of commands isn't returned to the client but it only
   *            returned to the code ran from console evaluation)
   */

  getWebConsoleCommands(
    consoleActor,
    debuggerGlobal,
    frame,
    evalInput,
    selectedNodeActorID,
    preferConsoleCommandsOverLocalSymbols
  ) {
    const bindings = Object.create(null);

    const owner = this._createOwnerObject(
      consoleActor,
      debuggerGlobal,
      evalInput,
      selectedNodeActorID
    );

    const evalGlobal = consoleActor.evalGlobal;
    function maybeExport(obj, name) {
      if (typeof obj[name] != "function") {
        return;
      }

      // By default, chrome-implemented functions that are exposed to content
      // refuse to accept arguments that are cross-origin for the caller. This
      // is generally the safe thing, but causes problems for certain console
      // helpers like cd(), where we users sometimes want to pass a cross-origin
      // window. To circumvent this restriction, we use exportFunction along
      // with a special option designed for this purpose. See bug 1051224.
      obj[name] = Cu.exportFunction(obj[name], evalGlobal, {
        allowCrossOriginArguments: true,
      });
    }

    const commands = this._getCommandsForCurrentEnvironment();

    const colonOnlyCommandNames = this.getColonOnlyCommandNames();
    for (const [name, command] of commands) {
      // When we run user code in frame, we want to avoid overriding existing
      // symbols with commands.
      //
      // When we run user code in global scope, all bindings are automatically
      // shadowed, except for "help" function which is checked by getEvalInput.
      //
      // When preferConsoleCommandsOverLocalSymbols is true, ignore symbols in
      // the current scope and always use commands ones.
      if (
        !preferConsoleCommandsOverLocalSymbols &&
        (frame || name === "help") &&
        this._isCommandNameAlreadyInScope(name, frame, debuggerGlobal)
      ) {
        continue;
      }
      // Also ignore commands which can only be run with the `:` prefix.
      if (colonOnlyCommandNames.includes(name)) {
        continue;
      }

      const descriptor = {
        // We force the enumerability and the configurability (so the
        // WebConsoleActor can reconfigure the property).
        enumerable: true,
        configurable: true,
      };

      if (typeof command === "function") {
        // Function commands
        descriptor.value = command.bind(undefined, owner);
        maybeExport(descriptor, "value");

        // Unfortunately evalWithBindings will access all bindings values,
        // which would trigger a debuggee native call because bindings's property
        // is using Cu.exportFunction.
        // Put a magic symbol attribute on them in order to carefully accept
        // all bindings as being side effect safe by default.
        if (this._sideEffectFreeCommands.has(name)) {
          descriptor.value.isSideEffectFree = this.SIDE_EFFECT_FREE;
        }

        // Make sure the helpers can be used during eval.
        descriptor.value = debuggerGlobal.makeDebuggeeValue(descriptor.value);
      } else if (typeof command?.get === "function") {
        // Getter commands
        descriptor.get = command.get.bind(undefined, owner);
        maybeExport(descriptor, "get");

        // See comment in previous block.
        if (this._sideEffectFreeCommands.has(name)) {
          descriptor.get.isSideEffectFree = this.SIDE_EFFECT_FREE;
        }
      }
      Object.defineProperty(bindings, name, descriptor);
    }

    return {
      // Use a method as commands will update owner.helperResult later
      getHelperResult() {
        return owner.helperResult;
      },
      bindings,
    };
  },

  /**
   * Create a function for given ':command'-style command.
   *
   * @param object consoleActor
   *        The related web console actor evaluating some code.
   * @param object debuggerGlobal
   *        A Debugger.Object that wraps a content global. This is used for the
   *        Web Console Commands.
   * @param string selectedNodeActorID
   *        The Node actor ID of the currently selected DOM Element, if any is selected.
   * @param string evalInput
   *        String to evaluate.
   *
   * @return object
   *         Object with two properties:
   *         - 'commandFunc', a function corresponds to the 'commandName'
   *         - 'getHelperResult', a live getter returning the data the command
   *           which executed want to convey to the frontend.
   */

  executeCommand(consoleActor, debuggerGlobal, selectedNodeActorID, evalInput) {
    const { command, args } = getCommandAndArgs(evalInput);
    const commands = this._getCommandsForCurrentEnvironment();
    if (!commands.has(command)) {
      throw new Error(`Unsupported command '${command}'`);
    }

    if (args.help || args.usage) {
      const l10nKey = USAGE_STRING_MAPPING[command];
      if (l10nKey) {
        const message = l10n.formatValueSync(l10nKey);
        if (message && message !== l10nKey) {
          return {
            result: null,
            helperResult: {
              type: "usage",
              message,
            },
          };
        }
      }
    }

    const validArguments = this._validArguments.get(command);
    if (validArguments) {
      for (const key of Object.keys(args)) {
        if (!validArguments.includes(key)) {
          throw new Error(
            `:${command} command doesn't support '${key}' argument.`
          );
        }
      }
    }

    const owner = this._createOwnerObject(
      consoleActor,
      debuggerGlobal,
      evalInput,
      selectedNodeActorID
    );

    const commandFunction = commands.get(command);

    // This is where we run the command passed to register method
    const result = commandFunction(owner, args);

    return {
      result,

      // commandFunction may mutate owner.helperResult which is used
      // to convey additional data to the frontend.
      helperResult: owner.helperResult,
    };
  },
};

exports.WebConsoleCommandsManager = WebConsoleCommandsManager;

/*
 * Built-in commands.
 *
 * A list of helper functions used by Firebug can be found here:
 *   http://getfirebug.com/wiki/index.php/Command_Line_API
 */


/**
 * Find the first node matching a CSS selector.
 *
 * @param string selector
 *        A string that is passed to window.document.querySelector
 * @param [optional] Node element
 *        An optional Node to replace window.document
 * @return Node or null
 *         The result of calling document.querySelectorAll(selector).
 */

WebConsoleCommandsManager.register({
  name: "$",
  isSideEffectFree: true,
  command(owner, selector, element) {
    try {
      if (
        element &&
        element.querySelector &&
        (element.nodeType == Node.ELEMENT_NODE ||
          element.nodeType == Node.DOCUMENT_NODE ||
          element.nodeType == Node.DOCUMENT_FRAGMENT_NODE)
      ) {
        return element.querySelector(selector);
      }
      return owner.window.document.querySelector(selector);
    } catch (err) {
      // Throw an error like `err` but that belongs to `owner.window`.
      throw new owner.window.DOMException(err.message, err.name);
    }
  },
});

/**
 * Find the nodes matching a CSS selector.
 *
 * @param string selector
 *        A string that is passed to window.document.querySelectorAll.
 * @param [optional] Node element
 *        An optional root Node, defaults to window.document
 * @return array of Node
 *         The result of calling document.querySelector(selector) in an array.
 */

WebConsoleCommandsManager.register({
  name: "$$",
  isSideEffectFree: true,
  command(owner, selector, element) {
    let scope = owner.window.document;
    try {
      if (
        element &&
        element.querySelectorAll &&
        (element.nodeType == Node.ELEMENT_NODE ||
          element.nodeType == Node.DOCUMENT_NODE ||
          element.nodeType == Node.DOCUMENT_FRAGMENT_NODE)
      ) {
        scope = element;
      }
      const nodes = scope.querySelectorAll(selector);
      const result = new owner.window.Array();
      // Calling owner.window.Array.from() doesn't work without accessing the
      // wrappedJSObject, so just loop through the results instead.
      for (let i = 0; i < nodes.length; i++) {
        result.push(nodes[i]);
      }
      return result;
    } catch (err) {
      // Throw an error like `err` but that belongs to `owner.window`.
      throw new owner.window.DOMException(err.message, err.name);
    }
  },
});

/**
 * Find the nodes matching a CSS selector, including those inside shadow DOM
 *
 * @param string selector
 *        A string that is passed to all `querySelectorAll` calls performed by this command.
 * @param [optional] Node element
 *        An optional root Node, defaults to window.document
 * @return array of Node
 *         An array containing the nodes returned by calling `querySelectorAll(selector)`
 *         on `element` and on all shadow hosts under element (recursively).
 */

WebConsoleCommandsManager.register({
  name: "$$$",
  isSideEffectFree: true,
  command(owner, selector, element) {
    let scope = owner.window.document;
    try {
      if (
        element?.querySelectorAll &&
        (element.nodeType == Node.ELEMENT_NODE ||
          element.nodeType == Node.DOCUMENT_NODE ||
          element.nodeType == Node.DOCUMENT_FRAGMENT_NODE)
      ) {
        scope = element;
      }

      const result = new owner.window.Array();

      const collectElements = root => {
        const nodes = root.querySelectorAll(selector);
        // Calling owner.window.Array.from() doesn't work without accessing the
        // wrappedJSObject, so just loop through the results instead.
        for (let i = 0, len = nodes.length; i < len; i++) {
          result.push(nodes[i]);
        }

        // If the scope is a host, run the query inside its shadow DOM
        if (root.openOrClosedShadowRoot) {
          collectElements(root.openOrClosedShadowRoot);
        }

        // Finally, run the query for all hosts in scope
        const all = root.querySelectorAll("*");
        for (let i = 0, len = all.length; i < len; i++) {
          const el = all[i];
          if (el.openOrClosedShadowRoot) {
            collectElements(el.openOrClosedShadowRoot);
          }
        }
      };

      collectElements(scope);

      return result;
    } catch (err) {
      // Throw an error like `err` but that belongs to `owner.window`.
      throw new owner.window.DOMException(err.message, err.name);
    }
  },
});

/**
 * Returns the result of the last console input evaluation
 *
 * @return object|undefined
 * Returns last console evaluation or undefined
 */

WebConsoleCommandsManager.register({
  name: "$_",
  isSideEffectFree: true,
  command: {
    get(owner) {
      return owner.consoleActor.getLastConsoleInputEvaluation();
    },
  },
});

/**
 * Runs an xPath query and returns all matched nodes.
 *
 * @param string xPath
 *        xPath search query to execute.
 * @param [optional] Node context
 *        Context to run the xPath query on. Uses window.document if not set.
 * @param [optional] string|number resultType
          Specify the result type. Default value XPathResult.ANY_TYPE
 * @return array of Node
 */

WebConsoleCommandsManager.register({
  name: "$x",
  isSideEffectFree: true,
  command(
    owner,
    xPath,
    context,
    resultType = owner.window.XPathResult.ANY_TYPE
  ) {
    const nodes = new owner.window.Array();
    // Not waiving Xrays, since we want the original Document.evaluate function,
    // instead of anything that's been redefined.
    const doc = owner.window.document;
    context = context || doc;
    switch (resultType) {
      case "number":
        resultType = owner.window.XPathResult.NUMBER_TYPE;
        break;

      case "string":
        resultType = owner.window.XPathResult.STRING_TYPE;
        break;

      case "bool":
        resultType = owner.window.XPathResult.BOOLEAN_TYPE;
        break;

      case "node":
        resultType = owner.window.XPathResult.FIRST_ORDERED_NODE_TYPE;
        break;

      case "nodes":
        resultType = owner.window.XPathResult.UNORDERED_NODE_ITERATOR_TYPE;
        break;
    }
    const results = doc.evaluate(xPath, context, null, resultType, null);
    if (results.resultType === owner.window.XPathResult.NUMBER_TYPE) {
      return results.numberValue;
    }
    if (results.resultType === owner.window.XPathResult.STRING_TYPE) {
      return results.stringValue;
    }
    if (results.resultType === owner.window.XPathResult.BOOLEAN_TYPE) {
      return results.booleanValue;
    }
    if (
      results.resultType === owner.window.XPathResult.ANY_UNORDERED_NODE_TYPE ||
      results.resultType === owner.window.XPathResult.FIRST_ORDERED_NODE_TYPE
    ) {
      return results.singleNodeValue;
    }
    if (
      results.resultType ===
        owner.window.XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE ||
      results.resultType === owner.window.XPathResult.ORDERED_NODE_SNAPSHOT_TYPE
    ) {
      for (let i = 0; i < results.snapshotLength; i++) {
        nodes.push(results.snapshotItem(i));
      }
      return nodes;
    }

    let node;
    while ((node = results.iterateNext())) {
      nodes.push(node);
    }

    return nodes;
  },
});

/**
 * Returns the currently selected object in the highlighter.
 *
 * @return Object representing the current selection in the
 *         Inspector, or null if no selection exists.
 */

WebConsoleCommandsManager.register({
  name: "$0",
  isSideEffectFree: true,
  command: {
    get(owner) {
      return owner.makeDebuggeeValue(owner.selectedNode);
    },
  },
});

/**
 * Clears the output of the WebConsole.
 */

WebConsoleCommandsManager.register({
  name: "clear",
  isSideEffectFree: false,
  command(owner) {
    owner.helperResult = {
      type: "clearOutput",
    };
  },
});

/**
 * Clears the input history of the WebConsole.
 */

WebConsoleCommandsManager.register({
  name: "clearHistory",
  isSideEffectFree: false,
  command(owner) {
    owner.helperResult = {
      type: "clearHistory",
    };
  },
});

/**
 * Returns the result of Object.keys(object).
 *
 * @param object object
 *        Object to return the property names from.
 * @return array of strings
 */

WebConsoleCommandsManager.register({
  name: "keys",
  isSideEffectFree: true,
  command(owner, object) {
    // Need to waive Xrays so we can iterate functions and accessor properties
    return Cu.cloneInto(Object.keys(Cu.waiveXrays(object)), owner.window);
  },
});

/**
 * Returns the values of all properties on object.
 *
 * @param object object
 *        Object to display the values from.
 * @return array of string
 */

WebConsoleCommandsManager.register({
  name: "values",
  isSideEffectFree: true,
  command(owner, object) {
    const values = [];
    // Need to waive Xrays so we can iterate functions and accessor properties
    const waived = Cu.waiveXrays(object);
    const names = Object.getOwnPropertyNames(waived);

    for (const name of names) {
      values.push(waived[name]);
    }

    return Cu.cloneInto(values, owner.window);
  },
});

/**
 * Opens a help window in MDN.
 */

WebConsoleCommandsManager.register({
  name: "help",
  isSideEffectFree: false,
  command(owner) {
    owner.helperResult = { type: "help" };
  },
});

/**
 * Inspects the passed object. This is done by opening the PropertyPanel.
 *
 * @param object object
 *        Object to inspect.
 */

WebConsoleCommandsManager.register({
  name: "inspect",
  isSideEffectFree: false,
  command(owner, object, forceExpandInConsole = false) {
    const dbgObj = owner.preprocessDebuggerObject(
      owner.makeDebuggeeValue(object)
    );

    const grip = owner.createValueGrip(dbgObj);
    owner.helperResult = {
      type: "inspectObject",
      input: owner.evalInput,
      object: grip,
      forceExpandInConsole,
    };
  },
});

/**
 * Copy the String representation of a value to the clipboard.
 *
 * @param any value
 *        A value you want to copy as a string.
 * @return void
 */

WebConsoleCommandsManager.register({
  name: "copy",
  isSideEffectFree: false,
  command(owner, value) {
    let payload;
    try {
      if (Element.isInstance(value)) {
        payload = value.outerHTML;
      } else if (typeof value == "string") {
        payload = value;
      } else {
        payload = JSON.stringify(value, null" ");
      }
    } catch (ex) {
      owner.helperResult = {
        type: "error",
        message: "webconsole.error.commands.copyError",
        messageArgs: [ex.toString()],
      };
      return;
    }
    owner.helperResult = {
      type: "copyValueToClipboard",
      value: payload,
    };
  },
});

/**
 * Take a screenshot of a page.
 *
 * @param object args
 *               The arguments to be passed to the screenshot
 * @return void
 */

WebConsoleCommandsManager.register({
  name: "screenshot",
  isSideEffectFree: false,
  command(owner, args = {}) {
    owner.helperResult = {
      type: "screenshotOutput",
      args,
    };
  },
});

/**
 * Shows a history of commands and expressions previously executed within the command line.
 *
 * @param object args
 *               The arguments to be passed to the history
 * @return void
 */

WebConsoleCommandsManager.register({
  name: "history",
  isSideEffectFree: false,
  command(owner, args = {}) {
    owner.helperResult = {
      type: "historyOutput",
      args,
    };
  },
});

/**
 * Block specific resource from loading
 *
 * @param object args
 *               an object with key "url", i.e. a filter
 *
 * @return void
 */

WebConsoleCommandsManager.register({
  name: "block",
  isSideEffectFree: false,
  command(owner, args = {}) {
    // Note that this command is implemented in the frontend, from actions's input.js
    // We only forward the command arguments back to the client.
    if (!args.url) {
      owner.helperResult = {
        type: "error",
        message: "webconsole.messages.commands.blockArgMissing",
      };
      return;
    }

    owner.helperResult = {
      type: "blockURL",
      args,
    };
  },
  validArguments: ["url"],
});

/*
 * Unblock a blocked a resource
 *
 * @param object filter
 *               an object with key "url", i.e. a filter
 *
 * @return void
 */

WebConsoleCommandsManager.register({
  name: "unblock",
  isSideEffectFree: false,
  command(owner, args = {}) {
    // Note that this command is implemented in the frontend, from actions's input.js
    // We only forward the command arguments back to the client.
    if (!args.url) {
      owner.helperResult = {
        type: "error",
        message: "webconsole.messages.commands.blockArgMissing",
      };
      return;
    }

    owner.helperResult = {
      type: "unblockURL",
      args,
    };
  },
  validArguments: ["url"],
});

/*
 * Toggle JavaScript tracing
 *
 * @param object args
 *        An object with various configuration only valid when starting the tracing.
 *
 * @return void
 */

WebConsoleCommandsManager.register({
  name: "trace",
  isSideEffectFree: false,
  command(owner, args) {
    // Disable :trace command on worker until this feature is enabled by default
    if (isWorker) {
      throw new Error(":trace command isn't supported in workers");
    }

    if (!owner.consoleActor.targetActor.isTracerFeatureEnabled) {
      throw new Error(
        ":trace requires 'devtools.debugger.features.javascript-tracing' preference to be true"
      );
    }
    const tracerActor =
      owner.consoleActor.targetActor.getTargetScopedActor("tracer");
    const logMethod = args.logMethod || "console";
    let traceDOMMutations = null;
    if ("dom-mutations" in args) {
      // When no value is passed, track all types of mutations
      if (args["dom-mutations"] === true) {
        traceDOMMutations = ["add""attributes""remove"];
      } else if (typeof args["dom-mutations"] == "string") {
        // Otherwise consider the value as coma seperated list and remove any white space.
        traceDOMMutations = args["dom-mutations"].split(",").map(e => e.trim());
        const acceptedValues = Object.values(lazy.JSTracer.DOM_MUTATIONS);
        if (!traceDOMMutations.every(e => acceptedValues.includes(e))) {
          throw new Error(
            `:trace --dom-mutations only accept a list of strings whose values can be: ${acceptedValues}`
          );
        }
      } else {
        throw new Error(
          ":trace --dom-mutations accept only no arguments, or a list mutation type strings (add,attributes,remove)"
        );
      }
    }
    // Note that toggleTracing does some sanity checks and will throw meaningful error
    // when the arguments are wrong.
    const enabled = tracerActor.toggleTracing({
      logMethod,
      prefix: args.prefix || null,
      traceFunctionReturn: !!args.returns,
      traceValues: !!args.values,
      traceOnNextInteraction: args["on-next-interaction"] || null,
      traceDOMMutations,
      maxDepth: args["max-depth"] || null,
      maxRecords: args["max-records"] || null,
    });

    owner.helperResult = {
      type: "traceOutput",
      enabled,
      logMethod,
    };
  },
  validArguments: [
    "logMethod",
    "max-depth",
    "max-records",
    "on-next-interaction",
    "dom-mutations",
    "prefix",
    "returns",
    "values",
  ],
});

Messung V0.5
C=91 H=90 G=90

¤ Dauer der Verarbeitung: 0.49 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge