@ -1,12 +1,12 @@
// Custom hacks:
// * Replaced .bind() calls with .on() for compatibility with jQuery 3
// * Replaced .unbind() calls with .off() for compatibility with jQuery 3
// Local hacks:
// * Replaced all .bind() calls with .on() to avoid jQuery Migrate warnings
// * Replaced all .unbind() calls with .off() to avoid jQuery Migrate warnings
/ *
* jQuery Mobile v1 . 4.5
* jQuery Mobile v1 . 5.0- alpha . 1
* http : //jquerymobile.com
*
* Copyright 2010 , 2014 jQuery Foundation , Inc . and other contributors
* Copyright jQuery Foundation , Inc . and other contributors
* Released under the MIT license .
* http : //jquery.org/license
*
@ -23,7 +23,21 @@
// Browser globals
factory ( root . jQuery , root , doc ) ;
}
} ( this , document , function ( jQuery , window , document , undefined ) { // This plugin is an experiment for abstracting away the touch and mouse
} ( this , document , function ( jQuery , window , document , undefined ) { / * !
* jQuery Mobile Virtual Mouse @ VERSION
* http : //jquerymobile.com
*
* Copyright jQuery Foundation and other contributors
* Released under the MIT license .
* http : //jquery.org/license
* /
//>>label: Virtual Mouse (vmouse) Bindings
//>>group: Core
//>>description: Normalizes touch/mouse events.
//>>docs: http://api.jquerymobile.com/?s=vmouse
// This plugin is an experiment for abstracting away the touch and mouse
// events so that developers don't have to worry about which method of input
// the device their document is loaded on supports.
//
@ -38,14 +52,26 @@
// The current version exposes the following virtual events to jQuery bind methods:
// "vmouseover vmousedown vmousemove vmouseup vclick vmouseout vmousecancel"
( function ( $ , window , document , undefined ) {
( function ( factory ) {
if ( typeof define === "function" && define . amd ) {
// AMD. Register as an anonymous module.
define ( 'vmouse' , [ "jquery" ] , factory ) ;
} else {
// Browser globals
factory ( jQuery ) ;
}
} ) ( function ( $ ) {
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 ( " " ) ,
generalProps = ( "altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " +
"metaKey relatedTarget shiftKey target timeStamp view which" ) . split ( " " ) ,
mouseHookProps = $ . event . mouseHooks ? $ . event . mouseHooks . props : [ ] ,
mouseEventProps = $ . event . props . concat ( mouseHookProps ) ,
mouseEventProps = generalP rops. concat ( mouseHookProps ) ,
activeDocHandlers = { } ,
resetTimerID = 0 ,
startX = 0 ,
@ -63,7 +89,8 @@ var dataPropertyName = "virtualMouseBindings",
$ . vmouse = {
moveDistanceThreshold : 10 ,
clickDistanceThreshold : 10 ,
resetTimerDuration : 1500
resetTimerDuration : 1500 ,
maximumTimeBetweenTouches : 100
} ;
function getNativeEvent ( event ) {
@ -83,7 +110,7 @@ function createVirtualEvent( event, eventType ) {
event . type = eventType ;
oe = event . originalEvent ;
props = $. event . p rops;
props = generalP rops;
// addresses separation of $.event.props in to $.event.mouseHook.props and Issue 3280
// https://github.com/jquery/jquery-mobile/issues/3280
@ -95,7 +122,7 @@ function createVirtualEvent( event, eventType ) {
// 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 ( i = props . length , prop ; i ; ) {
for ( i = props . length ; i ; ) {
prop = props [ -- i ] ;
event [ prop ] = oe [ prop ] ;
}
@ -103,18 +130,18 @@ function createVirtualEvent( event, eventType ) {
// make sure that if the mouse and click virtual events are generated
// without a .which one is defined
if ( t . search ( /mouse(down|up)|click/ ) > - 1 && ! event . which ) {
if ( t . search ( /mouse(down|up)|click/ ) > - 1 && ! event . which ) {
event . which = 1 ;
}
if ( t . search ( /^touch/ ) !== - 1 ) {
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 ) ;
touch = ( t && t . length ) ? t [ 0 ] : ( ( ct && ct . length ) ? ct [ 0 ] : undefined ) ;
if ( touch ) {
for ( j = 0 , len = touchEventProps . length ; j < len ; j ++ ) {
for ( j = 0 , len = touchEventProps . length ; j < len ; j ++ ) {
prop = touchEventProps [ j ] ;
event [ prop ] = touch [ prop ] ;
}
@ -181,6 +208,13 @@ function disableMouseBindings() {
enableTouchBindings ( ) ;
}
function clearResetTimer ( ) {
if ( resetTimerID ) {
clearTimeout ( resetTimerID ) ;
resetTimerID = 0 ;
}
}
function startResetTimer ( ) {
clearResetTimer ( ) ;
resetTimerID = setTimeout ( function ( ) {
@ -189,13 +223,6 @@ function startResetTimer() {
} , $ . vmouse . resetTimerDuration ) ;
}
function clearResetTimer ( ) {
if ( resetTimerID ) {
clearTimeout ( resetTimerID ) ;
resetTimerID = 0 ;
}
}
function triggerVirtualEvent ( eventType , event , flags ) {
var ve ;
@ -204,7 +231,7 @@ function triggerVirtualEvent( eventType, event, flags ) {
ve = createVirtualEvent ( event , eventType ) ;
$ ( event . target ) . trigger ( ve ) ;
$ ( event . target ) . trigger ( ve ) ;
}
return ve ;
@ -214,6 +241,22 @@ function mouseEventCallback( event ) {
var touchID = $ . data ( event . target , touchTargetPropertyName ) ,
ve ;
// It is unexpected if a click event is received before a touchend
// or touchmove event, however this is a known behavior in Mobile
// Safari when Mobile VoiceOver (as of iOS 8) is enabled and the user
// double taps to activate a link element. In these cases if a touch
// event is not received within the maximum time between touches,
// re-enable mouse bindings and call the mouse event handler again.
if ( event . type === "click" && $ . data ( event . target , "lastTouchType" ) === "touchstart" ) {
setTimeout ( function ( ) {
if ( $ . data ( event . target , "lastTouchType" ) === "touchstart" ) {
enableMouseBindings ( ) ;
delete $ . data ( event . target ) . lastTouchType ;
mouseEventCallback ( event ) ;
}
} , $ . vmouse . maximumTimeBetweenTouches ) ;
}
if ( ! blockMouseTriggers && ( ! lastTouchID || lastTouchID !== touchID ) ) {
ve = triggerVirtualEvent ( "v" + event . type , event ) ;
if ( ve ) {
@ -240,6 +283,8 @@ function handleTouchStart( event ) {
target = event . target ;
flags = getVirtualBindingFlags ( target ) ;
$ . data ( event . target , "lastTouchType" , event . type ) ;
if ( flags . hasVirtualBinding ) {
lastTouchID = nextTouchID ++ ;
@ -269,6 +314,8 @@ function handleScroll( event ) {
triggerVirtualEvent ( "vmousecancel" , event , getVirtualBindingFlags ( event . target ) ) ;
}
$ . data ( event . target , "lastTouchType" , event . type ) ;
didScroll = true ;
startResetTimer ( ) ;
}
@ -283,6 +330,8 @@ function handleTouchMove( event ) {
moveThreshold = $ . vmouse . moveDistanceThreshold ,
flags = getVirtualBindingFlags ( event . target ) ;
$ . data ( event . target , "lastTouchType" , event . type ) ;
didScroll = didScroll ||
( Math . abs ( t . pageX - startX ) > moveThreshold ||
Math . abs ( t . pageY - startY ) > moveThreshold ) ;
@ -296,11 +345,12 @@ function handleTouchMove( event ) {
}
function handleTouchEnd ( event ) {
if ( blockTouchTriggers ) {
if ( blockTouchTriggers || $ . data ( event . target , "lastTouchType" ) === undefined ) {
return ;
}
disableTouchBindings ( ) ;
delete $ . data ( event . target ) . lastTouchType ;
var flags = getVirtualBindingFlags ( event . target ) ,
ve , t ;
@ -314,18 +364,18 @@ function handleTouchEnd( event ) {
// touch. This means we need to rely on coordinates for blocking
// any click that is generated.
t = getNativeEvent ( event ) . changedTouches [ 0 ] ;
clickBlockList . push ( {
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 ( ) ;
@ -345,13 +395,14 @@ function hasVirtualBindings( ele ) {
return false ;
}
function dummyMouseHandler ( ) { }
function dummyMouseHandler ( ) {
}
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.
@ -384,7 +435,7 @@ function getSpecialEventObject( eventType ) {
// If this is the first virtual mouse binding for the document,
// register our touchstart handler on the document.
activeDocHandlers [ "touchstart" ] = ( activeDocHandlers [ "touchstart" ] || 0 ) + 1 ;
activeDocHandlers [ "touchstart" ] = ( activeDocHandlers [ "touchstart" ] || 0 ) + 1 ;
if ( activeDocHandlers [ "touchstart" ] === 1 ) {
$document . on ( "touchstart" , handleTouchStart )
@ -406,11 +457,11 @@ function getSpecialEventObject( eventType ) {
}
} ,
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 ] ;
-- activeDocHandlers [ eventType ] ;
if ( ! activeDocHandlers [ eventType ] ) {
$document . off ( realType , mouseEventCallback ) ;
@ -420,7 +471,7 @@ function getSpecialEventObject( eventType ) {
// If this is the last virtual mouse binding in existence,
// remove our document touchstart listener.
-- activeDocHandlers [ "touchstart" ] ;
-- activeDocHandlers [ "touchstart" ] ;
if ( ! activeDocHandlers [ "touchstart" ] ) {
$document . off ( "touchstart" , handleTouchStart )
@ -522,38 +573,115 @@ if ( eventCaptureSupported ) {
ele = ele . parentNode ;
}
}
} , true ) ;
} , true ) ;
}
} ) ( jQuery , window , document ) ;
} ) ;
/ * !
* jQuery Mobile Namespace @ VERSION
* http : //jquerymobile.com
*
* Copyright jQuery Foundation and other contributors
* Released under the MIT license .
* http : //jquery.org/license
* /
//>>label: Namespace
//>>group: Core
//>>description: The mobile namespace on the jQuery object
( function ( factory ) {
if ( typeof define === "function" && define . amd ) {
// AMD. Register as an anonymous module.
define ( 'ns' , [ "jquery" ] , factory ) ;
} else {
( function ( $ ) {
$ . mobile = { } ;
} ( jQuery ) ) ;
// Browser globals
factory ( jQuery ) ;
}
} ) ( function ( $ ) {
$ . mobile = { version : "@VERSION" } ;
return $ . mobile ;
} ) ;
/ * !
* jQuery Mobile Touch Support Test @ VERSION
* http : //jquerymobile.com
*
* Copyright jQuery Foundation and other contributors
* Released under the MIT license .
* http : //jquery.org/license
* /
//>>label: Touch support test
//>>group: Core
//>>description: Touch feature test
( function ( factory ) {
if ( typeof define === "function" && define . amd ) {
// AMD. Register as an anonymous module.
define ( 'support/touch' , [
"jquery" ,
"../ns" ] , factory ) ;
} else {
// Browser globals
factory ( jQuery ) ;
}
} ) ( function ( $ ) {
( function ( $ , undefined ) {
var support = {
var support = {
touch : "ontouchend" in document
} ;
} ;
$ . mobile . support = $ . mobile . support || { } ;
$ . extend ( $ . support , support ) ;
$ . extend ( $ . mobile . support , support ) ;
$ . mobile . support = $ . mobile . support || { } ;
$ . extend ( $ . support , support ) ;
$ . extend ( $ . mobile . support , support ) ;
} ( jQuery ) ) ;
return $ . support ;
} ) ;
/ * !
* jQuery Mobile Touch Events @ VERSION
* http : //jquerymobile.com
*
* Copyright jQuery Foundation and other contributors
* Released under the MIT license .
* http : //jquery.org/license
* /
//>>label: Touch
//>>group: Events
//>>description: Touch events including: touchstart, touchmove, touchend, tap, taphold, swipe, swipeleft, swiperight
( function ( factory ) {
if ( typeof define === "function" && define . amd ) {
( function ( $ , window , undefined ) {
var $document = $ ( document ) ,
// AMD. Register as an anonymous module.
define ( 'events/touch' , [
"jquery" ,
"../vmouse" ,
"../support/touch" ] , factory ) ;
} else {
// Browser globals
factory ( jQuery ) ;
}
} ) ( function ( $ ) {
var $document = $ ( document ) ,
supportTouch = $ . mobile . support . touch ,
scrollEvent = "touchmove scroll" ,
touchStartEvent = supportTouch ? "touchstart" : "mousedown" ,
touchStopEvent = supportTouch ? "touchend" : "mouseup" ,
touchMoveEvent = supportTouch ? "touchmove" : "mousemove" ;
// setup new event shortcuts
$ . each ( ( "touchstart touchmove touchend " +
"tap taphold " +
"swipe swipeleft swiperight " +
"scrollstart scrollstop" ) . split ( " " ) , function ( i , name ) {
// setup new event shortcuts
$ . each ( ( "touchstart touchmove touchend " +
"tap taphold " +
"swipe swipeleft swiperight" ) . split ( " " ) , function ( i , name ) {
$ . fn [ name ] = function ( fn ) {
return fn ? this . on ( name , fn ) : this . trigger ( name ) ;
@ -563,9 +691,9 @@ if ( eventCaptureSupported ) {
if ( $ . attrFn ) {
$ . attrFn [ name ] = true ;
}
} ) ;
} ) ;
function triggerCustomEvent ( obj , eventType , event , bubble ) {
function triggerCustomEvent ( obj , eventType , event , bubble ) {
var originalType = event . type ;
event . type = eventType ;
if ( bubble ) {
@ -574,48 +702,10 @@ if ( eventCaptureSupported ) {
$ . event . dispatch . call ( obj , event ) ;
}
event . type = originalType ;
}
// 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 . on ( scrollEvent , function ( event ) {
if ( ! $ . event . special . scrollstart . enabled ) {
return ;
}
if ( ! scrolling ) {
trigger ( event , true ) ;
}
clearTimeout ( timer ) ;
timer = setTimeout ( function ( ) {
trigger ( event , false ) ;
} , 50 ) ;
} ) ;
} ,
teardown : function ( ) {
$ ( this ) . off ( scrollEvent ) ;
}
} ;
}
// also handles taphold
$ . event . special . tap = {
// also handles taphold
$ . event . special . tap = {
tapholdThreshold : 750 ,
emitTapOnTaphold : true ,
setup : function ( ) {
@ -626,15 +716,18 @@ if ( eventCaptureSupported ) {
$this . on ( "vmousedown" , function ( event ) {
isTaphold = false ;
if ( event . which && event . which !== 1 ) {
return fals e;
return tru e;
}
var origTarget = event . target ,
tim er;
tim er, clickHandl er;
function clearTapTimer ( ) {
if ( timer ) {
$this . on ( "vclick" , clickHandler ) ;
clearTimeout ( timer ) ;
}
}
function clearTapHandlers ( ) {
clearTapTimer ( ) ;
@ -644,7 +737,7 @@ if ( eventCaptureSupported ) {
$document . off ( "vmousecancel" , clearTapHandlers ) ;
}
function clickHandler ( event ) {
clickHandler = function ( event ) {
clearTapHandlers ( ) ;
// ONLY trigger a 'tap' event if the start target is
@ -654,28 +747,29 @@ if ( eventCaptureSupported ) {
} else if ( isTaphold ) {
event . preventDefault ( ) ;
}
}
} ;
$this . on ( "vmouseup" , clearTapTimer ) ;
$this . on ( "vmouseup" , clearTapTimer )
. on ( "vclick" , clickHandler ) ;
$document . on ( "vmousecancel" , clearTapHandlers ) ;
timer = setTimeout ( function ( ) {
if ( ! $ . event . special . tap . emitTapOnTaphold ) {
isTaphold = true ;
}
timer = 0 ;
triggerCustomEvent ( thisObject , "taphold" , $ . Event ( "taphold" , { target : origTarget } ) ) ;
} , $ . event . special . tap . tapholdThreshold ) ;
} ) ;
} ) ;
} ,
teardown : function ( ) {
$ ( this ) . off ( "vmousedown" ) . off ( "vclick" ) . off ( "vmouseup" ) ;
$document . off ( "vmousecancel" ) ;
}
} ;
} ;
// Also handles swipeleft, swiperight
$ . event . special . swipe = {
// Also handles swipeleft, swiperight
$ . event . special . swipe = {
// More than this horizontal displacement, and we will suppress scrolling.
scrollSupressionThreshold : 30 ,
@ -684,12 +778,12 @@ if ( eventCaptureSupported ) {
durationThreshold : 1000 ,
// Swipe horizontal displacement must be more than this.
horizontalDistanceThreshold : 30 ,
horizontalDistanceThreshold : window . devicePixelRatio >= 2 ? 15 : 30 ,
// Swipe vertical displacement must be less than this.
verticalDistanceThreshold : 30 ,
verticalDistanceThreshold : window . devicePixelRatio >= 2 ? 15 : 30 ,
getLocation : function ( event ) {
getLocation : function ( event ) {
var winPageX = window . pageXOffset ,
winPageY = window . pageYOffset ,
x = event . clientX ,
@ -702,7 +796,7 @@ if ( eventCaptureSupported ) {
// in pageX/pageY. While pageX/page/ have the value 0
x = x - winPageX ;
y = y - winPageY ;
} else if ( y < ( event . pageY - winPageY ) || x < ( event . pageX - winPageX ) ) {
} else if ( y < ( event . pageY - winPageY ) || x < ( event . pageX - winPageX ) ) {
// Some Android browsers have totally bogus values for clientX/Y
// when scrolling/zooming a page. Detectable since clientX/clientY
@ -742,10 +836,10 @@ if ( eventCaptureSupported ) {
if ( stop . time - start . time < $ . event . special . swipe . durationThreshold &&
Math . abs ( start . coords [ 0 ] - stop . coords [ 0 ] ) > $ . event . special . swipe . horizontalDistanceThreshold &&
Math . abs ( start . coords [ 1 ] - stop . coords [ 1 ] ) < $ . event . special . swipe . verticalDistanceThreshold ) {
var direction = start . coords [ 0 ] > stop . coords [ 0 ] ? "swipeleft" : "swiperight" ;
var direction = start . coords [ 0 ] > stop . coords [ 0 ] ? "swipeleft" : "swiperight" ;
triggerCustomEvent ( thisObject , "swipe" , $ . Event ( "swipe" , { target : origTarget , swipestart : start , swipestop : stop } ) , true ) ;
triggerCustomEvent ( thisObject , direction , $ . Event ( direction , { target : origTarget , swipestart : start , swipestop : stop } ) , true ) ;
triggerCustomEvent ( thisObject , "swipe" , $ . Event ( "swipe" , { target : origTarget , swipestart : start , swipestop : stop } ) , true ) ;
triggerCustomEvent ( thisObject , direction , $ . Event ( direction , { target : origTarget , swipestart : start , swipestop : stop } ) , true ) ;
return true ;
}
return false ;
@ -844,13 +938,12 @@ if ( eventCaptureSupported ) {
}
}
}
} ;
$ . each ( {
scrollstop : "scrollstart" ,
} ;
$ . each ( {
taphold : "tap" ,
swipeleft : "swipe.left" ,
swiperight : "swipe.right"
} , function ( event , sourceEvent ) {
} , function ( event , sourceEvent ) {
$ . event . special [ event ] = {
setup : function ( ) {
@ -860,9 +953,11 @@ if ( eventCaptureSupported ) {
$ ( this ) . off ( sourceEvent ) ;
}
} ;
} ) ;
} ) ;
return $ . event . special ;
} ) ;
} ) ( jQuery , this ) ;
} ) ) ;