8 "./data/var/data_priv",
13 ], function( jQuery
, strundefined
, rnotwhite
, hasOwn
, slice
, support
, data_priv
) {
17 rmouseEvent
= /^(?:mouse|pointer|contextmenu)|click/,
18 rfocusMorph
= /^(?:focusinfocus|focusoutblur)$/,
19 rtypenamespace
= /^([^.]*)(?:\.(.+)|)$/;
21 function returnTrue() {
25 function returnFalse() {
29 function safeActiveElement() {
31 return document
.activeElement
;
36 * Helper functions for managing events -- not part of the public interface.
37 * Props to Dean Edwards' addEvent library for many of the ideas.
43 add: function( elem
, types
, handler
, data
, selector
) {
45 var handleObjIn
, eventHandle
, tmp
,
47 special
, handlers
, type
, namespaces
, origType
,
48 elemData
= data_priv
.get( elem
);
50 // Don't attach events to noData or text/comment nodes (but allow plain objects)
55 // Caller can pass in an object of custom data in lieu of the handler
56 if ( handler
.handler
) {
57 handleObjIn
= handler
;
58 handler
= handleObjIn
.handler
;
59 selector
= handleObjIn
.selector
;
62 // Make sure that the handler has a unique ID, used to find/remove it later
63 if ( !handler
.guid
) {
64 handler
.guid
= jQuery
.guid
++;
67 // Init the element's event structure and main handler, if this is the first
68 if ( !(events
= elemData
.events
) ) {
69 events
= elemData
.events
= {};
71 if ( !(eventHandle
= elemData
.handle
) ) {
72 eventHandle
= elemData
.handle = function( e
) {
73 // Discard the second event of a jQuery.event.trigger() and
74 // when an event is called after a page has unloaded
75 return typeof jQuery
!== strundefined
&& jQuery
.event
.triggered
!== e
.type
?
76 jQuery
.event
.dispatch
.apply( elem
, arguments
) : undefined;
80 // Handle multiple events separated by a space
81 types
= ( types
|| "" ).match( rnotwhite
) || [ "" ];
84 tmp
= rtypenamespace
.exec( types
[t
] ) || [];
85 type
= origType
= tmp
[1];
86 namespaces
= ( tmp
[2] || "" ).split( "." ).sort();
88 // There *must* be a type, no attaching namespace-only handlers
93 // If event changes its type, use the special event handlers for the changed type
94 special
= jQuery
.event
.special
[ type
] || {};
96 // If selector defined, determine special event api type, otherwise given type
97 type
= ( selector
? special
.delegateType : special
.bindType
) || type
;
99 // Update special based on newly reset type
100 special
= jQuery
.event
.special
[ type
] || {};
102 // handleObj is passed to all event handlers
103 handleObj
= jQuery
.extend({
110 needsContext: selector
&& jQuery
.expr
.match
.needsContext
.test( selector
),
111 namespace: namespaces
.join(".")
114 // Init the event handler queue if we're the first
115 if ( !(handlers
= events
[ type
]) ) {
116 handlers
= events
[ type
] = [];
117 handlers
.delegateCount
= 0;
119 // Only use addEventListener if the special events handler returns false
120 if ( !special
.setup
|| special
.setup
.call( elem
, data
, namespaces
, eventHandle
) === false ) {
121 if ( elem
.addEventListener
) {
122 elem
.addEventListener( type
, eventHandle
, false );
128 special
.add
.call( elem
, handleObj
);
130 if ( !handleObj
.handler
.guid
) {
131 handleObj
.handler
.guid
= handler
.guid
;
135 // Add to the element's handler list, delegates in front
137 handlers
.splice( handlers
.delegateCount
++, 0, handleObj
);
139 handlers
.push( handleObj
);
142 // Keep track of which events have ever been used, for event optimization
143 jQuery
.event
.global
[ type
] = true;
148 // Detach an event or set of events from an element
149 remove: function( elem
, types
, handler
, selector
, mappedTypes
) {
151 var j
, origCount
, tmp
,
152 events
, t
, handleObj
,
153 special
, handlers
, type
, namespaces
, origType
,
154 elemData
= data_priv
.hasData( elem
) && data_priv
.get( elem
);
156 if ( !elemData
|| !(events
= elemData
.events
) ) {
160 // Once for each type.namespace in types; type may be omitted
161 types
= ( types
|| "" ).match( rnotwhite
) || [ "" ];
164 tmp
= rtypenamespace
.exec( types
[t
] ) || [];
165 type
= origType
= tmp
[1];
166 namespaces
= ( tmp
[2] || "" ).split( "." ).sort();
168 // Unbind all events (on this namespace, if provided) for the element
170 for ( type
in events
) {
171 jQuery
.event
.remove( elem
, type
+ types
[ t
], handler
, selector
, true );
176 special
= jQuery
.event
.special
[ type
] || {};
177 type
= ( selector
? special
.delegateType : special
.bindType
) || type
;
178 handlers
= events
[ type
] || [];
179 tmp
= tmp
[2] && new RegExp( "(^|\\.)" + namespaces
.join("\\.(?:.*\\.|)") + "(\\.|$)" );
181 // Remove matching events
182 origCount
= j
= handlers
.length
;
184 handleObj
= handlers
[ j
];
186 if ( ( mappedTypes
|| origType
=== handleObj
.origType
) &&
187 ( !handler
|| handler
.guid
=== handleObj
.guid
) &&
188 ( !tmp
|| tmp
.test( handleObj
.namespace ) ) &&
189 ( !selector
|| selector
=== handleObj
.selector
|| selector
=== "**" && handleObj
.selector
) ) {
190 handlers
.splice( j
, 1 );
192 if ( handleObj
.selector
) {
193 handlers
.delegateCount
--;
195 if ( special
.remove
) {
196 special
.remove
.call( elem
, handleObj
);
201 // Remove generic event handler if we removed something and no more handlers exist
202 // (avoids potential for endless recursion during removal of special event handlers)
203 if ( origCount
&& !handlers
.length
) {
204 if ( !special
.teardown
|| special
.teardown
.call( elem
, namespaces
, elemData
.handle
) === false ) {
205 jQuery
.removeEvent( elem
, type
, elemData
.handle
);
208 delete events
[ type
];
212 // Remove the expando if it's no longer used
213 if ( jQuery
.isEmptyObject( events
) ) {
214 delete elemData
.handle
;
215 data_priv
.remove( elem
, "events" );
219 trigger: function( event
, data
, elem
, onlyHandlers
) {
221 var i
, cur
, tmp
, bubbleType
, ontype
, handle
, special
,
222 eventPath
= [ elem
|| document
],
223 type
= hasOwn
.call( event
, "type" ) ? event
.type : event
,
224 namespaces
= hasOwn
.call( event
, "namespace" ) ? event
.namespace.split(".") : [];
226 cur
= tmp
= elem
= elem
|| document
;
228 // Don't do events on text and comment nodes
229 if ( elem
.nodeType
=== 3 || elem
.nodeType
=== 8 ) {
233 // focus/blur morphs to focusin/out; ensure we're not firing them right now
234 if ( rfocusMorph
.test( type
+ jQuery
.event
.triggered
) ) {
238 if ( type
.indexOf(".") >= 0 ) {
239 // Namespaced trigger; create a regexp to match event type in handle()
240 namespaces
= type
.split(".");
241 type
= namespaces
.shift();
244 ontype
= type
.indexOf(":") < 0 && "on" + type
;
246 // Caller can pass in a jQuery.Event object, Object, or just an event type string
247 event
= event
[ jQuery
.expando
] ?
249 new jQuery
.Event( type
, typeof event
=== "object" && event
);
251 // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
252 event
.isTrigger
= onlyHandlers
? 2 : 3;
253 event
.namespace = namespaces
.join(".");
254 event
.namespace_re
= event
.namespace ?
255 new RegExp( "(^|\\.)" + namespaces
.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
258 // Clean up the event in case it is being reused
259 event
.result
= undefined;
260 if ( !event
.target
) {
264 // Clone any incoming data and prepend the event, creating the handler arg list
265 data
= data
== null ?
267 jQuery
.makeArray( data
, [ event
] );
269 // Allow special events to draw outside the lines
270 special
= jQuery
.event
.special
[ type
] || {};
271 if ( !onlyHandlers
&& special
.trigger
&& special
.trigger
.apply( elem
, data
) === false ) {
275 // Determine event propagation path in advance, per W3C events spec (#9951)
276 // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
277 if ( !onlyHandlers
&& !special
.noBubble
&& !jQuery
.isWindow( elem
) ) {
279 bubbleType
= special
.delegateType
|| type
;
280 if ( !rfocusMorph
.test( bubbleType
+ type
) ) {
281 cur
= cur
.parentNode
;
283 for ( ; cur
; cur
= cur
.parentNode
) {
284 eventPath
.push( cur
);
288 // Only add window if we got to document (e.g., not plain obj or detached DOM)
289 if ( tmp
=== (elem
.ownerDocument
|| document
) ) {
290 eventPath
.push( tmp
.defaultView
|| tmp
.parentWindow
|| window
);
294 // Fire handlers on the event path
296 while ( (cur
= eventPath
[i
++]) && !event
.isPropagationStopped() ) {
300 special
.bindType
|| type
;
303 handle
= ( data_priv
.get( cur
, "events" ) || {} )[ event
.type
] && data_priv
.get( cur
, "handle" );
305 handle
.apply( cur
, data
);
309 handle
= ontype
&& cur
[ ontype
];
310 if ( handle
&& handle
.apply
&& jQuery
.acceptData( cur
) ) {
311 event
.result
= handle
.apply( cur
, data
);
312 if ( event
.result
=== false ) {
313 event
.preventDefault();
319 // If nobody prevented the default action, do it now
320 if ( !onlyHandlers
&& !event
.isDefaultPrevented() ) {
322 if ( (!special
._default
|| special
._default
.apply( eventPath
.pop(), data
) === false) &&
323 jQuery
.acceptData( elem
) ) {
325 // Call a native DOM method on the target with the same name name as the event.
326 // Don't do default actions on window, that's where global variables be (#6170)
327 if ( ontype
&& jQuery
.isFunction( elem
[ type
] ) && !jQuery
.isWindow( elem
) ) {
329 // Don't re-trigger an onFOO event when we call its FOO() method
330 tmp
= elem
[ ontype
];
333 elem
[ ontype
] = null;
336 // Prevent re-triggering of the same event, since we already bubbled it above
337 jQuery
.event
.triggered
= type
;
339 jQuery
.event
.triggered
= undefined;
342 elem
[ ontype
] = tmp
;
351 dispatch: function( event
) {
353 // Make a writable jQuery.Event from the native event object
354 event
= jQuery
.event
.fix( event
);
356 var i
, j
, ret
, matched
, handleObj
,
358 args
= slice
.call( arguments
),
359 handlers
= ( data_priv
.get( this, "events" ) || {} )[ event
.type
] || [],
360 special
= jQuery
.event
.special
[ event
.type
] || {};
362 // Use the fix-ed jQuery.Event rather than the (read-only) native event
364 event
.delegateTarget
= this;
366 // Call the preDispatch hook for the mapped type, and let it bail if desired
367 if ( special
.preDispatch
&& special
.preDispatch
.call( this, event
) === false ) {
371 // Determine handlers
372 handlerQueue
= jQuery
.event
.handlers
.call( this, event
, handlers
);
374 // Run delegates first; they may want to stop propagation beneath us
376 while ( (matched
= handlerQueue
[ i
++ ]) && !event
.isPropagationStopped() ) {
377 event
.currentTarget
= matched
.elem
;
380 while ( (handleObj
= matched
.handlers
[ j
++ ]) && !event
.isImmediatePropagationStopped() ) {
382 // Triggered event must either 1) have no namespace, or 2) have namespace(s)
383 // a subset or equal to those in the bound event (both can have no namespace).
384 if ( !event
.namespace_re
|| event
.namespace_re
.test( handleObj
.namespace ) ) {
386 event
.handleObj
= handleObj
;
387 event
.data
= handleObj
.data
;
389 ret
= ( (jQuery
.event
.special
[ handleObj
.origType
] || {}).handle
|| handleObj
.handler
)
390 .apply( matched
.elem
, args
);
392 if ( ret
!== undefined ) {
393 if ( (event
.result
= ret
) === false ) {
394 event
.preventDefault();
395 event
.stopPropagation();
402 // Call the postDispatch hook for the mapped type
403 if ( special
.postDispatch
) {
404 special
.postDispatch
.call( this, event
);
410 handlers: function( event
, handlers
) {
411 var i
, matches
, sel
, handleObj
,
413 delegateCount
= handlers
.delegateCount
,
416 // Find delegate handlers
417 // Black-hole SVG <use> instance trees (#13180)
418 // Avoid non-left-click bubbling in Firefox (#3861)
419 if ( delegateCount
&& cur
.nodeType
&& (!event
.button
|| event
.type
!== "click") ) {
421 for ( ; cur
!== this; cur
= cur
.parentNode
|| this ) {
423 // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
424 if ( cur
.disabled
!== true || event
.type
!== "click" ) {
426 for ( i
= 0; i
< delegateCount
; i
++ ) {
427 handleObj
= handlers
[ i
];
429 // Don't conflict with Object.prototype properties (#13203)
430 sel
= handleObj
.selector
+ " ";
432 if ( matches
[ sel
] === undefined ) {
433 matches
[ sel
] = handleObj
.needsContext
?
434 jQuery( sel
, this ).index( cur
) >= 0 :
435 jQuery
.find( sel
, this, null, [ cur
] ).length
;
437 if ( matches
[ sel
] ) {
438 matches
.push( handleObj
);
441 if ( matches
.length
) {
442 handlerQueue
.push({ elem: cur
, handlers: matches
});
448 // Add the remaining (directly-bound) handlers
449 if ( delegateCount
< handlers
.length
) {
450 handlerQueue
.push({ elem: this, handlers: handlers
.slice( delegateCount
) });
456 // Includes some event props shared by KeyEvent and MouseEvent
457 props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
462 props: "char charCode key keyCode".split(" "),
463 filter: function( event
, original
) {
465 // Add which for key events
466 if ( event
.which
== null ) {
467 event
.which
= original
.charCode
!= null ? original
.charCode : original
.keyCode
;
475 props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
476 filter: function( event
, original
) {
477 var eventDoc
, doc
, body
,
478 button
= original
.button
;
480 // Calculate pageX/Y if missing and clientX/Y available
481 if ( event
.pageX
== null && original
.clientX
!= null ) {
482 eventDoc
= event
.target
.ownerDocument
|| document
;
483 doc
= eventDoc
.documentElement
;
484 body
= eventDoc
.body
;
486 event
.pageX
= original
.clientX
+ ( doc
&& doc
.scrollLeft
|| body
&& body
.scrollLeft
|| 0 ) - ( doc
&& doc
.clientLeft
|| body
&& body
.clientLeft
|| 0 );
487 event
.pageY
= original
.clientY
+ ( doc
&& doc
.scrollTop
|| body
&& body
.scrollTop
|| 0 ) - ( doc
&& doc
.clientTop
|| body
&& body
.clientTop
|| 0 );
490 // Add which for click: 1 === left; 2 === middle; 3 === right
491 // Note: button is not normalized, so don't use it
492 if ( !event
.which
&& button
!== undefined ) {
493 event
.which
= ( button
& 1 ? 1 : ( button
& 2 ? 3 : ( button
& 4 ? 2 : 0 ) ) );
500 fix: function( event
) {
501 if ( event
[ jQuery
.expando
] ) {
505 // Create a writable copy of the event object and normalize some properties
508 originalEvent
= event
,
509 fixHook
= this.fixHooks
[ type
];
512 this.fixHooks
[ type
] = fixHook
=
513 rmouseEvent
.test( type
) ? this.mouseHooks :
514 rkeyEvent
.test( type
) ? this.keyHooks :
517 copy
= fixHook
.props
? this.props
.concat( fixHook
.props
) : this.props
;
519 event
= new jQuery
.Event( originalEvent
);
524 event
[ prop
] = originalEvent
[ prop
];
527 // Support: Cordova 2.5 (WebKit) (#13255)
528 // All events should have a target; Cordova deviceready doesn't
529 if ( !event
.target
) {
530 event
.target
= document
;
533 // Support: Safari 6.0+, Chrome<28
534 // Target should not be a text node (#504, #13143)
535 if ( event
.target
.nodeType
=== 3 ) {
536 event
.target
= event
.target
.parentNode
;
539 return fixHook
.filter
? fixHook
.filter( event
, originalEvent
) : event
;
544 // Prevent triggered image.load events from bubbling to window.load
548 // Fire native event if possible so blur/focus sequence is correct
549 trigger: function() {
550 if ( this !== safeActiveElement() && this.focus
) {
555 delegateType: "focusin"
558 trigger: function() {
559 if ( this === safeActiveElement() && this.blur
) {
564 delegateType: "focusout"
567 // For checkbox, fire native event so checked state will be right
568 trigger: function() {
569 if ( this.type
=== "checkbox" && this.click
&& jQuery
.nodeName( this, "input" ) ) {
575 // For cross-browser consistency, don't fire native .click() on links
576 _default: function( event
) {
577 return jQuery
.nodeName( event
.target
, "a" );
582 postDispatch: function( event
) {
584 // Support: Firefox 20+
585 // Firefox doesn't alert if the returnValue field is not set.
586 if ( event
.result
!== undefined && event
.originalEvent
) {
587 event
.originalEvent
.returnValue
= event
.result
;
593 simulate: function( type
, elem
, event
, bubble
) {
594 // Piggyback on a donor event to simulate a different one.
595 // Fake originalEvent to avoid donor's stopPropagation, but if the
596 // simulated event prevents default then we do the same on the donor.
597 var e
= jQuery
.extend(
607 jQuery
.event
.trigger( e
, null, elem
);
609 jQuery
.event
.dispatch
.call( elem
, e
);
611 if ( e
.isDefaultPrevented() ) {
612 event
.preventDefault();
617 jQuery
.removeEvent = function( elem
, type
, handle
) {
618 if ( elem
.removeEventListener
) {
619 elem
.removeEventListener( type
, handle
, false );
623 jQuery
.Event = function( src
, props
) {
624 // Allow instantiation without the 'new' keyword
625 if ( !(this instanceof jQuery
.Event
) ) {
626 return new jQuery
.Event( src
, props
);
630 if ( src
&& src
.type
) {
631 this.originalEvent
= src
;
632 this.type
= src
.type
;
634 // Events bubbling up the document may have been marked as prevented
635 // by a handler lower down the tree; reflect the correct value.
636 this.isDefaultPrevented
= src
.defaultPrevented
||
637 src
.defaultPrevented
=== undefined &&
638 // Support: Android<4.0
639 src
.returnValue
=== false ?
648 // Put explicitly provided properties onto the event object
650 jQuery
.extend( this, props
);
653 // Create a timestamp if incoming event doesn't have one
654 this.timeStamp
= src
&& src
.timeStamp
|| jQuery
.now();
657 this[ jQuery
.expando
] = true;
660 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
661 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
662 jQuery
.Event
.prototype = {
663 isDefaultPrevented: returnFalse
,
664 isPropagationStopped: returnFalse
,
665 isImmediatePropagationStopped: returnFalse
,
667 preventDefault: function() {
668 var e
= this.originalEvent
;
670 this.isDefaultPrevented
= returnTrue
;
672 if ( e
&& e
.preventDefault
) {
676 stopPropagation: function() {
677 var e
= this.originalEvent
;
679 this.isPropagationStopped
= returnTrue
;
681 if ( e
&& e
.stopPropagation
) {
685 stopImmediatePropagation: function() {
686 var e
= this.originalEvent
;
688 this.isImmediatePropagationStopped
= returnTrue
;
690 if ( e
&& e
.stopImmediatePropagation
) {
691 e
.stopImmediatePropagation();
694 this.stopPropagation();
698 // Create mouseenter/leave events using mouseover/out and event-time checks
699 // Support: Chrome 15+
701 mouseenter: "mouseover",
702 mouseleave: "mouseout",
703 pointerenter: "pointerover",
704 pointerleave: "pointerout"
705 }, function( orig
, fix
) {
706 jQuery
.event
.special
[ orig
] = {
710 handle: function( event
) {
713 related
= event
.relatedTarget
,
714 handleObj
= event
.handleObj
;
716 // For mousenter/leave call the handler if related is outside the target.
717 // NB: No relatedTarget if the mouse left/entered the browser window
718 if ( !related
|| (related
!== target
&& !jQuery
.contains( target
, related
)) ) {
719 event
.type
= handleObj
.origType
;
720 ret
= handleObj
.handler
.apply( this, arguments
);
728 // Support: Firefox, Chrome, Safari
729 // Create "bubbling" focus and blur events
730 if ( !support
.focusinBubbles
) {
731 jQuery
.each({ focus: "focusin", blur: "focusout" }, function( orig
, fix
) {
733 // Attach a single capturing handler on the document while someone wants focusin/focusout
734 var handler = function( event
) {
735 jQuery
.event
.simulate( fix
, event
.target
, jQuery
.event
.fix( event
), true );
738 jQuery
.event
.special
[ fix
] = {
740 var doc
= this.ownerDocument
|| this,
741 attaches
= data_priv
.access( doc
, fix
);
744 doc
.addEventListener( orig
, handler
, true );
746 data_priv
.access( doc
, fix
, ( attaches
|| 0 ) + 1 );
748 teardown: function() {
749 var doc
= this.ownerDocument
|| this,
750 attaches
= data_priv
.access( doc
, fix
) - 1;
753 doc
.removeEventListener( orig
, handler
, true );
754 data_priv
.remove( doc
, fix
);
757 data_priv
.access( doc
, fix
, attaches
);
766 on: function( types
, selector
, data
, fn
, /*INTERNAL*/ one
) {
769 // Types can be a map of types/handlers
770 if ( typeof types
=== "object" ) {
771 // ( types-Object, selector, data )
772 if ( typeof selector
!== "string" ) {
773 // ( types-Object, data )
774 data
= data
|| selector
;
775 selector
= undefined;
777 for ( type
in types
) {
778 this.on( type
, selector
, data
, types
[ type
], one
);
783 if ( data
== null && fn
== null ) {
786 data
= selector
= undefined;
787 } else if ( fn
== null ) {
788 if ( typeof selector
=== "string" ) {
789 // ( types, selector, fn )
793 // ( types, data, fn )
796 selector
= undefined;
799 if ( fn
=== false ) {
807 fn = function( event
) {
808 // Can use an empty set, since event contains the info
809 jQuery().off( event
);
810 return origFn
.apply( this, arguments
);
812 // Use same guid so caller can remove using origFn
813 fn
.guid
= origFn
.guid
|| ( origFn
.guid
= jQuery
.guid
++ );
815 return this.each( function() {
816 jQuery
.event
.add( this, types
, fn
, data
, selector
);
819 one: function( types
, selector
, data
, fn
) {
820 return this.on( types
, selector
, data
, fn
, 1 );
822 off: function( types
, selector
, fn
) {
824 if ( types
&& types
.preventDefault
&& types
.handleObj
) {
825 // ( event ) dispatched jQuery.Event
826 handleObj
= types
.handleObj
;
827 jQuery( types
.delegateTarget
).off(
828 handleObj
.namespace ? handleObj
.origType
+ "." + handleObj
.namespace : handleObj
.origType
,
834 if ( typeof types
=== "object" ) {
835 // ( types-object [, selector] )
836 for ( type
in types
) {
837 this.off( type
, selector
, types
[ type
] );
841 if ( selector
=== false || typeof selector
=== "function" ) {
844 selector
= undefined;
846 if ( fn
=== false ) {
849 return this.each(function() {
850 jQuery
.event
.remove( this, types
, fn
, selector
);
854 trigger: function( type
, data
) {
855 return this.each(function() {
856 jQuery
.event
.trigger( type
, data
, this );
859 triggerHandler: function( type
, data
) {
862 return jQuery
.event
.trigger( type
, data
, elem
, true );