1+ /*!
2+ * jQuery UI Touch Punch 0.2.3
3+ *
4+ * Copyright 2011–2014, Dave Furfero
5+ * Dual licensed under the MIT or GPL Version 2 licenses.
6+ *
7+ * Depends:
8+ * jquery.ui.widget.js
9+ * jquery.ui.mouse.js
10+ */
11+ ( function ( $ ) {
12+
13+ // Detect touch support
14+ $ . support . touch = 'ontouchend' in document ;
15+
16+ // Ignore browsers without touch support
17+ if ( ! $ . support . touch ) {
18+ return ;
19+ }
20+
21+ var mouseProto = $ . ui . mouse . prototype ,
22+ _mouseInit = mouseProto . _mouseInit ,
23+ _mouseDestroy = mouseProto . _mouseDestroy ,
24+ touchHandled ;
25+
26+ /**
27+ * Simulate a mouse event based on a corresponding touch event
28+ * @param {Object } event A touch event
29+ * @param {String } simulatedType The corresponding mouse event
30+ */
31+ function simulateMouseEvent ( event , simulatedType ) {
32+
33+ // Ignore multi-touch events
34+ if ( event . originalEvent . touches . length > 1 ) {
35+ return ;
36+ }
37+
38+ event . preventDefault ( ) ;
39+
40+ var touch = event . originalEvent . changedTouches [ 0 ] ,
41+ simulatedEvent = document . createEvent ( 'MouseEvents' ) ;
42+
43+ // Initialize the simulated mouse event using the touch event's coordinates
44+ simulatedEvent . initMouseEvent (
45+ simulatedType , // type
46+ true , // bubbles
47+ true , // cancelable
48+ window , // view
49+ 1 , // detail
50+ touch . screenX , // screenX
51+ touch . screenY , // screenY
52+ touch . clientX , // clientX
53+ touch . clientY , // clientY
54+ false , // ctrlKey
55+ false , // altKey
56+ false , // shiftKey
57+ false , // metaKey
58+ 0 , // button
59+ null // relatedTarget
60+ ) ;
61+
62+ // Dispatch the simulated event to the target element
63+ event . target . dispatchEvent ( simulatedEvent ) ;
64+ }
65+
66+ /**
67+ * Handle the jQuery UI widget's touchstart events
68+ * @param {Object } event The widget element's touchstart event
69+ */
70+ mouseProto . _touchStart = function ( event ) {
71+
72+ var self = this ;
73+
74+ // Ignore the event if another widget is already being handled
75+ if ( touchHandled || ! self . _mouseCapture ( event . originalEvent . changedTouches [ 0 ] ) ) {
76+ return ;
77+ }
78+
79+ // Set the flag to prevent other widgets from inheriting the touch event
80+ touchHandled = true ;
81+
82+ // Track movement to determine if interaction was a click
83+ self . _touchMoved = false ;
84+
85+ // Simulate the mouseover event
86+ simulateMouseEvent ( event , 'mouseover' ) ;
87+
88+ // Simulate the mousemove event
89+ simulateMouseEvent ( event , 'mousemove' ) ;
90+
91+ // Simulate the mousedown event
92+ simulateMouseEvent ( event , 'mousedown' ) ;
93+ } ;
94+
95+ /**
96+ * Handle the jQuery UI widget's touchmove events
97+ * @param {Object } event The document's touchmove event
98+ */
99+ mouseProto . _touchMove = function ( event ) {
100+
101+ // Ignore event if not handled
102+ if ( ! touchHandled ) {
103+ return ;
104+ }
105+
106+ // Interaction was not a click
107+ this . _touchMoved = true ;
108+
109+ // Simulate the mousemove event
110+ simulateMouseEvent ( event , 'mousemove' ) ;
111+ } ;
112+
113+ /**
114+ * Handle the jQuery UI widget's touchend events
115+ * @param {Object } event The document's touchend event
116+ */
117+ mouseProto . _touchEnd = function ( event ) {
118+
119+ // Ignore event if not handled
120+ if ( ! touchHandled ) {
121+ return ;
122+ }
123+
124+ // Simulate the mouseup event
125+ simulateMouseEvent ( event , 'mouseup' ) ;
126+
127+ // Simulate the mouseout event
128+ simulateMouseEvent ( event , 'mouseout' ) ;
129+
130+ // If the touch interaction did not move, it should trigger a click
131+ if ( ! this . _touchMoved ) {
132+
133+ // Simulate the click event
134+ simulateMouseEvent ( event , 'click' ) ;
135+ }
136+
137+ // Unset the flag to allow other widgets to inherit the touch event
138+ touchHandled = false ;
139+ } ;
140+
141+ /**
142+ * A duck punch of the $.ui.mouse _mouseInit method to support touch events.
143+ * This method extends the widget with bound touch event handlers that
144+ * translate touch events to mouse events and pass them to the widget's
145+ * original mouse event handling methods.
146+ */
147+ mouseProto . _mouseInit = function ( ) {
148+
149+ var self = this ;
150+
151+ // Delegate the touch handlers to the widget's element
152+ self . element . bind ( {
153+ touchstart : $ . proxy ( self , '_touchStart' ) ,
154+ touchmove : $ . proxy ( self , '_touchMove' ) ,
155+ touchend : $ . proxy ( self , '_touchEnd' )
156+ } ) ;
157+
158+ // Call the original $.ui.mouse init method
159+ _mouseInit . call ( self ) ;
160+ } ;
161+
162+ /**
163+ * Remove the touch event handlers
164+ */
165+ mouseProto . _mouseDestroy = function ( ) {
166+
167+ var self = this ;
168+
169+ // Delegate the touch handlers to the widget's element
170+ self . element . unbind ( {
171+ touchstart : $ . proxy ( self , '_touchStart' ) ,
172+ touchmove : $ . proxy ( self , '_touchMove' ) ,
173+ touchend : $ . proxy ( self , '_touchEnd' )
174+ } ) ;
175+
176+ // Call the original $.ui.mouse destroy method
177+ _mouseDestroy . call ( self ) ;
178+ } ;
179+
180+ } ) ( jQuery ) ;
0 commit comments