tor-browser

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

GridElementWidthResizer.js (3951B)


      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 file,
      3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 "use strict";
      6 
      7 const {
      8  Component,
      9  createFactory,
     10 } = require("resource://devtools/client/shared/vendor/react.mjs");
     11 const PropTypes = require("resource://devtools/client/shared/vendor/react-prop-types.mjs");
     12 const Draggable = createFactory(
     13  require("resource://devtools/client/shared/components/splitter/Draggable.js")
     14 );
     15 
     16 class GridElementWidthResizer extends Component {
     17  static get propTypes() {
     18    return {
     19      getControlledElementNode: PropTypes.func.isRequired,
     20      enabled: PropTypes.bool,
     21      position: PropTypes.string.isRequired,
     22      className: PropTypes.string,
     23      onResizeEnd: PropTypes.func,
     24    };
     25  }
     26 
     27  constructor(props) {
     28    super(props);
     29 
     30    this.onStartMove = this.onStartMove.bind(this);
     31    this.onStopMove = this.onStopMove.bind(this);
     32    this.onMove = this.onMove.bind(this);
     33    this.state = {
     34      dragging: false,
     35      isRTLElement: false,
     36      defaultCursor: null,
     37      defaultWidth: null,
     38    };
     39  }
     40 
     41  componentDidUpdate(prevProps) {
     42    if (prevProps.enabled === true && this.props.enabled === false) {
     43      this.onStopMove();
     44      const controlledElementNode = this.props.getControlledElementNode();
     45      controlledElementNode.style.width = this.state.defaultWidth;
     46    }
     47  }
     48 
     49  // Dragging Events
     50 
     51  /**
     52   * Set 'resizing' cursor on entire document during splitter dragging.
     53   * This avoids cursor-flickering that happens when the mouse leaves
     54   * the splitter bar area (happens frequently).
     55   */
     56  onStartMove() {
     57    const controlledElementNode = this.props.getControlledElementNode();
     58    if (!controlledElementNode) {
     59      return;
     60    }
     61 
     62    const doc = controlledElementNode.ownerDocument;
     63    const defaultCursor = doc.documentElement.style.cursor;
     64    const defaultWidth = doc.documentElement.style.width;
     65    doc.documentElement.style.cursor = "ew-resize";
     66    doc.firstElementChild.classList.add("dragging");
     67 
     68    this.setState({
     69      dragging: true,
     70      isRTLElement:
     71        controlledElementNode.ownerDocument.defaultView.getComputedStyle(
     72          controlledElementNode
     73        ).direction === "rtl",
     74      defaultCursor,
     75      defaultWidth,
     76    });
     77  }
     78 
     79  onStopMove() {
     80    const controlledElementNode = this.props.getControlledElementNode();
     81    if (!this.state.dragging || !controlledElementNode) {
     82      return;
     83    }
     84    const doc = controlledElementNode.ownerDocument;
     85    doc.documentElement.style.cursor = this.state.defaultCursor;
     86    doc.firstElementChild.classList.remove("dragging");
     87 
     88    this.setState({
     89      dragging: false,
     90    });
     91 
     92    if (this.props.onResizeEnd) {
     93      const { width } = controlledElementNode.getBoundingClientRect();
     94      this.props.onResizeEnd(width);
     95    }
     96  }
     97 
     98  /**
     99   * Adjust size of the controlled panel.
    100   */
    101  onMove(x) {
    102    const controlledElementNode = this.props.getControlledElementNode();
    103    if (!this.state.dragging || !controlledElementNode) {
    104      return;
    105    }
    106    const nodeBounds = controlledElementNode.getBoundingClientRect();
    107    const { isRTLElement } = this.state;
    108    const { position } = this.props;
    109 
    110    const size =
    111      (isRTLElement && position === "end") ||
    112      (!isRTLElement && position === "start")
    113        ? nodeBounds.width + (nodeBounds.left - x)
    114        : x - nodeBounds.left;
    115 
    116    controlledElementNode.style.width = `${size}px`;
    117  }
    118 
    119  render() {
    120    if (!this.props.enabled) {
    121      return null;
    122    }
    123 
    124    const classNames = ["grid-element-width-resizer", this.props.position];
    125    if (this.props.className) {
    126      classNames.push(this.props.className);
    127    }
    128 
    129    return Draggable({
    130      className: classNames.join(" "),
    131      onStart: this.onStartMove,
    132      onStop: this.onStopMove,
    133      onMove: this.onMove,
    134    });
    135  }
    136 }
    137 
    138 module.exports = GridElementWidthResizer;