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

import { PropTypes, Component } from '../../libs';
import { addResizeListener, removeResizeListener } from '../../libs/utils/resize-event';

import { getScrollBarWidth } from './scrollbar-width';
import { Bar } from './Bar'

export class Scrollbar extends Component {
  constructor(props) {
    super(props);

    this.state = {
      sizeWidth: '0',
      sizeHeight: '0',
      moveX: 0,
      moveY: 0
    };

    this.update = this._update.bind(this)
  }

  get wrap(){
    return this.refs.wrap;
  }

  componentDidMount(){
    if (this.native) return;
    let rafId = requestAnimationFrame(this.update)
    this.cleanRAF = ()=>{
      cancelAnimationFrame(rafId)
    }
  }

  componentDidUpdate() {
    this.resizeDom = ReactDOM.findDOMNode(this.refs.resize)
    if (!this.props.noresize){
      addResizeListener(this.resizeDom, this.update)
      this.cleanResize = ()=>{
        removeResizeListener(this.resizeDom, this.update);
      }
    }
  }
  

  componentWillUnmount(){
    this.cleanRAF();
    this.cleanResize && this.cleanResize();
  }

  handleScroll() {
    const wrap = this.wrap;
    this.setState({
      moveY: ((wrap.scrollTop * 100) / wrap.clientHeight),
      moveX: ((wrap.scrollLeft * 100) / wrap.clientWidth)
    })
  }

  _update() {
    let heightPercentage, widthPercentage;
    const wrap = this.wrap;
    if (!wrap) return;
<commit_msg>#893, fix scrollbar don't clean event listener :bug:<commit_after>
import React from 'react';
import ReactDOM from 'react-dom'

import { PropTypes, Component } from '../../libs';
import { addResizeListener, removeResizeListener } from '../../libs/utils/resize-event';

import { getScrollBarWidth } from './scrollbar-width';
import { Bar } from './Bar'

export class Scrollbar extends Component {
  constructor(props) {
    super(props);

    this.state = {
      sizeWidth: '0',
      sizeHeight: '0',
      moveX: 0,
      moveY: 0
    };

    this.update = this._update.bind(this)
  }

  get wrap(){
    return this.refs.wrap;
  }

  componentDidMount(){
    if (this.native) return;
    let rafId = requestAnimationFrame(this.update)
    this.cleanRAF = ()=>{
      cancelAnimationFrame(rafId)
    }
  }

  componentDidUpdate() {
    this.resizeDom = ReactDOM.findDOMNode(this.refs.resize)
    if (!this.props.noresize){
      this.cleanResize && this.cleanResize();
      addResizeListener(this.resizeDom, this.update)
      this.cleanResize = ()=>{
        removeResizeListener(this.resizeDom, this.update);
      }
    }
  }
  

  componentWillUnmount(){
    this.cleanRAF();
    this.cleanResize && this.cleanResize();
  }

  handleScroll() {
    const wrap = this.wrap;
    this.setState({
      moveY: ((wrap.scrollTop * 100) / wrap.clientHeight),
      moveX: ((wrap.scrollLeft * 100) / wrap.clientWidth)
    })
  }

  _update() {
    let heightPercentage, widthPercentage;
    const wrap = this.wrap;
    if (!wrap) return;

{'fraction_non_alphanumeric': 0.1407035175879397, 'fraction_numerical': 0.007705192629815745, 'mean_word_length': 2.872892347600519, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, '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': '5296073', 'n_tokens_mistral': 979, 'n_tokens_neox': 955, 'n_words': 199}