tor-browser

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

KeyframesProgressBar.js (3425B)


      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 "use strict";
      6 
      7 const {
      8  createRef,
      9  PureComponent,
     10 } = require("resource://devtools/client/shared/vendor/react.mjs");
     11 const dom = require("resource://devtools/client/shared/vendor/react-dom-factories.js");
     12 const PropTypes = require("resource://devtools/client/shared/vendor/react-prop-types.mjs");
     13 
     14 class KeyframesProgressBar extends PureComponent {
     15  static get propTypes() {
     16    return {
     17      addAnimationsCurrentTimeListener: PropTypes.func.isRequired,
     18      animation: PropTypes.object.isRequired,
     19      getAnimationsCurrentTime: PropTypes.func.isRequired,
     20      removeAnimationsCurrentTimeListener: PropTypes.func.isRequired,
     21      simulateAnimationForKeyframesProgressBar: PropTypes.func.isRequired,
     22      timeScale: PropTypes.object.isRequired,
     23    };
     24  }
     25 
     26  constructor(props) {
     27    super(props);
     28 
     29    this._progressBarRef = createRef();
     30 
     31    this.onCurrentTimeUpdated = this.onCurrentTimeUpdated.bind(this);
     32  }
     33 
     34  componentDidMount() {
     35    const { addAnimationsCurrentTimeListener } = this.props;
     36 
     37    this.setupAnimation(this.props);
     38    addAnimationsCurrentTimeListener(this.onCurrentTimeUpdated);
     39  }
     40 
     41  // FIXME: https://bugzilla.mozilla.org/show_bug.cgi?id=1774507
     42  UNSAFE_componentWillReceiveProps(nextProps) {
     43    const { animation, getAnimationsCurrentTime, timeScale } = nextProps;
     44 
     45    this.setupAnimation(nextProps);
     46    this.updateOffset(getAnimationsCurrentTime(), animation, timeScale);
     47  }
     48 
     49  componentWillUnmount() {
     50    const { removeAnimationsCurrentTimeListener } = this.props;
     51 
     52    removeAnimationsCurrentTimeListener(this.onCurrentTimeUpdated);
     53    this.simulatedAnimation = null;
     54  }
     55 
     56  onCurrentTimeUpdated(currentTime) {
     57    const { animation, timeScale } = this.props;
     58    this.updateOffset(currentTime, animation, timeScale);
     59  }
     60 
     61  updateOffset(currentTime, animation, timeScale) {
     62    const { createdTime, playbackRate } = animation.state;
     63 
     64    const time =
     65      (timeScale.minStartTime + currentTime - createdTime) * playbackRate;
     66 
     67    if (isNaN(time)) {
     68      // Setting an invalid currentTime will throw so bail out if time is not a number for
     69      // any reason.
     70      return;
     71    }
     72 
     73    this.simulatedAnimation.currentTime = time;
     74    const position =
     75      this.simulatedAnimation.effect.getComputedTiming().progress;
     76 
     77    // onCurrentTimeUpdated is bound to requestAnimationFrame.
     78    // As to update the component too frequently has performance issue if React controlled,
     79    // update raw component directly. See Bug 1699039.
     80    this._progressBarRef.current.style.marginInlineStart = `${position * 100}%`;
     81  }
     82 
     83  setupAnimation(props) {
     84    const { animation, simulateAnimationForKeyframesProgressBar } = props;
     85 
     86    if (this.simulatedAnimation) {
     87      this.simulatedAnimation.cancel();
     88    }
     89 
     90    const timing = Object.assign({}, animation.state, {
     91      iterations: animation.state.iterationCount || Infinity,
     92    });
     93 
     94    this.simulatedAnimation = simulateAnimationForKeyframesProgressBar(timing);
     95  }
     96 
     97  render() {
     98    return dom.div(
     99      { className: "keyframes-progress-bar-area" },
    100      dom.div({
    101        className: "indication-bar keyframes-progress-bar",
    102        ref: this._progressBarRef,
    103      })
    104    );
    105  }
    106 }
    107 
    108 module.exports = KeyframesProgressBar;