<commit_before>/**
 * TODO: improve docs
 * withAnimatronics: (createAnimationStages, options) => higher-order component
 * @module withAnimatronics
 */

import React from 'react'

import Animator from './internal/animator'
import ContextTypes from './internal/context-types'
import { ControlsMachine } from './internal/machines/controls-machine'
import { AnimationMachine } from './internal/machines/animation-machine'

import Polyfills from './internal/polyfills'

const withAnimatronics = (
  createAnimationStages,
  {
    requestAnimationFrame = Polyfills.DEFAULT_REQUEST_ANIMATION_FRAME,
    cancelAnimationFrame = Polyfills.DEFAULT_CANCEL_ANIMATION_FRAME,
  } = {}
) => {

  const controls = ControlsMachine();
  const animation = AnimationMachine(requestAnimationFrame, cancelAnimationFrame);

  return BaseComponent => {

    class AnimatorComponent extends React.Component {
      constructor(props) {
        super(props);
        this.isAnimatronic = true;
        this._playAnimation = this._playAnimation.bind(this);
        this._rewindAnimation = this._rewindAnimation.bind(this);
        this._cancelAnimation = this._cancelAnimation.bind(this);
      }

      getChildContext() {
        return {
          animatronics: {
            registerComponent: controls.registerComponent,
            unregisterComponent: controls.unregisterComponent,
          }
        };
      }

      _rewindAnimation() {
        const rawAnimationStages = createAnimationStages(controls.getNodes());
        const createStages = typeof rawAnimationStages === 'function' ? rawAnimationStages : () => rawAnimationStages;
        Animator.rewindAnimation(
          createStages(),
          controls,
          animation,
          () => {},
        )
      }

      _playAnimation() {
        // TODO: warn when an event might have been passed in
        const rawAnimationStages = createAnimationStages(controls.getNodes());
        const createStages = typeof rawAnimationStages === 'function' ? rawAnimationStages : () => rawAnimationStages;
        Animator.playAnimation(
          createStages(),
          controls,
          animation,
          () => {},
        );
      }

      _cancelAnimation() {
        animation.stop();
      }

      render() {
        const { ...props } = this.props;
        return (
          <BaseComponent
            playAnimation={ this._playAnimation }
            rewindAnimation={ this._rewindAnimation }
            cancelAnimation={ this._cancelAnimation }
            { ...props }
          />
        );
      }<commit_msg>:bug: [withAnimatronics] stop the animation when the component unmounts<commit_after>/**
 * TODO: improve docs
 * withAnimatronics: (createAnimationStages, options) => higher-order component
 * @module withAnimatronics
 */

import React from 'react'

import Animator from './internal/animator'
import ContextTypes from './internal/context-types'
import { ControlsMachine } from './internal/machines/controls-machine'
import { AnimationMachine } from './internal/machines/animation-machine'

import Polyfills from './internal/polyfills'

const withAnimatronics = (
  createAnimationStages,
  {
    requestAnimationFrame = Polyfills.DEFAULT_REQUEST_ANIMATION_FRAME,
    cancelAnimationFrame = Polyfills.DEFAULT_CANCEL_ANIMATION_FRAME,
  } = {}
) => {

  const controls = ControlsMachine();
  const animation = AnimationMachine(requestAnimationFrame, cancelAnimationFrame);

  return BaseComponent => {

    class AnimatorComponent extends React.Component {
      constructor(props) {
        super(props);
        this.isAnimatronic = true;
        this._playAnimation = this._playAnimation.bind(this);
        this._rewindAnimation = this._rewindAnimation.bind(this);
        this._cancelAnimation = this._cancelAnimation.bind(this);
      }

      getChildContext() {
        return {
          animatronics: {
            registerComponent: controls.registerComponent,
            unregisterComponent: controls.unregisterComponent,
          }
        };
      }

      _rewindAnimation() {
        const rawAnimationStages = createAnimationStages(controls.getNodes());
        const createStages = typeof rawAnimationStages === 'function' ? rawAnimationStages : () => rawAnimationStages;
        Animator.rewindAnimation(
          createStages(),
          controls,
          animation,
          () => {},
        )
      }

      _playAnimation() {
        // TODO: warn when an event might have been passed in
        const rawAnimationStages = createAnimationStages(controls.getNodes());
        const createStages = typeof rawAnimationStages === 'function' ? rawAnimationStages : () => rawAnimationStages;
        Animator.playAnimation(
          createStages(),
          controls,
          animation,
          () => {},
        );
      }

      _cancelAnimation() {
        animation.stop();
      }

      componentWillUnmount() {
        animation.stop();
      }

      render() {
        const { ...props } = this.props;
        return (
          <BaseComponent
            playAnimation={ this._playAnimation }
            rewindAnimation={ this._rewindAnimation }
            cancelAnimation={ this._cancelAnimation }
            { ...props }
          />
        );
      }
{'fraction_non_alphanumeric': 0.10098709187547457, 'fraction_numerical': 0.0, 'mean_word_length': 2.5481481481481483, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '480089', 'n_tokens_mistral': 1356, 'n_tokens_neox': 1321, 'n_words': 264}