text: ﻿/*!
   * jQuery UI Touch Punch 0.2.3
   *
   * Copyright 2011–2014, Dave Furfero
   * Dual licensed under the MIT or GPL Version 2 licenses.
   *
   * Depends:
   *  jquery.ui.widget.js
   *  jquery.ui.mouse.js
   */
  (function ($) {
  
      // Detect touch support
      $.support.touch = 'ontouchend' in document;
  
      // Ignore browsers without touch support
      if (!$.support.touch) {
          return;
      }
  
      var mouseProto = $.ui.mouse.prototype,
          _mouseInit = mouseProto._mouseInit,
          _mouseDestroy = mouseProto._mouseDestroy,
          touchHandled;
  
      /**
       * Simulate a mouse event based on a corresponding touch event
       * @param {Object} event A touch event
       * @param {String} simulatedType The corresponding mouse event
       */
      function simulateMouseEvent(event, simulatedType) {
  
          // Ignore multi-touch events
          if (event.originalEvent.touches.length > 1) {
              return;
          }
  
          event.preventDefault();
  
          var touch = event.originalEvent.changedTouches[0],
              simulatedEvent = document.createEvent('MouseEvents');
  
          // Initialize the simulated mouse event using the touch event's coordinates
          simulatedEvent.initMouseEvent(
            simulatedType,    // type
            true,             // bubbles                    
            true,             // cancelable                 
            window,           // view                       
            1,                // detail                     
            touch.screenX,    // screenX                    
            touch.screenY,    // screenY                    
            touch.clientX,    // clientX                    
            touch.clientY,    // clientY                    
            false,            // ctrlKey                    
            false,            // altKey                     
            false,            // shiftKey                   
            false,            // metaKey                    
            0,                // button                     
            null              // relatedTarget              
          );
  
          // Dispatch the simulated event to the target element
          event.target.dispatchEvent(simulatedEvent);
      }
  
      /**
       * Handle the jQuery UI widget's touchstart events
       * @param {Object} event The widget element's touchstart event
       */
      mouseProto._touchStart = function (event) {
  
          var self = this;
  
          // Ignore the event if another widget is already being handled
          if (touchHandled || !self._mouseCapture(event.originalEvent.changedTouches[0])) {
              return;
          }
  
          // Set the flag to prevent other widgets from inheriting the touch event
          touchHandled = true;
  
          // Track movement to determine if interaction was a click
          self._touchMoved = false;
  
          // Simulate the mouseover event
          simulateMouseEvent(event, 'mouseover');
  
          // Simulate the mousemove event
          simulateMouseEvent(event, 'mousemove');
  
          // Simulate the mousedown event
          simulateMouseEvent(event, 'mousedown');
      };
  
      /**
       * Handle the jQuery UI widget's touchmove events
       * @param {Object} event The document's touchmove event
       */
      mouseProto._touchMove = function (event) {
  
          // Ignore event if not handled
          if (!touchHandled) {
              return;
          }
  
          // Interaction was not a click
          this._touchMoved = true;
  
          // Simulate the mousemove event
          simulateMouseEvent(event, 'mousemove');
      };
  
      /**
       * Handle the jQuery UI widget's touchend events
       * @param {Object} event The document's touchend event
       */
      mouseProto._touchEnd = function (event) {
  
          // Ignore event if not handled
          if (!touchHandled) {
              return;
          }
  
          // Simulate the mouseup event
          simulateMouseEvent(event, 'mouseup');
  
          // Simulate the mouseout event
          simulateMouseEvent(event, 'mouseout');
  
          // If the touch interaction did not move, it should trigger a click
          if (!this._touchMoved) {
  
              // Simulate the click event
              simulateMouseEvent(event, 'click');
          }
  
          // Unset the flag to allow other widgets to inherit the touch event
          touchHandled = false;
      };
  
      /**
       * A duck punch of the $.ui.mouse _mouseInit method to support touch events.
       * This method extends the widget with bound touch event handlers that
       * translate touch events to mouse events and pass them to the widget's
       * original mouse event handling methods.
       */
      mouseProto._mouseInit = function () {
  
          var self = this;
  
          // Delegate the touch handlers to the widget's element
          self.element.bind({
              touchstart: $.proxy(self, '_touchStart'),
              touchmove: $.proxy(self, '_touchMove'),
              touchend: $.proxy(self, '_touchEnd')
          });
  
          // Call the original $.ui.mouse init method
          _mouseInit.call(self);
      };
  
      /**
       * Remove the touch event handlers
       */
      mouseProto._mouseDestroy = function () {
  
          var self = this;
  
          // Delegate the touch handlers to the widget's element
          self.element.unbind({
              touchstart: $.proxy(self, '_touchStart'),
              touchmove: $.proxy(self, '_touchMove'),
              touchend: $.proxy(self, '_touchEnd')
          });
  
          // Call the original $.ui.mouse destroy method
          _mouseDestroy.call(self);
      };
  
  })(jQuery);