tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Frame.js (6561B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
      4 
      5 import React, { Component, memo } from "devtools/client/shared/vendor/react";
      6 import PropTypes from "devtools/client/shared/vendor/react-prop-types";
      7 
      8 import DebuggerImage from "../../shared/DebuggerImage";
      9 import { formatDisplayName } from "../../../utils/pause/frames/index";
     10 import { getFileURL } from "../../../utils/source";
     11 import FrameIndent from "./FrameIndent";
     12 const classnames = require("resource://devtools/client/shared/classnames.js");
     13 
     14 function FrameTitle({ frame, options = {}, l10n }) {
     15  const displayName = formatDisplayName(frame, options, l10n);
     16  return React.createElement(
     17    "span",
     18    {
     19      className: "title",
     20    },
     21    displayName
     22  );
     23 }
     24 
     25 FrameTitle.propTypes = {
     26  frame: PropTypes.object.isRequired,
     27  options: PropTypes.object.isRequired,
     28  l10n: PropTypes.object.isRequired,
     29 };
     30 
     31 function getFrameLocation(frame, shouldDisplayOriginalLocation) {
     32  if (shouldDisplayOriginalLocation) {
     33    return frame.location;
     34  }
     35  return frame.generatedLocation || frame.location;
     36 }
     37 const FrameLocation = memo(
     38  ({ frame, displayFullUrl = false, shouldDisplayOriginalLocation }) => {
     39    if (frame.library) {
     40      return React.createElement(
     41        "span",
     42        {
     43          className: "location",
     44        },
     45        frame.library,
     46        React.createElement(DebuggerImage, {
     47          name: frame.library.toLowerCase(),
     48          className: "annotation-logo",
     49        })
     50      );
     51    }
     52    const location = getFrameLocation(frame, shouldDisplayOriginalLocation);
     53    const filename = displayFullUrl
     54      ? getFileURL(location.source, false)
     55      : location.source.shortName;
     56    return React.createElement(
     57      "span",
     58      {
     59        className: "location",
     60        title: location.source.url,
     61      },
     62      React.createElement(
     63        "span",
     64        {
     65          className: "filename",
     66        },
     67        filename
     68      ),
     69      ":",
     70      React.createElement(
     71        "span",
     72        {
     73          className: "line",
     74        },
     75        location.line
     76      )
     77    );
     78  }
     79 );
     80 FrameLocation.displayName = "FrameLocation";
     81 
     82 FrameLocation.propTypes = {
     83  frame: PropTypes.object.isRequired,
     84  displayFullUrl: PropTypes.bool.isRequired,
     85 };
     86 
     87 export default class FrameComponent extends Component {
     88  static defaultProps = {
     89    hideLocation: false,
     90    shouldMapDisplayName: true,
     91    disableContextMenu: false,
     92  };
     93 
     94  static get propTypes() {
     95    return {
     96      disableContextMenu: PropTypes.bool.isRequired,
     97      displayFullUrl: PropTypes.bool.isRequired,
     98      frame: PropTypes.object.isRequired,
     99      getFrameTitle: PropTypes.func,
    100      hideLocation: PropTypes.bool.isRequired,
    101      isInGroup: PropTypes.bool,
    102      panel: PropTypes.oneOf(["debugger", "webconsole"]).isRequired,
    103      selectFrame: PropTypes.func.isRequired,
    104      selectedFrame: PropTypes.object,
    105      isTracerFrameSelected: PropTypes.bool.isRequired,
    106      shouldMapDisplayName: PropTypes.bool.isRequired,
    107      shouldDisplayOriginalLocation: PropTypes.bool,
    108      showFrameContextMenu: PropTypes.func.isRequired,
    109    };
    110  }
    111 
    112  get isSelectable() {
    113    return this.props.panel == "webconsole";
    114  }
    115 
    116  get isDebugger() {
    117    return this.props.panel == "debugger";
    118  }
    119 
    120  render() {
    121    const {
    122      frame,
    123      selectedFrame,
    124      isTracerFrameSelected,
    125      hideLocation,
    126      shouldMapDisplayName,
    127      displayFullUrl,
    128      getFrameTitle,
    129      shouldDisplayOriginalLocation,
    130      isInGroup,
    131    } = this.props;
    132    const { l10n } = this.context;
    133 
    134    const isSelected =
    135      !isTracerFrameSelected && selectedFrame && selectedFrame.id === frame.id;
    136 
    137    const className = classnames("frame", {
    138      selected: isSelected,
    139      // When a JS Tracer frame is selected, the frame will still be considered as selected,
    140      // and switch from a blue to a grey background. It will still be considered as selected
    141      // from the point of view of stepping buttons.
    142      inactive:
    143        isTracerFrameSelected && selectedFrame && selectedFrame.id === frame.id,
    144      // Dead frames will likely not have inspectable scope
    145      dead: frame.state && frame.state !== "on-stack",
    146    });
    147 
    148    const location = getFrameLocation(frame, shouldDisplayOriginalLocation);
    149    const title = getFrameTitle
    150      ? getFrameTitle(`${getFileURL(location.source, false)}:${location.line}`)
    151      : undefined;
    152 
    153    return React.createElement(
    154      React.Fragment,
    155      null,
    156      frame.asyncCause &&
    157        React.createElement(
    158          "div",
    159          {
    160            className: "location-async-cause",
    161            tabIndex: -1,
    162            role: "presentation",
    163          },
    164          this.isSelectable && React.createElement(FrameIndent, null),
    165          this.isDebugger
    166            ? React.createElement(
    167                "span",
    168                {
    169                  className: "async-label",
    170                },
    171                frame.asyncCause
    172              )
    173            : l10n.getFormatStr("stacktrace.asyncStack", frame.asyncCause),
    174          this.isSelectable &&
    175            React.createElement("br", {
    176              className: "clipboard-only",
    177            })
    178        ),
    179      React.createElement(
    180        "div",
    181        {
    182          title,
    183          className,
    184          tabIndex: -1,
    185          role: "option",
    186          id: frame.id,
    187          "aria-selected": isSelected ? "true" : "false",
    188          // used by test helpers
    189          "data-url": location.source.url,
    190          "data-line": location.line,
    191          "data-column": location.column + 1,
    192        },
    193        this.isSelectable &&
    194          React.createElement(FrameIndent, {
    195            indentLevel: isInGroup ? 2 : 1,
    196          }),
    197        React.createElement(FrameTitle, {
    198          frame,
    199          options: {
    200            shouldMapDisplayName,
    201          },
    202          l10n,
    203        }),
    204        !hideLocation &&
    205          React.createElement(
    206            "span",
    207            {
    208              className: "clipboard-only",
    209            },
    210            " "
    211          ),
    212        !hideLocation &&
    213          React.createElement(FrameLocation, {
    214            frame,
    215            displayFullUrl,
    216            shouldDisplayOriginalLocation,
    217          }),
    218        this.isSelectable &&
    219          React.createElement("br", {
    220            className: "clipboard-only",
    221          })
    222      )
    223    );
    224  }
    225 }
    226 
    227 FrameComponent.displayName = "Frame";
    228 FrameComponent.contextTypes = { l10n: PropTypes.object };