--- a/js/jquery.mobile-1.0b2.js +++ b/js/jquery.mobile-1.0b2.js @@ -1,5 +1,5 @@ /*! - * jQuery Mobile v1.0b1 + * jQuery Mobile v1.0b2 * http://jquerymobile.com/ * * Copyright 2010, jQuery Project @@ -274,20 +274,27 @@ * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license */ -(function($, undefined ) { + +(function( $, undefined ) { $.widget( "mobile.widget", { _getCreateOptions: function() { + var elem = this.element, options = {}; + $.each( this.options, function( option ) { + var value = elem.jqmData( option.replace( /[A-Z]/g, function( c ) { - return "-" + c.toLowerCase(); - } ) ); + return "-" + c.toLowerCase(); + }) + ); + if ( value !== undefined ) { options[ option ] = value; } }); + return options; } }); @@ -299,14 +306,10 @@ * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license */ -(function($, undefined ) { - -var $window = $(window), - $html = $( "html" ), - - //media-query-like width breakpoints, which are translated to classes on the html element - resolutionBreakpoints = [320,480,768,1024]; - +(function( $, undefined ) { + +var $window = $( window ), + $html = $( "html" ); /* $.mobile.media method: pass a CSS media type or query and get a bool return note: this feature relies on actual media query support for media queries, though types will work most anywhere @@ -323,17 +326,18 @@ return function( query ) { if ( !( query in cache ) ) { - var styleBlock = document.createElement('style'), - cssrule = "@media " + query + " { #jquery-mediatest { position:absolute; } }"; - //must set type for IE! - styleBlock.type = "text/css"; - if (styleBlock.styleSheet){ - styleBlock.styleSheet.cssText = cssrule; - } - else { - styleBlock.appendChild(document.createTextNode(cssrule)); - } - + var styleBlock = document.createElement( "style" ), + cssrule = "@media " + query + " { #jquery-mediatest { position:absolute; } }"; + + //must set type for IE! + styleBlock.type = "text/css"; + + if ( styleBlock.styleSheet ){ + styleBlock.styleSheet.cssText = cssrule; + } else { + styleBlock.appendChild( document.createTextNode(cssrule) ); + } + $html.prepend( fakeBody ).prepend( styleBlock ); cache[ query ] = testDiv.css( "position" ) === "absolute"; fakeBody.add( styleBlock ).remove(); @@ -341,122 +345,51 @@ return cache[ query ]; }; })(); - -/* - private function for adding/removing breakpoint classes to HTML element for faux media-query support - It does not require media query support, instead using JS to detect screen width > cross-browser support - This function is called on orientationchange, resize, and mobileinit, and is bound via the 'htmlclass' event namespace -*/ -function detectResolutionBreakpoints(){ - var currWidth = $window.width(), - minPrefix = "min-width-", - maxPrefix = "max-width-", - minBreakpoints = [], - maxBreakpoints = [], - unit = "px", - breakpointClasses; - - $html.removeClass( minPrefix + resolutionBreakpoints.join(unit + " " + minPrefix) + unit + " " + - maxPrefix + resolutionBreakpoints.join( unit + " " + maxPrefix) + unit ); - - $.each(resolutionBreakpoints,function( i, breakPoint ){ - if( currWidth >= breakPoint ){ - minBreakpoints.push( minPrefix + breakPoint + unit ); - } - if( currWidth <= breakPoint ){ - maxBreakpoints.push( maxPrefix + breakPoint + unit ); - } - }); - - if( minBreakpoints.length ){ breakpointClasses = minBreakpoints.join(" "); } - if( maxBreakpoints.length ){ breakpointClasses += " " + maxBreakpoints.join(" "); } - - $html.addClass( breakpointClasses ); -}; - -/* $.mobile.addResolutionBreakpoints method: - pass either a number or an array of numbers and they'll be added to the min/max breakpoint classes - Examples: - $.mobile.addResolutionBreakpoints( 500 ); - $.mobile.addResolutionBreakpoints( [500, 1200] ); -*/ -$.mobile.addResolutionBreakpoints = function( newbps ){ - if( $.type( newbps ) === "array" ){ - resolutionBreakpoints = resolutionBreakpoints.concat( newbps ); - } - else { - resolutionBreakpoints.push( newbps ); - } - resolutionBreakpoints.sort(function(a,b){ return a-b; }); - detectResolutionBreakpoints(); -}; - -/* on mobileinit, add classes to HTML element - and set handlers to update those on orientationchange and resize*/ -$(document).bind("mobileinit.htmlclass", function(){ - /* bind to orientationchange and resize - to add classes to HTML element for min/max breakpoints and orientation */ - var ev = $.support.orientation; - $window.bind("orientationchange.htmlclass throttledResize.htmlclass", function(event){ - //add orientation class to HTML element on flip/resize. - if(event.orientation){ - $html.removeClass( "portrait landscape" ).addClass( event.orientation ); - } - //add classes to HTML element for min/max breakpoints - detectResolutionBreakpoints(); - }); -}); - -/* Manually trigger an orientationchange event when the dom ready event fires. - This will ensure that any viewport meta tag that may have been injected - has taken effect already, allowing us to properly calculate the width of the - document. -*/ -$(function(){ - //trigger event manually - $window.trigger( "orientationchange.htmlclass" ); -}); })(jQuery);/* * jQuery Mobile Framework : support tests * Copyright (c) jQuery Project * Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. -* Note: Code is in draft form and is subject to change */ -( function( $, undefined ) { - -var fakeBody = $( "<body>" ).prependTo( "html" ), + +(function( $, undefined ) { + +var fakeBody = $( "<body>" ).prependTo( "html" ), fbCSS = fakeBody[ 0 ].style, vendors = [ "webkit", "moz", "o" ], - webos = "palmGetResource" in window, //only used to rule out scrollTop + webos = "palmGetResource" in window, //only used to rule out scrollTop bb = window.blackberry; //only used to rule out box shadow, as it's filled opaque on BB // thx Modernizr -function propExists( prop ){ +function propExists( prop ) { var uc_prop = prop.charAt( 0 ).toUpperCase() + prop.substr( 1 ), - props = ( prop + " " + vendors.join( uc_prop + " " ) + uc_prop ).split( " " ); - for( var v in props ){ - if( fbCSS[ v ] !== undefined ){ + props = ( prop + " " + vendors.join( uc_prop + " " ) + uc_prop ).split( " " ); + + for ( var v in props ){ + if ( fbCSS[ v ] !== undefined ) { return true; } } } -// test for dynamic-updating base tag support ( allows us to avoid href,src attr rewriting ) -function baseTagTest(){ +// Test for dynamic-updating base tag support ( allows us to avoid href,src attr rewriting ) +function baseTagTest() { var fauxBase = location.protocol + "//" + location.host + location.pathname + "ui-dir/", base = $( "head base" ), fauxEle = null, - href = ""; + href = "", + link, rebase; + if ( !base.length ) { - base = fauxEle = $( "<base>", { "href": fauxBase} ).appendTo( "head" ); - } - else { + base = fauxEle = $( "<base>", { "href": fauxBase }).appendTo( "head" ); + } else { href = base.attr( "href" ); } - var link = $( "<a href='testurl'></a>" ).prependTo( fakeBody ), - rebase = link[ 0 ].href; + + link = $( "<a href='testurl'></a>" ).prependTo( fakeBody ); + rebase = link[ 0 ].href; base[ 0 ].href = href ? href : location.pathname; + if ( fauxEle ) { fauxEle.remove(); } @@ -467,13 +400,15 @@ // non-UA-based IE version check by James Padolsey, modified by jdalton - from http://gist.github.com/527683 // allows for inclusion of IE 6+, including Windows Mobile 7 $.mobile.browser = {}; -$.mobile.browser.ie = ( function() { - var v = 3, - div = document.createElement( "div" ), +$.mobile.browser.ie = (function() { + var v = 3, + div = document.createElement( "div" ), a = div.all || []; - while ( div.innerHTML = "<!--[if gt IE " + ( ++v ) + "]><br><![endif]-->", a[ 0 ] ); - return v > 4 ? v : !v; -}() ); + + while ( div.innerHTML = "<!--[if gt IE " + ( ++v ) + "]><br><![endif]-->", a[ 0 ] ); + + return v > 4 ? v : !v; +})(); $.extend( $.support, { @@ -486,15 +421,51 @@ boxShadow: !!propExists( "boxShadow" ) && !bb, scrollTop: ( "pageXOffset" in window || "scrollTop" in document.documentElement || "scrollTop" in fakeBody[ 0 ] ) && !webos, dynamicBaseTag: baseTagTest(), - eventCapture: ( "addEventListener" in document ) // This is a weak test. We may want to beef this up later. -} ); + // TODO: This is a weak test. We may want to beef this up later. + eventCapture: "addEventListener" in document +}); fakeBody.remove(); -// for ruling out shadows via css -if( !$.support.boxShadow ){ $( "html" ).addClass( "ui-mobile-nosupport-boxshadow" ); } - -} )( jQuery );/* + +// $.mobile.ajaxBlacklist is used to override ajaxEnabled on platforms that have known conflicts with hash history updates (BB5, Symbian) +// or that generally work better browsing in regular http for full page refreshes (Opera Mini) +// Note: This detection below is used as a last resort. +// We recommend only using these detection methods when all other more reliable/forward-looking approaches are not possible +var nokiaLTE7_3 = (function(){ + + var ua = window.navigator.userAgent; + + //The following is an attempt to match Nokia browsers that are running Symbian/s60, with webkit, version 7.3 or older + return ua.indexOf( "Nokia" ) > -1 && + ( ua.indexOf( "Symbian/3" ) > -1 || ua.indexOf( "Series60/5" ) > -1 ) && + ua.indexOf( "AppleWebKit" ) > -1 && + ua.match( /(BrowserNG|NokiaBrowser)\/7\.[0-3]/ ); +})(); + +$.mobile.ajaxBlacklist = + // BlackBerry browsers, pre-webkit + window.blackberry && !window.WebKitPoint || + // Opera Mini + window.operamini && Object.prototype.toString.call( window.operamini ) === "[object OperaMini]" || + // Symbian webkits pre 7.3 + nokiaLTE7_3; + +// Lastly, this workaround is the only way we've found so far to get pre 7.3 Symbian webkit devices +// to render the stylesheets when they're referenced before this script, as we'd recommend doing. +// This simply reappends the CSS in place, which for some reason makes it apply +if ( nokiaLTE7_3 ) { + $(function() { + $( "head link[rel=stylesheet]" ).attr( "rel", "alternate stylesheet" ).attr( "rel", "stylesheet" ); + }); +} + +// For ruling out shadows via css +if ( !$.support.boxShadow ) { + $( "html" ).addClass( "ui-mobile-nosupport-boxshadow" ); +} + +})( jQuery );/* * jQuery Mobile Framework : "mouse" plugin * Copyright (c) jQuery Project * Dual licensed under the MIT or GPL Version 2 licenses. @@ -516,12 +487,12 @@ // The current version exposes the following virtual events to jQuery bind methods: // "vmouseover vmousedown vmousemove vmouseup vclick vmouseout vmousecancel" -(function($, window, document, undefined) { +(function( $, window, document, undefined ) { var dataPropertyName = "virtualMouseBindings", touchTargetPropertyName = "virtualTouchID", - virtualEventNames = "vmouseover vmousedown vmousemove vmouseup vclick vmouseout vmousecancel".split(" "), - touchEventProps = "clientX clientY pageX pageY screenX screenY".split(" "), + virtualEventNames = "vmouseover vmousedown vmousemove vmouseup vclick vmouseout vmousecancel".split( " " ), + touchEventProps = "clientX clientY pageX pageY screenX screenY".split( " " ), activeDocHandlers = {}, resetTimerID = 0, startX = 0, @@ -531,7 +502,7 @@ blockMouseTriggers = false, blockTouchTriggers = false, eventCaptureSupported = $.support.eventCapture, - $document = $(document), + $document = $( document ), nextTouchID = 1, lastTouchID = 0; @@ -541,42 +512,45 @@ resetTimerDuration: 1500 }; -function getNativeEvent(event) -{ - while (event && typeof event.originalEvent !== "undefined") { +function getNativeEvent( event ) { + + while ( event && typeof event.originalEvent !== "undefined" ) { event = event.originalEvent; } return event; } -function createVirtualEvent(event, eventType) -{ - var t = event.type; +function createVirtualEvent( event, eventType ) { + + var t = event.type, + oe, props, ne, prop, ct, touch, i, j; + event = $.Event(event); event.type = eventType; - - var oe = event.originalEvent; - var props = $.event.props; - + + oe = event.originalEvent; + props = $.event.props; + // copy original event properties over to the new event // this would happen if we could call $.event.fix instead of $.Event // but we don't have a way to force an event to be fixed multiple times - if (oe) { - for ( var i = props.length, prop; i; ) { + if ( oe ) { + for ( i = props.length, prop; i; ) { prop = props[ --i ]; - event[prop] = oe[prop]; + event[ prop ] = oe[ prop ]; } } - - if (t.search(/^touch/) !== -1){ - var ne = getNativeEvent(oe), - t = ne.touches, - ct = ne.changedTouches, - touch = (t && t.length) ? t[0] : ((ct && ct.length) ? ct[0] : undefined); - if (touch){ - for (var i = 0, len = touchEventProps.length; i < len; i++){ - var prop = touchEventProps[i]; - event[prop] = touch[prop]; + + if ( t.search(/^touch/) !== -1 ) { + ne = getNativeEvent( oe ); + t = ne.touches; + ct = ne.changedTouches; + touch = ( t && t.length ) ? t[0] : ( (ct && ct.length) ? ct[ 0 ] : undefined ); + + if ( touch ) { + for ( j = 0, len = touchEventProps.length; j < len; j++){ + prop = touchEventProps[ j ]; + event[ prop ] = touch[ prop ]; } } } @@ -584,14 +558,18 @@ return event; } -function getVirtualBindingFlags(element) -{ - var flags = {}; - while (element){ - var b = $.data(element, dataPropertyName); - for (var k in b) { - if (b[k]){ - flags[k] = flags.hasVirtualBinding = true; +function getVirtualBindingFlags( element ) { + + var flags = {}, + b, k; + + while ( element ) { + + b = $.data( element, dataPropertyName ); + + for ( k in b ) { + if ( b[ k ] ) { + flags[ k ] = flags.hasVirtualBinding = true; } } element = element.parentNode; @@ -599,11 +577,13 @@ return flags; } -function getClosestElementWithVirtualBinding(element, eventType) -{ - while (element){ - var b = $.data(element, dataPropertyName); - if (b && (!eventType || b[eventType])) { +function getClosestElementWithVirtualBinding( element, eventType ) { + var b; + while ( element ) { + + b = $.data( element, dataPropertyName ); + + if ( b && ( !eventType || b[ eventType ] ) ) { return element; } element = element.parentNode; @@ -611,18 +591,15 @@ return null; } -function enableTouchBindings() -{ +function enableTouchBindings() { blockTouchTriggers = false; } -function disableTouchBindings() -{ +function disableTouchBindings() { blockTouchTriggers = true; } -function enableMouseBindings() -{ +function enableMouseBindings() { lastTouchID = 0; clickBlockList.length = 0; blockMouseTriggers = false; @@ -632,148 +609,158 @@ disableTouchBindings(); } -function disableMouseBindings() -{ +function disableMouseBindings() { // When mouse bindings are disabled, our // touch bindings are enabled. enableTouchBindings(); } -function startResetTimer() -{ +function startResetTimer() { clearResetTimer(); resetTimerID = setTimeout(function(){ resetTimerID = 0; enableMouseBindings(); - }, $.vmouse.resetTimerDuration); + }, $.vmouse.resetTimerDuration ); } -function clearResetTimer() -{ - if (resetTimerID){ - clearTimeout(resetTimerID); +function clearResetTimer() { + if ( resetTimerID ){ + clearTimeout( resetTimerID ); resetTimerID = 0; } } -function triggerVirtualEvent(eventType, event, flags) -{ - var defaultPrevented = false; - - if ((flags && flags[eventType]) || (!flags && getClosestElementWithVirtualBinding(event.target, eventType))) { - var ve = createVirtualEvent(event, eventType); - $(event.target).trigger(ve); +function triggerVirtualEvent( eventType, event, flags ) { + var defaultPrevented = false, + ve; + + if ( ( flags && flags[ eventType ] ) || + ( !flags && getClosestElementWithVirtualBinding( event.target, eventType ) ) ) { + + ve = createVirtualEvent( event, eventType ); + + $( event.target).trigger( ve ); + defaultPrevented = ve.isDefaultPrevented(); } return defaultPrevented; } -function mouseEventCallback(event) -{ +function mouseEventCallback( event ) { var touchID = $.data(event.target, touchTargetPropertyName); - if (!blockMouseTriggers && (!lastTouchID || lastTouchID !== touchID)){ - triggerVirtualEvent("v" + event.type, event); + + if ( !blockMouseTriggers && ( !lastTouchID || lastTouchID !== touchID ) ){ + triggerVirtualEvent( "v" + event.type, event ); } } -function handleTouchStart(event) -{ - var touches = getNativeEvent(event).touches; - if (touches && touches.length === 1){ - var target = event.target, - flags = getVirtualBindingFlags(target); - - if (flags.hasVirtualBinding){ +function handleTouchStart( event ) { + + var touches = getNativeEvent( event ).touches, + target, flags; + + if ( touches && touches.length === 1 ) { + + target = event.target; + flags = getVirtualBindingFlags( target ); + + if ( flags.hasVirtualBinding ) { + lastTouchID = nextTouchID++; - $.data(target, touchTargetPropertyName, lastTouchID); - + $.data( target, touchTargetPropertyName, lastTouchID ); + clearResetTimer(); - + disableMouseBindings(); didScroll = false; - - var t = getNativeEvent(event).touches[0]; + + var t = getNativeEvent( event ).touches[ 0 ]; startX = t.pageX; startY = t.pageY; - - triggerVirtualEvent("vmouseover", event, flags); - triggerVirtualEvent("vmousedown", event, flags); + + triggerVirtualEvent( "vmouseover", event, flags ); + triggerVirtualEvent( "vmousedown", event, flags ); } } } -function handleScroll(event) -{ - if (blockTouchTriggers){ +function handleScroll( event ) { + if ( blockTouchTriggers ) { return; } - if (!didScroll){ - triggerVirtualEvent("vmousecancel", event, getVirtualBindingFlags(event.target)); + if ( !didScroll ) { + triggerVirtualEvent( "vmousecancel", event, getVirtualBindingFlags( event.target ) ); } didScroll = true; startResetTimer(); } -function handleTouchMove(event) -{ - if (blockTouchTriggers){ +function handleTouchMove( event ) { + if ( blockTouchTriggers ) { return; } - var t = getNativeEvent(event).touches[0]; - - var didCancel = didScroll, + var t = getNativeEvent( event ).touches[ 0 ], + didCancel = didScroll, moveThreshold = $.vmouse.moveDistanceThreshold; - didScroll = didScroll - || (Math.abs(t.pageX - startX) > moveThreshold || Math.abs(t.pageY - startY) > moveThreshold); - - var flags = getVirtualBindingFlags(event.target); - if (didScroll && !didCancel){ - triggerVirtualEvent("vmousecancel", event, flags); + didScroll = didScroll || + ( Math.abs(t.pageX - startX) > moveThreshold || + Math.abs(t.pageY - startY) > moveThreshold ), + flags = getVirtualBindingFlags( event.target ); + + if ( didScroll && !didCancel ) { + triggerVirtualEvent( "vmousecancel", event, flags ); } - triggerVirtualEvent("vmousemove", event, flags); + + triggerVirtualEvent( "vmousemove", event, flags ); startResetTimer(); } -function handleTouchEnd(event) -{ - if (blockTouchTriggers){ +function handleTouchEnd( event ) { + if ( blockTouchTriggers ) { return; } disableTouchBindings(); - var flags = getVirtualBindingFlags(event.target); - triggerVirtualEvent("vmouseup", event, flags); - if (!didScroll){ - if (triggerVirtualEvent("vclick", event, flags)){ + var flags = getVirtualBindingFlags( event.target ), + t; + triggerVirtualEvent( "vmouseup", event, flags ); + + if ( !didScroll ) { + if ( triggerVirtualEvent( "vclick", event, flags ) ) { // The target of the mouse events that follow the touchend // event don't necessarily match the target used during the // touch. This means we need to rely on coordinates for blocking // any click that is generated. - var t = getNativeEvent(event).changedTouches[0]; - clickBlockList.push({ touchID: lastTouchID, x: t.clientX, y: t.clientY }); + t = getNativeEvent( event ).changedTouches[ 0 ]; + clickBlockList.push({ + touchID: lastTouchID, + x: t.clientX, + y: t.clientY + }); // Prevent any mouse events that follow from triggering // virtual event notifications. blockMouseTriggers = true; } } - triggerVirtualEvent("vmouseout", event, flags); + triggerVirtualEvent( "vmouseout", event, flags); didScroll = false; - + startResetTimer(); } -function hasVirtualBindings(ele) -{ - var bindings = $.data(ele, dataPropertyName), k; - if (bindings){ - for (k in bindings){ - if (bindings[k]){ +function hasVirtualBindings( ele ) { + var bindings = $.data( ele, dataPropertyName ), + k; + + if ( bindings ) { + for ( k in bindings ) { + if ( bindings[ k ] ) { return true; } } @@ -783,49 +770,49 @@ function dummyMouseHandler(){} -function getSpecialEventObject(eventType) -{ - var realType = eventType.substr(1); +function getSpecialEventObject( eventType ) { + var realType = eventType.substr( 1 ); + return { - setup: function(data, namespace) { + setup: function( data, namespace ) { // If this is the first virtual mouse binding for this element, // add a bindings object to its data. - if (!hasVirtualBindings(this)){ - $.data(this, dataPropertyName, {}); + if ( !hasVirtualBindings( this ) ) { + $.data( this, dataPropertyName, {}); } // If setup is called, we know it is the first binding for this // eventType, so initialize the count for the eventType to zero. - - var bindings = $.data(this, dataPropertyName); - bindings[eventType] = true; + var bindings = $.data( this, dataPropertyName ); + bindings[ eventType ] = true; // If this is the first virtual mouse event for this type, // register a global handler on the document. - activeDocHandlers[eventType] = (activeDocHandlers[eventType] || 0) + 1; - if (activeDocHandlers[eventType] === 1){ - $document.bind(realType, mouseEventCallback); + activeDocHandlers[ eventType ] = ( activeDocHandlers[ eventType ] || 0 ) + 1; + + if ( activeDocHandlers[ eventType ] === 1 ) { + $document.bind( realType, mouseEventCallback ); } // Some browsers, like Opera Mini, won't dispatch mouse/click events // for elements unless they actually have handlers registered on them. // To get around this, we register dummy handlers on the elements. - $(this).bind(realType, dummyMouseHandler); + $( this ).bind( realType, dummyMouseHandler ); // For now, if event capture is not supported, we rely on mouse handlers. - if (eventCaptureSupported){ + if ( eventCaptureSupported ) { // If this is the first virtual mouse binding for the document, // register our touchstart handler on the document. - - activeDocHandlers["touchstart"] = (activeDocHandlers["touchstart"] || 0) + 1; - if (activeDocHandlers["touchstart"] === 1) { - $document.bind("touchstart", handleTouchStart) - - .bind("touchend", handleTouchEnd) - + + activeDocHandlers[ "touchstart" ] = ( activeDocHandlers[ "touchstart" ] || 0) + 1; + + if (activeDocHandlers[ "touchstart" ] === 1) { + $document.bind( "touchstart", handleTouchStart ) + .bind( "touchend", handleTouchEnd ) + // On touch platforms, touching the screen and then dragging your finger // causes the window content to scroll after some distance threshold is // exceeded. On these platforms, a scroll prevents a click event from being @@ -835,56 +822,58 @@ // events until *AFTER* the user lifts their finger (touchend). This means // we need to watch both scroll and touchmove events to figure out whether // or not a scroll happenens before the touchend event is fired. - - .bind("touchmove", handleTouchMove) - .bind("scroll", handleScroll); + + .bind( "touchmove", handleTouchMove ) + .bind( "scroll", handleScroll ); } } }, - teardown: function(data, namespace) { + teardown: function( data, namespace ) { // If this is the last virtual binding for this eventType, // remove its global handler from the document. - --activeDocHandlers[eventType]; - if (!activeDocHandlers[eventType]){ - $document.unbind(realType, mouseEventCallback); - } - - if (eventCaptureSupported){ + --activeDocHandlers[ eventType ]; + + if ( !activeDocHandlers[ eventType ] ) { + $document.unbind( realType, mouseEventCallback ); + } + + if ( eventCaptureSupported ) { // If this is the last virtual mouse binding in existence, // remove our document touchstart listener. - - --activeDocHandlers["touchstart"]; - if (!activeDocHandlers["touchstart"]) { - $document.unbind("touchstart", handleTouchStart) - .unbind("touchmove", handleTouchMove) - .unbind("touchend", handleTouchEnd) - .unbind("scroll", handleScroll); - } - } - - var $this = $(this), - bindings = $.data(this, dataPropertyName); + + --activeDocHandlers[ "touchstart" ]; + + if ( !activeDocHandlers[ "touchstart" ] ) { + $document.unbind( "touchstart", handleTouchStart ) + .unbind( "touchmove", handleTouchMove ) + .unbind( "touchend", handleTouchEnd ) + .unbind( "scroll", handleScroll ); + } + } + + var $this = $( this ), + bindings = $.data( this, dataPropertyName ); // teardown may be called when an element was // removed from the DOM. If this is the case, // jQuery core may have already stripped the element // of any data bindings so we need to check it before // using it. - if (bindings){ - bindings[eventType] = false; + if ( bindings ) { + bindings[ eventType ] = false; } // Unregister the dummy event handler. - $this.unbind(realType, dummyMouseHandler); + $this.unbind( realType, dummyMouseHandler ); // If this is the last virtual mouse binding on the // element, remove the binding data from the element. - if (!hasVirtualBindings(this)){ - $this.removeData(dataPropertyName); + if ( !hasVirtualBindings( this ) ) { + $this.removeData( dataPropertyName ); } } }; @@ -892,21 +881,23 @@ // Expose our custom events to the jQuery bind/unbind mechanism. -for (var i = 0; i < virtualEventNames.length; i++){ - $.event.special[virtualEventNames[i]] = getSpecialEventObject(virtualEventNames[i]); +for ( var i = 0; i < virtualEventNames.length; i++ ){ + $.event.special[ virtualEventNames[ i ] ] = getSpecialEventObject( virtualEventNames[ i ] ); } // Add a capture click handler to block clicks. // Note that we require event capture support for this so if the device // doesn't support it, we punt for now and rely solely on mouse events. -if (eventCaptureSupported){ - document.addEventListener("click", function(e){ - var cnt = clickBlockList.length; - var target = e.target; - if (cnt) { - var x = e.clientX, - y = e.clientY, - threshold = $.vmouse.clickDistanceThreshold; +if ( eventCaptureSupported ) { + document.addEventListener( "click", function( e ){ + var cnt = clickBlockList.length, + target = e.target, + x, y, ele, i, o, touchID; + + if ( cnt ) { + x = e.clientX; + y = e.clientY; + threshold = $.vmouse.clickDistanceThreshold; // The idea here is to run through the clickBlockList to see if // the current click event is in the proximity of one of our @@ -934,13 +925,16 @@ // mouse/click handler on one of its ancestors, the target will be the // innermost child of the touched element, even if that child is no where // near the point of touch. - - var ele = target; - while (ele) { - for (var i = 0; i < cnt; i++) { - var o = clickBlockList[i], - touchID = 0; - if ((ele === target && Math.abs(o.x - x) < threshold && Math.abs(o.y - y) < threshold) || $.data(ele, touchTargetPropertyName) === o.touchID){ + + ele = target; + + while ( ele ) { + for ( i = 0; i < cnt; i++ ) { + o = clickBlockList[ i ]; + touchID = 0; + + if ( ( ele === target && Math.abs( o.x - x ) < threshold && Math.abs( o.y - y ) < threshold ) || + $.data( ele, touchTargetPropertyName ) === o.touchID ) { // XXX: We may want to consider removing matches from the block list // instead of waiting for the reset timer to fire. e.preventDefault(); @@ -953,20 +947,23 @@ } }, true); } -})(jQuery, window, document); +})( jQuery, window, document ); /* * jQuery Mobile Framework : events * Copyright (c) jQuery Project * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license */ -(function($, undefined ) { +(function( $, window, undefined ) { // add new event shortcuts -$.each( "touchstart touchmove touchend orientationchange throttledresize tap taphold swipe swipeleft swiperight scrollstart scrollstop".split( " " ), function( i, name ) { +$.each( ( "touchstart touchmove touchend orientationchange throttledresize " + + "tap taphold swipe swipeleft swiperight scrollstart scrollstop" ).split( " " ), function( i, name ) { + $.fn[ name ] = function( fn ) { return fn ? this.bind( name, fn ) : this.trigger( name ); }; + $.attrFn[ name ] = true; }); @@ -976,8 +973,7 @@ touchStopEvent = supportTouch ? "touchend" : "mouseup", touchMoveEvent = supportTouch ? "touchmove" : "mousemove"; -function triggerCustomEvent(obj, eventType, event) -{ +function triggerCustomEvent( obj, eventType, event ) { var originalType = event.type; event.type = eventType; $.event.handle.call( obj, event ); @@ -986,29 +982,32 @@ // also handles scrollstop $.event.special.scrollstart = { + enabled: true, - + setup: function() { + var thisObject = this, $this = $( thisObject ), scrolling, timer; - + function trigger( event, state ) { scrolling = state; triggerCustomEvent( thisObject, scrolling ? "scrollstart" : "scrollstop", event ); } - + // iPhone triggers scroll after a small delay; use touchmove instead $this.bind( scrollEvent, function( event ) { + if ( !$.event.special.scrollstart.enabled ) { return; } - + if ( !scrolling ) { trigger( event, true ); } - + clearTimeout( timer ); timer = setTimeout(function() { trigger( event, false ); @@ -1022,120 +1021,130 @@ setup: function() { var thisObject = this, $this = $( thisObject ); - - $this - .bind("vmousedown", function( event ) { - if ( event.which && event.which !== 1 ) { - return false; - } - - var touching = true, - origTarget = event.target, - origEvent = event.originalEvent, - timer; - - function clearTapHandlers() { - touching = false; - clearTimeout(timer); - $this.unbind("vclick", clickHandler).unbind("vmousecancel", clearTapHandlers); - } - - function clickHandler(event) { - clearTapHandlers(); - - /* ONLY trigger a 'tap' event if the start target is - * the same as the stop target. - */ - if ( origTarget == event.target ) { - triggerCustomEvent( thisObject, "tap", event ); - } - } - - $this.bind("vmousecancel", clearTapHandlers).bind("vclick", clickHandler); - - timer = setTimeout(function() { - if ( t