// For whatever reason, IE has trouble passing the window object
// around, causing it to be cloned in the process
// For whatever reason, IE has trouble passing the window object
// around, causing it to be cloned in the process
- handler = this.proxy( fn, function() {
- // Pass arguments and context to original handler
- return fn.apply(this, arguments);
- });
+ handler = this.proxy( fn );
if ( jQuery.event.specialAll[type] )
jQuery.event.specialAll[type].setup.call(elem, data, namespaces);
if ( jQuery.event.specialAll[type] )
jQuery.event.specialAll[type].setup.call(elem, data, namespaces);
// Namespaced event handlers
var namespaces = type.split(".");
type = namespaces.shift();
// Namespaced event handlers
var namespaces = type.split(".");
type = namespaces.shift();
if ( jQuery.event.specialAll[type] )
jQuery.event.specialAll[type].teardown.call(elem, namespaces);
if ( jQuery.event.specialAll[type] )
jQuery.event.specialAll[type].teardown.call(elem, namespaces);
- trigger: function( event, data, elem, extra) {
+ // bubbling is internal
+ trigger: function( event, data, elem, bubbling ) {
- event = typeof event === "object" ?
- // jQuery.Event object
- event[expando] ? event :
- // Object literal
- jQuery.extend( jQuery.Event(type), event ) :
- // Just the event type (string)
- jQuery.Event(type);
-
- if ( type.indexOf("!") >= 0 ) {
- event.type = type = type.slice(0, -1);
- event.exclusive = true;
- }
-
- // Handle a global trigger
- if ( !elem ) {
- // Don't bubble custom events when global (to avoid too much overhead)
- event.stopPropagation();
- // Only trigger if we've ever bound an event for it
- if ( this.global[type] )
- jQuery.each( jQuery.cache, function(){
- if ( this.events && this.events[type] )
- jQuery.event.trigger( event, data, this.handle.elem );
- });
+ if( !bubbling ){
+ event = typeof event === "object" ?
+ // jQuery.Event object
+ event[expando] ? event :
+ // Object literal
+ jQuery.extend( jQuery.Event(type), event ) :
+ // Just the event type (string)
+ jQuery.Event(type);
+
+ if ( type.indexOf("!") >= 0 ) {
+ event.type = type = type.slice(0, -1);
+ event.exclusive = true;
+ }
+
+ // Handle a global trigger
+ if ( !elem ) {
+ // Don't bubble custom events when global (to avoid too much overhead)
+ event.stopPropagation();
+ // Only trigger if we've ever bound an event for it
+ if ( this.global[type] )
+ jQuery.each( jQuery.cache, function(){
+ if ( this.events && this.events[type] )
+ jQuery.event.trigger( event, data, this.handle.elem );
+ });
+ }
// Clone the incoming data, if any
data = jQuery.makeArray(data);
// Clone the incoming data, if any
data = jQuery.makeArray(data);
-
- // AT_TARGET phase (not bubbling)
- if( !event.target ){
- // Clean up in case it is reused
- event.result = undefined;
- event.target = elem;
- }
-
- // Fix for custom events
- event.currentTarget = elem;
-
- var fn = jQuery.isFunction( elem[ type ] );
-
- // Trigger the event, it is assumed that "handle" is a function
- var handle = jQuery.data(elem, "handle");
- if ( handle )
- handle.apply( elem, data );
-
- // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
- if ( (!fn || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
- event.result = false;
-
- // Extra functions don't get the custom event object
- data.shift();
+ event.currentTarget = elem;
- // Handle triggering of extra function
- if ( extra && jQuery.isFunction( extra ) ) {
- // call the extra function and tack the current return value on the end for possible inspection
- var ret = extra.apply( elem, event.result == null ? data : data.concat( event.result ) );
- // if anything is returned, give it precedence and have it overwrite the previous value
- if ( ret !== undefined )
- event.result = ret;
- }
+ // Trigger the event, it is assumed that "handle" is a function
+ var handle = jQuery.data(elem, "handle");
+ if ( handle )
+ handle.apply( elem, data );
- // Trigger the native events (except for clicks on links)
- if ( event.target === elem && fn && !event.isDefaultPrevented() && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
- this.triggered = true;
- try {
- elem[ type ]();
- // prevent IE from throwing an error for some hidden elements
- } catch (e) {}
- }
+ // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
+ if ( (!elem[type] || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
+ event.result = false;
- if ( !event.isPropagationStopped() ) {
- var parent = elem.parentNode || elem.ownerDocument;
- if ( parent )
- jQuery.event.trigger(event, data, parent);
- }
+ // Trigger the native events (except for clicks on links)
+ if ( !bubbling && elem[type] && !event.isDefaultPrevented() && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
+ this.triggered = true;
+ try {
+ elem[ type ]();
+ // prevent IE from throwing an error for some hidden elements
+ } catch (e) {}
+ }
- this.triggered = false;
+ if ( !event.isPropagationStopped() ) {
+ var parent = elem.parentNode || elem.ownerDocument;
+ if ( parent )
+ jQuery.event.trigger(event, data, parent, true);
// Cache this now, all = true means, any handler
all = !namespaces.length && !event.exclusive;
// Cache this now, all = true means, any handler
all = !namespaces.length && !event.exclusive;
- props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
+ props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
// Set the guid of unique handler to the same of original handler, so it can be removed
proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;
// So proxy can be declared as an argument
// Set the guid of unique handler to the same of original handler, so it can be removed
proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;
// So proxy can be declared as an argument
jQuery.each( (jQuery.data(this, "events").live || {}), function(){
if ( name.test(this.type) )
remove++;
});
jQuery.each( (jQuery.data(this, "events").live || {}), function(){
if ( name.test(this.type) )
remove++;
});
// Allow instantiation without the 'new' keyword
if( !this.preventDefault )
return new jQuery.Event(src);
// Allow instantiation without the 'new' keyword
if( !this.preventDefault )
return new jQuery.Event(src);
while ( parent && parent != this )
try { parent = parent.parentNode; }
catch(e) { parent = this; }
while ( parent && parent != this )
try { parent = parent.parentNode; }
catch(e) { parent = this; }
mouseout: 'mouseleave'
}, function( orig, fix ){
jQuery.event.special[ fix ] = {
mouseout: 'mouseleave'
}, function( orig, fix ){
jQuery.event.special[ fix ] = {
- jQuery(document).bind( liveConvert(type, this.selector), this.selector, fn );
+ var proxy = jQuery.event.proxy( fn );
+ proxy.guid += this.selector + type;
+
+ jQuery( this.context ).bind( liveConvert(type, this.selector), this.selector, proxy );
+
jQuery.each(jQuery.data(this, "events").live || [], function(i, fn){
if ( check.test(fn.type) ) {
var elem = jQuery(event.target).closest(fn.data)[0];
jQuery.each(jQuery.data(this, "events").live || [], function(i, fn){
if ( check.test(fn.type) ) {
var elem = jQuery(event.target).closest(fn.data)[0];
+
+ elems.sort(function(a,b) {
+ return jQuery.data(a.elem, "closest") - jQuery.data(b.elem, "closest");
+ });
+
+ jQuery.each(elems, function(){
+ event.currentTarget = this.elem;
+ if ( this.fn.call(this.elem, event, this.fn.data) === false )
+ return (stop = false);
+ });
+
- return ["live", type, selector.replace(/\./g, "_")].join(".");
+ return ["live", type, selector.replace(/\./g, "`").replace(/ /g, "|")].join(".");
// Prevent memory leaks in IE
// And prevent errors on refresh with events like mouseover in other browsers
// Window isn't included so as not to unbind existing unload events
// Prevent memory leaks in IE
// And prevent errors on refresh with events like mouseover in other browsers
// Window isn't included so as not to unbind existing unload events
-jQuery( window ).bind( 'unload', function(){
+// More info:
+// - http://isaacschlueter.com/2006/10/msie-memory-leaks/
+// - https://bugzilla.mozilla.org/show_bug.cgi?id=252542
+jQuery( window ).bind( 'unload', function(){
for ( var id in jQuery.cache )
// Skip the window
if ( id != 1 && jQuery.cache[ id ].handle )
jQuery.event.remove( jQuery.cache[ id ].handle.elem );
for ( var id in jQuery.cache )
// Skip the window
if ( id != 1 && jQuery.cache[ id ].handle )
jQuery.event.remove( jQuery.cache[ id ].handle.elem );