960
var // Promise methods
961
promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ),
962
// Static reference to slice
960
// String to Object flags format cache
963
// Convert String-formatted flags into Object-formatted ones and store in cache
964
function createFlags( flags ) {
965
var object = flagsCache[ flags ] = {},
967
flags = flags.split( /\s+/ );
968
for ( i = 0, length = flags.length; i < length; i++ ) {
969
object[ flags[i] ] = true;
975
* Create a callback list using the following parameters:
977
* flags: an optional list of space-separated flags that will change how
978
* the callback list behaves
980
* By default a callback list will act like an event callback list and can be
981
* "fired" multiple times.
985
* once: will ensure the callback list can only be fired once (like a Deferred)
987
* memory: will keep track of previous values and will call any callback added
988
* after the list has been fired right away with the latest "memorized"
989
* values (like a Deferred)
991
* unique: will ensure a callback can only be added once (no duplicate in the list)
993
* stopOnFalse: interrupt callings when a callback returns false
996
jQuery.Callbacks = function( flags ) {
998
// Convert flags from String-formatted to Object-formatted
999
// (we check in cache first)
1000
flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {};
1002
var // Actual callback list
1004
// Stack of fire calls for repeatable lists
1006
// Last fire value (for non-forgettable lists)
1008
// Flag to know if list is currently firing
1010
// First callback to fire (used internally by add and fireWith)
1012
// End of the loop when firing
1014
// Index of currently firing callback (modified by remove if needed)
1016
// Add one or several callbacks to the list
1017
add = function( args ) {
1023
for ( i = 0, length = args.length; i < length; i++ ) {
1025
type = jQuery.type( elem );
1026
if ( type === "array" ) {
1027
// Inspect recursively
1029
} else if ( type === "function" ) {
1030
// Add if not in unique mode and callback is not in
1031
if ( !flags.unique || !self.has( elem ) ) {
1038
fire = function( context, args ) {
1040
memory = !flags.memory || [ context, args ];
1042
firingIndex = firingStart || 0;
1044
firingLength = list.length;
1045
for ( ; list && firingIndex < firingLength; firingIndex++ ) {
1046
if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) {
1047
memory = true; // Mark as halted
1053
if ( !flags.once ) {
1054
if ( stack && stack.length ) {
1055
memory = stack.shift();
1056
self.fireWith( memory[ 0 ], memory[ 1 ] );
1058
} else if ( memory === true ) {
1065
// Actual Callbacks object
1067
// Add a callback or a collection of callbacks to the list
1070
var length = list.length;
1072
// Do we need to add the callbacks to the
1073
// current firing batch?
1075
firingLength = list.length;
1076
// With memory, if we're not firing then
1077
// we should call right away, unless previous
1078
// firing was halted (stopOnFalse)
1079
} else if ( memory && memory !== true ) {
1080
firingStart = length;
1081
fire( memory[ 0 ], memory[ 1 ] );
1086
// Remove a callback from the list
1087
remove: function() {
1089
var args = arguments,
1091
argLength = args.length;
1092
for ( ; argIndex < argLength ; argIndex++ ) {
1093
for ( var i = 0; i < list.length; i++ ) {
1094
if ( args[ argIndex ] === list[ i ] ) {
1095
// Handle firingIndex and firingLength
1097
if ( i <= firingLength ) {
1099
if ( i <= firingIndex ) {
1104
// Remove the element
1105
list.splice( i--, 1 );
1106
// If we have some unicity property then
1107
// we only need to do this once
1108
if ( flags.unique ) {
1117
// Control if a given callback is in the list
1118
has: function( fn ) {
1121
length = list.length;
1122
for ( ; i < length; i++ ) {
1123
if ( fn === list[ i ] ) {
1130
// Remove all callbacks from the list
1135
// Have the list do nothing anymore
1136
disable: function() {
1137
list = stack = memory = undefined;
1141
disabled: function() {
1144
// Lock the list in its current state
1147
if ( !memory || memory === true ) {
1153
locked: function() {
1156
// Call all callbacks with the given context and arguments
1157
fireWith: function( context, args ) {
1160
if ( !flags.once ) {
1161
stack.push( [ context, args ] );
1163
} else if ( !( flags.once && memory ) ) {
1164
fire( context, args );
1169
// Call all the callbacks with the given arguments
1171
self.fireWith( this, arguments );
1174
// To know if the callbacks have already been called at least once
1186
var // Static reference to slice
963
1187
sliceDeferred = [].slice;
966
// Create a simple deferred (one callbacks list)
967
_Deferred: function() {
968
var // callbacks list
970
// stored [ context , args ]
972
// to avoid firing when already doing so
974
// flag to know if the deferred has been cancelled
976
// the deferred itself
979
// done( f1, f2, ...)
982
var args = arguments,
992
for ( i = 0, length = args.length; i < length; i++ ) {
994
type = jQuery.type( elem );
995
if ( type === "array" ) {
996
deferred.done.apply( deferred, elem );
997
} else if ( type === "function" ) {
998
callbacks.push( elem );
1002
deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );
1008
// resolve with given context and args
1009
resolveWith: function( context, args ) {
1010
if ( !cancelled && !fired && !firing ) {
1011
// make sure args are available (#8421)
1015
while( callbacks[ 0 ] ) {
1016
callbacks.shift().apply( context, args );
1020
fired = [ context, args ];
1027
// resolve with this as context and given arguments
1028
resolve: function() {
1029
deferred.resolveWith( this, arguments );
1033
// Has this deferred been resolved?
1034
isResolved: function() {
1035
return !!( firing || fired );
1039
cancel: function() {
1049
// Full fledged deferred (two callbacks list)
1050
1191
Deferred: function( func ) {
1051
var deferred = jQuery._Deferred(),
1052
failDeferred = jQuery._Deferred(),
1054
// Add errorDeferred methods, then and promise
1055
jQuery.extend( deferred, {
1056
then: function( doneCallbacks, failCallbacks ) {
1057
deferred.done( doneCallbacks ).fail( failCallbacks );
1060
always: function() {
1061
return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments );
1063
fail: failDeferred.done,
1064
rejectWith: failDeferred.resolveWith,
1065
reject: failDeferred.resolve,
1066
isRejected: failDeferred.isResolved,
1067
pipe: function( fnDone, fnFail ) {
1068
return jQuery.Deferred(function( newDefer ) {
1070
done: [ fnDone, "resolve" ],
1071
fail: [ fnFail, "reject" ]
1072
}, function( handler, data ) {
1076
if ( jQuery.isFunction( fn ) ) {
1077
deferred[ handler ](function() {
1078
returned = fn.apply( this, arguments );
1079
if ( returned && jQuery.isFunction( returned.promise ) ) {
1080
returned.promise().then( newDefer.resolve, newDefer.reject );
1082
newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] );
1086
deferred[ handler ]( newDefer[ action ] );
1192
var doneList = jQuery.Callbacks( "once memory" ),
1193
failList = jQuery.Callbacks( "once memory" ),
1194
progressList = jQuery.Callbacks( "memory" ),
1199
notify: progressList
1204
progress: progressList.add,
1211
isResolved: doneList.fired,
1212
isRejected: failList.fired,
1214
then: function( doneCallbacks, failCallbacks, progressCallbacks ) {
1215
deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks );
1218
always: function() {
1219
deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments );
1222
pipe: function( fnDone, fnFail, fnProgress ) {
1223
return jQuery.Deferred(function( newDefer ) {
1225
done: [ fnDone, "resolve" ],
1226
fail: [ fnFail, "reject" ],
1227
progress: [ fnProgress, "notify" ]
1228
}, function( handler, data ) {
1232
if ( jQuery.isFunction( fn ) ) {
1233
deferred[ handler ](function() {
1234
returned = fn.apply( this, arguments );
1235
if ( returned && jQuery.isFunction( returned.promise ) ) {
1236
returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify );
1238
newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] );
1242
deferred[ handler ]( newDefer[ action ] );
1247
// Get a promise for this deferred
1248
// If obj is provided, the promise aspect is added to the object
1249
promise: function( obj ) {
1250
if ( obj == null ) {
1253
for ( var key in promise ) {
1254
obj[ key ] = promise[ key ];
1091
// Get a promise for this deferred
1092
// If obj is provided, the promise aspect is added to the object
1093
promise: function( obj ) {
1094
if ( obj == null ) {
1100
var i = promiseMethods.length;
1102
obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ];
1107
// Make sure only one callback list will be used
1108
deferred.done( failDeferred.cancel ).fail( deferred.cancel );
1110
delete deferred.cancel;
1260
deferred = promise.promise({}),
1263
for ( key in lists ) {
1264
deferred[ key ] = lists[ key ].fire;
1265
deferred[ key + "With" ] = lists[ key ].fireWith;
1269
deferred.done( function() {
1271
}, failList.disable, progressList.lock ).fail( function() {
1273
}, doneList.disable, progressList.lock );
1111
1275
// Call given func if any
1113
1277
func.call( deferred, deferred );
1115
1281
return deferred;
1118
1284
// Deferred helper
1119
1285
when: function( firstParam ) {
1120
var args = arguments,
1286
var args = sliceDeferred.call( arguments, 0 ),
1122
1288
length = args.length,
1289
pValues = new Array( length ),
1123
1290
count = length,
1124
1292
deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
1295
promise = deferred.promise();
1127
1296
function resolveFunc( i ) {
1128
1297
return function( value ) {
1129
1298
args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
1130
1299
if ( !( --count ) ) {
1131
// Strange bug in FF4:
1132
// Values changed onto the arguments object sometimes end up as undefined values
1133
// outside the $.when method. Cloning the object into a fresh array solves the issue
1134
deferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) );
1300
deferred.resolveWith( deferred, args );
1304
function progressFunc( i ) {
1305
return function( value ) {
1306
pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
1307
deferred.notifyWith( promise, pValues );
1138
1310
if ( length > 1 ) {
1139
for( ; i < length; i++ ) {
1140
if ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) {
1141
args[ i ].promise().then( resolveFunc(i), deferred.reject );
1311
for ( ; i < length; i++ ) {
1312
if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) {
1313
args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) );
1283
1458
input.setAttribute("checked", "checked");
1284
1459
div.appendChild( input );
1285
1460
fragment = document.createDocumentFragment();
1286
fragment.appendChild( div.firstChild );
1461
fragment.appendChild( div.lastChild );
1288
1463
// WebKit doesn't clone checked state correctly in fragments
1289
1464
support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
1293
// Figure out if the W3C box model works as expected
1294
div.style.width = div.style.paddingLeft = "1px";
1296
body = document.getElementsByTagName( "body" )[ 0 ];
1297
// We use our own, invisible, body unless the body is already present
1298
// in which case we use a div (#9239)
1299
testElement = document.createElement( body ? "div" : "body" );
1300
testElementStyle = {
1301
visibility: "hidden",
1309
jQuery.extend( testElementStyle, {
1310
position: "absolute",
1315
for ( i in testElementStyle ) {
1316
testElement.style[ i ] = testElementStyle[ i ];
1318
testElement.appendChild( div );
1319
testElementParent = body || documentElement;
1320
testElementParent.insertBefore( testElement, testElementParent.firstChild );
1322
1466
// Check if a disconnected checkbox will retain its checked
1323
1467
// value of true after appended to the DOM (IE6/7)
1324
1468
support.appendChecked = input.checked;
1326
support.boxModel = div.offsetWidth === 2;
1328
if ( "zoom" in div.style ) {
1329
// Check if natively block-level elements act like inline-block
1330
// elements when setting their display to 'inline' and giving
1332
// (IE < 8 does this)
1333
div.style.display = "inline";
1335
support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );
1337
// Check if elements with layout shrink-wrap their children
1339
div.style.display = "";
1340
div.innerHTML = "<div style='width:4px;'></div>";
1341
support.shrinkWrapBlocks = ( div.offsetWidth !== 2 );
1344
div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
1345
tds = div.getElementsByTagName( "td" );
1347
// Check if table cells still have offsetWidth/Height when they are set
1348
// to display:none and there are still other visible table cells in a
1349
// table row; if so, offsetWidth/Height are not reliable for use when
1350
// determining if an element has been hidden directly using
1351
// display:none (it is still safe to use offsets if a parent element is
1352
// hidden; don safety goggles and see bug #4512 for more information).
1353
// (only IE 8 fails this test)
1354
isSupported = ( tds[ 0 ].offsetHeight === 0 );
1356
tds[ 0 ].style.display = "";
1357
tds[ 1 ].style.display = "none";
1359
// Check if empty table cells still have offsetWidth/Height
1360
// (IE < 8 fail this test)
1361
support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
1470
fragment.removeChild( input );
1471
fragment.appendChild( div );
1362
1473
div.innerHTML = "";
1364
1475
// Check if div with explicit width and no margin-right incorrectly
1404
// Null connected elements to avoid leaks in IE
1405
testElement = fragment = select = opt = body = marginDiv = div = input = null;
1512
fragment.removeChild( div );
1514
// Null elements to avoid leaks in IE
1515
fragment = select = opt = marginDiv = div = input = null;
1517
// Run tests that need a body at doc ready
1519
var container, outer, inner, table, td, offsetSupport,
1520
conMarginTop, ptlm, vb, style, html,
1521
body = document.getElementsByTagName("body")[0];
1524
// Return for frameset docs that don't have a body
1529
ptlm = "position:absolute;top:0;left:0;width:1px;height:1px;margin:0;";
1530
vb = "visibility:hidden;border:0;";
1531
style = "style='" + ptlm + "border:5px solid #000;padding:0;'";
1532
html = "<div " + style + "><div></div></div>" +
1533
"<table " + style + " cellpadding='0' cellspacing='0'>" +
1534
"<tr><td></td></tr></table>";
1536
container = document.createElement("div");
1537
container.style.cssText = vb + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px";
1538
body.insertBefore( container, body.firstChild );
1540
// Construct the test element
1541
div = document.createElement("div");
1542
container.appendChild( div );
1544
// Check if table cells still have offsetWidth/Height when they are set
1545
// to display:none and there are still other visible table cells in a
1546
// table row; if so, offsetWidth/Height are not reliable for use when
1547
// determining if an element has been hidden directly using
1548
// display:none (it is still safe to use offsets if a parent element is
1549
// hidden; don safety goggles and see bug #4512 for more information).
1550
// (only IE 8 fails this test)
1551
div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
1552
tds = div.getElementsByTagName( "td" );
1553
isSupported = ( tds[ 0 ].offsetHeight === 0 );
1555
tds[ 0 ].style.display = "";
1556
tds[ 1 ].style.display = "none";
1558
// Check if empty table cells still have offsetWidth/Height
1559
// (IE <= 8 fail this test)
1560
support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
1562
// Figure out if the W3C box model works as expected
1564
div.style.width = div.style.paddingLeft = "1px";
1565
jQuery.boxModel = support.boxModel = div.offsetWidth === 2;
1567
if ( typeof div.style.zoom !== "undefined" ) {
1568
// Check if natively block-level elements act like inline-block
1569
// elements when setting their display to 'inline' and giving
1571
// (IE < 8 does this)
1572
div.style.display = "inline";
1574
support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );
1576
// Check if elements with layout shrink-wrap their children
1578
div.style.display = "";
1579
div.innerHTML = "<div style='width:4px;'></div>";
1580
support.shrinkWrapBlocks = ( div.offsetWidth !== 2 );
1583
div.style.cssText = ptlm + vb;
1584
div.innerHTML = html;
1586
outer = div.firstChild;
1587
inner = outer.firstChild;
1588
td = outer.nextSibling.firstChild.firstChild;
1591
doesNotAddBorder: ( inner.offsetTop !== 5 ),
1592
doesAddBorderForTableAndCells: ( td.offsetTop === 5 )
1595
inner.style.position = "fixed";
1596
inner.style.top = "20px";
1598
// safari subtracts parent border width here which is 5px
1599
offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 );
1600
inner.style.position = inner.style.top = "";
1602
outer.style.overflow = "hidden";
1603
outer.style.position = "relative";
1605
offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 );
1606
offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop );
1608
body.removeChild( container );
1609
div = container = null;
1611
jQuery.extend( support, offsetSupport );
1407
1614
return support;
1410
// Keep track of boxModel
1411
jQuery.boxModel = jQuery.support.boxModel;
2572
var rnamespaces = /\.(.*)$/,
2573
rformElems = /^(?:textarea|input|select)$/i,
2576
rescape = /[^\w\s.|`]/g,
2577
fcleanup = function( nm ) {
2578
return nm.replace(rescape, "\\$&");
2807
var rformElems = /^(?:textarea|input|select)$/i,
2808
rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/,
2809
rhoverHack = /\bhover(\.\S+)?\b/,
2811
rmouseEvent = /^(?:mouse|contextmenu)|click/,
2812
rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
2813
rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,
2814
quickParse = function( selector ) {
2815
var quick = rquickIs.exec( selector );
2818
// [ _, tag, id, class ]
2819
quick[1] = ( quick[1] || "" ).toLowerCase();
2820
quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" );
2824
quickIs = function( elem, m ) {
2825
var attrs = elem.attributes || {};
2827
(!m[1] || elem.nodeName.toLowerCase() === m[1]) &&
2828
(!m[2] || (attrs.id || {}).value === m[2]) &&
2829
(!m[3] || m[3].test( (attrs[ "class" ] || {}).value ))
2832
hoverHack = function( events ) {
2833
return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" );
2582
* A number of helper functions used for managing events.
2583
* Many of the ideas behind this code originated from
2584
* Dean Edwards' addEvent library.
2837
* Helper functions for managing events -- not part of the public interface.
2838
* Props to Dean Edwards' addEvent library for many of the ideas.
2586
2840
jQuery.event = {
2588
// Bind an event to an element
2589
// Original by Dean Edwards
2590
add: function( elem, types, handler, data ) {
2591
if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2595
if ( handler === false ) {
2596
handler = returnFalse;
2597
} else if ( !handler ) {
2598
// Fixes bug #7229. Fix recommended by jdalton
2602
var handleObjIn, handleObj;
2842
add: function( elem, types, handler, data, selector ) {
2844
var elemData, eventHandle, events,
2845
t, tns, type, namespaces, handleObj,
2846
handleObjIn, quick, handlers, special;
2848
// Don't attach events to noData or text/comment nodes (allow plain objects tho)
2849
if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) {
2853
// Caller can pass in an object of custom data in lieu of the handler
2604
2854
if ( handler.handler ) {
2605
2855
handleObjIn = handler;
2606
2856
handler = handleObjIn.handler;
2609
// Make sure that the function being executed has a unique ID
2859
// Make sure that the handler has a unique ID, used to find/remove it later
2610
2860
if ( !handler.guid ) {
2611
2861
handler.guid = jQuery.guid++;
2614
// Init the element's event structure
2615
var elemData = jQuery._data( elem );
2617
// If no elemData is found then we must be trying to bind to one of the
2618
// banned noData elements
2623
var events = elemData.events,
2624
eventHandle = elemData.handle;
2864
// Init the element's event structure and main handler, if this is the first
2865
events = elemData.events;
2626
2866
if ( !events ) {
2627
2867
elemData.events = events = {};
2869
eventHandle = elemData.handle;
2630
2870
if ( !eventHandle ) {
2631
2871
elemData.handle = eventHandle = function( e ) {
2632
2872
// Discard the second event of a jQuery.event.trigger() and
2633
2873
// when an event is called after a page has unloaded
2634
2874
return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
2635
jQuery.event.handle.apply( eventHandle.elem, arguments ) :
2875
jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
2878
// Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
2879
eventHandle.elem = elem;
2640
// Add elem as a property of the handle function
2641
// This is to prevent a memory leak with non-native events in IE.
2642
eventHandle.elem = elem;
2644
2882
// Handle multiple events separated by a space
2645
2883
// jQuery(...).bind("mouseover mouseout", fn);
2646
types = types.split(" ");
2648
var type, i = 0, namespaces;
2650
while ( (type = types[ i++ ]) ) {
2651
handleObj = handleObjIn ?
2652
jQuery.extend({}, handleObjIn) :
2653
{ handler: handler, data: data };
2655
// Namespaced event handlers
2656
if ( type.indexOf(".") > -1 ) {
2657
namespaces = type.split(".");
2658
type = namespaces.shift();
2659
handleObj.namespace = namespaces.slice(0).sort().join(".");
2663
handleObj.namespace = "";
2666
handleObj.type = type;
2667
if ( !handleObj.guid ) {
2668
handleObj.guid = handler.guid;
2671
// Get the current list of functions bound to this event
2672
var handlers = events[ type ],
2673
special = jQuery.event.special[ type ] || {};
2675
// Init the event handler queue
2884
types = jQuery.trim( hoverHack(types) ).split( " " );
2885
for ( t = 0; t < types.length; t++ ) {
2887
tns = rtypenamespace.exec( types[t] ) || [];
2889
namespaces = ( tns[2] || "" ).split( "." ).sort();
2891
// If event changes its type, use the special event handlers for the changed type
2892
special = jQuery.event.special[ type ] || {};
2894
// If selector defined, determine special event api type, otherwise given type
2895
type = ( selector ? special.delegateType : special.bindType ) || type;
2897
// Update special based on newly reset type
2898
special = jQuery.event.special[ type ] || {};
2900
// handleObj is passed to all event handlers
2901
handleObj = jQuery.extend({
2908
quick: quickParse( selector ),
2909
namespace: namespaces.join(".")
2912
// Init the event handler queue if we're the first
2913
handlers = events[ type ];
2676
2914
if ( !handlers ) {
2677
2915
handlers = events[ type ] = [];
2916
handlers.delegateCount = 0;
2679
// Check for a special event handler
2680
// Only use addEventListener/attachEvent if the special
2681
// events handler returns false
2918
// Only use addEventListener/attachEvent if the special events handler returns false
2682
2919
if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
2683
2920
// Bind the global event handler to the element
2684
2921
if ( elem.addEventListener ) {
2714
2955
// Detach an event or set of events from an element
2715
remove: function( elem, types, handler, pos ) {
2716
// don't do events on text and comment nodes
2717
if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2721
if ( handler === false ) {
2722
handler = returnFalse;
2725
var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
2726
elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
2727
events = elemData && elemData.events;
2729
if ( !elemData || !events ) {
2733
// types is actually an event object here
2734
if ( types && types.type ) {
2735
handler = types.handler;
2739
// Unbind all events for the element
2740
if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
2741
types = types || "";
2743
for ( type in events ) {
2744
jQuery.event.remove( elem, type + types );
2750
// Handle multiple events separated by a space
2751
// jQuery(...).unbind("mouseover mouseout", fn);
2752
types = types.split(" ");
2754
while ( (type = types[ i++ ]) ) {
2757
all = type.indexOf(".") < 0;
2761
// Namespaced event handlers
2762
namespaces = type.split(".");
2763
type = namespaces.shift();
2765
namespace = new RegExp("(^|\\.)" +
2766
jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
2769
eventType = events[ type ];
2776
for ( j = 0; j < eventType.length; j++ ) {
2777
handleObj = eventType[ j ];
2779
if ( all || namespace.test( handleObj.namespace ) ) {
2780
jQuery.event.remove( elem, origType, handleObj.handler, j );
2781
eventType.splice( j--, 1 );
2956
remove: function( elem, types, handler, selector, mappedTypes ) {
2958
var elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
2959
t, tns, type, origType, namespaces, origCount,
2960
j, events, special, handle, eventType, handleObj;
2962
if ( !elemData || !(events = elemData.events) ) {
2966
// Once for each type.namespace in types; type may be omitted
2967
types = jQuery.trim( hoverHack( types || "" ) ).split(" ");
2968
for ( t = 0; t < types.length; t++ ) {
2969
tns = rtypenamespace.exec( types[t] ) || [];
2970
type = origType = tns[1];
2971
namespaces = tns[2];
2973
// Unbind all events (on this namespace, if provided) for the element
2975
for ( type in events ) {
2976
jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
2788
2981
special = jQuery.event.special[ type ] || {};
2982
type = ( selector? special.delegateType : special.bindType ) || type;
2983
eventType = events[ type ] || [];
2984
origCount = eventType.length;
2985
namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null;
2790
for ( j = pos || 0; j < eventType.length; j++ ) {
2987
// Remove matching events
2988
for ( j = 0; j < eventType.length; j++ ) {
2791
2989
handleObj = eventType[ j ];
2793
if ( handler.guid === handleObj.guid ) {
2794
// remove the given handler for the given type
2795
if ( all || namespace.test( handleObj.namespace ) ) {
2796
if ( pos == null ) {
2797
eventType.splice( j--, 1 );
2991
if ( ( mappedTypes || origType === handleObj.origType ) &&
2992
( !handler || handler.guid === handleObj.guid ) &&
2993
( !namespaces || namespaces.test( handleObj.namespace ) ) &&
2994
( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
2995
eventType.splice( j--, 1 );
2800
if ( special.remove ) {
2801
special.remove.call( elem, handleObj );
2997
if ( handleObj.selector ) {
2998
eventType.delegateCount--;
2805
if ( pos != null ) {
3000
if ( special.remove ) {
3001
special.remove.call( elem, handleObj );
2811
// remove generic event handler if no more handlers exist
2812
if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
3006
// Remove generic event handler if we removed something and no more handlers exist
3007
// (avoids potential for endless recursion during removal of special event handlers)
3008
if ( eventType.length === 0 && origCount !== eventType.length ) {
2813
3009
if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
2814
3010
jQuery.removeEvent( elem, type, elemData.handle );
2818
3013
delete events[ type ];
2822
3017
// Remove the expando if it's no longer used
2823
3018
if ( jQuery.isEmptyObject( events ) ) {
2824
var handle = elemData.handle;
3019
handle = elemData.handle;
2825
3020
if ( handle ) {
2826
3021
handle.elem = null;
2829
delete elemData.events;
2830
delete elemData.handle;
2832
if ( jQuery.isEmptyObject( elemData ) ) {
2833
jQuery.removeData( elem, undefined, true );
3024
// removeData also checks for emptiness and clears the expando if empty
3025
// so use it instead of delete
3026
jQuery.removeData( elem, [ "events", "handle" ], true );
2838
3030
// Events that are safe to short-circuit if no handlers are attached.
2839
3031
// Native DOM events should not be added, they may have inline handlers.
2877
3079
new jQuery.Event( type );
2879
3081
event.type = type;
3082
event.isTrigger = true;
2880
3083
event.exclusive = exclusive;
2881
event.namespace = namespaces.join(".");
2882
event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)");
2884
// triggerHandler() and global events don't bubble or run the default action
2885
if ( onlyHandlers || !elem ) {
2886
event.preventDefault();
2887
event.stopPropagation();
3084
event.namespace = namespaces.join( "." );
3085
event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null;
3086
ontype = type.indexOf( ":" ) < 0 ? "on" + type : "";
2890
3088
// Handle a global trigger
2892
3091
// TODO: Stop taunting the data cache; remove global events and always attach to document
2893
jQuery.each( jQuery.cache, function() {
2894
// internalKey variable is just used to make it easier to find
2895
// and potentially change this stuff later; currently it just
2896
// points to jQuery.expando
2897
var internalKey = jQuery.expando,
2898
internalCache = this[ internalKey ];
2899
if ( internalCache && internalCache.events && internalCache.events[ type ] ) {
2900
jQuery.event.trigger( event, data, internalCache.handle.elem );
3092
cache = jQuery.cache;
3093
for ( i in cache ) {
3094
if ( cache[ i ].events && cache[ i ].events[ type ] ) {
3095
jQuery.event.trigger( event, data, cache[ i ].handle.elem, true );
2906
// Don't do events on text and comment nodes
2907
if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2911
3101
// Clean up the event in case it is being reused
2912
3102
event.result = undefined;
2913
event.target = elem;
3103
if ( !event.target ) {
3104
event.target = elem;
2915
3107
// Clone any incoming data and prepend the event, creating the handler arg list
2916
3108
data = data != null ? jQuery.makeArray( data ) : [];
2917
3109
data.unshift( event );
2920
// IE doesn't like method names with a colon (#3533, #8272)
2921
ontype = type.indexOf(":") < 0 ? "on" + type : "";
2923
// Fire event on the current element, then bubble up the DOM tree
2925
var handle = jQuery._data( cur, "handle" );
2927
event.currentTarget = cur;
3111
// Allow special events to draw outside the lines
3112
special = jQuery.event.special[ type ] || {};
3113
if ( special.trigger && special.trigger.apply( elem, data ) === false ) {
3117
// Determine event propagation path in advance, per W3C events spec (#9951)
3118
// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
3119
eventPath = [[ elem, special.bindType || type ]];
3120
if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
3122
bubbleType = special.delegateType || type;
3123
cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode;
3125
for ( ; cur; cur = cur.parentNode ) {
3126
eventPath.push([ cur, bubbleType ]);
3130
// Only add window if we got to document (e.g., not plain obj or detached DOM)
3131
if ( old && old === elem.ownerDocument ) {
3132
eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]);
3136
// Fire handlers on the event path
3137
for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) {
3139
cur = eventPath[i][0];
3140
event.type = eventPath[i][1];
3142
handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
2928
3143
if ( handle ) {
2929
3144
handle.apply( cur, data );
2932
// Trigger an inline bound script
2933
if ( ontype && jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) {
2934
event.result = false;
3146
// Note that this is a bare JS function and not a jQuery handler
3147
handle = ontype && cur[ ontype ];
3148
if ( handle && jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) {
2935
3149
event.preventDefault();
2938
// Bubble up to document, then to window
2939
cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window;
2940
} while ( cur && !event.isPropagationStopped() );
2942
3154
// If nobody prevented the default action, do it now
2943
if ( !event.isDefaultPrevented() ) {
2945
special = jQuery.event.special[ type ] || {};
3155
if ( !onlyHandlers && !event.isDefaultPrevented() ) {
2947
if ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) &&
3157
if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) &&
2948
3158
!(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
2950
3160
// Call a native DOM method on the target with the same name name as the event.
2951
// Can't use an .isFunction)() check here because IE6/7 fails that test.
2952
// IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch.
2954
if ( ontype && elem[ type ] ) {
2955
// Don't re-trigger an onFOO event when we call its FOO() method
2956
old = elem[ ontype ];
2959
elem[ ontype ] = null;
2962
jQuery.event.triggered = type;
2965
} catch ( ieError ) {}
2968
elem[ ontype ] = old;
3161
// Can't use an .isFunction() check here because IE6/7 fails that test.
3162
// Don't do default actions on window, that's where global variables be (#6170)
3163
// IE<9 dies on focus/blur to hidden element (#1486)
3164
if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) {
3166
// Don't re-trigger an onFOO event when we call its FOO() method
3167
old = elem[ ontype ];
3170
elem[ ontype ] = null;
3173
// Prevent re-triggering of the same event, since we already bubbled it above
3174
jQuery.event.triggered = type;
3176
jQuery.event.triggered = undefined;
3179
elem[ ontype ] = old;
2971
jQuery.event.triggered = undefined;
2975
3185
return event.result;
2978
handle: function( event ) {
3188
dispatch: function( event ) {
3190
// Make a writable jQuery.Event from the native event object
2979
3191
event = jQuery.event.fix( event || window.event );
2980
// Snapshot the handlers list since a called handler may add/remove events.
2981
var handlers = ((jQuery._data( this, "events" ) || {})[ event.type ] || []).slice(0),
3193
var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []),
3194
delegateCount = handlers.delegateCount,
3195
args = [].slice.call( arguments, 0 ),
2982
3196
run_all = !event.exclusive && !event.namespace,
2983
args = Array.prototype.slice.call( arguments, 0 );
3198
i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related;
2985
// Use the fix-ed Event rather than the (read-only) native event
3200
// Use the fix-ed jQuery.Event rather than the (read-only) native event
2986
3201
args[0] = event;
2987
event.currentTarget = this;
2989
for ( var j = 0, l = handlers.length; j < l; j++ ) {
2990
var handleObj = handlers[ j ];
2992
// Triggered event must 1) be non-exclusive and have no namespace, or
2993
// 2) have namespace(s) a subset or equal to those in the bound event.
2994
if ( run_all || event.namespace_re.test( handleObj.namespace ) ) {
2995
// Pass in a reference to the handler function itself
2996
// So that we can later remove it
2997
event.handler = handleObj.handler;
2998
event.data = handleObj.data;
2999
event.handleObj = handleObj;
3001
var ret = handleObj.handler.apply( this, args );
3003
if ( ret !== undefined ) {
3005
if ( ret === false ) {
3006
event.preventDefault();
3007
event.stopPropagation();
3011
if ( event.isImmediatePropagationStopped() ) {
3202
event.delegateTarget = this;
3204
// Determine handlers that should run if there are delegated events
3205
// Avoid disabled elements in IE (#6911) and non-left-click bubbling in Firefox (#3861)
3206
if ( delegateCount && !event.target.disabled && !(event.button && event.type === "click") ) {
3208
// Pregenerate a single jQuery object for reuse with .is()
3209
jqcur = jQuery(this);
3210
jqcur.context = this.ownerDocument || this;
3212
for ( cur = event.target; cur != this; cur = cur.parentNode || this ) {
3216
for ( i = 0; i < delegateCount; i++ ) {
3217
handleObj = handlers[ i ];
3218
sel = handleObj.selector;
3220
if ( selMatch[ sel ] === undefined ) {
3222
handleObj.quick ? quickIs( cur, handleObj.quick ) : jqcur.is( sel )
3225
if ( selMatch[ sel ] ) {
3226
matches.push( handleObj );
3229
if ( matches.length ) {
3230
handlerQueue.push({ elem: cur, matches: matches });
3235
// Add the remaining (directly-bound) handlers
3236
if ( handlers.length > delegateCount ) {
3237
handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) });
3240
// Run delegates first; they may want to stop propagation beneath us
3241
for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) {
3242
matched = handlerQueue[ i ];
3243
event.currentTarget = matched.elem;
3245
for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) {
3246
handleObj = matched.matches[ j ];
3248
// Triggered event must either 1) be non-exclusive and have no namespace, or
3249
// 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
3250
if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) {
3252
event.data = handleObj.data;
3253
event.handleObj = handleObj;
3255
ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
3256
.apply( matched.elem, args );
3258
if ( ret !== undefined ) {
3260
if ( ret === false ) {
3261
event.preventDefault();
3262
event.stopPropagation();
3016
3269
return event.result;
3019
props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
3272
// Includes some event props shared by KeyEvent and MouseEvent
3273
// *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 ***
3274
props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
3279
props: "char charCode key keyCode".split(" "),
3280
filter: function( event, original ) {
3282
// Add which for key events
3283
if ( event.which == null ) {
3284
event.which = original.charCode != null ? original.charCode : original.keyCode;
3292
props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
3293
filter: function( event, original ) {
3294
var eventDoc, doc, body,
3295
button = original.button,
3296
fromElement = original.fromElement;
3298
// Calculate pageX/Y if missing and clientX/Y available
3299
if ( event.pageX == null && original.clientX != null ) {
3300
eventDoc = event.target.ownerDocument || document;
3301
doc = eventDoc.documentElement;
3302
body = eventDoc.body;
3304
event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
3305
event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 );
3308
// Add relatedTarget, if necessary
3309
if ( !event.relatedTarget && fromElement ) {
3310
event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;
3313
// Add which for click: 1 === left; 2 === middle; 3 === right
3314
// Note: button is not normalized, so don't use it
3315
if ( !event.which && button !== undefined ) {
3316
event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
3021
3323
fix: function( event ) {
3022
3324
if ( event[ jQuery.expando ] ) {
3026
// store a copy of the original event object
3027
// and "clone" to set read-only properties
3028
var originalEvent = event;
3328
// Create a writable copy of the event object and normalize some properties
3330
originalEvent = event,
3331
fixHook = jQuery.event.fixHooks[ event.type ] || {},
3332
copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
3029
3334
event = jQuery.Event( originalEvent );
3031
for ( var i = this.props.length, prop; i; ) {
3032
prop = this.props[ --i ];
3336
for ( i = copy.length; i; ) {
3033
3338
event[ prop ] = originalEvent[ prop ];
3036
// Fix target property, if necessary
3341
// Fix target property, if necessary (#1925, IE 6/7/8 & Safari2)
3037
3342
if ( !event.target ) {
3038
// Fixes #1925 where srcElement might not be defined either
3039
event.target = event.srcElement || document;
3343
event.target = originalEvent.srcElement || document;
3042
// check if target is a textnode (safari)
3346
// Target should not be a text node (#504, Safari)
3043
3347
if ( event.target.nodeType === 3 ) {
3044
3348
event.target = event.target.parentNode;
3047
// Add relatedTarget, if necessary
3048
if ( !event.relatedTarget && event.fromElement ) {
3049
event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
3052
// Calculate pageX/Y if missing and clientX/Y available
3053
if ( event.pageX == null && event.clientX != null ) {
3054
var eventDocument = event.target.ownerDocument || document,
3055
doc = eventDocument.documentElement,
3056
body = eventDocument.body;
3058
event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
3059
event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
3062
// Add which for key events
3063
if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
3064
event.which = event.charCode != null ? event.charCode : event.keyCode;
3067
// Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
3068
if ( !event.metaKey && event.ctrlKey ) {
3351
// For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8)
3352
if ( event.metaKey === undefined ) {
3069
3353
event.metaKey = event.ctrlKey;
3072
// Add which for click: 1 === left; 2 === middle; 3 === right
3073
// Note: button is not normalized, so don't use it
3074
if ( !event.which && event.button !== undefined ) {
3075
event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
3356
return fixHook.filter? fixHook.filter( event, originalEvent ) : event;
3081
// Deprecated, use jQuery.guid instead
3084
// Deprecated, use jQuery.proxy instead
3085
proxy: jQuery.proxy,
3089
3361
// Make sure the ready event is setup
3090
setup: jQuery.bindReady,
3091
teardown: jQuery.noop
3095
add: function( handleObj ) {
3096
jQuery.event.add( this,
3097
liveConvert( handleObj.origType, handleObj.selector ),
3098
jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
3101
remove: function( handleObj ) {
3102
jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
3362
setup: jQuery.bindReady
3366
// Prevent triggered image.load events from bubbling to window.load
3371
delegateType: "focusin"
3374
delegateType: "focusout"
3106
3377
beforeunload: {
3216
3512
isImmediatePropagationStopped: returnFalse
3219
// Checks if an event happened on an element within another element
3220
// Used in jQuery.event.special.mouseenter and mouseleave handlers
3221
var withinElement = function( event ) {
3223
// Check if mouse(over|out) are still within the same parent element
3224
var related = event.relatedTarget,
3226
eventType = event.type;
3228
event.type = event.data;
3230
if ( related !== this ) {
3233
inside = jQuery.contains( this, related );
3238
jQuery.event.handle.apply( this, arguments );
3240
event.type = eventType;
3245
// In case of event delegation, we only need to rename the event.type,
3246
// liveHandler will take care of the rest.
3247
delegate = function( event ) {
3248
event.type = event.data;
3249
jQuery.event.handle.apply( this, arguments );
3252
// Create mouseenter and mouseleave events
3515
// Create mouseenter/leave events using mouseover/out and event-time checks
3254
3517
mouseenter: "mouseover",
3255
3518
mouseleave: "mouseout"
3256
3519
}, function( orig, fix ) {
3257
3520
jQuery.event.special[ orig ] = {
3258
setup: function( data ) {
3259
jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
3261
teardown: function( data ) {
3262
jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
3524
handle: function( event ) {
3526
related = event.relatedTarget,
3527
handleObj = event.handleObj,
3528
selector = handleObj.selector,
3531
// For mousenter/leave call the handler if related is outside the target.
3532
// NB: No relatedTarget if the mouse left/entered the browser window
3533
if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
3534
event.type = handleObj.origType;
3535
ret = handleObj.handler.apply( this, arguments );
3267
// submit delegation
3543
// IE submit delegation
3268
3544
if ( !jQuery.support.submitBubbles ) {
3270
3546
jQuery.event.special.submit = {
3271
setup: function( data, namespaces ) {
3272
if ( !jQuery.nodeName( this, "form" ) ) {
3273
jQuery.event.add(this, "click.specialSubmit", function( e ) {
3274
// Avoid triggering error on non-existent type attribute in IE VML (#7071)
3275
var elem = e.target,
3276
type = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.type : "";
3278
if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
3279
trigger( "submit", this, arguments );
3283
jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
3284
var elem = e.target,
3285
type = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.type : "";
3287
if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
3288
trigger( "submit", this, arguments );
3548
// Only need this for delegated form submit events
3549
if ( jQuery.nodeName( this, "form" ) ) {
3553
// Lazy-add a submit handler when a descendant form may potentially be submitted
3554
jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
3555
// Node name check avoids a VML-related crash in IE (#9807)
3556
var elem = e.target,
3557
form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined;
3558
if ( form && !form._submit_attached ) {
3559
jQuery.event.add( form, "submit._submit", function( event ) {
3560
// If form was submitted by the user, bubble the event up the tree
3561
if ( this.parentNode && !event.isTrigger ) {
3562
jQuery.event.simulate( "submit", this.parentNode, event, true );
3565
form._submit_attached = true;
3568
// return undefined since we don't need an event listener
3297
teardown: function( namespaces ) {
3298
jQuery.event.remove( this, ".specialSubmit" );
3571
teardown: function() {
3572
// Only need this for delegated form submit events
3573
if ( jQuery.nodeName( this, "form" ) ) {
3577
// Remove delegated handlers; cleanData eventually reaps submit handlers attached above
3578
jQuery.event.remove( this, "._submit" );
3304
// change delegation, happens here so we have bind.
3583
// IE change delegation and checkbox/radio fix
3305
3584
if ( !jQuery.support.changeBubbles ) {
3309
getVal = function( elem ) {
3310
var type = jQuery.nodeName( elem, "input" ) ? elem.type : "",
3313
if ( type === "radio" || type === "checkbox" ) {
3316
} else if ( type === "select-multiple" ) {
3317
val = elem.selectedIndex > -1 ?
3318
jQuery.map( elem.options, function( elem ) {
3319
return elem.selected;
3323
} else if ( jQuery.nodeName( elem, "select" ) ) {
3324
val = elem.selectedIndex;
3330
testChange = function testChange( e ) {
3331
var elem = e.target, data, val;
3333
if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {
3337
data = jQuery._data( elem, "_change_data" );
3340
// the current data will be also retrieved by beforeactivate
3341
if ( e.type !== "focusout" || elem.type !== "radio" ) {
3342
jQuery._data( elem, "_change_data", val );
3345
if ( data === undefined || val === data ) {
3349
if ( data != null || val ) {
3351
e.liveFired = undefined;
3352
jQuery.event.trigger( e, arguments[1], elem );
3356
3586
jQuery.event.special.change = {
3358
focusout: testChange,
3360
beforedeactivate: testChange,
3362
click: function( e ) {
3363
var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
3365
if ( type === "radio" || type === "checkbox" || jQuery.nodeName( elem, "select" ) ) {
3366
testChange.call( this, e );
3370
// Change has to be called before submit
3371
// Keydown will be called before keypress, which is used in submit-event delegation
3372
keydown: function( e ) {
3373
var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
3375
if ( (e.keyCode === 13 && !jQuery.nodeName( elem, "textarea" ) ) ||
3376
(e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
3377
type === "select-multiple" ) {
3378
testChange.call( this, e );
3382
// Beforeactivate happens also before the previous element is blurred
3383
// with this event you can't trigger a change event, but you can store
3385
beforeactivate: function( e ) {
3590
if ( rformElems.test( this.nodeName ) ) {
3591
// IE doesn't fire change on a check/radio until blur; trigger it on click
3592
// after a propertychange. Eat the blur-change in special.change.handle.
3593
// This still fires onchange a second time for check/radio after blur.
3594
if ( this.type === "checkbox" || this.type === "radio" ) {
3595
jQuery.event.add( this, "propertychange._change", function( event ) {
3596
if ( event.originalEvent.propertyName === "checked" ) {
3597
this._just_changed = true;
3600
jQuery.event.add( this, "click._change", function( event ) {
3601
if ( this._just_changed && !event.isTrigger ) {
3602
this._just_changed = false;
3603
jQuery.event.simulate( "change", this, event, true );
3609
// Delegated event; lazy-add a change handler on descendant inputs
3610
jQuery.event.add( this, "beforeactivate._change", function( e ) {
3386
3611
var elem = e.target;
3387
jQuery._data( elem, "_change_data", getVal(elem) );
3391
setup: function( data, namespaces ) {
3392
if ( this.type === "file" ) {
3396
for ( var type in changeFilters ) {
3397
jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
3400
return rformElems.test( this.nodeName );
3403
teardown: function( namespaces ) {
3404
jQuery.event.remove( this, ".specialChange" );
3613
if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) {
3614
jQuery.event.add( elem, "change._change", function( event ) {
3615
if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
3616
jQuery.event.simulate( "change", this.parentNode, event, true );
3619
elem._change_attached = true;
3624
handle: function( event ) {
3625
var elem = event.target;
3627
// Swallow native change events from checkbox/radio, we already triggered them above
3628
if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {
3629
return event.handleObj.handler.apply( this, arguments );
3633
teardown: function() {
3634
jQuery.event.remove( this, "._change" );
3406
3636
return rformElems.test( this.nodeName );
3410
changeFilters = jQuery.event.special.change.filters;
3412
// Handle when the input is .focus()'d
3413
changeFilters.focus = changeFilters.beforeactivate;
3416
function trigger( type, elem, args ) {
3417
// Piggyback on a donor event to simulate a different one.
3418
// Fake originalEvent to avoid donor's stopPropagation, but if the
3419
// simulated event prevents default then we do the same on the donor.
3420
// Don't pass args or remember liveFired; they apply to the donor event.
3421
var event = jQuery.extend( {}, args[ 0 ] );
3423
event.originalEvent = {};
3424
event.liveFired = undefined;
3425
jQuery.event.handle.call( elem, event );
3426
if ( event.isDefaultPrevented() ) {
3427
args[ 0 ].preventDefault();
3431
3641
// Create "bubbling" focus and blur events
3451
function handler( donor ) {
3452
// Donor event is always a native one; fix it and switch its type.
3453
// Let focusin/out handler cancel the donor focus/blur event.
3454
var e = jQuery.event.fix( donor );
3456
e.originalEvent = {};
3457
jQuery.event.trigger( e, null, e.target );
3458
if ( e.isDefaultPrevented() ) {
3459
donor.preventDefault();
3465
jQuery.each(["bind", "one"], function( i, name ) {
3466
jQuery.fn[ name ] = function( type, data, fn ) {
3469
// Handle object literals
3470
if ( typeof type === "object" ) {
3471
for ( var key in type ) {
3472
this[ name ](key, data, type[key], fn);
3477
if ( arguments.length === 2 || data === false ) {
3482
if ( name === "one" ) {
3483
handler = function( event ) {
3484
jQuery( this ).unbind( event, handler );
3485
return fn.apply( this, arguments );
3668
on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
3671
// Types can be a map of types/handlers
3672
if ( typeof types === "object" ) {
3673
// ( types-Object, selector, data )
3674
if ( typeof selector !== "string" ) {
3675
// ( types-Object, data )
3677
selector = undefined;
3679
for ( type in types ) {
3680
this.on( type, selector, data, types[ type ], one );
3685
if ( data == null && fn == null ) {
3688
data = selector = undefined;
3689
} else if ( fn == null ) {
3690
if ( typeof selector === "string" ) {
3691
// ( types, selector, fn )
3695
// ( types, data, fn )
3698
selector = undefined;
3701
if ( fn === false ) {
3709
fn = function( event ) {
3710
// Can use an empty set, since event contains the info
3711
jQuery().off( event );
3712
return origFn.apply( this, arguments );
3487
handler.guid = fn.guid || jQuery.guid++;
3492
if ( type === "unload" && name !== "one" ) {
3493
this.one( type, data, fn );
3496
for ( var i = 0, l = this.length; i < l; i++ ) {
3497
jQuery.event.add( this[i], type, handler, data );
3714
// Use same guid so caller can remove using origFn
3715
fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
3717
return this.each( function() {
3718
jQuery.event.add( this, types, fn, data, selector );
3721
one: function( types, selector, data, fn ) {
3722
return this.on.call( this, types, selector, data, fn, 1 );
3724
off: function( types, selector, fn ) {
3725
if ( types && types.preventDefault && types.handleObj ) {
3726
// ( event ) dispatched jQuery.Event
3727
var handleObj = types.handleObj;
3728
jQuery( types.delegateTarget ).off(
3729
handleObj.namespace? handleObj.type + "." + handleObj.namespace : handleObj.type,
3735
if ( typeof types === "object" ) {
3736
// ( types-object [, selector] )
3737
for ( var type in types ) {
3738
this.off( type, selector, types[ type ] );
3742
if ( selector === false || typeof selector === "function" ) {
3745
selector = undefined;
3747
if ( fn === false ) {
3750
return this.each(function() {
3751
jQuery.event.remove( this, types, fn, selector );
3755
bind: function( types, data, fn ) {
3756
return this.on( types, null, data, fn );
3758
unbind: function( types, fn ) {
3759
return this.off( types, null, fn );
3762
live: function( types, data, fn ) {
3763
jQuery( this.context ).on( types, this.selector, data, fn );
3506
unbind: function( type, fn ) {
3507
// Handle object literals
3508
if ( typeof type === "object" && !type.preventDefault ) {
3509
for ( var key in type ) {
3510
this.unbind(key, type[key]);
3514
for ( var i = 0, l = this.length; i < l; i++ ) {
3515
jQuery.event.remove( this[i], type, fn );
3766
die: function( types, fn ) {
3767
jQuery( this.context ).off( types, this.selector || "**", fn );
3522
3771
delegate: function( selector, types, data, fn ) {
3523
return this.live( types, data, fn, selector );
3772
return this.on( types, selector, data, fn );
3526
3774
undelegate: function( selector, types, fn ) {
3527
if ( arguments.length === 0 ) {
3528
return this.unbind( "live" );
3531
return this.die( types, null, fn, selector );
3775
// ( namespace ) or ( selector, types [, fn] )
3776
return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn );
3535
3779
trigger: function( type, data ) {
3581
mouseenter: "mouseover",
3582
mouseleave: "mouseout"
3585
jQuery.each(["live", "die"], function( i, name ) {
3586
jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
3587
var type, i = 0, match, namespaces, preType,
3588
selector = origSelector || this.selector,
3589
context = origSelector ? this : jQuery( this.context );
3591
if ( typeof types === "object" && !types.preventDefault ) {
3592
for ( var key in types ) {
3593
context[ name ]( key, data, types[key], selector );
3599
if ( name === "die" && !types &&
3600
origSelector && origSelector.charAt(0) === "." ) {
3602
context.unbind( origSelector );
3607
if ( data === false || jQuery.isFunction( data ) ) {
3608
fn = data || returnFalse;
3612
types = (types || "").split(" ");
3614
while ( (type = types[ i++ ]) != null ) {
3615
match = rnamespaces.exec( type );
3619
namespaces = match[0];
3620
type = type.replace( rnamespaces, "" );
3623
if ( type === "hover" ) {
3624
types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
3630
if ( liveMap[ type ] ) {
3631
types.push( liveMap[ type ] + namespaces );
3632
type = type + namespaces;
3635
type = (liveMap[ type ] || type) + namespaces;
3638
if ( name === "live" ) {
3639
// bind live handler
3640
for ( var j = 0, l = context.length; j < l; j++ ) {
3641
jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
3642
{ data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
3646
// unbind live handler
3647
context.unbind( "live." + liveConvert( type, selector ), fn );
3655
function liveHandler( event ) {
3656
var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
3659
events = jQuery._data( this, "events" );
3661
// Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911)
3662
if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) {
3666
if ( event.namespace ) {
3667
namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
3670
event.liveFired = this;
3672
var live = events.live.slice(0);
3674
for ( j = 0; j < live.length; j++ ) {
3675
handleObj = live[j];
3677
if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
3678
selectors.push( handleObj.selector );
3681
live.splice( j--, 1 );
3685
match = jQuery( event.target ).closest( selectors, event.currentTarget );
3687
for ( i = 0, l = match.length; i < l; i++ ) {
3690
for ( j = 0; j < live.length; j++ ) {
3691
handleObj = live[j];
3693
if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) && !close.elem.disabled ) {
3697
// Those two events require additional checking
3698
if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
3699
event.type = handleObj.preType;
3700
related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
3702
// Make sure not to accidentally match a child element with the same selector
3703
if ( related && jQuery.contains( elem, related ) ) {
3708
if ( !related || related !== elem ) {
3709
elems.push({ elem: elem, handleObj: handleObj, level: close.level });
3715
for ( i = 0, l = elems.length; i < l; i++ ) {
3718
if ( maxLevel && match.level > maxLevel ) {
3722
event.currentTarget = match.elem;
3723
event.data = match.handleObj.data;
3724
event.handleObj = match.handleObj;
3726
ret = match.handleObj.origHandler.apply( match.elem, arguments );
3728
if ( ret === false || event.isPropagationStopped() ) {
3729
maxLevel = match.level;
3731
if ( ret === false ) {
3734
if ( event.isImmediatePropagationStopped() ) {
3743
function liveConvert( type, selector ) {
3744
return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspaces, "&");
3747
3821
jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
3748
3822
"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
3749
"change select submit keydown keypress keyup error").split(" "), function( i, name ) {
3823
"change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
3751
3825
// Handle event binding
3752
3826
jQuery.fn[ name ] = function( data, fn ) {