tor-browser

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

HighlightLine.js (4653B)


      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 /**
      6 * Uses of this panel are:-
      7 * - Highlight line when source is opened using view source links from other panels
      8 * - Highlight line with function or class from an Outline search result selection
      9 * - Highlight line from a Quick open panel search result selection
     10 * - Highlight the last selected line when a source is selected
     11 * - Highlight the breakpoint line when the breakpoint is selected
     12 */
     13 
     14 import { Component } from "devtools/client/shared/vendor/react";
     15 import PropTypes from "devtools/client/shared/vendor/react-prop-types";
     16 import { toEditorLine } from "../../utils/editor/index";
     17 
     18 import { connect } from "devtools/client/shared/vendor/react-redux";
     19 import {
     20  getVisibleSelectedFrame,
     21  getSelectedLocation,
     22  getSelectedSourceTextContent,
     23  getPauseCommand,
     24  getCurrentThread,
     25  getShouldHighlightSelectedLocation,
     26 } from "../../selectors/index";
     27 
     28 function isDebugLine(selectedFrame, selectedLocation) {
     29  if (!selectedFrame) {
     30    return false;
     31  }
     32 
     33  return (
     34    selectedFrame.location.source.id == selectedLocation.source.id &&
     35    selectedFrame.location.line == selectedLocation.line
     36  );
     37 }
     38 
     39 export class HighlightLine extends Component {
     40  isStepping = false;
     41  previousEditorLine = null;
     42 
     43  static get propTypes() {
     44    return {
     45      pauseCommand: PropTypes.oneOf([
     46        "expression",
     47        "resume",
     48        "stepOver",
     49        "stepIn",
     50        "stepOut",
     51      ]),
     52      selectedFrame: PropTypes.object,
     53      selectedLocation: PropTypes.object.isRequired,
     54      selectedSourceTextContent: PropTypes.object.isRequired,
     55      shouldHighlightSelectedLocation: PropTypes.bool.isRequired,
     56      editor: PropTypes.object,
     57    };
     58  }
     59 
     60  shouldComponentUpdate(nextProps) {
     61    return this.shouldSetHighlightLine(nextProps);
     62  }
     63 
     64  componentDidUpdate(prevProps) {
     65    this.highlightLine(prevProps);
     66  }
     67 
     68  componentDidMount() {
     69    this.highlightLine(null);
     70  }
     71 
     72  shouldSetHighlightLine({ selectedLocation, selectedSourceTextContent }) {
     73    const editorLine = toEditorLine(
     74      selectedLocation.source,
     75      selectedLocation.line
     76    );
     77 
     78    if (!selectedLocation || !selectedSourceTextContent) {
     79      return false;
     80    }
     81 
     82    if (this.isStepping && editorLine === this.previousEditorLine) {
     83      return false;
     84    }
     85 
     86    return true;
     87  }
     88 
     89  highlightLine(prevProps) {
     90    const { pauseCommand, shouldHighlightSelectedLocation } = this.props;
     91    if (pauseCommand) {
     92      this.isStepping = true;
     93    }
     94 
     95    if (prevProps) {
     96      this.clearHighlightLine(prevProps);
     97    }
     98    if (shouldHighlightSelectedLocation) {
     99      this.setHighlightLine();
    100    }
    101  }
    102 
    103  setHighlightLine() {
    104    const { selectedLocation, selectedFrame, editor } = this.props;
    105    if (!this.shouldSetHighlightLine(this.props)) {
    106      return;
    107    }
    108 
    109    this.isStepping = false;
    110    const editorLine = toEditorLine(
    111      selectedLocation.source,
    112      selectedLocation.line
    113    );
    114    this.previousEditorLine = editorLine;
    115 
    116    if (
    117      !selectedLocation.line ||
    118      isDebugLine(selectedFrame, selectedLocation)
    119    ) {
    120      return;
    121    }
    122 
    123    editor.setLineContentMarker({
    124      id: editor.markerTypes.HIGHLIGHT_LINE_MARKER,
    125      lineClassName: "highlight-line",
    126      lines: [{ line: editorLine }],
    127    });
    128    this.clearHighlightLineAfterDuration();
    129  }
    130 
    131  clearHighlightLineAfterDuration() {
    132    const editorWrapper = document.querySelector(".editor-wrapper");
    133 
    134    if (editorWrapper === null) {
    135      return;
    136    }
    137 
    138    const duration = parseInt(
    139      getComputedStyle(editorWrapper).getPropertyValue(
    140        "--highlight-line-duration"
    141      ),
    142      10
    143    );
    144 
    145    setTimeout(() => this.clearHighlightLine(this.props), duration);
    146  }
    147 
    148  clearHighlightLine({ selectedLocation, selectedSourceTextContent }) {
    149    if (!selectedLocation || !selectedSourceTextContent) {
    150      return;
    151    }
    152 
    153    const { editor } = this.props;
    154    if (!editor) {
    155      return;
    156    }
    157    editor.removeLineContentMarker("highlight-line-marker");
    158  }
    159 
    160  render() {
    161    return null;
    162  }
    163 }
    164 
    165 export default connect(state => {
    166  const selectedLocation = getSelectedLocation(state);
    167  if (!selectedLocation) {
    168    return {};
    169  }
    170  return {
    171    pauseCommand: getPauseCommand(state, getCurrentThread(state)),
    172    shouldHighlightSelectedLocation: getShouldHighlightSelectedLocation(state),
    173    selectedFrame: getVisibleSelectedFrame(state),
    174    selectedLocation,
    175    selectedSourceTextContent: getSelectedSourceTextContent(state),
    176  };
    177 })(HighlightLine);