X-Git-Url: http://git.asbjorn.it/?a=blobdiff_plain;f=src%2Fevent.js;h=79a6b9529d4b88173afd03196c31b9ef72d39e0a;hb=f298cce100c6fe23840ac95e66aaea9cb2bfb447;hp=983e9e52f331ba25d515ff2c768336ef3ea4f18f;hpb=5dc6b7ce3469eaadb37a151d449e8d36571d1894;p=jquery.git diff --git a/src/event.js b/src/event.js index 983e9e5..79a6b95 100644 --- a/src/event.js +++ b/src/event.js @@ -1,3 +1,9 @@ +var fcleanup = function( nm ) { + return nm.replace(/[^\w\s\.\|`]/g, function( ch ) { + return "\\" + ch; + }); +}; + /* * A number of helper functions used for managing events. * Many of the ideas behind this code originated from @@ -142,7 +148,7 @@ jQuery.event = { var namespaces = type.split("."); type = namespaces.shift(); var all = !namespaces.length, - cleaned = jQuery.map( namespaces.slice(0).sort() , function(nm){ return nm.replace(/[^\w\s\.\|`]/g, function(ch){return "\\"+ch; }); }), + cleaned = jQuery.map( namespaces.slice(0).sort(), fcleanup ), namespace = new RegExp("(^|\\.)" + cleaned.join("\\.(?:.*\\.)?") + "(\\.|$)"), special = this.special[ type ] || {}; @@ -224,6 +230,7 @@ jQuery.event = { 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() { @@ -389,7 +396,7 @@ jQuery.event = { event.metaKey = event.ctrlKey; } - // Add which for click: 1 == left; 2 == middle; 3 == right + // Add which for click: 1 === left; 2 === middle; 3 === right // Note: button is not normalized, so don't use it if ( !event.which && event.button !== undefined ) { event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) )); @@ -403,10 +410,15 @@ jQuery.event = { thisObject = proxy; proxy = undefined; } + // FIXME: Should proxy be redefined to be applied with thisObject if defined? - proxy = proxy || function() { return fn.apply( thisObject !== undefined ? thisObject : this, arguments ); }; + proxy = proxy || function() { + return fn.apply( thisObject !== undefined ? thisObject : this, arguments ); + }; + // 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 return proxy; }, @@ -462,7 +474,7 @@ jQuery.event = { } }; -jQuery.Event = function( src ){ +jQuery.Event = function( src ) { // Allow instantiation without the 'new' keyword if ( !this.preventDefault ) { return new jQuery.Event( src ); @@ -524,7 +536,7 @@ jQuery.Event.prototype = { // otherwise set the cancelBubble property of the original event to true (IE) e.cancelBubble = true; }, - stopImmediatePropagation: function(){ + stopImmediatePropagation: function() { this.isImmediatePropagationStopped = returnTrue; this.stopPropagation(); }, @@ -532,23 +544,30 @@ jQuery.Event.prototype = { isPropagationStopped: returnFalse, isImmediatePropagationStopped: returnFalse }; + // Checks if an event happened on an element within another element // Used in jQuery.event.special.mouseenter and mouseleave handlers var withinElement = function( event ) { // Check if mouse(over|out) are still within the same parent element var parent = event.relatedTarget; + // Traverse up the tree - while ( parent && parent != this ) { + while ( parent && parent !== this ) { // Firefox sometimes assigns relatedTarget a XUL element // which we cannot access the parentNode property of - try { parent = parent.parentNode; } + try { + parent = parent.parentNode; + // assuming we've left the element since we most likely mousedover a xul element - catch(e) { break; } + } catch(e) { + break; + } } - if ( parent != this ) { + if ( parent !== this ) { // set the correct event type event.type = event.data; + // handle event if we actually just moused on to a non sub-element jQuery.event.handle.apply( this, arguments ); } @@ -568,10 +587,10 @@ jQuery.each({ mouseleave: "mouseout" }, function( orig, fix ) { jQuery.event.special[ orig ] = { - setup: function(data){ + setup: function( data ) { jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig ); }, - teardown: function(data){ + teardown: function( data ) { jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement ); } }; @@ -672,7 +691,7 @@ jQuery.event.special.change = { }, // Change has to be called before submit - // Keydown will be called before keypress, wich is used in submit-event delegation + // Keydown will be called before keypress, which is used in submit-event delegation keydown: function( e ) { var elem = e.target, type = elem.type; @@ -690,7 +709,7 @@ jQuery.event.special.change = { var elem = e.target; if ( elem.nodeName.toLowerCase() === "input" && elem.type === "radio" ) { - return jQuery.data( elem, "_change_data", getVal(elem) ); + jQuery.data( elem, "_change_data", getVal(elem) ); } } }, @@ -720,27 +739,26 @@ function trigger( type, elem, args ) { } // Create "bubbling" focus and blur events -if ( !jQuery.support.focusBubbles ) { +if ( document.addEventListener ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + jQuery.event.special[ fix ] = { + setup: function() { + this.addEventListener( orig, handler, true ); + }, + teardown: function() { + this.removeEventListener( orig, handler, true ); + } + }; -jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ){ - jQuery.event.special[ orig ] = { - setup: function() { - jQuery.event.add( this, fix, ieHandler ); - }, - teardown: function() { - jQuery.event.remove( this, fix, ieHandler ); + function handler( e ) { + e = jQuery.event.fix( e ); + e.type = fix; + return jQuery.event.handle.call( this, e ); } - }; - - function ieHandler() { - arguments[0].type = orig; - return jQuery.event.handle.apply(this, arguments); - } -}); - + }); } -jQuery.each(["bind", "one"], function(i, name) { +jQuery.each(["bind", "one"], function( i, name ) { jQuery.fn[ name ] = function( type, data, fn, thisObject ) { // Handle object literals if ( typeof type === "object" ) { @@ -756,7 +774,7 @@ jQuery.each(["bind", "one"], function(i, name) { data = undefined; } fn = thisObject === undefined ? fn : jQuery.event.proxy( fn, thisObject ); - var handler = name == "one" ? jQuery.event.proxy( fn, function( event ) { + var handler = name === "one" ? jQuery.event.proxy( fn, function( event ) { jQuery( this ).unbind( event, handler ); return fn.apply( this, arguments ); }) : fn; @@ -801,14 +819,14 @@ jQuery.fn.extend({ var args = arguments, i = 1; // link all the functions, so any of them can unbind this click handler - while( i < args.length ) { + while ( i < args.length ) { jQuery.event.proxy( fn, args[ i++ ] ); } return this.click( jQuery.event.proxy( fn, function( event ) { // Figure out which function to execute - var lastToggle = ( jQuery.data( this, 'lastToggle' + fn.guid ) || 0 ) % i; - jQuery.data( this, 'lastToggle' + fn.guid, lastToggle + 1 ); + var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i; + jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 ); // Make sure that clicks stop event.preventDefault();