Eine aufbereitete Darstellung der Quelle

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

Benutzer

Quelle  tooltips-overlay.js

  Sprache: JAVA
 

/* This Source Code Form is subject to the terms of the Mozilla Public
 *License,v. 2.. If a  of  MPL   distributedwith this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


"usestrict";

/**
 * The tooltip overlays are tooltips that appear when hovering over property values and
 * editor tooltips that appear when clicking swatch based editors.
 */


const flags = require("resource://devtools/shared/flags.js");
const {
  VIEW_NODE_ATTR_TYPE,
  VIEW_NODE_CSS_EXPLAINERS,
  VIEW_NODE_CSS_QUERY_CONTAINER,
  VIEW_NODE_CSS_SELECTOR_WARNINGS,
  VIEW_NODE_FONT_TYPE,
  VIEW_NODE_IMAGE_URL_TYPE,
  VIEW_NODE_INACTIVE_CSS,
  VIEW_NODE_VALUE_TYPE,
  VIEW_NODE_VARIABLE_TYPE,
} = require("resource://devtools/client/inspector/shared/node-types.js");

loader.lazyRequireGetter(
  this,
  "getCssVariableColor",
  "resource://devtools/client/shared/theme.js",
  true
);
loader.lazyRequireGetter(
  this,
  "HTMLTooltip",
  "resource://devtools/client/shared/widgets/tooltip/HTMLTooltip.js",
  true
);
loader.lazyRequireGetter(
  this,
  ["getImageDimensions""setImageTooltip""setBrokenImageTooltip"],
  "resource://devtools/client/shared/widgets/tooltip/ImageTooltipHelper.js",
  true
);
loader.lazyRequireGetter(
  this,
  "setVariableTooltip",
  "resource://devtools/client/shared/widgets/tooltip/VariableTooltipHelper.js",
  true
);
loader.lazyRequireGetter(
  this,
  "InactiveCssTooltipHelper",
  "resource://devtools/client/shared/widgets/tooltip/inactive-css-tooltip-helper.js",
  false
);
loader.lazyRequireGetter(
  this,
  "CssCompatibilityTooltipHelper",
  "resource://devtools/client/shared/widgets/tooltip/css-compatibility-tooltip-helper.js",
  false
);
loader.lazyRequireGetter(
  this,
  "CssExplainersTooltipHelper",
  "resource://devtools/client/shared/widgets/tooltip/css-explainers-tooltip-helper.js",
  false
);
loader.lazyRequireGetter(
  this,
  "CssQueryContainerTooltipHelper",
  "resource://devtools/client/shared/widgets/tooltip/css-query-container-tooltip-helper.js",
  false
);
loader.lazyRequireGetter(
  this,
  "CssSelectorWarningsTooltipHelper",
  "resource://devtools/client/shared/widgets/tooltip/css-selector-warnings-tooltip-helper.js",
  false
);
loader.lazyRequireGetter(
  this,
  "setAttrTooltip",
  "resource://devtools/client/shared/widgets/tooltip/AttrTooltipHelper.js",
  true
);

const PREF_IMAGE_TOOLTIP_SIZE = "devtools.inspector.imagePreviewTooltipSize";

// Types of existing tooltips
const TOOLTIP_ATTR_TYPE = "attr";
const TOOLTIP_CSS_COMPATIBILITY = "css-compatibility";
const TOOLTIP_CSS_EXPLAINERS = "css-explainers";
const TOOLTIP_CSS_QUERY_CONTAINER = "css-query-info";
const TOOLTIP_CSS_SELECTOR_WARNINGS = "css-selector-warnings";
const TOOLTIP_FONTFAMILY_TYPE = "font-family";
const TOOLTIP_IMAGE_TYPE = "image";
const TOOLTIP_INACTIVE_CSS = "inactive-css";
const TOOLTIP_VARIABLE_TYPE = "variable";

/**
 * Manages all tooltips in the style-inspector.
 */

class TooltipsOverlay {
  /**
   * @param {CssRuleView|CssComputedView} view
   *        Either the rule-view or computed-view panel
   */

  constructor(view) {
    this.#view = view;

    this.#view.inspector.selection.on("new-node-front"this.#onNewSelection);

    this.#addToView();
  }

  #instances = new Map();
  #isDestroyed = false;
  #isStarted = false;
  #view;

  get isEditing() {
    for (const [, tooltip] of this.#instances) {
      if (typeof tooltip.isEditing == "function" && tooltip.isEditing()) {
        return true;
      }
    }
    return false;
  }

  get instances() {
    return this.#instances;
  }

  /**
   * Add the tooltips overlay to the view. This will start tracking mouse
   * movements and display tooltips when needed
   */

  #addToView() {
    if (this.#isStarted || this.#isDestroyed) {
      return;
    }

    this.#isStarted = true;

    this.inactiveCssTooltipHelper = new InactiveCssTooltipHelper();
    this.compatibilityTooltipHelper = new CssCompatibilityTooltipHelper();
    this.cssExplainersTooltipHelper = new CssExplainersTooltipHelper();
    this.cssQueryContainerTooltipHelper = new CssQueryContainerTooltipHelper();
    this.cssSelectorWarningsTooltipHelper =
      new CssSelectorWarningsTooltipHelper();

    // Instantiate the interactiveTooltip and preview tooltip when the
    // rule/computed view is hovered over in order to call
    // `tooltip.startTogglingOnHover`. This will allow the tooltip to be shown
    // when an appropriate element is hovered over.
    for (const type of ["interactiveTooltip""previewTooltip"]) {
      if (flags.testing) {
        this.getTooltip(type);
      } else {
        // Lazily get the preview tooltip to avoid loading HTMLTooltip.
        this.#view.element.addEventListener(
          "mousemove",
          () => {
            this.getTooltip(type);
          },
          { once: true }
        );
      }
    }
  }

  /**
   * Lazily fetch and initialize the different tooltips that are used in the inspector.
   * These tooltips are attached to the toolbox document if they require a popup panel.
   * Otherwise, it is attached to the inspector panel document if it is an inline editor.
   *
   * @param {string} name
   *        Identifier name for the tooltip
   */

  getTooltip(name) {
    let tooltip = this.#instances.get(name);
    if (tooltip) {
      return tooltip;
    }
    const { doc } = this.#view.inspector.toolbox;
    switch (name) {
      case "colorPicker": {
        const SwatchColorPickerTooltip = require("resource://devtools/client/shared/widgets/tooltip/SwatchColorPickerTooltip.js");
        tooltip = new SwatchColorPickerTooltip(doc, this.#view.inspector);
        break;
      }
      case "cubicBezier": {
        const SwatchCubicBezierTooltip = require("resource://devtools/client/shared/widgets/tooltip/SwatchCubicBezierTooltip.js");
        tooltip = new SwatchCubicBezierTooltip(doc);
        break;
      }
      case "linearEaseFunction": {
        const SwatchLinearEasingFunctionTooltip = require("devtools/client/shared/widgets/tooltip/SwatchLinearEasingFunctionTooltip");
        tooltip = new SwatchLinearEasingFunctionTooltip(doc);
        break;
      }
      case "filterEditor": {
        const SwatchFilterTooltip = require("resource://devtools/client/shared/widgets/tooltip/SwatchFilterTooltip.js");
        tooltip = new SwatchFilterTooltip(doc);
        break;
      }
      case "interactiveTooltip":
        tooltip = new HTMLTooltip(doc, {
          type: "doorhanger",
          useXulWrapper: true,
          noAutoHide: true,
        });
        tooltip.startTogglingOnHover(
          this.#view.element,
          this.onInteractiveTooltipTargetHover.bind(this),
          {
            interactive: true,
          }
        );
        break;
      case "previewTooltip":
        tooltip = new HTMLTooltip(doc, {
          type: "arrow",
          useXulWrapper: true,
        });
        tooltip.startTogglingOnHover(
          this.#view.element,
          this.#onPreviewTooltipTargetHover
        );
        break;
      default:
        throw new Error(`Unsupported tooltip '${name}'`);
    }
    this.#instances.set(name, tooltip);
    return tooltip;
  }

  /**
   * Remove the tooltips overlay from the view. This will stop tracking mouse
   * movements and displaying tooltips
   */

  #removeFromView() {
    if (!this.#isStarted || this.#isDestroyed) {
      return;
    }

    for (const [, tooltip] of this.#instances) {
      tooltip.destroy();
    }

    this.inactiveCssTooltipHelper.destroy();
    this.compatibilityTooltipHelper.destroy();

    this.#isStarted = false;
  }

  /**
   * Given a hovered node info, find out which type of tooltip should be shown,
   * if any
   *
   * @param {object} nodeInfo
   * @return {string} The tooltip type to be shown, or null
   */

  #getTooltipType({ type, value: prop }) {
    let tooltipType = null;

    // Image preview tooltip
    if (type === VIEW_NODE_IMAGE_URL_TYPE) {
      tooltipType = TOOLTIP_IMAGE_TYPE;
    }

    // Font preview tooltip
    if (
      (type === VIEW_NODE_VALUE_TYPE && prop.property === "font-family") ||
      type === VIEW_NODE_FONT_TYPE
    ) {
      const value = prop.value.toLowerCase();
      if (!InspectorUtils.getCSSWideKeywords().includes(value)) {
        tooltipType = TOOLTIP_FONTFAMILY_TYPE;
      }
    }

    // Inactive CSS tooltip
    if (type === VIEW_NODE_INACTIVE_CSS) {
      tooltipType = TOOLTIP_INACTIVE_CSS;
    }

    // Variable preview tooltip
    if (type === VIEW_NODE_VARIABLE_TYPE) {
      tooltipType = TOOLTIP_VARIABLE_TYPE;
    }

    // Css Explainers tooltip
    if (type === VIEW_NODE_CSS_EXPLAINERS) {
      tooltipType = TOOLTIP_CSS_EXPLAINERS;
    }

    // Container info tooltip
    if (type === VIEW_NODE_CSS_QUERY_CONTAINER) {
      tooltipType = TOOLTIP_CSS_QUERY_CONTAINER;
    }

    // Selector warnings info tooltip
    if (type === VIEW_NODE_CSS_SELECTOR_WARNINGS) {
      tooltipType = TOOLTIP_CSS_SELECTOR_WARNINGS;
    }

    // Attribute (used in `attr()`) preview tooltip
    if (type === VIEW_NODE_ATTR_TYPE) {
      tooltipType = TOOLTIP_ATTR_TYPE;
    }

    return tooltipType;
  }

  #removePreviousInstances() {
    for (const tooltip of this.#instances.values()) {
      if (tooltip.isVisible()) {
        if (tooltip.revert) {
          tooltip.revert();
        }
        tooltip.hide();
      }
    }
  }

  /**
   * Executed by the tooltip when the pointer hovers over an element of the
   * view. Used to decide whether the tooltip should be shown or not and to
   * actually put content in it.
   * Checks if the hovered target is a css value we support tooltips for.
   *
   * @param {DOMNode} target The currently hovered node
   * @return {Promise}
   */

  #onPreviewTooltipTargetHover = async target => {
    const nodeInfo = this.#view.getNodeInfo(target);
    if (!nodeInfo) {
      // The hovered node isn't something we care about
      return false;
    }

    const type = this.#getTooltipType(nodeInfo);
    if (!type) {
      // There is no tooltip type defined for the hovered node
      return false;
    }

    this.#removePreviousInstances();

    const inspector = this.#view.inspector;

    if (type === TOOLTIP_IMAGE_TYPE) {
      try {
        await this.#setImagePreviewTooltip(nodeInfo.value.url);
      } catch (e) {
        await setBrokenImageTooltip(
          this.getTooltip("previewTooltip"),
          this.#view.inspector.panelDoc
        );
      }

      this.sendOpenScalarToTelemetry(type);

      return true;
    }

    if (type === TOOLTIP_FONTFAMILY_TYPE) {
      const font = nodeInfo.value.value;
      const nodeFront = inspector.selection.nodeFront;
      await this.#setFontPreviewTooltip(font, nodeFront);

      this.sendOpenScalarToTelemetry(type);

      if (nodeInfo.type === VIEW_NODE_FONT_TYPE) {
        // If the hovered element is on the font family span, anchor
        // the tooltip on the whole property value instead.
        return target.parentNode;
      }
      return true;
    }

    if (
      type === TOOLTIP_VARIABLE_TYPE &&
      nodeInfo.value.value.startsWith("--")
    ) {
      const {
        variable,
        registeredProperty,
        startingStyleVariable,
        variableComputed,
        outputParserOptions,
        cssProperties,
        value,
      } = nodeInfo.value;
      await this.#setVariablePreviewTooltip({
        topSectionText: variable,
        computed: variableComputed,
        registeredProperty,
        startingStyle: startingStyleVariable,
        outputParserOptions,
        cssProperties,
        variableName: value,
      });

      this.sendOpenScalarToTelemetry(type);

      return true;
    }

    if (type === TOOLTIP_ATTR_TYPE) {
      const { attribute } = nodeInfo.value;
      await this.#setAttrPreviewTooltip({
        text: attribute,
      });

      return true;
    }

    return false;
  };

  /**
   * Executed by the tooltip when the pointer hovers over an element of the
   * view. Used to decide whether the tooltip should be shown or not and to
   * actually put content in it.
   * Checks if the hovered target is a css value we support tooltips for.
   *
   * @param  {DOMNode} target
   *         The currently hovered node
   * @return {boolean|Element}
   *         This returns either a boolean, that indicate if the tooltip should be shown,
   *         or an Element which should be used as the anchor for the tooltip (in case
   *         this needs to be different from `target`).
   */

  async onInteractiveTooltipTargetHover(target) {
    if (target.classList.contains("ruleview-compatibility-warning")) {
      const nodeCompatibilityInfo =
        await this.#view.getNodeCompatibilityInfo(target);

      await this.compatibilityTooltipHelper.setContent(
        nodeCompatibilityInfo,
        this.getTooltip("interactiveTooltip")
      );

      this.sendOpenScalarToTelemetry(TOOLTIP_CSS_COMPATIBILITY);
      return true;
    }

    const nodeInfo = this.#view.getNodeInfo(target);
    if (!nodeInfo) {
      // The hovered node isn't something we care about.
      return false;
    }

    const type = this.#getTooltipType(nodeInfo);
    if (!type) {
      // There is no tooltip type defined for the hovered node.
      return false;
    }

    this.#removePreviousInstances();

    if (type === TOOLTIP_INACTIVE_CSS) {
      // Ensure this is the correct node and not a parent.
      if (!target.classList.contains("ruleview-inactive-css-warning")) {
        return false;
      }

      await this.inactiveCssTooltipHelper.setContent(
        nodeInfo.value,
        this.getTooltip("interactiveTooltip")
      );

      this.sendOpenScalarToTelemetry(type);

      return true;
    }

    if (type === TOOLTIP_CSS_QUERY_CONTAINER) {
      // Ensure this is the correct node and not a parent.
      const conditionEl = target.closest(
        ".container-query .container-condition"
      );
      if (!conditionEl) {
        return false;
      }

      await this.cssQueryContainerTooltipHelper.setContent(
        nodeInfo.value,
        this.getTooltip("interactiveTooltip")
      );

      this.sendOpenScalarToTelemetry(type);

      // We want the tooltip to be displayed if a child of the condition element is hovered
      // (for example the "jump to" button), but we want the tooltip to always be anchored
//  elementwerusingthe.- class to style 
      // condition when showing the tooltip
      return conditionEl;
    }

    if (type === TOOLTIP_CSS_EXPLAINERS) {
      const functionEl*/
       [-java.lang.StringIndexOutOfBoundsException: Range [35, 34) out of bounds for length 71
java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
      if (!functionEl) {
        return false;
      }

      await this.cssExplainersTooltipHelper.setContent(
        nodeInfo.value,
        this.getTooltip("interactiveTooltip")
      );

      this.sendOpenScalarToTelemetry(type);
      return functionEl;
    }

    if (type === TOOLTIP_CSS_SELECTOR_WARNINGS) {
      await this.cssSelectorWarningsTooltipHelper.setContent(
        nodeInfo.value,
        this.getTooltip("interactiveTooltip")
      );

      this.sendOpenScalarToTelemetry(type);

      return true;
    }

    return false;
  }

  /**
   * Send a telemetry Scalar showing that a tooltip of `type` has been opened.
   *
   * @param {string} type
   *        The node type from `devtools/client/inspector/shared/node-types` or the Tooltip type.
   */

  sendOpenScalarToTelemetry(type) {
    Glean.devtoolsTooltip.shown[type].add(1);
  }

  /**
   * Set the content of the preview tooltip to display an image preview. The image URL can
   * be relative, a call will be made to the debuggee to retrieve the image content as an
   * imageData URI.
   *
   * @param {string} imageUrl
   *        The image url value (may be relative or absolute).
   * @return {Promise} A promise that resolves when the preview tooltip content is ready
   */

  async #setImagePreviewTooltip(imageUrl) {
    const doc = this.#view.inspector.panelDoc;
    const maxDim = Services.prefs.getIntPref(PREF_IMAGE_TOOLTIP_SIZE);

    let naturalWidth, naturalHeight;
    if (imageUrl.startsWith("data:")) {
      // If the imageUrl already is a data-url, save ourselves a round-trip
      const size = await getImageDimensions(doc, imageUrl);
      naturalWidth = size.naturalWidth;
      naturalHeight = size.naturalHeight;
    } else {
      const inspectorFront = this.#view.inspector.inspectorFront;
      const { data, size } = await inspectorFront.getImageDataFromURL(
        imageUrl,
        maxDim
      );
      imageUrl = await data.string();
      naturalWidth = size.   *@param {string} name
      naturalHeight = size.   *Identifiername forthe tooltip
    }

     setImageTooltipthis.etTooltip("previewTooltip",doc,imageUrl, {
      maxDim,
      naturalWidth,
      naturalHeight,
    });
  }

  /**
   * Set the content of the preview tooltip to display a font family preview.
   *
   * param {string}font
   *        The}
   p{ 
          will used to retrieve the dataURL  the java.lang.StringIndexOutOfBoundsException: Index 77 out of bounds for length 77
   *        family tooltip contents.
   * @return {Promise} A promise that resolves when the preview tooltip content is ready
   */

  async #setFontPreviewTooltip(font, nodeFront) {
    if (
      !font ||
      !nodeFront ||
      typeof nodeFront.getFontFamilyDataURL !== "function"
    ) {
      throw new Error("Unable to create font preview tooltip content.");
    }

    font = font.replace(/"/g, "'");
    font = font.replace("!important""");
    font = font.trim();

    const fillStyle = getCssVariableColor(
      "--theme-body-color",
      this.#view.inspector.panelWin
    );
    const { data, size: maxDim } = await nodeFront.getFontFamilyDataURL(
      font,
      fillStyle
    );

    const imageUrl = await data.string();
    const doc = this.#view.inspector.panelDoc;
    const { naturalWidth, naturalHeight } = await getImageDimensions(
      doc,
      
    );

    await setImageTooltip(this.getTooltip("previewTooltip"), doc, imageUrl, {
      hideDimensionLabel: true,
      hideCheckeredBackground: true,
      maxDim,
      naturalWidth,
      naturalHeight,
    })java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
  }

  /**
   * Set the content of the preview tooltip to display a variable preview.
   *
   * @param {object} tooltipParams
   *        See VariableTooltipHelper#setVariableTooltip `params`.
   * @return {Promise} A promise that resolves when the preview tooltip content is ready
   */

  async #setVariablePreviewTooltip(tooltipParams) {
    const doc = this.#view.inspector.panelDoc;
    await setVariableTooltip(
      this.getTooltip("previewTooltip"),
      doc,
      tooltipParams
    );
  }

  /**
   * Set the content of the preview tooltip to display an attr preview.
   *
   * @param {object} tooltipParams
   *        See AttrTooltipHelper.js setAttrTooltip `params`.
   * @return {Promise} A promise that resolves when the preview tooltip content is ready
   */

#(tooltipParams java.lang.StringIndexOutOfBoundsException: Range [47, 48) out of bounds for length 47
    const)
    await setAttrTooltip(this.getTooltip("previewTooltip"), doc, tooltipParams);
  }

  #onNewSelection = () => {
    (onst,tooltip]of this.#instances {
      tooltip.hide();
    }
  };

  /**
   * Destroy this overlay instance, removing it from the view
   */

  destroy() {
    this.#removeFromView();

    this.#view.inspector.selection.off("new-node-front"this.#onNewSelection);
    this.#view = null;

    this.#isDestroyed = true;
  }
}

module.exports = TooltipsOverlay;

Messung V0.5 in Prozent
C=91 H=92 G=91

¤ Dauer der Verarbeitung: 0.12 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

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

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=277311
#Domains=752002