Tizen 2.1 base
[platform/framework/web/web-ui-fw.git] / libs / js / jquery-mobile-1.0.1pre / js / jquery.mobile.event.js
1 /* 
2 * "events" plugin - Handles events
3 */
4
5 (function( $, window, undefined ) {
6
7 // add new event shortcuts
8 $.each( ( "touchstart touchmove touchend orientationchange throttledresize " +
9                                         "tap taphold swipe swipeleft swiperight scrollstart scrollstop" ).split( " " ), function( i, name ) {
10
11         $.fn[ name ] = function( fn ) {
12                 return fn ? this.bind( name, fn ) : this.trigger( name );
13         };
14
15         $.attrFn[ name ] = true;
16 });
17
18 var supportTouch = $.support.touch,
19         scrollEvent = "touchmove scroll",
20         touchStartEvent = supportTouch ? "touchstart" : "mousedown",
21         touchStopEvent = supportTouch ? "touchend" : "mouseup",
22         touchMoveEvent = supportTouch ? "touchmove" : "mousemove";
23
24 function triggerCustomEvent( obj, eventType, event ) {
25         var originalType = event.type;
26         event.type = eventType;
27         $.event.handle.call( obj, event );
28         event.type = originalType;
29 }
30
31 // also handles scrollstop
32 $.event.special.scrollstart = {
33
34         enabled: true,
35
36         setup: function() {
37
38                 var thisObject = this,
39                         $this = $( thisObject ),
40                         scrolling,
41                         timer;
42
43                 function trigger( event, state ) {
44                         scrolling = state;
45                         triggerCustomEvent( thisObject, scrolling ? "scrollstart" : "scrollstop", event );
46                 }
47
48                 // iPhone triggers scroll after a small delay; use touchmove instead
49                 $this.bind( scrollEvent, function( event ) {
50
51                         if ( !$.event.special.scrollstart.enabled ) {
52                                 return;
53                         }
54
55                         if ( !scrolling ) {
56                                 trigger( event, true );
57                         }
58
59                         clearTimeout( timer );
60                         timer = setTimeout(function() {
61                                 trigger( event, false );
62                         }, 50 );
63                 });
64         }
65 };
66
67 // also handles taphold
68 $.event.special.tap = {
69         setup: function() {
70                 var thisObject = this,
71                         $this = $( thisObject );
72
73                 $this.bind( "vmousedown", function( event ) {
74
75                         if ( event.which && event.which !== 1 ) {
76                                 return false;
77                         }
78
79                         var origTarget = event.target,
80                                 origEvent = event.originalEvent,
81                                 timer;
82
83                         function clearTapTimer() {
84                                 clearTimeout( timer );
85                         }
86
87                         function clearTapHandlers() {
88                                 clearTapTimer();
89
90                                 $this.unbind( "vclick", clickHandler )
91                                         .unbind( "vmouseup", clearTapTimer )
92                                         .unbind( "vmousecancel", clearTapHandlers );
93                         }
94
95                         function clickHandler(event) {
96                                 clearTapHandlers();
97
98                                 // ONLY trigger a 'tap' event if the start target is
99                                 // the same as the stop target.
100                                 if ( origTarget == event.target ) {
101                                         triggerCustomEvent( thisObject, "tap", event );
102                                 }
103                         }
104
105                         $this.bind( "vmousecancel", clearTapHandlers )
106                                 .bind( "vmouseup", clearTapTimer )
107                                 .bind( "vclick", clickHandler );
108
109                         timer = setTimeout(function() {
110                                         triggerCustomEvent( thisObject, "taphold", $.Event( "taphold" ) );
111                         }, 750 );
112                 });
113         }
114 };
115
116 // also handles swipeleft, swiperight
117 $.event.special.swipe = {
118         scrollSupressionThreshold: 10, // More than this horizontal displacement, and we will suppress scrolling.
119
120         durationThreshold: 1000, // More time than this, and it isn't a swipe.
121
122         horizontalDistanceThreshold: 30,  // Swipe horizontal displacement must be more than this.
123
124         verticalDistanceThreshold: 75,  // Swipe vertical displacement must be less than this.
125
126         setup: function() {
127                 var thisObject = this,
128                         $this = $( thisObject );
129
130                 $this.bind( touchStartEvent, function( event ) {
131                         var data = event.originalEvent.touches ?
132                                                                 event.originalEvent.touches[ 0 ] : event,
133                                 start = {
134                                         time: ( new Date() ).getTime(),
135                                         coords: [ data.pageX, data.pageY ],
136                                         origin: $( event.target )
137                                 },
138                                 stop;
139
140                         function moveHandler( event ) {
141
142                                 if ( !start ) {
143                                         return;
144                                 }
145
146                                 var data = event.originalEvent.touches ?
147                                                 event.originalEvent.touches[ 0 ] : event;
148
149                                 stop = {
150                                         time: ( new Date() ).getTime(),
151                                         coords: [ data.pageX, data.pageY ]
152                                 };
153
154                                 // prevent scrolling
155                                 if ( Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.scrollSupressionThreshold ) {
156                                         event.preventDefault();
157                                 }
158                         }
159
160                         $this.bind( touchMoveEvent, moveHandler )
161                                 .one( touchStopEvent, function( event ) {
162                                         $this.unbind( touchMoveEvent, moveHandler );
163
164                                         if ( start && stop ) {
165                                                 if ( stop.time - start.time < $.event.special.swipe.durationThreshold &&
166                                                                 Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.horizontalDistanceThreshold &&
167                                                                 Math.abs( start.coords[ 1 ] - stop.coords[ 1 ] ) < $.event.special.swipe.verticalDistanceThreshold ) {
168
169                                                         start.origin.trigger( "swipe" )
170                                                                 .trigger( start.coords[0] > stop.coords[ 0 ] ? "swipeleft" : "swiperight" );
171                                                 }
172                                         }
173                                         start = stop = undefined;
174                                 });
175                 });
176         }
177 };
178
179 (function( $, window ) {
180         // "Cowboy" Ben Alman
181
182         var win = $( window ),
183                 special_event,
184                 get_orientation,
185                 last_orientation;
186
187         $.event.special.orientationchange = special_event = {
188                 setup: function() {
189                         // If the event is supported natively, return false so that jQuery
190                         // will bind to the event using DOM methods.
191                         if ( $.support.orientation && $.mobile.orientationChangeEnabled ) {
192                                 return false;
193                         }
194
195                         // Get the current orientation to avoid initial double-triggering.
196                         last_orientation = get_orientation();
197
198                         // Because the orientationchange event doesn't exist, simulate the
199                         // event by testing window dimensions on resize.
200                         win.bind( "throttledresize", handler );
201                 },
202                 teardown: function(){
203                         // If the event is not supported natively, return false so that
204                         // jQuery will unbind the event using DOM methods.
205                         if ( $.support.orientation && $.mobile.orientationChangeEnabled ) {
206                                 return false;
207                         }
208
209                         // Because the orientationchange event doesn't exist, unbind the
210                         // resize event handler.
211                         win.unbind( "throttledresize", handler );
212                 },
213                 add: function( handleObj ) {
214                         // Save a reference to the bound event handler.
215                         var old_handler = handleObj.handler;
216
217
218                         handleObj.handler = function( event ) {
219                                 // Modify event object, adding the .orientation property.
220                                 event.orientation = get_orientation();
221
222                                 // Call the originally-bound event handler and return its result.
223                                 return old_handler.apply( this, arguments );
224                         };
225                 }
226         };
227
228         // If the event is not supported natively, this handler will be bound to
229         // the window resize event to simulate the orientationchange event.
230         function handler() {
231                 // Get the current orientation.
232                 var orientation = get_orientation();
233
234                 if ( orientation !== last_orientation ) {
235                         // The orientation has changed, so trigger the orientationchange event.
236                         last_orientation = orientation;
237                         win.trigger( "orientationchange" );
238                 }
239         }
240
241         // Get the current page orientation. This method is exposed publicly, should it
242         // be needed, as jQuery.event.special.orientationchange.orientation()
243         $.event.special.orientationchange.orientation = get_orientation = function() {
244                 var isPortrait = true, elem = document.documentElement;
245
246                 // prefer window orientation to the calculation based on screensize as
247                 // the actual screen resize takes place before or after the orientation change event
248                 // has been fired depending on implementation (eg android 2.3 is before, iphone after).
249                 // More testing is required to determine if a more reliable method of determining the new screensize
250                 // is possible when orientationchange is fired. (eg, use media queries + element + opacity)
251                 if ( $.support.orientation ) {
252                         // if the window orientation registers as 0 or 180 degrees report
253                         // portrait, otherwise landscape
254                         isPortrait = window.orientation % 180 == 0;
255                 } else {
256                         isPortrait = elem && elem.clientWidth / elem.clientHeight < 1.1;
257                 }
258
259                 return isPortrait ? "portrait" : "landscape";
260         };
261
262 })( jQuery, window );
263
264
265 // throttled resize event
266 (function() {
267
268         $.event.special.throttledresize = {
269                 setup: function() {
270                         $( this ).bind( "resize", handler );
271                 },
272                 teardown: function(){
273                         $( this ).unbind( "resize", handler );
274                 }
275         };
276
277         var throttle = 250,
278                 handler = function() {
279                         curr = ( new Date() ).getTime();
280                         diff = curr - lastCall;
281
282                         if ( diff >= throttle ) {
283
284                                 lastCall = curr;
285                                 $( this ).trigger( "throttledresize" );
286
287                         } else {
288
289                                 if ( heldCall ) {
290                                         clearTimeout( heldCall );
291                                 }
292
293                                 // Promise a held call will still execute
294                                 heldCall = setTimeout( handler, throttle - diff );
295                         }
296                 },
297                 lastCall = 0,
298                 heldCall,
299                 curr,
300                 diff;
301 })();
302
303
304 $.each({
305         scrollstop: "scrollstart",
306         taphold: "tap",
307         swipeleft: "swipe",
308         swiperight: "swipe"
309 }, function( event, sourceEvent ) {
310
311         $.event.special[ event ] = {
312                 setup: function() {
313                         $( this ).bind( sourceEvent, $.noop );
314                 }
315         };
316 });
317
318 })( jQuery, this );