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

Quelle  ToolboxToolbar.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 {
  Component,
  createFactory,
} = require("resource://devtools/client/shared/vendor/react.js");
const dom = require("resource://devtools/client/shared/vendor/react-dom-factories.js");
const PropTypes = require("resource://devtools/client/shared/vendor/react-prop-types.js");
const { div, button } = dom;
const MenuButton = createFactory(
  require("resource://devtools/client/shared/components/menu/MenuButton.js")
);
const ToolboxTabs = createFactory(
  require("resource://devtools/client/framework/components/ToolboxTabs.js")
);
loader.lazyGetter(this"MeatballMenu"function () {
  return createFactory(
    require("resource://devtools/client/framework/components/MeatballMenu.js")
  );
});
loader.lazyGetter(this"MenuItem"function () {
  return createFactory(
    require("resource://devtools/client/shared/components/menu/MenuItem.js")
  );
});
loader.lazyGetter(this"MenuList"function () {
  return createFactory(
    require("resource://devtools/client/shared/components/menu/MenuList.js")
  );
});
loader.lazyGetter(this"LocalizationProvider"function () {
  return createFactory(
    require("resource://devtools/client/shared/vendor/fluent-react.js")
      .LocalizationProvider
  );
});
loader.lazyGetter(this"DebugTargetInfo", () =>
  createFactory(
    require("resource://devtools/client/framework/components/DebugTargetInfo.js")
  )
);
loader.lazyGetter(this"ChromeDebugToolbar", () =>
  createFactory(
    require("resource://devtools/client/framework/components/ChromeDebugToolbar.js")
  )
);

loader.lazyRequireGetter(
  this,
  "getUnicodeUrl",
  "resource://devtools/client/shared/unicode-url.js",
  true
);

/**
 * This is the overall component for the toolbox toolbar. It is designed to not know how
 * the state is being managed, and attempts to be as pure as possible. The
 * ToolboxController component controls the changing state, and passes in everything as
 * props.
 */

class ToolboxToolbar extends Component {
  static get propTypes() {
    return {
      // The currently focused item (for arrow keyboard navigation)
      // This ID determines the tabindex being 0 or -1.
      focusedButton: PropTypes.string,
      // List of command button definitions.
      toolboxButtons: PropTypes.array,
      // The id of the currently selected tool, e.g. "inspector"
      currentToolId: PropTypes.string,
      // An optionally highlighted tools, e.g. "inspector" (used by ToolboxTabs
      // component).
      highlightedTools: PropTypes.instanceOf(Set),
      // List of tool panel definitions (used by ToolboxTabs component).
      panelDefinitions: PropTypes.array,
      // List of possible docking options.
      hostTypes: PropTypes.arrayOf(
        PropTypes.shape({
          position: PropTypes.string.isRequired,
          switchHost: PropTypes.func.isRequired,
        })
      ),
      // Current docking type. Typically one of the position values in
      // |hostTypes| but this is not always the case (e.g. for "browsertoolbox").
      currentHostType: PropTypes.string,
      // Are docking options enabled? They are not enabled in certain situations
      // like when the toolbox is opened in a tab.
      areDockOptionsEnabled: PropTypes.bool,
      // Do we need to add UI for closing the toolbox? We don't when the
      // toolbox is undocked, for example.
      canCloseToolbox: PropTypes.bool,
      // Is the split console currently visible?
      isSplitConsoleActive: PropTypes.bool,
      // Are we disabling the behavior where pop-ups are automatically closed
      // when clicking outside them?
      //
      // This is a tri-state value that may be true/false or undefined where
      // undefined means that the option is not relevant in this context
      // (i.e. we're not in a browser toolbox).
      disableAutohide: PropTypes.bool,
      // Are we displaying the window always on top?
      //
      // This is a tri-state value that may be true/false or undefined where
      // undefined means that the option is not relevant in this context
      // (i.e. we're not in a local web extension toolbox).
      alwaysOnTop: PropTypes.bool,
      // Is the toolbox currently focused?
      //
      // This will only be defined when alwaysOnTop is true.
      focusedState: PropTypes.bool,
      // Function to turn the options panel on / off.
      toggleOptions: PropTypes.func.isRequired,
      // Function to turn the split console on / off.
      toggleSplitConsole: PropTypes.func,
      // Function to turn the disable pop-up autohide behavior on / off.
      toggleNoAutohide: PropTypes.func,
      // Function to turn the always on top behavior on / off.
      toggleAlwaysOnTop: PropTypes.func,
      // Function to completely close the toolbox.
      closeToolbox: PropTypes.func,
      // Keep a record of what button is focused.
      focusButton: PropTypes.func,
      // Hold off displaying the toolbar until enough information is ready for
      // it to render nicely.
      canRender: PropTypes.bool,
      // Localization interface.
      L10N: PropTypes.object.isRequired,
      // The devtools toolbox
      toolbox: PropTypes.object,
      // Call back function to detect tabs order updated.
      onTabsOrderUpdated: PropTypes.func.isRequired,
      // Count of visible toolbox buttons which is used by ToolboxTabs component
      // to recognize that the visibility of toolbox buttons were changed.
      // Because in the component we cannot compare the visibility since the
      // button definition instance in toolboxButtons will be unchanged.
      visibleToolboxButtonCount: PropTypes.number,
      // Data to show debug target info, if needed
      debugTargetData: PropTypes.shape({
        runtimeInfo: PropTypes.object.isRequired,
        descriptorType: PropTypes.string.isRequired,
      }),
      // The loaded Fluent localization bundles.
      fluentBundles: PropTypes.array.isRequired,
    };
  }

  constructor(props) {
    super(props);

    this.hideMenu = this.hideMenu.bind(this);
    this.createFrameList = this.createFrameList.bind(this);
    this.highlightFrame = this.highlightFrame.bind(this);
  }

  componentDidMount() {
    this.props.toolbox.on("panel-changed"this.hideMenu);
  }

  componentWillUnmount() {
    this.props.toolbox.off("panel-changed"this.hideMenu);
  }

  hideMenu() {
    if (this.refs.meatballMenuButton) {
      this.refs.meatballMenuButton.hideMenu();
    }

    if (this.refs.frameMenuButton) {
      this.refs.frameMenuButton.hideMenu();
    }
  }

  /**
   * A little helper function to call renderToolboxButtons for buttons at the start
   * of the toolbox.
   */

  renderToolboxButtonsStart() {
    return this.renderToolboxButtons(true);
  }

  /**
   * A little helper function to call renderToolboxButtons for buttons at the end
   * of the toolbox.
   */

  renderToolboxButtonsEnd() {
    return this.renderToolboxButtons(false);
  }

  /**
   * Render all of the tabs, this takes in a list of toolbox button states. These are plain
   * objects that have all of the relevant information needed to render the button.
   * See Toolbox.prototype._createButtonState in devtools/client/framework/toolbox.js for
   * documentation on this object.
   *
   * @param {String} focusedButton - The id of the focused button.
   * @param {Array} toolboxButtons - Array of objects that define the command buttons.
   * @param {Function} focusButton - Keep a record of the currently focused button.
   * @param {boolean} isStart - Render either the starting buttons, or ending buttons.
   */

  renderToolboxButtons(isStart) {
    const { focusedButton, toolboxButtons, focusButton } = this.props;
    const visibleButtons = toolboxButtons.filter(command => {
      const { isVisible, isInStartContainer } = command;
      return isVisible && (isStart ? isInStartContainer : !isInStartContainer);
    });

    if (visibleButtons.length === 0) {
      return null;
    }

    // The RDM button, if present, should always go last
    const rdmIndex = visibleButtons.findIndex(
      button => button.id === "command-button-responsive"
    );
    if (rdmIndex !== -1 && rdmIndex !== visibleButtons.length - 1) {
      const rdm = visibleButtons.splice(rdmIndex, 1)[0];
      visibleButtons.push(rdm);
    }

    const renderedButtons = visibleButtons.map(command => {
      const {
        id,
        description,
        disabled,
        onClick,
        isChecked,
        isToggle,
        className: buttonClass,
        onKeyDown,
      } = command;

      // If button is frame button, create menu button in order to
      // use the doorhanger menu.
      if (id === "command-button-frames") {
        return this.renderFrameButton(command);
      }

      if (id === "command-button-errorcount") {
        return this.renderErrorIcon(command);
      }

      return button({
        id,
        title: description,
        disabled,
        "aria-pressed": !isToggle ? null : isChecked,
        className: `devtools-tabbar-button command-button ${
          buttonClass || ""
        } ${isChecked ? "checked" : ""}`,
        onClick: event => {
          onClick(event);
          focusButton(id);
        },
        onFocus: () => focusButton(id),
        tabIndex: id === focusedButton ? "0" : "-1",
        onKeyDown: event => {
          onKeyDown(event);
        },
        onContextMenu: event => {
          const menu = command.getContextMenu();
          if (!menu) {
            return;
          }

          event.preventDefault();
          event.stopPropagation();

          menu.popup(event.screenX, event.screenY, window.parent.document);
        },
      });
    });

    // Add the appropriate separator, if needed.
    const children = renderedButtons;
    if (renderedButtons.length) {
      if (isStart) {
        children.push(this.renderSeparator());
        // For the end group we add a separator *before* the RDM button if it
        // exists, but only if it is not the only button.
      } else if (rdmIndex !== -1 && renderedButtons.length > 1) {
        children.splice(children.length - 1, 0, this.renderSeparator());
      }
    }

    return div(
      { id: `toolbox-buttons-${isStart ? "start" : "end"}` },
      ...children
    );
  }

  renderFrameButton(command) {
    const { id, isChecked, disabled, description } = command;

    const { toolbox } = this.props;

    return MenuButton(
      {
        id,
        disabled,
        menuId: id + "-panel",
        toolboxDoc: toolbox.doc,
        className: `devtools-tabbar-button command-button ${
          isChecked ? "checked" : ""
        }`,
        ref: "frameMenuButton",
        title: description,
        onCloseButton: async () => {
          // Only try to unhighlight if the inspectorFront has been created already
          const inspectorFront = toolbox.target.getCachedFront("inspector");
          if (inspectorFront) {
            const highlighter = toolbox.getHighlighter();
            await highlighter.unhighlight();
          }
        },
      },
      this.createFrameList
    );
  }

  renderErrorIcon(command) {
    let { errorCount, id } = command;

    if (!errorCount) {
      return null;
    }

    if (errorCount > 99) {
      errorCount = "99+";
    }

    const errorIconTooltip = this.props.toolbox.isSplitConsoleEnabled()
      ? this.props.L10N.getStr("toolbox.errorCountButton.tooltip")
      : this.props.L10N.getStr("toolbox.errorCountButtonConsoleTab.tooltip");

    return button(
      {
        id,
        className: "devtools-tabbar-button command-button toolbox-error",
        onClick: () => {
          if (this.props.currentToolId !== "webconsole") {
            this.props.toolbox.openSplitConsole();
          }
        },
        title:
          this.props.currentToolId !== "webconsole" ? errorIconTooltip : null,
      },
      errorCount
    );
  }

  highlightFrame(id) {
    const { toolbox } = this.props;
    if (!id) {
      return;
    }

    toolbox.onHighlightFrame(id);
  }

  createFrameList() {
    const { toolbox } = this.props;
    if (toolbox.frameMap.size < 1) {
      return null;
    }

    const items = [];
    toolbox.frameMap.forEach(frame => {
      const label = toolbox.commands.descriptorFront.isWebExtensionDescriptor
        ? toolbox.getExtensionPathName(frame.url)
        : getUnicodeUrl(frame.url);

      const item = MenuItem({
        id: frame.id.toString(),
        key: "toolbox-frame-key-" + frame.id,
        label,
        checked: frame.id === toolbox.selectedFrameId,
        onClick: () => toolbox.onIframePickerFrameSelected(frame.id),
      });

      // Always put the top level frame at the top
      if (frame.isTopLevel) {
        items.unshift(item);
      } else {
        items.push(item);
      }
    });

    return MenuList(
      {
        id: "toolbox-frame-menu",
        onHighlightedChildChange: this.highlightFrame,
      },
      items
    );
  }

  /**
   * Render a separator.
   */

  renderSeparator() {
    return div({ className: "devtools-separator" });
  }

  /**
   * Render the toolbox control buttons. The following props are expected:
   *
   * @param {string} props.focusedButton
   *        The id of the focused button.
   * @param {string} props.currentToolId
   *        The id of the currently selected tool, e.g. "inspector".
   * @param {Object[]} props.hostTypes
   *        Array of host type objects.
   * @param {string} props.hostTypes[].position
   *        Position name.
   * @param {Function} props.hostTypes[].switchHost
   *        Function to switch the host.
   * @param {string} props.currentHostType
   *        The current docking configuration.
   * @param {boolean} props.areDockOptionsEnabled
   *        They are not enabled in certain situations like when the toolbox is
   *        in a tab.
   * @param {boolean} props.canCloseToolbox
   *        Do we need to add UI for closing the toolbox? We don't when the
   *        toolbox is undocked, for example.
   * @param {boolean} props.isSplitConsoleActive
   *         Is the split console currently visible?
   *        toolbox is undocked, for example.
   * @param {boolean|undefined} props.disableAutohide
   *        Are we disabling the behavior where pop-ups are automatically
   *        closed when clicking outside them?
   *        (Only defined for the browser toolbox.)
   * @param {Function} props.selectTool
   *        Function to select a tool based on its id.
   * @param {Function} props.toggleOptions
   *        Function to turn the options panel on / off.
   * @param {Function} props.toggleSplitConsole
   *        Function to turn the split console on / off.
   * @param {Function} props.toggleNoAutohide
   *        Function to turn the disable pop-up autohide behavior on / off.
   * @param {Function} props.toggleAlwaysOnTop
   *        Function to turn the always on top behavior on / off.
   * @param {Function} props.closeToolbox
   *        Completely close the toolbox.
   * @param {Function} props.focusButton
   *        Keep a record of the currently focused button.
   * @param {Object} props.L10N
   *        Localization interface.
   * @param {Object} props.toolbox
   *        The devtools toolbox. Used by the MenuButton component to display
   *        the menu popup.
   * @param {Object} refs
   *        The components refs object. Used to keep a reference to the MenuButton
   *        for the meatball menu so that we can tell it to resize its contents
   *        when they change.
   */

  renderToolboxControls() {
    const {
      focusedButton,
      canCloseToolbox,
      closeToolbox,
      focusButton,
      L10N,
      toolbox,
    } = this.props;

    const meatballMenuButtonId = "toolbox-meatball-menu-button";

    const meatballMenuButton = MenuButton(
      {
        id: meatballMenuButtonId,
        menuId: meatballMenuButtonId + "-panel",
        toolboxDoc: toolbox.doc,
        onFocus: () => focusButton(meatballMenuButtonId),
        className: "devtools-tabbar-button",
        title: L10N.getStr("toolbox.meatballMenu.button.tooltip"),
        tabIndex: focusedButton === meatballMenuButtonId ? "0" : "-1",
        ref: "meatballMenuButton",
      },
      MeatballMenu({
        ...this.props,
        hostTypes: this.props.areDockOptionsEnabled ? this.props.hostTypes : [],
        onResize: () => {
          this.refs.meatballMenuButton.resizeContent();
        },
      })
    );

    const closeButtonId = "toolbox-close";

    const closeButton = canCloseToolbox
      ? button({
          id: closeButtonId,
          onFocus: () => focusButton(closeButtonId),
          className: "devtools-tabbar-button",
          title: L10N.getStr("toolbox.closebutton.tooltip"),
          onClick: () => closeToolbox(),
          tabIndex: focusedButton === "toolbox-close" ? "0" : "-1",
        })
      : null;

    return div({ id: "toolbox-controls" }, meatballMenuButton, closeButton);
  }

  /**
   * The render function is kept fairly short for maintainability. See the individual
   * render functions for how each of the sections is rendered.
   */

  render() {
    const { L10N, debugTargetData, toolbox, fluentBundles } = this.props;
    const classnames = ["devtools-tabbar"];
    const startButtons = this.renderToolboxButtonsStart();
    const endButtons = this.renderToolboxButtonsEnd();

    if (!startButtons) {
      classnames.push("devtools-tabbar-has-start");
    }
    if (!endButtons) {
      classnames.push("devtools-tabbar-has-end");
    }

    const toolbar = this.props.canRender
      ? div(
          {
            className: classnames.join(" "),
          },
          startButtons,
          ToolboxTabs(this.props),
          endButtons,
          this.renderToolboxControls()
        )
      : div({ className: classnames.join(" ") });

    const debugTargetInfo = debugTargetData
      ? DebugTargetInfo({
          alwaysOnTop: this.props.alwaysOnTop,
          focusedState: this.props.focusedState,
          toggleAlwaysOnTop: this.props.toggleAlwaysOnTop,
          debugTargetData,
          L10N,
          toolbox,
        })
      : null;

    // Display the toolbar in the MBT and about:debugging MBT if we have server support for it.
    const chromeDebugToolbar = toolbox.commands.targetCommand.descriptorFront
      .isBrowserProcessDescriptor
      ? ChromeDebugToolbar()
      : null;

    return LocalizationProvider(
      { bundles: fluentBundles },
      div({}, chromeDebugToolbar, debugTargetInfo, toolbar)
    );
  }
}

module.exports = ToolboxToolbar;

100%


¤ Dauer der Verarbeitung: 0.2 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.