<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import React, { PureComponent, PropTypes } from 'react';
import TimeRuler from './TimeRuler';
import SelectionScrubberOverlay from './SelectionScrubberOverlay';
import clamp from 'clamp';
import { getContentRect } from '../css-geometry-tools';
import { withSize } from '../with-size';

class TimeSelectionScrubberImpl extends PureComponent {

  constructor(props) {
    super(props);
    this.state = {
      hoverLocation: null,
    };
    this._onMouseDown = this._onMouseDown.bind(this);
    this._onMouseMove = this._onMouseMove.bind(this);
    this.handlers = null;
    this._container = null;
    this._containerCreated = c => { this._container = c; };
  }

  _onMouseDown(e) {
    if (!this._container || e.button !== 0) {
      return;
    }

    const r = getContentRect(this._container);
    if (e.pageX < r.left || e.pageX >= r.right ||
        e.pageY < r.top || e.pageY >= r.bottom) {
      return;
    }

    // Don't steal focus. The -moz-user-focus: ignore declaration achieves
    // this more reliably in Gecko, so this preventDefault is mostly for other
    // browsers.
    e.preventDefault();

    const { rangeStart, rangeEnd, minSelectionStartWidth } = this.props;
    const mouseDownTime = (e.pageX - r.left) / r.width * (rangeEnd - rangeStart) + rangeStart;

    let isRangeSelecting = false;

    const mouseMoveHandler = e => {
      const mouseMoveTime = (e.pageX - r.left) / r.width * (rangeEnd - rangeStart) + rangeStart;
      const selectionStart = clamp(Math.min(mouseDownTime, mouseMoveTime), rangeStart, rangeEnd);
      const selectionEnd = clamp(Math.max(mouseDownTime, mouseMoveTime), rangeStart, rangeEnd);
      if (isRangeSelecting || selectionEnd - selectionStart >= minSelectionStartWidth) {
        isRangeSelecting = true;
        this.props.onSelectionChange({
          hasSelection: true,
          selectionStart, selectionEnd,
          isModifying: true,
        });
      }
    };

    const mouseUpHandler = e => {
      if (isRangeSelecting) {
        const mouseMoveTime = (e.pageX - r.left) / r.width * (rangeEnd - rangeStart) + rangeStart;
        const selectionStart = clamp(Math.min(mouseDownTime, mouseMoveTime), rangeStart, rangeEnd);
        const selectionEnd = clamp(Math.max(mouseDownTime, mouseMoveTime), rangeStart, rangeEnd);
        this.props.onSelectionChange({
          hasSelection: true,
          selectionStart, selectionEnd,
          isModifying: false,
        });
        e.stopPropagation();
        this._uninstallMoveAndUpHandlers();
        return;
      }

      const { selection } = this.props;
      if (!selection.hasSelection) {
        return;
      }

      const mouseUpTime = (e.pageX - r.left) / r.width * (rangeEnd - rangeStart) + rangeStart;
      const { selectionStart, selectionEnd } = selection;
      if (mouseUpTime < selectionStart ||
          mouseUpTime >= selectionEnd) {
        // Unset selection.
        this.props.onSelectionChange({
          hasSelection: false,
          isModifying: false,
        });
      }

      // Do not stopPropagation(), so that graph gets mouseup event.
      this._uninstallMoveAndUpHandlers();
    };

    this._installMoveAndUpHandlers(mouseMoveHandler, mouseUpHandler);
  }

  _installMoveAndUpHandlers(mouseMoveHandler, mouseUpHandler) {
    this._handlers = { mouseMoveHandler, mouseUpHandler };
    window.addEventListener('mousemove', mouseMoveHandler, true);
    window.addEventListener('mouseup', mouseUpHandler, true);
  }

  _uninstallMoveAndUpHandlers() {
    if (this._handlers) {
      const { mouseMoveHandler, mouseUpHandler } = this._handlers;
      window.removeEventListener('mousemove', mouseMoveHandler, true);
      window.removeEventListener('mouseup', mouseUpHandler, true);
    }
  }

  _onMouseMove(e) {
    if (!this._container) {
      return;
    }

    const r = getContentRect(this._container);
    if (e.pageX < r.left || e.pageX >= r.right ||<commit_msg>Uninstall selection drag event handlers properly. (#361)<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import React, { PureComponent, PropTypes } from 'react';
import TimeRuler from './TimeRuler';
import SelectionScrubberOverlay from './SelectionScrubberOverlay';
import clamp from 'clamp';
import { getContentRect } from '../css-geometry-tools';
import { withSize } from '../with-size';

class TimeSelectionScrubberImpl extends PureComponent {

  constructor(props) {
    super(props);
    this.state = {
      hoverLocation: null,
    };
    this._onMouseDown = this._onMouseDown.bind(this);
    this._onMouseMove = this._onMouseMove.bind(this);
    this.handlers = null;
    this._container = null;
    this._containerCreated = c => { this._container = c; };
  }

  _onMouseDown(e) {
    if (!this._container || e.button !== 0) {
      return;
    }

    const r = getContentRect(this._container);
    if (e.pageX < r.left || e.pageX >= r.right ||
        e.pageY < r.top || e.pageY >= r.bottom) {
      return;
    }

    // Don't steal focus. The -moz-user-focus: ignore declaration achieves
    // this more reliably in Gecko, so this preventDefault is mostly for other
    // browsers.
    e.preventDefault();

    const { rangeStart, rangeEnd, minSelectionStartWidth } = this.props;
    const mouseDownTime = (e.pageX - r.left) / r.width * (rangeEnd - rangeStart) + rangeStart;

    let isRangeSelecting = false;

    const mouseMoveHandler = e => {
      const mouseMoveTime = (e.pageX - r.left) / r.width * (rangeEnd - rangeStart) + rangeStart;
      const selectionStart = clamp(Math.min(mouseDownTime, mouseMoveTime), rangeStart, rangeEnd);
      const selectionEnd = clamp(Math.max(mouseDownTime, mouseMoveTime), rangeStart, rangeEnd);
      if (isRangeSelecting || selectionEnd - selectionStart >= minSelectionStartWidth) {
        isRangeSelecting = true;
        this.props.onSelectionChange({
          hasSelection: true,
          selectionStart, selectionEnd,
          isModifying: true,
        });
      }
    };

    const mouseUpHandler = e => {
      if (isRangeSelecting) {
        const mouseMoveTime = (e.pageX - r.left) / r.width * (rangeEnd - rangeStart) + rangeStart;
        const selectionStart = clamp(Math.min(mouseDownTime, mouseMoveTime), rangeStart, rangeEnd);
        const selectionEnd = clamp(Math.max(mouseDownTime, mouseMoveTime), rangeStart, rangeEnd);
        this.props.onSelectionChange({
          hasSelection: true,
          selectionStart, selectionEnd,
          isModifying: false,
        });
        e.stopPropagation();
        this._uninstallMoveAndUpHandlers();
        return;
      }

      const { selection } = this.props;
      if (selection.hasSelection) {
        const mouseUpTime = (e.pageX - r.left) / r.width * (rangeEnd - rangeStart) + rangeStart;
        const { selectionStart, selectionEnd } = selection;
        if (mouseUpTime < selectionStart ||
            mouseUpTime >= selectionEnd) {
          // Unset selection.
          this.props.onSelectionChange({
            hasSelection: false,
            isModifying: false,
          });
        }
      }

      // Do not stopPropagation(), so that graph gets mouseup event.
      this._uninstallMoveAndUpHandlers();
    };

    this._installMoveAndUpHandlers(mouseMoveHandler, mouseUpHandler);
  }

  _installMoveAndUpHandlers(mouseMoveHandler, mouseUpHandler) {
    this._handlers = { mouseMoveHandler, mouseUpHandler };
    window.addEventListener('mousemove', mouseMoveHandler, true);
    window.addEventListener('mouseup', mouseUpHandler, true);
  }

  _uninstallMoveAndUpHandlers() {
    if (this._handlers) {
      const { mouseMoveHandler, mouseUpHandler } = this._handlers;
      window.removeEventListener('mousemove', mouseMoveHandler, true);
      window.removeEventListener('mouseup', mouseUpHandler, true);
    }
  }

  _onMouseMove(e) {
    if (!this._container) {
      return;
    }

    const r = getContentRect(this._container);
    if (e.pageX < r.left || e.pageX >= r.right ||
{'fraction_non_alphanumeric': 0.11490125673249552, 'fraction_numerical': 0.0015559545182525433, 'mean_word_length': 2.8792943361188486, 'pattern_counts': {'":': 0, '<': 11, '<?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': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2360116', 'n_tokens_mistral': 2462, 'n_tokens_neox': 2403, 'n_words': 583}