source: pro-violet-viettel/docs/template/assets/js/uncompressed/jquery.mobile.custom.js

Last change on this file was 400, checked in by dungnv, 11 years ago
  • Property svn:mime-type set to text/plain
File size: 29.3 KB
Line 
1/*
2* jQuery Mobile v1.3.2
3* http://jquerymobile.com
4*
5* Copyright 2010, 2013 jQuery Foundation, Inc. and other contributors
6* Released under the MIT license.
7* http://jquery.org/license
8*
9*/
10
11(function ( root, doc, factory ) {
12        if ( typeof define === "function" && define.amd ) {
13                // AMD. Register as an anonymous module.
14                define( [ "jquery" ], function ( $ ) {
15                        factory( $, root, doc );
16                        return $.mobile;
17                });
18        } else {
19                // Browser globals
20                factory( root.jQuery, root, doc );
21        }
22}( this, document, function ( jQuery, window, document, undefined ) {
23// This plugin is an experiment for abstracting away the touch and mouse
24// events so that developers don't have to worry about which method of input
25// the device their document is loaded on supports.
26//
27// The idea here is to allow the developer to register listeners for the
28// basic mouse events, such as mousedown, mousemove, mouseup, and click,
29// and the plugin will take care of registering the correct listeners
30// behind the scenes to invoke the listener at the fastest possible time
31// for that device, while still retaining the order of event firing in
32// the traditional mouse environment, should multiple handlers be registered
33// on the same element for different events.
34//
35// The current version exposes the following virtual events to jQuery bind methods:
36// "vmouseover vmousedown vmousemove vmouseup vclick vmouseout vmousecancel"
37
38(function( $, window, document, undefined ) {
39
40var dataPropertyName = "virtualMouseBindings",
41        touchTargetPropertyName = "virtualTouchID",
42        virtualEventNames = "vmouseover vmousedown vmousemove vmouseup vclick vmouseout vmousecancel".split( " " ),
43        touchEventProps = "clientX clientY pageX pageY screenX screenY".split( " " ),
44        mouseHookProps = $.event.mouseHooks ? $.event.mouseHooks.props : [],
45        mouseEventProps = $.event.props.concat( mouseHookProps ),
46        activeDocHandlers = {},
47        resetTimerID = 0,
48        startX = 0,
49        startY = 0,
50        didScroll = false,
51        clickBlockList = [],
52        blockMouseTriggers = false,
53        blockTouchTriggers = false,
54        eventCaptureSupported = "addEventListener" in document,
55        $document = $( document ),
56        nextTouchID = 1,
57        lastTouchID = 0, threshold;
58
59$.vmouse = {
60        moveDistanceThreshold: 10,
61        clickDistanceThreshold: 10,
62        resetTimerDuration: 1500
63};
64
65function getNativeEvent( event ) {
66
67        while ( event && typeof event.originalEvent !== "undefined" ) {
68                event = event.originalEvent;
69        }
70        return event;
71}
72
73function createVirtualEvent( event, eventType ) {
74
75        var t = event.type,
76                oe, props, ne, prop, ct, touch, i, j, len;
77
78        event = $.Event( event );
79        event.type = eventType;
80
81        oe = event.originalEvent;
82        props = $.event.props;
83
84        // addresses separation of $.event.props in to $.event.mouseHook.props and Issue 3280
85        // https://github.com/jquery/jquery-mobile/issues/3280
86        if ( t.search( /^(mouse|click)/ ) > -1 ) {
87                props = mouseEventProps;
88        }
89
90        // copy original event properties over to the new event
91        // this would happen if we could call $.event.fix instead of $.Event
92        // but we don't have a way to force an event to be fixed multiple times
93        if ( oe ) {
94                for ( i = props.length, prop; i; ) {
95                        prop = props[ --i ];
96                        event[ prop ] = oe[ prop ];
97                }
98        }
99
100        // make sure that if the mouse and click virtual events are generated
101        // without a .which one is defined
102        if ( t.search(/mouse(down|up)|click/) > -1 && !event.which ) {
103                event.which = 1;
104        }
105
106        if ( t.search(/^touch/) !== -1 ) {
107                ne = getNativeEvent( oe );
108                t = ne.touches;
109                ct = ne.changedTouches;
110                touch = ( t && t.length ) ? t[0] : ( ( ct && ct.length ) ? ct[ 0 ] : undefined );
111
112                if ( touch ) {
113                        for ( j = 0, len = touchEventProps.length; j < len; j++) {
114                                prop = touchEventProps[ j ];
115                                event[ prop ] = touch[ prop ];
116                        }
117                }
118        }
119
120        return event;
121}
122
123function getVirtualBindingFlags( element ) {
124
125        var flags = {},
126                b, k;
127
128        while ( element ) {
129
130                b = $.data( element, dataPropertyName );
131
132                for (  k in b ) {
133                        if ( b[ k ] ) {
134                                flags[ k ] = flags.hasVirtualBinding = true;
135                        }
136                }
137                element = element.parentNode;
138        }
139        return flags;
140}
141
142function getClosestElementWithVirtualBinding( element, eventType ) {
143        var b;
144        while ( element ) {
145
146                b = $.data( element, dataPropertyName );
147
148                if ( b && ( !eventType || b[ eventType ] ) ) {
149                        return element;
150                }
151                element = element.parentNode;
152        }
153        return null;
154}
155
156function enableTouchBindings() {
157        blockTouchTriggers = false;
158}
159
160function disableTouchBindings() {
161        blockTouchTriggers = true;
162}
163
164function enableMouseBindings() {
165        lastTouchID = 0;
166        clickBlockList.length = 0;
167        blockMouseTriggers = false;
168
169        // When mouse bindings are enabled, our
170        // touch bindings are disabled.
171        disableTouchBindings();
172}
173
174function disableMouseBindings() {
175        // When mouse bindings are disabled, our
176        // touch bindings are enabled.
177        enableTouchBindings();
178}
179
180function startResetTimer() {
181        clearResetTimer();
182        resetTimerID = setTimeout( function() {
183                resetTimerID = 0;
184                enableMouseBindings();
185        }, $.vmouse.resetTimerDuration );
186}
187
188function clearResetTimer() {
189        if ( resetTimerID ) {
190                clearTimeout( resetTimerID );
191                resetTimerID = 0;
192        }
193}
194
195function triggerVirtualEvent( eventType, event, flags ) {
196        var ve;
197
198        if ( ( flags && flags[ eventType ] ) ||
199                                ( !flags && getClosestElementWithVirtualBinding( event.target, eventType ) ) ) {
200
201                ve = createVirtualEvent( event, eventType );
202
203                $( event.target).trigger( ve );
204        }
205
206        return ve;
207}
208
209function mouseEventCallback( event ) {
210        var touchID = $.data( event.target, touchTargetPropertyName );
211
212        if ( !blockMouseTriggers && ( !lastTouchID || lastTouchID !== touchID ) ) {
213                var ve = triggerVirtualEvent( "v" + event.type, event );
214                if ( ve ) {
215                        if ( ve.isDefaultPrevented() ) {
216                                event.preventDefault();
217                        }
218                        if ( ve.isPropagationStopped() ) {
219                                event.stopPropagation();
220                        }
221                        if ( ve.isImmediatePropagationStopped() ) {
222                                event.stopImmediatePropagation();
223                        }
224                }
225        }
226}
227
228function handleTouchStart( event ) {
229
230        var touches = getNativeEvent( event ).touches,
231                target, flags;
232
233        if ( touches && touches.length === 1 ) {
234
235                target = event.target;
236                flags = getVirtualBindingFlags( target );
237
238                if ( flags.hasVirtualBinding ) {
239
240                        lastTouchID = nextTouchID++;
241                        $.data( target, touchTargetPropertyName, lastTouchID );
242
243                        clearResetTimer();
244
245                        disableMouseBindings();
246                        didScroll = false;
247
248                        var t = getNativeEvent( event ).touches[ 0 ];
249                        startX = t.pageX;
250                        startY = t.pageY;
251
252                        triggerVirtualEvent( "vmouseover", event, flags );
253                        triggerVirtualEvent( "vmousedown", event, flags );
254                }
255        }
256}
257
258function handleScroll( event ) {
259        if ( blockTouchTriggers ) {
260                return;
261        }
262
263        if ( !didScroll ) {
264                triggerVirtualEvent( "vmousecancel", event, getVirtualBindingFlags( event.target ) );
265        }
266
267        didScroll = true;
268        startResetTimer();
269}
270
271function handleTouchMove( event ) {
272        if ( blockTouchTriggers ) {
273                return;
274        }
275
276        var t = getNativeEvent( event ).touches[ 0 ],
277                didCancel = didScroll,
278                moveThreshold = $.vmouse.moveDistanceThreshold,
279                flags = getVirtualBindingFlags( event.target );
280
281                didScroll = didScroll ||
282                        ( Math.abs( t.pageX - startX ) > moveThreshold ||
283                                Math.abs( t.pageY - startY ) > moveThreshold );
284
285
286        if ( didScroll && !didCancel ) {
287                triggerVirtualEvent( "vmousecancel", event, flags );
288        }
289
290        triggerVirtualEvent( "vmousemove", event, flags );
291        startResetTimer();
292}
293
294function handleTouchEnd( event ) {
295        if ( blockTouchTriggers ) {
296                return;
297        }
298
299        disableTouchBindings();
300
301        var flags = getVirtualBindingFlags( event.target ),
302                t;
303        triggerVirtualEvent( "vmouseup", event, flags );
304
305        if ( !didScroll ) {
306                var ve = triggerVirtualEvent( "vclick", event, flags );
307                if ( ve && ve.isDefaultPrevented() ) {
308                        // The target of the mouse events that follow the touchend
309                        // event don't necessarily match the target used during the
310                        // touch. This means we need to rely on coordinates for blocking
311                        // any click that is generated.
312                        t = getNativeEvent( event ).changedTouches[ 0 ];
313                        clickBlockList.push({
314                                touchID: lastTouchID,
315                                x: t.clientX,
316                                y: t.clientY
317                        });
318
319                        // Prevent any mouse events that follow from triggering
320                        // virtual event notifications.
321                        blockMouseTriggers = true;
322                }
323        }
324        triggerVirtualEvent( "vmouseout", event, flags);
325        didScroll = false;
326
327        startResetTimer();
328}
329
330function hasVirtualBindings( ele ) {
331        var bindings = $.data( ele, dataPropertyName ),
332                k;
333
334        if ( bindings ) {
335                for ( k in bindings ) {
336                        if ( bindings[ k ] ) {
337                                return true;
338                        }
339                }
340        }
341        return false;
342}
343
344function dummyMouseHandler() {}
345
346function getSpecialEventObject( eventType ) {
347        var realType = eventType.substr( 1 );
348
349        return {
350                setup: function( data, namespace ) {
351                        // If this is the first virtual mouse binding for this element,
352                        // add a bindings object to its data.
353
354                        if ( !hasVirtualBindings( this ) ) {
355                                $.data( this, dataPropertyName, {} );
356                        }
357
358                        // If setup is called, we know it is the first binding for this
359                        // eventType, so initialize the count for the eventType to zero.
360                        var bindings = $.data( this, dataPropertyName );
361                        bindings[ eventType ] = true;
362
363                        // If this is the first virtual mouse event for this type,
364                        // register a global handler on the document.
365
366                        activeDocHandlers[ eventType ] = ( activeDocHandlers[ eventType ] || 0 ) + 1;
367
368                        if ( activeDocHandlers[ eventType ] === 1 ) {
369                                $document.bind( realType, mouseEventCallback );
370                        }
371
372                        // Some browsers, like Opera Mini, won't dispatch mouse/click events
373                        // for elements unless they actually have handlers registered on them.
374                        // To get around this, we register dummy handlers on the elements.
375
376                        $( this ).bind( realType, dummyMouseHandler );
377
378                        // For now, if event capture is not supported, we rely on mouse handlers.
379                        if ( eventCaptureSupported ) {
380                                // If this is the first virtual mouse binding for the document,
381                                // register our touchstart handler on the document.
382
383                                activeDocHandlers[ "touchstart" ] = ( activeDocHandlers[ "touchstart" ] || 0) + 1;
384
385                                if ( activeDocHandlers[ "touchstart" ] === 1 ) {
386                                        $document.bind( "touchstart", handleTouchStart )
387                                                .bind( "touchend", handleTouchEnd )
388
389                                                // On touch platforms, touching the screen and then dragging your finger
390                                                // causes the window content to scroll after some distance threshold is
391                                                // exceeded. On these platforms, a scroll prevents a click event from being
392                                                // dispatched, and on some platforms, even the touchend is suppressed. To
393                                                // mimic the suppression of the click event, we need to watch for a scroll
394                                                // event. Unfortunately, some platforms like iOS don't dispatch scroll
395                                                // events until *AFTER* the user lifts their finger (touchend). This means
396                                                // we need to watch both scroll and touchmove events to figure out whether
397                                                // or not a scroll happenens before the touchend event is fired.
398
399                                                .bind( "touchmove", handleTouchMove )
400                                                .bind( "scroll", handleScroll );
401                                }
402                        }
403                },
404
405                teardown: function( data, namespace ) {
406                        // If this is the last virtual binding for this eventType,
407                        // remove its global handler from the document.
408
409                        --activeDocHandlers[ eventType ];
410
411                        if ( !activeDocHandlers[ eventType ] ) {
412                                $document.unbind( realType, mouseEventCallback );
413                        }
414
415                        if ( eventCaptureSupported ) {
416                                // If this is the last virtual mouse binding in existence,
417                                // remove our document touchstart listener.
418
419                                --activeDocHandlers[ "touchstart" ];
420
421                                if ( !activeDocHandlers[ "touchstart" ] ) {
422                                        $document.unbind( "touchstart", handleTouchStart )
423                                                .unbind( "touchmove", handleTouchMove )
424                                                .unbind( "touchend", handleTouchEnd )
425                                                .unbind( "scroll", handleScroll );
426                                }
427                        }
428
429                        var $this = $( this ),
430                                bindings = $.data( this, dataPropertyName );
431
432                        // teardown may be called when an element was
433                        // removed from the DOM. If this is the case,
434                        // jQuery core may have already stripped the element
435                        // of any data bindings so we need to check it before
436                        // using it.
437                        if ( bindings ) {
438                                bindings[ eventType ] = false;
439                        }
440
441                        // Unregister the dummy event handler.
442
443                        $this.unbind( realType, dummyMouseHandler );
444
445                        // If this is the last virtual mouse binding on the
446                        // element, remove the binding data from the element.
447
448                        if ( !hasVirtualBindings( this ) ) {
449                                $this.removeData( dataPropertyName );
450                        }
451                }
452        };
453}
454
455// Expose our custom events to the jQuery bind/unbind mechanism.
456
457for ( var i = 0; i < virtualEventNames.length; i++ ) {
458        $.event.special[ virtualEventNames[ i ] ] = getSpecialEventObject( virtualEventNames[ i ] );
459}
460
461// Add a capture click handler to block clicks.
462// Note that we require event capture support for this so if the device
463// doesn't support it, we punt for now and rely solely on mouse events.
464if ( eventCaptureSupported ) {
465        document.addEventListener( "click", function( e ) {
466                var cnt = clickBlockList.length,
467                        target = e.target,
468                        x, y, ele, i, o, touchID;
469
470                if ( cnt ) {
471                        x = e.clientX;
472                        y = e.clientY;
473                        threshold = $.vmouse.clickDistanceThreshold;
474
475                        // The idea here is to run through the clickBlockList to see if
476                        // the current click event is in the proximity of one of our
477                        // vclick events that had preventDefault() called on it. If we find
478                        // one, then we block the click.
479                        //
480                        // Why do we have to rely on proximity?
481                        //
482                        // Because the target of the touch event that triggered the vclick
483                        // can be different from the target of the click event synthesized
484                        // by the browser. The target of a mouse/click event that is syntehsized
485                        // from a touch event seems to be implementation specific. For example,
486                        // some browsers will fire mouse/click events for a link that is near
487                        // a touch event, even though the target of the touchstart/touchend event
488                        // says the user touched outside the link. Also, it seems that with most
489                        // browsers, the target of the mouse/click event is not calculated until the
490                        // time it is dispatched, so if you replace an element that you touched
491                        // with another element, the target of the mouse/click will be the new
492                        // element underneath that point.
493                        //
494                        // Aside from proximity, we also check to see if the target and any
495                        // of its ancestors were the ones that blocked a click. This is necessary
496                        // because of the strange mouse/click target calculation done in the
497                        // Android 2.1 browser, where if you click on an element, and there is a
498                        // mouse/click handler on one of its ancestors, the target will be the
499                        // innermost child of the touched element, even if that child is no where
500                        // near the point of touch.
501
502                        ele = target;
503
504                        while ( ele ) {
505                                for ( i = 0; i < cnt; i++ ) {
506                                        o = clickBlockList[ i ];
507                                        touchID = 0;
508
509                                        if ( ( ele === target && Math.abs( o.x - x ) < threshold && Math.abs( o.y - y ) < threshold ) ||
510                                                                $.data( ele, touchTargetPropertyName ) === o.touchID ) {
511                                                // XXX: We may want to consider removing matches from the block list
512                                                //      instead of waiting for the reset timer to fire.
513                                                e.preventDefault();
514                                                e.stopPropagation();
515                                                return;
516                                        }
517                                }
518                                ele = ele.parentNode;
519                        }
520                }
521        }, true);
522}
523})( jQuery, window, document );
524
525(function( $ ) {
526        $.mobile = {};
527}( jQuery ));
528        (function( $, undefined ) {
529                var support = {
530                        touch: "ontouchend" in document
531                };
532
533                $.mobile.support = $.mobile.support || {};
534                $.extend( $.support, support );
535                $.extend( $.mobile.support, support );
536        }( jQuery ));
537
538
539(function( $, window, undefined ) {
540        var $document = $( document );
541
542        // add new event shortcuts
543        $.each( ( "touchstart touchmove touchend " +
544                "tap taphold " +
545                "swipe swipeleft swiperight " +
546                "scrollstart scrollstop" ).split( " " ), function( i, name ) {
547
548                $.fn[ name ] = function( fn ) {
549                        return fn ? this.bind( name, fn ) : this.trigger( name );
550                };
551
552                // jQuery < 1.8
553                if ( $.attrFn ) {
554                        $.attrFn[ name ] = true;
555                }
556        });
557
558        var supportTouch = $.mobile.support.touch,
559                scrollEvent = "touchmove scroll",
560                touchStartEvent = supportTouch ? "touchstart" : "mousedown",
561                touchStopEvent = supportTouch ? "touchend" : "mouseup",
562                touchMoveEvent = supportTouch ? "touchmove" : "mousemove";
563
564        function triggerCustomEvent( obj, eventType, event ) {
565                var originalType = event.type;
566                event.type = eventType;
567                $.event.dispatch.call( obj, event );
568                event.type = originalType;
569        }
570
571        // also handles scrollstop
572        $.event.special.scrollstart = {
573
574                enabled: true,
575
576                setup: function() {
577
578                        var thisObject = this,
579                                $this = $( thisObject ),
580                                scrolling,
581                                timer;
582
583                        function trigger( event, state ) {
584                                scrolling = state;
585                                triggerCustomEvent( thisObject, scrolling ? "scrollstart" : "scrollstop", event );
586                        }
587
588                        // iPhone triggers scroll after a small delay; use touchmove instead
589                        $this.bind( scrollEvent, function( event ) {
590
591                                if ( !$.event.special.scrollstart.enabled ) {
592                                        return;
593                                }
594
595                                if ( !scrolling ) {
596                                        trigger( event, true );
597                                }
598
599                                clearTimeout( timer );
600                                timer = setTimeout( function() {
601                                        trigger( event, false );
602                                }, 50 );
603                        });
604                }
605        };
606
607        // also handles taphold
608        $.event.special.tap = {
609                tapholdThreshold: 750,
610
611                setup: function() {
612                        var thisObject = this,
613                                $this = $( thisObject );
614
615                        $this.bind( "vmousedown", function( event ) {
616
617                                if ( event.which && event.which !== 1 ) {
618                                        return false;
619                                }
620
621                                var origTarget = event.target,
622                                        origEvent = event.originalEvent,
623                                        timer;
624
625                                function clearTapTimer() {
626                                        clearTimeout( timer );
627                                }
628
629                                function clearTapHandlers() {
630                                        clearTapTimer();
631
632                                        $this.unbind( "vclick", clickHandler )
633                                                .unbind( "vmouseup", clearTapTimer );
634                                        $document.unbind( "vmousecancel", clearTapHandlers );
635                                }
636
637                                function clickHandler( event ) {
638                                        clearTapHandlers();
639
640                                        // ONLY trigger a 'tap' event if the start target is
641                                        // the same as the stop target.
642                                        if ( origTarget === event.target ) {
643                                                triggerCustomEvent( thisObject, "tap", event );
644                                        }
645                                }
646
647                                $this.bind( "vmouseup", clearTapTimer )
648                                        .bind( "vclick", clickHandler );
649                                $document.bind( "vmousecancel", clearTapHandlers );
650
651                                timer = setTimeout( function() {
652                                        triggerCustomEvent( thisObject, "taphold", $.Event( "taphold", { target: origTarget } ) );
653                                }, $.event.special.tap.tapholdThreshold );
654                        });
655                }
656        };
657
658        // also handles swipeleft, swiperight
659        $.event.special.swipe = {
660                scrollSupressionThreshold: 30, // More than this horizontal displacement, and we will suppress scrolling.
661
662                durationThreshold: 1000, // More time than this, and it isn't a swipe.
663
664                horizontalDistanceThreshold: 30,  // Swipe horizontal displacement must be more than this.
665
666                verticalDistanceThreshold: 75,  // Swipe vertical displacement must be less than this.
667
668                start: function( event ) {
669                        var data = event.originalEvent.touches ?
670                                        event.originalEvent.touches[ 0 ] : event;
671                        return {
672                                                time: ( new Date() ).getTime(),
673                                                coords: [ data.pageX, data.pageY ],
674                                                origin: $( event.target )
675                                        };
676                },
677
678                stop: function( event ) {
679                        var data = event.originalEvent.touches ?
680                                        event.originalEvent.touches[ 0 ] : event;
681                        return {
682                                                time: ( new Date() ).getTime(),
683                                                coords: [ data.pageX, data.pageY ]
684                                        };
685                },
686
687                handleSwipe: function( start, stop ) {
688                        if ( stop.time - start.time < $.event.special.swipe.durationThreshold &&
689                                Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.horizontalDistanceThreshold &&
690                                Math.abs( start.coords[ 1 ] - stop.coords[ 1 ] ) < $.event.special.swipe.verticalDistanceThreshold ) {
691
692                                start.origin.trigger( "swipe" )
693                                        .trigger( start.coords[0] > stop.coords[ 0 ] ? "swipeleft" : "swiperight" );
694                        }
695                },
696
697                setup: function() {
698                        var thisObject = this,
699                                $this = $( thisObject );
700
701                        $this.bind( touchStartEvent, function( event ) {
702                                var start = $.event.special.swipe.start( event ),
703                                        stop;
704
705                                function moveHandler( event ) {
706                                        if ( !start ) {
707                                                return;
708                                        }
709
710                                        stop = $.event.special.swipe.stop( event );
711
712                                        // prevent scrolling
713                                        if ( Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.scrollSupressionThreshold ) {
714                                                event.preventDefault();
715                                        }
716                                }
717
718                                $this.bind( touchMoveEvent, moveHandler )
719                                        .one( touchStopEvent, function() {
720                                                $this.unbind( touchMoveEvent, moveHandler );
721
722                                                if ( start && stop ) {
723                                                        $.event.special.swipe.handleSwipe( start, stop );
724                                                }
725                                                start = stop = undefined;
726                                        });
727                        });
728                }
729        };
730        $.each({
731                scrollstop: "scrollstart",
732                taphold: "tap",
733                swipeleft: "swipe",
734                swiperight: "swipe"
735        }, function( event, sourceEvent ) {
736
737                $.event.special[ event ] = {
738                        setup: function() {
739                                $( this ).bind( sourceEvent, $.noop );
740                        }
741                };
742        });
743
744})( jQuery, this );
745
746(function( $, window, undefined ) {
747        var nsNormalizeDict = {};
748
749        // jQuery.mobile configurable options
750        $.mobile = $.extend($.mobile, {
751
752                // Version of the jQuery Mobile Framework
753                version: "1.3.2",
754
755                // Namespace used framework-wide for data-attrs. Default is no namespace
756                ns: "",
757
758                // Define the url parameter used for referencing widget-generated sub-pages.
759                // Translates to to example.html&ui-page=subpageIdentifier
760                // hash segment before &ui-page= is used to make Ajax request
761                subPageUrlKey: "ui-page",
762
763                // Class assigned to page currently in view, and during transitions
764                activePageClass: "ui-page-active",
765
766                // Class used for "active" button state, from CSS framework
767                activeBtnClass: "ui-btn-active",
768
769                // Class used for "focus" form element state, from CSS framework
770                focusClass: "ui-focus",
771
772                // Automatically handle clicks and form submissions through Ajax, when same-domain
773                ajaxEnabled: true,
774
775                // Automatically load and show pages based on location.hash
776                hashListeningEnabled: true,
777
778                // disable to prevent jquery from bothering with links
779                linkBindingEnabled: true,
780
781                // Set default page transition - 'none' for no transitions
782                defaultPageTransition: "fade",
783
784                // Set maximum window width for transitions to apply - 'false' for no limit
785                maxTransitionWidth: false,
786
787                // Minimum scroll distance that will be remembered when returning to a page
788                minScrollBack: 250,
789
790                // DEPRECATED: the following property is no longer in use, but defined until 2.0 to prevent conflicts
791                touchOverflowEnabled: false,
792
793                // Set default dialog transition - 'none' for no transitions
794                defaultDialogTransition: "pop",
795
796                // Error response message - appears when an Ajax page request fails
797                pageLoadErrorMessage: "Error Loading Page",
798
799                // For error messages, which theme does the box uses?
800                pageLoadErrorMessageTheme: "e",
801
802                // replace calls to window.history.back with phonegaps navigation helper
803                // where it is provided on the window object
804                phonegapNavigationEnabled: false,
805
806                //automatically initialize the DOM when it's ready
807                autoInitializePage: true,
808
809                pushStateEnabled: true,
810
811                // allows users to opt in to ignoring content by marking a parent element as
812                // data-ignored
813                ignoreContentEnabled: false,
814
815                // turn of binding to the native orientationchange due to android orientation behavior
816                orientationChangeEnabled: true,
817
818                buttonMarkup: {
819                        hoverDelay: 200
820                },
821
822                // define the window and the document objects
823                window: $( window ),
824                document: $( document ),
825
826                // TODO might be useful upstream in jquery itself ?
827                keyCode: {
828                        ALT: 18,
829                        BACKSPACE: 8,
830                        CAPS_LOCK: 20,
831                        COMMA: 188,
832                        COMMAND: 91,
833                        COMMAND_LEFT: 91, // COMMAND
834                        COMMAND_RIGHT: 93,
835                        CONTROL: 17,
836                        DELETE: 46,
837                        DOWN: 40,
838                        END: 35,
839                        ENTER: 13,
840                        ESCAPE: 27,
841                        HOME: 36,
842                        INSERT: 45,
843                        LEFT: 37,
844                        MENU: 93, // COMMAND_RIGHT
845                        NUMPAD_ADD: 107,
846                        NUMPAD_DECIMAL: 110,
847                        NUMPAD_DIVIDE: 111,
848                        NUMPAD_ENTER: 108,
849                        NUMPAD_MULTIPLY: 106,
850                        NUMPAD_SUBTRACT: 109,
851                        PAGE_DOWN: 34,
852                        PAGE_UP: 33,
853                        PERIOD: 190,
854                        RIGHT: 39,
855                        SHIFT: 16,
856                        SPACE: 32,
857                        TAB: 9,
858                        UP: 38,
859                        WINDOWS: 91 // COMMAND
860                },
861
862                // Place to store various widget extensions
863                behaviors: {},
864
865                // Scroll page vertically: scroll to 0 to hide iOS address bar, or pass a Y value
866                silentScroll: function( ypos ) {
867                        if ( $.type( ypos ) !== "number" ) {
868                                ypos = $.mobile.defaultHomeScroll;
869                        }
870
871                        // prevent scrollstart and scrollstop events
872                        $.event.special.scrollstart.enabled = false;
873
874                        setTimeout( function() {
875                                window.scrollTo( 0, ypos );
876                                $.mobile.document.trigger( "silentscroll", { x: 0, y: ypos });
877                        }, 20 );
878
879                        setTimeout( function() {
880                                $.event.special.scrollstart.enabled = true;
881                        }, 150 );
882                },
883
884                // Expose our cache for testing purposes.
885                nsNormalizeDict: nsNormalizeDict,
886
887                // Take a data attribute property, prepend the namespace
888                // and then camel case the attribute string. Add the result
889                // to our nsNormalizeDict so we don't have to do this again.
890                nsNormalize: function( prop ) {
891                        if ( !prop ) {
892                                return;
893                        }
894
895                        return nsNormalizeDict[ prop ] || ( nsNormalizeDict[ prop ] = $.camelCase( $.mobile.ns + prop ) );
896                },
897
898                // Find the closest parent with a theme class on it. Note that
899                // we are not using $.fn.closest() on purpose here because this
900                // method gets called quite a bit and we need it to be as fast
901                // as possible.
902                getInheritedTheme: function( el, defaultTheme ) {
903                        var e = el[ 0 ],
904                                ltr = "",
905                                re = /ui-(bar|body|overlay)-([a-z])\b/,
906                                c, m;
907
908                        while ( e ) {
909                                c = e.className || "";
910                                if ( c && ( m = re.exec( c ) ) && ( ltr = m[ 2 ] ) ) {
911                                        // We found a parent with a theme class
912                                        // on it so bail from this loop.
913                                        break;
914                                }
915
916                                e = e.parentNode;
917                        }
918
919                        // Return the theme letter we found, if none, return the
920                        // specified default.
921
922                        return ltr || defaultTheme || "a";
923                },
924
925                // TODO the following $ and $.fn extensions can/probably should be moved into jquery.mobile.core.helpers
926                //
927                // Find the closest javascript page element to gather settings data jsperf test
928                // http://jsperf.com/single-complex-selector-vs-many-complex-selectors/edit
929                // possibly naive, but it shows that the parsing overhead for *just* the page selector vs
930                // the page and dialog selector is negligable. This could probably be speed up by
931                // doing a similar parent node traversal to the one found in the inherited theme code above
932                closestPageData: function( $target ) {
933                        return $target
934                                .closest( ':jqmData(role="page"), :jqmData(role="dialog")' )
935                                .data( "mobile-page" );
936                },
937
938                enhanceable: function( $set ) {
939                        return this.haveParents( $set, "enhance" );
940                },
941
942                hijackable: function( $set ) {
943                        return this.haveParents( $set, "ajax" );
944                },
945
946                haveParents: function( $set, attr ) {
947                        if ( !$.mobile.ignoreContentEnabled ) {
948                                return $set;
949                        }
950
951                        var count = $set.length,
952                                $newSet = $(),
953                                e, $element, excluded;
954
955                        for ( var i = 0; i < count; i++ ) {
956                                $element = $set.eq( i );
957                                excluded = false;
958                                e = $set[ i ];
959
960                                while ( e ) {
961                                        var c = e.getAttribute ? e.getAttribute( "data-" + $.mobile.ns + attr ) : "";
962
963                                        if ( c === "false" ) {
964                                                excluded = true;
965                                                break;
966                                        }
967
968                                        e = e.parentNode;
969                                }
970
971                                if ( !excluded ) {
972                                        $newSet = $newSet.add( $element );
973                                }
974                        }
975
976                        return $newSet;
977                },
978
979                getScreenHeight: function() {
980                        // Native innerHeight returns more accurate value for this across platforms,
981                        // jQuery version is here as a normalized fallback for platforms like Symbian
982                        return window.innerHeight || $.mobile.window.height();
983                }
984        }, $.mobile );
985
986        // Mobile version of data and removeData and hasData methods
987        // ensures all data is set and retrieved using jQuery Mobile's data namespace
988        $.fn.jqmData = function( prop, value ) {
989                var result;
990                if ( typeof prop !== "undefined" ) {
991                        if ( prop ) {
992                                prop = $.mobile.nsNormalize( prop );
993                        }
994
995                        // undefined is permitted as an explicit input for the second param
996                        // in this case it returns the value and does not set it to undefined
997                        if( arguments.length < 2 || value === undefined ){
998                                result = this.data( prop );
999                        } else {
1000                                result = this.data( prop, value );
1001                        }
1002                }
1003                return result;
1004        };
1005
1006        $.jqmData = function( elem, prop, value ) {
1007                var result;
1008                if ( typeof prop !== "undefined" ) {
1009                        result = $.data( elem, prop ? $.mobile.nsNormalize( prop ) : prop, value );
1010                }
1011                return result;
1012        };
1013
1014        $.fn.jqmRemoveData = function( prop ) {
1015                return this.removeData( $.mobile.nsNormalize( prop ) );
1016        };
1017
1018        $.jqmRemoveData = function( elem, prop ) {
1019                return $.removeData( elem, $.mobile.nsNormalize( prop ) );
1020        };
1021
1022        $.fn.removeWithDependents = function() {
1023                $.removeWithDependents( this );
1024        };
1025
1026        $.removeWithDependents = function( elem ) {
1027                var $elem = $( elem );
1028
1029                ( $elem.jqmData( 'dependents' ) || $() ).remove();
1030                $elem.remove();
1031        };
1032
1033        $.fn.addDependents = function( newDependents ) {
1034                $.addDependents( $( this ), newDependents );
1035        };
1036
1037        $.addDependents = function( elem, newDependents ) {
1038                var dependents = $( elem ).jqmData( 'dependents' ) || $();
1039
1040                $( elem ).jqmData( 'dependents', $.merge( dependents, newDependents ) );
1041        };
1042
1043        // note that this helper doesn't attempt to handle the callback
1044        // or setting of an html element's text, its only purpose is
1045        // to return the html encoded version of the text in all cases. (thus the name)
1046        $.fn.getEncodedText = function() {
1047                return $( "<div/>" ).text( $( this ).text() ).html();
1048        };
1049
1050        // fluent helper function for the mobile namespaced equivalent
1051        $.fn.jqmEnhanceable = function() {
1052                return $.mobile.enhanceable( this );
1053        };
1054
1055        $.fn.jqmHijackable = function() {
1056                return $.mobile.hijackable( this );
1057        };
1058
1059        // Monkey-patching Sizzle to filter the :jqmData selector
1060        var oldFind = $.find,
1061                jqmDataRE = /:jqmData\(([^)]*)\)/g;
1062
1063        $.find = function( selector, context, ret, extra ) {
1064                selector = selector.replace( jqmDataRE, "[data-" + ( $.mobile.ns || "" ) + "$1]" );
1065
1066                return oldFind.call( this, selector, context, ret, extra );
1067        };
1068
1069        $.extend( $.find, oldFind );
1070
1071        $.find.matches = function( expr, set ) {
1072                return $.find( expr, null, null, set );
1073        };
1074
1075        $.find.matchesSelector = function( node, expr ) {
1076                return $.find( expr, null, null, [ node ] ).length > 0;
1077        };
1078})( jQuery, this );
1079
1080
1081}));
Note: See TracBrowser for help on using the repository browser.