<commit_before>import React from 'react';
import ReactDOM from 'react-dom';
import style from './style';

class Ripple extends React.Component {
  static propTypes = {
    centered: React.PropTypes.bool,
    className: React.PropTypes.string,
    loading: React.PropTypes.bool,
    spread: React.PropTypes.number
  };

  static defaultProps = {
    centered: false,
    className: '',
    loading: false,
    spread: 2
  };

  state = {
    active: false,
    left: null,
    restarting: false,
    top: null,
    width: null
  };

  handleEnd = () => {
    document.removeEventListener('mouseup', this.handleEnd);
    this.setState({active: false});
  };

  start = ({ pageX, pageY }) => {
    document.addEventListener('mouseup', this.handleEnd);
    const {top, left, width} = this._getDescriptor(pageX, pageY);
    this.setState({active: false, restarting: true, width: 0}, () => {
      this.refs.ripple.offsetWidth;  //eslint-disable-line no-unused-expressions
      this.setState({active: true, restarting: false, top, left, width});
    });
  };

  _getDescriptor (pageX, pageY) {
    const { left, top, height, width } = ReactDOM.findDOMNode(this).getBoundingClientRect();
    return {
      left: this.props.centered ? width / 2 : pageX - left + window.scrollX,<commit_msg>Add touch support for ripple<commit_after>import React from 'react';
import ReactDOM from 'react-dom';
import style from './style';

class Ripple extends React.Component {
  static propTypes = {
    centered: React.PropTypes.bool,
    className: React.PropTypes.string,
    loading: React.PropTypes.bool,
    spread: React.PropTypes.number
  };

  static defaultProps = {
    centered: false,
    className: '',
    loading: false,
    spread: 2
  };

  state = {
    active: false,
    left: null,
    restarting: false,
    top: null,
    width: null
  };

  handleEnd = (touch = false) => {
    document.removeEventListener(touch ? 'touchend' : 'mouseup', this.handleEnd);
    this.setState({active: false});
  };

  start = ({ pageX, pageY }, touch = false) => {
    document.addEventListener(touch ? 'touchend' : 'mouseup', this.handleEnd.bind(this, touch));
    const {top, left, width} = this._getDescriptor(pageX, pageY);
    this.setState({active: false, restarting: true, width: 0}, () => {
      this.refs.ripple.offsetWidth;  //eslint-disable-line no-unused-expressions
      this.setState({active: true, restarting: false, top, left, width});
    });
  };

  _getDescriptor (pageX, pageY) {
    const { left, top, height, width } = ReactDOM.findDOMNode(this).getBoundingClientRect();
    return {
      left: this.props.centered ? width / 2 : pageX - left + window.scrollX,
{'fraction_non_alphanumeric': 0.14200074934432372, 'fraction_numerical': 0.0022480329711502436, 'mean_word_length': 3.3344155844155843, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, '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': '2237814', 'n_tokens_mistral': 851, 'n_tokens_neox': 835, 'n_words': 202}