Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/devtools/client/fronts/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 9 kB image not shown  

Quelle  inspector.js   Sprache: JAVA

 
/* This Source 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";

const Telemetry = require("resource://devtools/client/shared/telemetry.js");
const {
  FrontClassWithSpec,
  registerFront,
} = require("resource://devtools/shared/protocol.js");
const {
  inspectorSpec,
} = require("resource://devtools/shared/specs/inspector.js");

loader.lazyRequireGetter(
  this,
  "captureScreenshot",
  "resource://devtools/client/shared/screenshot.js",
  true
);
const lazy = {};

ChromeUtils.defineESModuleGetters(lazy, {
  TYPES: "resource://devtools/shared/highlighters.mjs",
});

const TELEMETRY_EYEDROPPER_OPENED = "DEVTOOLS_EYEDROPPER_OPENED_COUNT";
const TELEMETRY_EYEDROPPER_OPENED_MENU =
  "DEVTOOLS_MENU_EYEDROPPER_OPENED_COUNT";
const SHOW_ALL_ANONYMOUS_CONTENT_PREF =
  "devtools.inspector.showAllAnonymousContent";

const telemetry = new Telemetry();

/**
 * Client side of the inspector actor, which is used to create
 * inspector-related actors, including the walker.
 */

class InspectorFront extends FrontClassWithSpec(inspectorSpec) {
  constructor(client, targetFront, parentFront) {
    super(client, targetFront, parentFront);

    this._client = client;
    this._highlighters = new Map();

    // Attribute name from which to retrieve the actorID out of the target actor's form
    this.formAttributeName = "inspectorActor";

    // Map of highlighter types to unsettled promises to create a highlighter of that type
    this._pendingGetHighlighterMap = new Map();

    this.noopStylesheetListener = () => {};
  }

  // async initialization
  async initialize() {
    if (this.initialized) {
      return this.initialized;
    }

    // Watch STYLESHEET resources to fill the ResourceCommand cache.
    // StyleRule front's `get parentStyleSheet()` will query the cache to
    // retrieve the resource corresponding to the parent stylesheet of a rule.
    const { resourceCommand } = this.targetFront.commands;
    // Backup resourceCommand, targetFront.commands might be null in `destroy`.
    this.resourceCommand = resourceCommand;
    await resourceCommand.watchResources([resourceCommand.TYPES.STYLESHEET], {
      onAvailable: this.noopStylesheetListener,
    });

    // Bail out if the inspector is closed while watchResources was pending
    if (this.isDestroyed()) {
      return null;
    }

    const promises = [this._getWalker(), this._getPageStyle()];
    if (this.targetFront.commands.descriptorFront.isTabDescriptor) {
      promises.push(this._enableViewportSizeOnResizeHighlighter());
    }

    this.initialized = await Promise.all(promises);

    return this.initialized;
  }

  async _getWalker() {
    const showAllAnonymousContent = Services.prefs.getBoolPref(
      SHOW_ALL_ANONYMOUS_CONTENT_PREF
    );
    this.walker = await this.getWalker({
      showAllAnonymousContent,
    });

    // We need to reparent the RootNode of remote iframe Walkers
    // so that their parent is the NodeFront of the <iframe>
    // element, coming from another process/target/WalkerFront.
    await this.walker.reparentRemoteFrame();
  }

  hasHighlighter(type) {
    return this._highlighters.has(type);
  }

  async _getPageStyle() {
    this.pageStyle = await super.getPageStyle();
  }

  async _enableViewportSizeOnResizeHighlighter() {
    const highlighter = await this.getOrCreateHighlighterByType(
      lazy.TYPES.VIEWPORT_SIZE_ON_RESIZE
    );
    await highlighter.show(this);
  }

  async getCompatibilityFront() {
    if (!this._compatibility) {
      this._compatibility = await super.getCompatibility();
    }

    return this._compatibility;
  }

  destroy() {
    if (this.isDestroyed()) {
      return;
    }
    this._compatibility = null;

    const { resourceCommand } = this;
    resourceCommand.unwatchResources([resourceCommand.TYPES.STYLESHEET], {
      onAvailable: this.noopStylesheetListener,
    });
    this.resourceCommand = null;

    this.walker = null;

    // CustomHighlighter fronts are managed by InspectorFront and so will be
    // automatically destroyed. But we have to clear the `_highlighters`
    // Map as well as explicitly call `finalize` request on all of them.
    this.destroyHighlighters();
    super.destroy();
  }

  destroyHighlighters() {
    for (const type of this._highlighters.keys()) {
      if (this._highlighters.has(type)) {
        const highlighter = this._highlighters.get(type);
        if (!highlighter.isDestroyed()) {
          highlighter.finalize();
        }
        this._highlighters.delete(type);
      }
    }
  }

  async getHighlighterByType(typeName) {
    let highlighter = null;
    try {
      highlighter = await super.getHighlighterByType(typeName);
    } catch (_) {
      throw new Error(
        "The target doesn't support " +
          `creating highlighters by types or ${typeName} is unknown`
      );
    }
    return highlighter;
  }

  getKnownHighlighter(type) {
    return this._highlighters.get(type);
  }

  /**
   * Return a highlighter instance of the given type.
   * If an instance was previously created, return it. Else, create and return a new one.
   *
   * Store a promise for the request to create a new highlighter. If another request
   * comes in before that promise is resolved, wait for it to resolve and return the
   * highlighter instance it resolved with instead of creating a new request.
   *
   * @param  {String} type
   *         Highlighter type
   * @return {Promise}
   *         Promise which resolves with a highlighter instance of the given type
   */

  async getOrCreateHighlighterByType(type) {
    let front = this._highlighters.get(type);
    let pendingGetHighlighter = this._pendingGetHighlighterMap.get(type);

    if (!front && !pendingGetHighlighter) {
      pendingGetHighlighter = (async () => {
        const highlighter = await this.getHighlighterByType(type);
        this._highlighters.set(type, highlighter);
        this._pendingGetHighlighterMap.delete(type);
        return highlighter;
      })();

      this._pendingGetHighlighterMap.set(type, pendingGetHighlighter);
    }

    if (pendingGetHighlighter) {
      front = await pendingGetHighlighter;
    }

    return front;
  }

  async pickColorFromPage(options) {
    let screenshot = null;

    // @backward-compat { version 87 } ScreenshotContentActor was only added in 87.
    //                  When connecting to older server, the eyedropper will  use drawWindow
    //                  to retrieve the screenshot of the page (that's a decent fallback,
    //                  even if it doesn't handle remote frames).
    if (this.targetFront.hasActor("screenshotContent")) {
      try {
        // We use the screenshot actors as it can retrieve an image of the current viewport,
        // handling remote frame if need be.
        const { data } = await captureScreenshot(this.targetFront, {
          browsingContextID: this.targetFront.browsingContextID,
          disableFlash: true,
          ignoreDprForFileScale: true,
        });
        screenshot = data;
      } catch (e) {
        // We simply log the error and still call pickColorFromPage as it will default to
        // use drawWindow in order to get the screenshot of the page (that's a decent
        // fallback, even if it doesn't handle remote frames).
        console.error(
          "Error occured when taking a screenshot for the eyedropper",
          e
        );
      }
    }

    await super.pickColorFromPage({
      ...options,
      screenshot,
    });

    if (options?.fromMenu) {
      telemetry.getHistogramById(TELEMETRY_EYEDROPPER_OPENED_MENU).add(true);
    } else {
      telemetry.getHistogramById(TELEMETRY_EYEDROPPER_OPENED).add(true);
    }
  }

  /**
   * Given a node grip, return a NodeFront on the right context.
   *
   * @param {Object} grip: The node grip.
   * @returns {Promise<NodeFront|null>} A promise that resolves with  a NodeFront or null
   *                                    if the NodeFront couldn't be created/retrieved.
   */

  async getNodeFrontFromNodeGrip(grip) {
    return this.getNodeActorFromContentDomReference(grip.contentDomReference);
  }

  async getNodeActorFromContentDomReference(contentDomReference) {
    const { browsingContextId } = contentDomReference;
    // If the contentDomReference lives in the same browsing context id than the
    // current one, we can directly use the current walker.
    if (this.targetFront.browsingContextID === browsingContextId) {
      return this.walker.getNodeActorFromContentDomReference(
        contentDomReference
      );
    }

    // If the contentDomReference has a different browsing context than the current one,
    // we are either in Fission or in the Multiprocess Browser Toolbox, so we need to
    // retrieve the walker of the WindowGlobalTarget.
    // Get the target for this remote frame element

    // Tab and Process Descriptors expose a Watcher, which should be used to
    // fetch the node's target.
    let target;
    const { watcherFront } = this.targetFront.commands;
    if (watcherFront) {
      target = await watcherFront.getWindowGlobalTarget(browsingContextId);
    } else {
      // For descriptors which don't expose a watcher (e.g. WebExtension)
      // we used to call RootActor::getBrowsingContextDescriptor, but it was
      // removed in FF77.
      // Support for watcher in WebExtension descriptors is Bug 1644341.
      throw new Error(
        `Unable to call getNodeActorFromContentDomReference for ${this.targetFront.actorID}`
      );
    }
    const { walker } = await target.getFront("inspector");
    return walker.getNodeActorFromContentDomReference(contentDomReference);
  }
}

exports.InspectorFront = InspectorFront;
registerFront(InspectorFront);

98%


¤ Dauer der Verarbeitung: 0.12 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 ist noch experimentell.