<commit_before>library swiper;

import 'dart:html';
import 'dart:async';
import 'package:logging/logging.dart';

final _log = new Logger('swiper');

/**
 * A touch (and mouse) slider for swiping through images and html.
 */
class Swiper {
  /// How many pixels until a swipe is detected.
  static const int DISTANCE_THRESHOLD = 20;
  
  /// The container for all swipe pages. 
  Element container;
  
  // --------------
  // Options
  // --------------
  
  /// Speed of prev and next transitions in milliseconds. Default is 300.
  int speed;
  
  /// Stop any touches on the container from scrolling the page. Default is false.
  bool disableScroll;
  
  /// Disable swiping with touch events.
  bool disableTouch;  

  /// Disable swiping with mouse events.
  bool disableMouse;
  
  
  // -------------------
  // Events
  // -------------------
  StreamController<int> _onPageChange;
  StreamController<int> _onTransitionEnd;
  
  /**
   * Fired when the current page changed.
   * 
   * The data is the page index. To get the page, use [currentPage].
   */
  Stream<int> get onPageChange {
    if (_onPageChange == null) {
      _onPageChange = new StreamController<int>.broadcast(
          onCancel: () => _onPageChange = null);
    }
    return _onPageChange.stream;
  }
  
  /**
   * Fired when the transition ends. When the user swipes again before the 
   * previous transition ended, this event is only fired once, at the end of all 
   * transitions.
   * 
   * The data is the page index. To get the page, use [currentPage].
   */
  Stream<int> get onTransitionEnd {
    if (_onTransitionEnd == null) {
      _onTransitionEnd = new StreamController<int>.broadcast(
          onCancel: () => _onTransitionEnd = null);
    }
    return _onTransitionEnd.stream;
  }
  
  
  // -------------------
  // Private Properties
  // -------------------
  
  /// Width of one slide.
  int _pageWidth;
  
  /// The current page index.
  int _currentIndex = 0;
  
  /// The x-position of the current page.
  int _currentPageX = 0;
  
  /// Coordinates where the mousedown or touchstart events occured.
  Point _startCoords;
  
  /// Delta movement of touchmove or mousemove. Positive x-value means right,
  /// positive y-value means down.
  Point _moveDelta = const Point(0, 0);
  
  /// Used for testing first move event.
  bool _isScrolling;
  
  // Track the listener subscriptions to later be able to unsubscribe.
  List<StreamSubscription> _pointerDownSubs = [];
  List<StreamSubscription> _pointerMoveAndUpSubs = [];
  
  /**
   * Creates a new [Swiper]. 
   * 
   * The [swiperElement] must contain a child element that is the **container**
   * of all swipe pages.
   */
  Swiper(Element swiperElement, {this.speed: 300, this.disableScroll: false,
        this.disableMouse: false, this.disableTouch: false, startIndex: 0}) {
    _log.finest('Initializing Swiper');
    
    // Get the pages container.
    container = swiperElement.children[0];
    
    // Set default transition style.
    container.style
        ..transitionProperty = 'transform'
        ..transitionTimingFunction = 'ease-out';
    
    // Horizontally stack pages.
    _stackPages();
    
    // Init size.
    _pageWidth = _calcPageWidth();
    
    // Go to initial page.
    moveToIndex(startIndex, speed: 0);
    
    // We're ready, set to visible.
    swiperElement.style.visibility = 'visible';

    // Install pointer down event listeners.
    _pointerDownSubs.add(container.onTouchStart.listen((e) => 
        _handlePointerDown(touchEvent: e)));
    _pointerDownSubs.add(container.onMouseDown.listen((e) => 
        _handlePointerDown(mouseEvent: e)));
    
    // Install transition end listener.
    container.onTransitionEnd.listen((_) {
      _log.finest('Transition end event: currentIndex=$currentIndex');
      if (_onTransitionEnd != null) {
        _onTransitionEnd.add(currentIndex);
      }
    });
    
    // Install window resize listener (but only after visibility has been set).
    new Future(() => 
        window.onResize.listen((e) {
          _pageWidth = _calcPageWidth();
          _setTranslateWithIndex(speed: 0);
        }
      )
    );
  }
  
  /**
   * Stacks the pages of [container] horizontally with the `left` css attribute.
   */
  void _stackPages() {
    // Position pages with left attribute of 100%, 200%, 300%, etc.
    for (int i = 0; i < container.children.length; i++) {
      container.children[i].style.left = '${i}00%';      
    }
  }

  /**
   * The current page index.
   */
  int get currentIndex => _currentIndex;
  
  /**
   * The current page.
   */
  Element get currentPage => container.children[currentIndex];
   
  /**
   * Moves to the page at [index]. 
   * 
   * The [speed] is the duration of the transition in milliseconds. 
   * If no [speed] is provided, the speed attribute of this [Swiper] is used.
   */
  void moveToIndex(int index, {int speed}) {
    if (speed == null) {
      speed = this.speed;
    }
     
    _log.finest('Moving to index: index=$index, speed=$speed');
    
    int oldIndex = currentIndex;
     
    if (index < 0) {
      _currentIndex = 0;
    } else if (index > container.children.length - 1) {
      _currentIndex = container.children.length - 1;
    } else {
      _currentIndex = index;
    }
    
    _setTranslateWithIndex(speed: speed);
     
    if (oldIndex != currentIndex) {
      _log.finest('Page change event: currentIndex=$currentIndex');<commit_msg>Option for noPageChangeEvent<commit_after>library swiper;

import 'dart:html';
import 'dart:async';
import 'package:logging/logging.dart';

final _log = new Logger('swiper');

/**
 * A touch (and mouse) slider for swiping through images and html.
 */
class Swiper {
  /// How many pixels until a swipe is detected.
  static const int DISTANCE_THRESHOLD = 20;
  
  /// The container for all swipe pages. 
  Element container;
  
  // --------------
  // Options
  // --------------
  
  /// Speed of prev and next transitions in milliseconds. Default is 300.
  int speed;
  
  /// Stop any touches on the container from scrolling the page. Default is false.
  bool disableScroll;
  
  /// Disable swiping with touch events.
  bool disableTouch;  

  /// Disable swiping with mouse events.
  bool disableMouse;
  
  
  // -------------------
  // Events
  // -------------------
  StreamController<int> _onPageChange;
  StreamController<int> _onTransitionEnd;
  
  /**
   * Fired when the current page changed.
   * 
   * The data is the page index. To get the page, use [currentPage].
   */
  Stream<int> get onPageChange {
    if (_onPageChange == null) {
      _onPageChange = new StreamController<int>.broadcast(
          onCancel: () => _onPageChange = null);
    }
    return _onPageChange.stream;
  }
  
  /**
   * Fired when the transition ends. When the user swipes again before the 
   * previous transition ended, this event is only fired once, at the end of all 
   * transitions.
   * 
   * The data is the page index. To get the page, use [currentPage].
   */
  Stream<int> get onTransitionEnd {
    if (_onTransitionEnd == null) {
      _onTransitionEnd = new StreamController<int>.broadcast(
          onCancel: () => _onTransitionEnd = null);
    }
    return _onTransitionEnd.stream;
  }
  
  
  // -------------------
  // Private Properties
  // -------------------
  
  /// Width of one slide.
  int _pageWidth;
  
  /// The current page index.
  int _currentIndex = 0;
  
  /// The x-position of the current page.
  int _currentPageX = 0;
  
  /// Coordinates where the mousedown or touchstart events occured.
  Point _startCoords;
  
  /// Delta movement of touchmove or mousemove. Positive x-value means right,
  /// positive y-value means down.
  Point _moveDelta = const Point(0, 0);
  
  /// Used for testing first move event.
  bool _isScrolling;
  
  // Track the listener subscriptions to later be able to unsubscribe.
  List<StreamSubscription> _pointerDownSubs = [];
  List<StreamSubscription> _pointerMoveAndUpSubs = [];
  
  /**
   * Creates a new [Swiper]. 
   * 
   * The [swiperElement] must contain a child element that is the **container**
   * of all swipe pages.
   */
  Swiper(Element swiperElement, {this.speed: 300, this.disableScroll: false,
        this.disableMouse: false, this.disableTouch: false, startIndex: 0}) {
    _log.finest('Initializing Swiper');
    
    // Get the pages container.
    container = swiperElement.children[0];
    
    // Set default transition style.
    container.style
        ..transitionProperty = 'transform'
        ..transitionTimingFunction = 'ease-out';
    
    // Horizontally stack pages.
    _stackPages();
    
    // Init size.
    _pageWidth = _calcPageWidth();
    
    // Go to initial page.
    moveToIndex(startIndex, speed: 0);
    
    // We're ready, set to visible.
    swiperElement.style.visibility = 'visible';

    // Install pointer down event listeners.
    _pointerDownSubs.add(container.onTouchStart.listen((e) => 
        _handlePointerDown(touchEvent: e)));
    _pointerDownSubs.add(container.onMouseDown.listen((e) => 
        _handlePointerDown(mouseEvent: e)));
    
    // Install transition end listener.
    container.onTransitionEnd.listen((_) {
      _log.finest('Transition end event: currentIndex=$currentIndex');
      if (_onTransitionEnd != null) {
        _onTransitionEnd.add(currentIndex);
      }
    });
    
    // Install window resize listener (but only after visibility has been set).
    new Future(() => 
        window.onResize.listen((e) {
          _pageWidth = _calcPageWidth();
          _setTranslateWithIndex(speed: 0);
        }
      )
    );
  }
  
  /**
   * Stacks the pages of [container] horizontally with the `left` css attribute.
   */
  void _stackPages() {
    // Position pages with left attribute of 100%, 200%, 300%, etc.
    for (int i = 0; i < container.children.length; i++) {
      container.children[i].style.left = '${i}00%';      
    }
  }

  /**
   * The current page index.
   */
  int get currentIndex => _currentIndex;
  
  /**
   * The current page.
   */
  Element get currentPage => container.children[currentIndex];
   
  /**
   * Moves to the page at [index]. 
   * 
   * The [speed] is the duration of the transition in milliseconds. 
   * If no [speed] is provided, the speed attribute of this [Swiper] is used.
   */
  void moveToIndex(int index, {int speed, bool noPageChangeEvent: false}) {
    if (speed == null) {
      speed = this.speed;
    }
     
    _log.finest('Moving to index: index=$index, speed=$speed');
    
    int oldIndex = currentIndex;
     
    if (index < 0) {
      _currentIndex = 0;
    } else if (index > container.children.length - 1) {
      _currentIndex = container.children.length - 1;
    } else {
      _currentIndex = index;
    }
    
    _setTranslateWithIndex(speed: speed);
     
    if (oldIndex != currentIndex && !noPageChangeEvent) {
      _log.finest('Page change event: currentIndex=$currentIndex');
{'fraction_non_alphanumeric': 0.12698268003646307, 'fraction_numerical': 0.005834092980856883, 'mean_word_length': 2.3694717444717446, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 35, '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': '297497', 'n_tokens_mistral': 3346, 'n_tokens_neox': 3229, 'n_words': 975}