All files / src SSVGTransition.js

93.1% Statements 27/29
70% Branches 14/20
87.5% Functions 7/8
92.85% Lines 26/28

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95                1x                     105x   105x 84x 11x 11x 11x           105x   105x   105x   105x       21x 21x 21x 21x             31x 31x 31x   31x 31x 5x   5x                     732x           732x             732x         766x            
// @ts-check
 
import { parseDuration } from './timing/Duration';
import { builtinTimingFunctions, parseTimingFunction } from './timing/TimingFunction';
 
import { defaultTo, isNil } from './utils';
 
/** @enum {number} */
export const TransitionType = {
  direct: 0,
  strict: 1
};
 
export default class SSVGTransition {
  /**
   * @param {Element|null} [parent]
   * @param {SSVGTransition|null} [defaults]
   */
  constructor(parent, defaults) {
    this.defaults = defaults || this;
 
    if (parent) {
      for (let i = 0; i < parent.children.length; ++i) {
        const transition = parent.children[i];
        Eif (transition.tagName === 'transition') {
          this.parseTransition(transition);
        }
      }
    }
 
    /** @type {number?=} */
    this._duration; /* eslint-disable-line no-unused-expressions *//* jshint ignore:line */
    /** @type {((t: number) => number)?=} */
    this._timingFunction; /* eslint-disable-line no-unused-expressions *//* jshint ignore:line */
    /** @type {number?=} */
    this._delay; /* eslint-disable-line no-unused-expressions *//* jshint ignore:line */
    /** @type {TransitionType} */
    this._type; /* eslint-disable-line no-unused-expressions *//* jshint ignore:line */
  }
 
  setDefaults() {
    this._duration = 0;
    this._timingFunction = builtinTimingFunctions.linear;
    this._delay = 0;
    this._type = TransitionType.strict;
  }
 
  /**
   * @param {Element} elt
   */
  parseTransition(elt) {
    this._duration = defaultTo(parseDuration(elt.getAttribute('duration')), this._duration);
    this._timingFunction = defaultTo(parseTimingFunction(elt.getAttribute('timing-function')), this._timingFunction);
    this._delay = defaultTo(parseDuration(elt.getAttribute('delay')), this._delay);
 
    const type = elt.getAttribute('type');
    if (type) {
      if (type in TransitionType) {
        // @ts-ignore
        this._type = TransitionType[type];
      }
      else E{
        throw new SyntaxError('invalid transition type: ' + type);
      }
    }
  }
 
  /** @return {number} */
  get duration() {
    // @ts-ignore
    return isNil(this._duration) ? this.defaults._duration : this._duration;
  }
 
  /** @return {(t: number) => number} */
  get timingFunction() {
    // @ts-ignore
    return isNil(this._timingFunction) ?
      this.defaults._timingFunction : this._timingFunction;
  }
 
  /** @return {number} */
  get delay() {
    // @ts-ignore
    return isNil(this._delay) ? this.defaults._delay : this._delay;
  }
 
  /** @return {TransitionType} */
  get type() {
    return isNil(this._type) ? this.defaults._type : this._type;
  }
 
  /** @return {boolean} */
  get isImmediate() { return (this.duration > 0) || (this.delay > 0); }
}