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

Quelle  panel.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 EventEmitter = require("resource://devtools/shared/event-emitter.js");
loader.lazyRequireGetter(
  this,
  "openContentLink",
  "resource://devtools/client/shared/link.js",
  true
);

/**
 * This object represents DOM panel. It's responsibility is to
 * render Document Object Model of the current debugger target.
 */

function DomPanel(iframeWindow, toolbox, commands) {
  this.panelWin = iframeWindow;
  this._toolbox = toolbox;
  this._commands = commands;

  this.onContentMessage = this.onContentMessage.bind(this);
  this.onPanelVisibilityChange = this.onPanelVisibilityChange.bind(this);

  this.pendingRequests = new Map();

  EventEmitter.decorate(this);
}

DomPanel.prototype = {
  /**
   * Open is effectively an asynchronous constructor.
   *
   * @return object
   *         A promise that is resolved when the DOM panel completes opening.
   */

  async open() {
    // Wait for the retrieval of root object properties before resolving open
    const onGetProperties = new Promise(resolve => {
      this._resolveOpen = resolve;
    });

    await this.initialize();

    await onGetProperties;

    return this;
  },

  // Initialization

  async initialize() {
    this.panelWin.addEventListener(
      "devtools/content/message",
      this.onContentMessage,
      true
    );

    this._toolbox.on("select"this.onPanelVisibilityChange);

    // onTargetAvailable is mandatory when calling watchTargets
    this._onTargetAvailable = () => {};
    this._onTargetSelected = this._onTargetSelected.bind(this);
    await this._commands.targetCommand.watchTargets({
      types: [this._commands.targetCommand.TYPES.FRAME],
      onAvailable: this._onTargetAvailable,
      onSelected: this._onTargetSelected,
    });

    this.onResourceAvailable = this.onResourceAvailable.bind(this);
    await this._commands.resourceCommand.watchResources(
      [this._commands.resourceCommand.TYPES.DOCUMENT_EVENT],
      {
        onAvailable: this.onResourceAvailable,
      }
    );

    // Export provider object with useful API for DOM panel.
    const provider = {
      getToolbox: this.getToolbox.bind(this),
      getPrototypeAndProperties: this.getPrototypeAndProperties.bind(this),
      openLink: this.openLink.bind(this),
      // Resolve DomPanel.open once the object properties are fetched
      onPropertiesFetched: () => {
        if (this._resolveOpen) {
          this._resolveOpen();
          this._resolveOpen = null;
        }
      },
    };

    exportIntoContentScope(this.panelWin, provider, "DomProvider");
  },

  destroy() {
    if (this._destroyed) {
      return;
    }
    this._destroyed = true;

    this._commands.targetCommand.unwatchTargets({
      types: [this._commands.targetCommand.TYPES.FRAME],
      onAvailable: this._onTargetAvailable,
      onSelected: this._onTargetSelected,
    });
    this._commands.resourceCommand.unwatchResources(
      [this._commands.resourceCommand.TYPES.DOCUMENT_EVENT],
      { onAvailable: this.onResourceAvailable }
    );
    this._toolbox.off("select"this.onPanelVisibilityChange);

    this.emit("destroyed");
  },

  // Events

  refresh() {
    // Do not refresh if the panel isn't visible.
    if (!this.isPanelVisible()) {
      return;
    }

    // Do not refresh if it isn't necessary.
    if (!this.shouldRefresh) {
      return;
    }

    // Alright reset the flag we are about to refresh the panel.
    this.shouldRefresh = false;

    this.getRootGrip().then(rootGrip => {
      this.postContentMessage("initialize", rootGrip);
    });
  },

  /**
   * Make sure the panel is refreshed, either when navigation occurs or when a frame is
   * selected in the iframe picker.
   * The panel is refreshed immediately if it's currently selected or lazily when the user
   * actually selects it.
   */

  forceRefresh() {
    this.shouldRefresh = true;
    // This will end up calling scriptCommand execute method to retrieve the `window` grip
    // on targetCommand.selectedTargetFront.
    this.refresh();
  },

  _onTargetSelected() {
    this.forceRefresh();
  },

  onResourceAvailable(resources) {
    for (const resource of resources) {
      // Only consider top level document, and ignore remote iframes top document
      if (
        resource.resourceType ===
          this._commands.resourceCommand.TYPES.DOCUMENT_EVENT &&
        resource.name === "dom-complete" &&
        resource.targetFront.isTopLevel
      ) {
        this.forceRefresh();
      }
    }
  },

  /**
   * Make sure the panel is refreshed (if needed) when it's selected.
   */

  onPanelVisibilityChange() {
    this.refresh();
  },

  // Helpers

  /**
   * Return true if the DOM panel is currently selected.
   */

  isPanelVisible() {
    return this._toolbox.currentToolId === "dom";
  },

  async getPrototypeAndProperties(objectFront) {
    if (!objectFront.actorID) {
      console.error("No actor!", objectFront);
      throw new Error("Failed to get object front.");
    }

    // Bail out if target doesn't exist (toolbox maybe closed already).
    if (!this.currentTarget) {
      return null;
    }

    // Check for a previously stored request for grip.
    let request = this.pendingRequests.get(objectFront.actorID);

    // If no request is in progress create a new one.
    if (!request) {
      request = objectFront.getPrototypeAndProperties();
      this.pendingRequests.set(objectFront.actorID, request);
    }

    const response = await request;
    this.pendingRequests.delete(objectFront.actorID);

    // Fire an event about not having any pending requests.
    if (!this.pendingRequests.size) {
      this.emit("no-pending-requests");
    }

    return response;
  },

  openLink(url) {
    openContentLink(url);
  },

  async getRootGrip() {
    const { result } = await this._toolbox.commands.scriptCommand.execute(
      "window",
      {
        disableBreaks: true,
      }
    );
    return result;
  },

  postContentMessage(type, args) {
    const data = {
      type,
      args,
    };

    const event = new this.panelWin.MessageEvent("devtools/chrome/message", {
      bubbles: true,
      cancelable: true,
      data,
    });

    this.panelWin.dispatchEvent(event);
  },

  onContentMessage(event) {
    const data = event.data;
    const method = data.type;
    if (typeof this[method] == "function") {
      this[method](data.args);
    }
  },

  getToolbox() {
    return this._toolbox;
  },

  get currentTarget() {
    return this._toolbox.target;
  },
};

// Helpers

function exportIntoContentScope(win, obj, defineAs) {
  const clone = Cu.createObjectIn(win, {
    defineAs,
  });

  const props = Object.getOwnPropertyNames(obj);
  for (let i = 0; i < props.length; i++) {
    const propName = props[i];
    const propValue = obj[propName];
    if (typeof propValue == "function") {
      Cu.exportFunction(propValue, clone, {
        defineAs: propName,
      });
    }
  }
}

// Exports from this module
exports.DomPanel = DomPanel;

Messung V0.5
C=93 H=99 G=95

¤ Dauer der Verarbeitung: 0.5 Sekunden  ¤

*© 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.