Merge branch 'bug-3333' of https://github.com/rdworth/jquery into rdworth-bug-3333
authorjeresig <jeresig@gmail.com>
Thu, 24 Mar 2011 22:58:20 +0000 (18:58 -0400)
committerjeresig <jeresig@gmail.com>
Thu, 24 Mar 2011 22:58:20 +0000 (18:58 -0400)
Makefile
src/event.js
test/unit/event.js

index 84816a1..2c7bb80 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -42,17 +42,15 @@ VER = sed "s/@VERSION/${JQ_VER}/"
 
 DATE=$(shell git log -1 --pretty=format:%ad)
 
-all: jquery min lint
+all: update_submodules core
+
+core: jquery min lint
        @@echo "jQuery build complete."
 
 ${DIST_DIR}:
        @@mkdir -p ${DIST_DIR}
 
-init:
-       @@if [ -d .git ]; then git submodule update --init --recursive; fi
-
-jquery: init ${JQ}
-jq: init ${JQ}
+jquery: ${JQ}
 
 ${JQ}: ${MODULES} | ${DIST_DIR}
        @@echo "Building" ${JQ}
@@ -99,6 +97,18 @@ distclean: clean
        @@echo "Removing submodules"
        @@rm -rf test/qunit src/sizzle
 
+# change pointers for submodules and update them to what is specified in jQuery
+# --merge  doesn't work when doing an initial clone, thus test if we have non-existing
+#  submodules, then do an real update
+update_submodules:
+       @@if [ -d .git ]; then \
+               if git submodule status | grep -q -E '^-'; then \
+                       git submodule update --init --recursive; \
+               else \
+                       git submodule update --init --recursive --merge; \
+               fi; \
+       fi;
+
 # update the submodules to the latest at the most logical branch
 pull_submodules:
        @@git submodule foreach "git pull origin \$$(git branch --no-color --contains \$$(git rev-parse HEAD) | grep -v \( | head -1)"
@@ -107,4 +117,4 @@ pull_submodules:
 pull: pull_submodules
        @@git pull ${REMOTE} ${BRANCH}
 
-.PHONY: all jquery lint min init jq clean
+.PHONY: all jquery lint min clean distclean update_submodules pull_submodules pull core
index f7e0a08..bc2cf76 100644 (file)
@@ -70,10 +70,10 @@ jQuery.event = {
                }
 
                if ( !eventHandle ) {
-                       elemData.handle = eventHandle = function() {
+                       elemData.handle = eventHandle = function( e ) {
                                // Handle the second event of a trigger and when
                                // an event is called after a page has unloaded
-                               return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
+                               return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
                                        jQuery.event.handle.apply( eventHandle.elem, arguments ) :
                                        undefined;
                        };
@@ -380,7 +380,7 @@ jQuery.event = {
                                                        target[ "on" + targetType ] = null;
                                                }
 
-                                               jQuery.event.triggered = true;
+                                               jQuery.event.triggered = event.type;
                                                target[ targetType ]();
                                        }
 
@@ -391,7 +391,7 @@ jQuery.event = {
                                        target[ "on" + targetType ] = old;
                                }
 
-                               jQuery.event.triggered = false;
+                               jQuery.event.triggered = undefined;
                        }
                }
        },
@@ -661,7 +661,7 @@ var withinElement = function( event ) {
 
                // Chrome does something similar, the parentNode property
                // can be accessed but is null.
-               if ( parent !== document && !parent.parentNode ) {
+               if ( parent && parent !== document && !parent.parentNode ) {
                        return;
                }
                // Traverse up the tree
@@ -868,19 +868,33 @@ function trigger( type, elem, args ) {
 // Create "bubbling" focus and blur events
 if ( document.addEventListener ) {
        jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
+       
+               // Attach a single capturing handler while someone wants focusin/focusout
+               var attaches = 0;
+               
                jQuery.event.special[ fix ] = {
                        setup: function() {
-                               this.addEventListener( orig, handler, true );
+                               if ( attaches++ === 0 ) {
+                                       document.addEventListener( orig, handler, true );
+                               }
                        },
                        teardown: function() {
-                               this.removeEventListener( orig, handler, true );
+                               if ( --attaches === 0 ) {
+                                       document.removeEventListener( orig, handler, true );
+                               }
                        }
                };
 
-               function handler( e ) {
-                       e = jQuery.event.fix( e );
+               function handler( donor ) {
+                       // Donor event is always a native one; fix it and switch its type.
+                       // Let focusin/out handler cancel the donor focus/blur event.
+                       var e = jQuery.event.fix( donor );
                        e.type = fix;
-                       return jQuery.event.handle.call( this, e );
+                       e.originalEvent = {};
+                       jQuery.event.trigger( e, null, e.target );
+                       if ( e.isDefaultPrevented() ) {
+                               donor.preventDefault();
+                       }
                }
        });
 }
index b7b2604..1e40e0f 100644 (file)
@@ -683,6 +683,20 @@ test("hover()", function() {
        equals( times, 4, "hover handlers fired" );
 });
 
+test("mouseover triggers mouseenter", function() {
+       expect(1);
+       
+       var count = 0,
+               elem = jQuery("<a />");
+       elem.mouseenter(function () {
+         count++;
+       });
+       elem.trigger('mouseover');
+       equals(count, 1, "make sure mouseover triggers a mouseenter" );
+       
+       elem.remove();
+});
+
 test("trigger() shortcuts", function() {
        expect(6);
 
@@ -1966,6 +1980,31 @@ test("window resize", function() {
        ok( !jQuery._data(window, "__events__"), "Make sure all the events are gone." );
 });
 
+test("focusin bubbles", function() {
+       expect(4);
+       
+       var input = jQuery( '<input type="text" />' ).prependTo( "body" ), 
+               order = 0;
+
+       jQuery( "body" ).bind( "focusin.focusinBubblesTest", function(){
+               equals( 1, order++, "focusin on the body second" );
+       });
+
+       input.bind( "focusin.focusinBubblesTest", function(){
+               equals( 0, order++, "focusin on the element first" );
+       });
+
+       // DOM focus method
+       input[0].focus();
+       // jQuery trigger, which calls DOM focus
+       order = 0;
+       input[0].blur();
+       input.trigger( "focus" );
+
+       input.remove();
+       jQuery( "body" ).unbind( "focusin.focusinBubblesTest" );
+});
+
 /*
 test("jQuery(function($) {})", function() {
        stop();