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

Quelle  Frame.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,
} = 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 {
  getUnicodeUrl,
  getUnicodeUrlPath,
  getUnicodeHostname,
} = require("resource://devtools/client/shared/unicode-url.js");
const {
  getSourceNames,
  parseURL,
  getSourceMappedFile,
} = require("resource://devtools/client/shared/source-utils.js");
const { LocalizationHelper } = require("resource://devtools/shared/l10n.js");
const {
  MESSAGE_SOURCE,
} = require("resource://devtools/client/webconsole/constants.js");

const l10n = new LocalizationHelper(
  "devtools/client/locales/components.properties"
);
const webl10n = new LocalizationHelper(
  "devtools/client/locales/webconsole.properties"
);

function savedFrameToLocation(frame) {
  const { source: url, line, column, sourceId } = frame;
  return {
    url,
    line,
    column,
    // The sourceId will be a string if it's a source actor ID, otherwise
    // it is either a Spidermonkey-internal ID from a SavedFrame or missing,
    // and in either case we can't use the ID for anything useful.
    id: typeof sourceId === "string" ? sourceId : null,
  };
}

/**
 * Get the tooltip message.
 * @param {string|undefined} messageSource
 * @param {string} url
 * @returns {string}
 */

function getTooltipMessage(messageSource, url) {
  if (messageSource && messageSource === MESSAGE_SOURCE.CSS) {
    return l10n.getFormatStr("frame.viewsourceinstyleeditor", url);
  }
  return l10n.getFormatStr("frame.viewsourceindebugger", url);
}

class Frame extends Component {
  static get propTypes() {
    return {
      // Optional className that will be put into the element.
      className: PropTypes.string,
      // SavedFrame, or an object containing all the required properties.
      frame: PropTypes.shape({
        functionDisplayName: PropTypes.string,
        // This could be a SavedFrame with a numeric sourceId, or it could
        // be a SavedFrame-like client-side object, in which case the
        // "sourceId" will be a source actor ID.
        sourceId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
        source: PropTypes.string.isRequired,
        line: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
        column: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
      }).isRequired,
      // Clicking on the frame link -- probably should link to the debugger.
      onClick: PropTypes.func,
      // Option to display a function name before the source link.
      showFunctionName: PropTypes.bool,
      // Option to display a function name even if it's anonymous.
      showAnonymousFunctionName: PropTypes.bool,
      // Option to display a host name after the source link.
      showHost: PropTypes.bool,
      // Option to display a host name if the filename is empty or just '/'
      showEmptyPathAsHost: PropTypes.bool,
      // Option to display a full source instead of just the filename.
      showFullSourceUrl: PropTypes.bool,
      // Service to enable the source map feature for console.
      sourceMapURLService: PropTypes.object,
      // The source of the message
      messageSource: PropTypes.string,
    };
  }

  static get defaultProps() {
    return {
      showFunctionName: false,
      showAnonymousFunctionName: false,
      showHost: false,
      showEmptyPathAsHost: false,
      showFullSourceUrl: false,
    };
  }

  constructor(props) {
    super(props);
    this.state = {
      originalLocation: null,
    };
    this._locationChanged = this._locationChanged.bind(this);
  }

  componentDidMount() {
    if (this.props.sourceMapURLService) {
      const location = savedFrameToLocation(this.props.frame);
      // Many things that make use of this component either:
      // a) Pass in no sourceId because they have no way to know.
      // b) Pass in no sourceId because the actor wasn't created when the
      //    server sent its response.
      //
      // and due to that, we need to use subscribeByLocation in order to
      // handle both cases with an without an ID.
      this.unsubscribeSourceMapURLService =
        this.props.sourceMapURLService.subscribeByLocation(
          location,
          this._locationChanged
        );
    }
  }

  componentWillUnmount() {
    if (this.unsubscribeSourceMapURLService) {
      this.unsubscribeSourceMapURLService();
    }
  }

  _locationChanged(originalLocation) {
    this.setState({ originalLocation });
  }

  /**
   * Get current location's source, line, and column.
   * @returns {{source: string, line: number|null, column: number|null}}
   */

  #getCurrentLocationInfo = () => {
    const { frame } = this.props;
    const { originalLocation } = this.state;

    const generatedLocation = savedFrameToLocation(frame);
    const currentLocation = originalLocation || generatedLocation;

    const source = currentLocation.url || "";
    const line =
      currentLocation.line != void 0 ? Number(currentLocation.line) : null;
    const column =
      currentLocation.column != void 0 ? Number(currentLocation.column) : null;
    return {
      source,
      line,
      column,
    };
  };

  /**
   * Get unicode hostname of the source link.
   * @returns {string}
   */

  #getCurrentLocationUnicodeHostName = () => {
    const { source } = this.#getCurrentLocationInfo();

    const { host } = getSourceNames(source);
    return host ? getUnicodeHostname(host) : "";
  };

  /**
   * Check if the current location is linkable.
   * @returns {boolean}
   */

  #isCurrentLocationLinkable = () => {
    const { frame } = this.props;
    const { originalLocation } = this.state;

    const generatedLocation = savedFrameToLocation(frame);

    // Reparse the URL to determine if we should link this; `getSourceNames`
    // has already cached this indirectly. We don't want to attempt to
    // link to "self-hosted" and "(unknown)".
    // Source mapped sources might not necessary linkable, but they
    // are still valid in the debugger.
    // If we have a source ID then we can show the source in the debugger.
    return !!(
      originalLocation ||
      generatedLocation.id ||
      !!parseURL(generatedLocation.url)
    );
  };

  /**
   * Get the props of the top element.
   */

  #getTopElementProps = () => {
    const { className } = this.props;

    const { source, line, column } = this.#getCurrentLocationInfo();
    const { long } = getSourceNames(source);
    const props = {
      "data-url"long,
      className: "frame-link" + (className ? ` ${className}` : ""),
    };

    // If we have a line number > 0.
    if (line) {
      // Add `data-line` attribute for testing
      props["data-line"] = line;

      // Intentionally exclude 0
      if (column) {
        // Add `data-column` attribute for testing
        props["data-column"] = column;
      }
    }
    return props;
  };

  /**
   * Get the props of the source element.
   */

  #getSourceElementsProps = () => {
    const { frame, onClick, messageSource } = this.props;

    const generatedLocation = savedFrameToLocation(frame);
    const { source, line, column } = this.#getCurrentLocationInfo();
    const { long } = getSourceNames(source);
    let url = getUnicodeUrl(long);

    // Exclude all falsy values, including `0`, as line numbers start with 1.
    if (line) {
      url += `:${line}`;
      // Intentionally exclude 0
      if (column) {
        url += `:${column}`;
      }
    }

    const isLinkable = this.#isCurrentLocationLinkable();

    // Inner el is useful for achieving ellipsis on the left and correct LTR/RTL
    // ordering. See CSS styles for frame-link-source-[inner] and bug 1290056.
    const tooltipMessage = getTooltipMessage(messageSource, url);

    const sourceElConfig = {
      key: "source",
      className: "frame-link-source",
      title: isLinkable ? tooltipMessage : url,
    };

    if (isLinkable) {
      return {
        ...sourceElConfig,
        onClick: e => {
          // We always need to prevent the default behavior of <a> link
          e.preventDefault();
          if (onClick) {
            e.stopPropagation();

            onClick(generatedLocation);
          }
        },
        href: source,
        draggable: false,
      };
    }

    return sourceElConfig;
  };

  /**
   * Render the source elements.
   * @returns {React.ReactNode}
   */

  #renderSourceElements = () => {
    const { line, column } = this.#getCurrentLocationInfo();

    const sourceElements = [this.#renderDisplaySource()];

    if (line) {
      let lineInfo = `:${line}`;

      // Intentionally exclude 0
      if (column) {
        lineInfo += `:${column}`;
      }

      sourceElements.push(
        dom.span(
          {
            key: "line",
            className: "frame-link-line",
          },
          lineInfo
        )
      );
    }

    if (this.#isCurrentLocationLinkable()) {
      return dom.a(this.#getSourceElementsProps(), sourceElements);
    }
    // If source is not a URL (self-hosted, eval, etc.), don't make
    // it an anchor link, as we can't link to it.
    return dom.span(this.#getSourceElementsProps(), sourceElements);
  };

  /**
   * Render the display source.
   * @returns {React.ReactNode}
   */

  #renderDisplaySource = () => {
    const { showEmptyPathAsHost, showFullSourceUrl } = this.props;
    const { originalLocation } = this.state;

    const { source } = this.#getCurrentLocationInfo();
    const { shortlong, host } = getSourceNames(source);
    const unicodeShort = getUnicodeUrlPath(short);
    const unicodeLong = getUnicodeUrl(long);
    let displaySource = showFullSourceUrl ? unicodeLong : unicodeShort;
    if (originalLocation) {
      displaySource = getSourceMappedFile(displaySource);

      // In case of pretty-printed HTML file, we would only get the formatted suffix; replace
      // it with the full URL instead
      if (showEmptyPathAsHost && displaySource == ":formatted") {
        displaySource = host + displaySource;
      }
    } else if (
      showEmptyPathAsHost &&
      (displaySource === "" || displaySource === "/")
    ) {
      displaySource = host;
    }

    return dom.span(
      {
        key: "filename",
        className: "frame-link-filename",
      },
      displaySource
    );
  };

  /**
   * Render the function display name.
   * @returns {React.ReactNode}
   */

  #renderFunctionDisplayName = () => {
    const { frame, showFunctionName, showAnonymousFunctionName } = this.props;
    if (!showFunctionName) {
      return null;
    }
    const functionDisplayName = frame.functionDisplayName;
    if (functionDisplayName || showAnonymousFunctionName) {
      return [
        dom.span(
          {
            key: "function-display-name",
            className: "frame-link-function-display-name",
          },
          functionDisplayName || webl10n.getStr("stacktrace.anonymousFunction")
        ),
        " ",
      ];
    }
    return null;
  };

  render() {
    const { showHost } = this.props;

    const elements = [
      this.#renderFunctionDisplayName(),
      this.#renderSourceElements(),
    ];

    const unicodeHost = showHost
      ? this.#getCurrentLocationUnicodeHostName()
      : null;
    if (unicodeHost) {
      elements.push(" ");
      elements.push(
        dom.span(
          {
            key: "host",
            className: "frame-link-host",
          },
          unicodeHost
        )
      );
    }

    return dom.span(this.#getTopElementProps(), ...elements);
  }
}

module.exports = Frame;

100%


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