]> source.dussan.org Git - jquery-ui.git/commitdiff
Datepicker Tests: Fix IE tests by accounting for async nature of focus/blur and by...
authorMike Sherov <mike.sherov@gmail.com>
Sun, 7 Apr 2013 18:16:31 +0000 (14:16 -0400)
committerMike Sherov <mike.sherov@gmail.com>
Sun, 7 Apr 2013 18:16:31 +0000 (14:16 -0400)
A partial fix was implemented to resolve #6694, and this commit completes the fix so we can programmatically focus a date picker without focus being fired twice.

tests/unit/datepicker/datepicker_options.js
tests/unit/datepicker/datepicker_test_helpers.js
ui/jquery.ui.datepicker.js

index 1efd854a9493e18f121c6738ba5ca245530f71d6..c1dcfb2b75445de9f0f57ebc92957f96d22aeacb 100644 (file)
@@ -87,56 +87,53 @@ test("change", function() {
        equal($.datepicker._defaults.showOn, "focus", "Retain default showOn");
 });
 
-asyncTest("invocation", function() {
+asyncTest( "invocation", function() {
        expect( 29 );
        var button, image,
-               inp = TestHelpers.datepicker.init("#inp"),
-               dp = $("#ui-datepicker-div"),
-               body = $("body");
+               inp = TestHelpers.datepicker.init( "#inp" ),
+               dp = $( "#ui-datepicker-div" ),
+               body = $( "body" );
 
        function step1() {
                // On focus
-               button = inp.siblings("button");
-               ok(button.length === 0, "Focus - button absent");
-               image = inp.siblings("img");
-               ok(image.length === 0, "Focus - image absent");
-               inp[0].focus();
-               setTimeout(function() {
-                       ok(dp.is(":visible"), "Focus - rendered on focus");
-                       inp.simulate("keydown", {keyCode: $.ui.keyCode.ESCAPE});
-                       ok(!dp.is(":visible"), "Focus - hidden on exit");
-                       inp[0].blur();
-                       setTimeout(function() {
-                               inp[0].focus();
-                               setTimeout(function() {
-                                       ok(dp.is(":visible"), "Focus - rendered on focus");
-                                       body.simulate("mousedown", {});
-                                       ok(!dp.is(":visible"), "Focus - hidden on external click");
-                                       inp.datepicker("hide").datepicker("destroy");
+               button = inp.siblings( "button" );
+               ok( button.length === 0, "Focus - button absent" );
+               image = inp.siblings( "img" );
+               ok( image.length === 0, "Focus - image absent" );
+
+               inp.one( "focus", function() {
+                       ok( dp.is( ":visible" ), "Focus - rendered on focus" );
+                       inp.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } );
+                       ok( !dp.is( ":visible" ), "Focus - hidden on exit" );
 
-                                       step2();
-                               });
+                       TestHelpers.datepicker.onBlurThenFocus( inp, function() {
+                               ok( dp.is( ":visible" ), "Focus - rendered on focus" );
+                               body.simulate( "mousedown", {} );
+                               ok( !dp.is( ":visible" ), "Focus - hidden on external click" );
+                               inp.datepicker( "hide" ).datepicker( "destroy" );
+
+                               step2();
                        });
-               });
+               })[ 0 ].focus();
        }
 
        function step2() {
                // On button
-               inp = TestHelpers.datepicker.init("#inp", {showOn: "button", buttonText: "Popup"});
-               ok(!dp.is(":visible"), "Button - initially hidden");
-               button = inp.siblings("button");
-               image = inp.siblings("img");
-               ok(button.length === 1, "Button - button present");
-               ok(image.length === 0, "Button - image absent");
-               equal(button.text(), "Popup", "Button - button text");
-               inp[0].focus();
-               setTimeout(function() {
-                       ok(!dp.is(":visible"), "Button - not rendered on focus");
+               inp = TestHelpers.datepicker.init( "#inp", { showOn: "button", buttonText: "Popup" } );
+               ok( !dp.is( ":visible" ), "Button - initially hidden" );
+               button = inp.siblings( "button" );
+               image = inp.siblings( "img" );
+               ok( button.length === 1, "Button - button present" );
+               ok( image.length === 0, "Button - image absent" );
+               equal( button.text(), "Popup", "Button - button text" );
+
+               TestHelpers.datepicker.onBlurThenFocus( inp, function() {
+                       ok( !dp.is( ":visible" ), "Button - not rendered on focus" );
                        button.click();
-                       ok(dp.is(":visible"), "Button - rendered on button click");
+                       ok( dp.is( ":visible" ), "Button - rendered on button click" );
                        button.click();
-                       ok(!dp.is(":visible"), "Button - hidden on second button click");
-                       inp.datepicker("hide").datepicker("destroy");
+                       ok( !dp.is( ":visible" ), "Button - hidden on second button click" );
+                       inp.datepicker( "hide" ).datepicker( "destroy" );
 
                        step3();
                });
@@ -144,23 +141,27 @@ asyncTest("invocation", function() {
 
        function step3() {
                // On image button
-               inp = TestHelpers.datepicker.init("#inp", {showOn: "button", buttonImageOnly: true,
-                       buttonImage: "images/calendar.gif", buttonText: "Cal"});
-               ok(!dp.is(":visible"), "Image button - initially hidden");
-               button = inp.siblings("button");
-               ok(button.length === 0, "Image button - button absent");
-               image = inp.siblings("img");
-               ok(image.length === 1, "Image button - image present");
-               equal(image.attr("src"), "images/calendar.gif", "Image button - image source");
-               equal(image.attr("title"), "Cal", "Image button - image text");
-               inp[0].focus();
-               setTimeout(function() {
-                       ok(!dp.is(":visible"), "Image button - not rendered on focus");
+               inp = TestHelpers.datepicker.init( "#inp", {
+                       showOn: "button",
+                       buttonImageOnly: true,
+                       buttonImage: "images/calendar.gif",
+                       buttonText: "Cal"
+               });
+               ok( !dp.is( ":visible" ), "Image button - initially hidden" );
+               button = inp.siblings( "button" );
+               ok( button.length === 0, "Image button - button absent" );
+               image = inp.siblings( "img" );
+               ok( image.length === 1, "Image button - image present" );
+               equal( image.attr( "src" ), "images/calendar.gif", "Image button - image source" );
+               equal( image.attr( "title" ), "Cal", "Image button - image text" );
+
+               TestHelpers.datepicker.onBlurThenFocus( inp, function() {
+                       ok( !dp.is( ":visible" ), "Image button - not rendered on focus" );
                        image.click();
-                       ok(dp.is(":visible"), "Image button - rendered on image click");
+                       ok( dp.is( ":visible" ), "Image button - rendered on image click" );
                        image.click();
-                       ok(!dp.is(":visible"), "Image button - hidden on second image click");
-                       inp.datepicker("hide").datepicker("destroy");
+                       ok( !dp.is( ":visible" ), "Image button - hidden on second image click" );
+                       inp.datepicker( "hide" ).datepicker( "destroy" );
 
                        step4();
                });
@@ -168,29 +169,26 @@ asyncTest("invocation", function() {
 
        function step4() {
                // On both
-               inp = TestHelpers.datepicker.init("#inp", {showOn: "both", buttonImage: "images/calendar.gif"});
-               ok(!dp.is(":visible"), "Both - initially hidden");
-               button = inp.siblings("button");
-               ok(button.length === 1, "Both - button present");
-               image = inp.siblings("img");
-               ok(image.length === 0, "Both - image absent");
-               image = button.children("img");
-               ok(image.length === 1, "Both - button image present");
-               inp[0].blur();
-               setTimeout(function() {
-                       inp[0].focus();
-                       setTimeout(function() {
-                               ok(dp.is(":visible"), "Both - rendered on focus");
-                               body.simulate("mousedown", {});
-                               ok(!dp.is(":visible"), "Both - hidden on external click");
-                               button.click();
-                               ok(dp.is(":visible"), "Both - rendered on button click");
-                               button.click();
-                               ok(!dp.is(":visible"), "Both - hidden on second button click");
-                               inp.datepicker("hide").datepicker("destroy");
+               inp = TestHelpers.datepicker.init( "#inp", { showOn: "both", buttonImage: "images/calendar.gif"} );
+               ok( !dp.is( ":visible" ), "Both - initially hidden" );
+               button = inp.siblings( "button" );
+               ok( button.length === 1, "Both - button present" );
+               image = inp.siblings( "img" );
+               ok( image.length === 0, "Both - image absent" );
+               image = button.children( "img" );
+               ok( image.length === 1, "Both - button image present" );
 
-                               start();
-                       });
+               TestHelpers.datepicker.onBlurThenFocus( inp, function() {
+                       ok( dp.is( ":visible" ), "Both - rendered on focus" );
+                       body.simulate( "mousedown", {} );
+                       ok( !dp.is( ":visible" ), "Both - hidden on external click" );
+                       button.click();
+                       ok( dp.is( ":visible" ), "Both - rendered on button click" );
+                       button.click();
+                       ok( !dp.is( ":visible" ), "Both - hidden on second button click" );
+                       inp.datepicker( "hide" ).datepicker( "destroy" );
+
+                       start();
                });
        }
 
index a9605edffa6075ae987bd61e30323ab0c5c96f4c..504bcc76731ff0f91a84683b0018a683e333ef93 100644 (file)
@@ -18,5 +18,12 @@ TestHelpers.datepicker = {
                $.datepicker.setDefaults($.datepicker.regional[""]);
                return $(id).datepicker($.extend({showAnim: ""}, options || {}));
        },
+       onBlurThenFocus: function( element, callback ) {
+               element.one( "blur", function(){
+                       element.one( "focus", function(){
+                               callback();
+                       })[ 0 ].focus();
+               })[ 0 ].blur();
+       },
        PROP_NAME: "datepicker"
 };
\ No newline at end of file
index 976534c943e5e615284488dd18a8d8996a680e02..b433cb79b318782dbe98eb3862b768023ac06f40 100644 (file)
@@ -774,9 +774,10 @@ $.extend(Datepicker.prototype, {
                                inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
                        }
 
-                       if (inst.input.is(":visible") && !inst.input.is(":disabled")) {
+                       if ( $.datepicker._shouldFocusInput( inst ) ) {
                                inst.input.focus();
                        }
+
                        $.datepicker._curInst = inst;
                }
        },
@@ -803,10 +804,7 @@ $.extend(Datepicker.prototype, {
                inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
                        "Class"]("ui-datepicker-rtl");
 
-               // #6694 - don't focus the input if it's already focused
-               // this breaks the change event in IE
-               if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && inst.input &&
-                       inst.input.is(":visible") && !inst.input.is(":disabled") && inst.input[0] !== document.activeElement) {
+               if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
                        inst.input.focus();
                }
 
@@ -823,6 +821,13 @@ $.extend(Datepicker.prototype, {
                }
        },
 
+       // #6694 - don't focus the input if it's already focused
+       // this breaks the change event in IE
+       // Support: IE and jQuery <1.9
+       _shouldFocusInput: function( inst ) {
+               return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
+       },
+
        /* Check positioning to remain on screen. */
        _checkOffset: function(inst, offset, isFixed) {
                var dpWidth = inst.dpDiv.outerWidth(),