From fb57cc8aba32eb1d544b75e6a2c05785eeecf0cd Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Thu, 18 Aug 2011 21:39:27 +0200 Subject: Tooltip: Change default to flipfit for both dimensions, now that it is available. Fixes positioning issue when tooltipped element is at the top of the screen. --- ui/jquery.ui.tooltip.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/jquery.ui.tooltip.js b/ui/jquery.ui.tooltip.js index 5e32459fc..2f8d92969 100644 --- a/ui/jquery.ui.tooltip.js +++ b/ui/jquery.ui.tooltip.js @@ -27,7 +27,7 @@ $.widget( "ui.tooltip", { position: { my: "left+15 center", at: "right center", - collision: "flip fit" + collision: "flipfit flipfit" }, show: true, tooltipClass: null, -- cgit v1.2.3 From 96e5c241e1b26224c53738b590e07290db7a3e54 Mon Sep 17 00:00:00 2001 From: Corey Frang Date: Fri, 19 Aug 2011 06:03:59 -0500 Subject: Dialog: Tabbing out of a modal dialog was possible because keypress doesn't fire for tabs everywhere, switched to keyup. Added Unit Test - Caught by @DomenicDenicola - Fixes #3123 - Tabbing stops in modal dialog --- tests/unit/dialog/dialog_tickets.js | 31 ++++++++++++++++++++++++++++++- ui/jquery.ui.dialog.js | 2 +- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/tests/unit/dialog/dialog_tickets.js b/tests/unit/dialog/dialog_tickets.js index 1cfdcefea..e65f939e0 100644 --- a/tests/unit/dialog/dialog_tickets.js +++ b/tests/unit/dialog/dialog_tickets.js @@ -3,7 +3,36 @@ */ (function($) { -module("dialog: tickets"); +module( "dialog: tickets" ); + +asyncTest( "#3123: Prevent tabbing out of modal dialogs", function() { + expect( 3 ); + + var el = $( "
" ).dialog({ modal: true }), + inputs = el.find( "input" ), + widget = el.dialog( "widget" ); + + inputs.eq( 1 ).focus(); + equal( document.activeElement, inputs[1], "Focus set on second input" ); + inputs.eq( 1 ).simulate( "keyup", { keyCode: $.ui.keyCode.TAB }); + + setTimeout( checkTab, 2 ); + + function checkTab() { + ok( $.contains( widget, document.activeElement ), "Tab key event moved focus within the modal" ); + + // check shift tab + $( document.activeElement ).simulate( "keydown", { keyCode: $.ui.keyCode.TAB, shiftKey: true }); + setTimeout( checkShiftTab, 2 ); + } + + function checkShiftTab() { + ok( $.contains( widget, document.activeElement ), "Shift-Tab key event moved focus within the modal" ); + + el.remove(); + start(); + } +}); test("#4826: setting resizable false toggles resizable on dialog", function() { expect(6); diff --git a/ui/jquery.ui.dialog.js b/ui/jquery.ui.dialog.js index 493ed07e6..e8107db7c 100644 --- a/ui/jquery.ui.dialog.js +++ b/ui/jquery.ui.dialog.js @@ -293,7 +293,7 @@ $.widget("ui.dialog", { // prevent tabbing out of modal dialogs if ( options.modal ) { - uiDialog.bind( "keypress.ui-dialog", function( event ) { + uiDialog.bind( "keyup.ui-dialog", function( event ) { if ( event.keyCode !== $.ui.keyCode.TAB ) { return; } -- cgit v1.2.3 From 96c2c8e639abc1894cdb1588982219f31634a164 Mon Sep 17 00:00:00 2001 From: kborchers Date: Fri, 19 Aug 2011 20:19:38 -0500 Subject: Position: Added the missing div required for the fraction tests that were added to fix the broken test --- tests/unit/position/position_deprecated.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/unit/position/position_deprecated.html b/tests/unit/position/position_deprecated.html index 16d88ea2e..c80490f74 100644 --- a/tests/unit/position/position_deprecated.html +++ b/tests/unit/position/position_deprecated.html @@ -55,5 +55,9 @@ elements smaller than 10px have a line-height set on them to avoid a bug in IE6
+
+
+
+ -- cgit v1.2.3 From dfe75e1b552013c440186645a7a1ae9ec3c757b5 Mon Sep 17 00:00:00 2001 From: Corey Frang Date: Sat, 20 Aug 2011 18:05:39 -0500 Subject: Dialog: Update to 96e5c24 - keyup apparently doesn't work like I thought it would everywhere, switching back to keydown. --- tests/unit/dialog/dialog_tickets.js | 2 +- ui/jquery.ui.dialog.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/dialog/dialog_tickets.js b/tests/unit/dialog/dialog_tickets.js index e65f939e0..b203ca7d5 100644 --- a/tests/unit/dialog/dialog_tickets.js +++ b/tests/unit/dialog/dialog_tickets.js @@ -14,7 +14,7 @@ asyncTest( "#3123: Prevent tabbing out of modal dialogs", function() { inputs.eq( 1 ).focus(); equal( document.activeElement, inputs[1], "Focus set on second input" ); - inputs.eq( 1 ).simulate( "keyup", { keyCode: $.ui.keyCode.TAB }); + inputs.eq( 1 ).simulate( "keydown", { keyCode: $.ui.keyCode.TAB }); setTimeout( checkTab, 2 ); diff --git a/ui/jquery.ui.dialog.js b/ui/jquery.ui.dialog.js index e8107db7c..065d640fb 100644 --- a/ui/jquery.ui.dialog.js +++ b/ui/jquery.ui.dialog.js @@ -293,7 +293,7 @@ $.widget("ui.dialog", { // prevent tabbing out of modal dialogs if ( options.modal ) { - uiDialog.bind( "keyup.ui-dialog", function( event ) { + uiDialog.bind( "keydown.ui-dialog", function( event ) { if ( event.keyCode !== $.ui.keyCode.TAB ) { return; } -- cgit v1.2.3 From 87f78973b919130880a42651596edbae0b2a7741 Mon Sep 17 00:00:00 2001 From: Scott González Date: Tue, 30 Aug 2011 20:22:35 -0400 Subject: Tabs: Pass the required deep parameter to cloneNode(). Fixes completely broken tabs in Opera. Thanks monoblaine. --- ui/jquery.ui.tabs.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/jquery.ui.tabs.js b/ui/jquery.ui.tabs.js index b6f178ed9..d4c5f6b69 100644 --- a/ui/jquery.ui.tabs.js +++ b/ui/jquery.ui.tabs.js @@ -25,7 +25,7 @@ var isLocal = (function() { return function( anchor ) { // clone the node to work around IE 6 not normalizing the href property // if it's manually set, i.e., a.href = "#foo" kills the normalization - anchor = anchor.cloneNode(); + anchor = anchor.cloneNode( false ); return anchor.hash.length > 1 && anchor.href.replace( rhash, "" ) === currentPage; }; -- cgit v1.2.3 From c5ba0535cf8fad222bf54249fb74339faafa9310 Mon Sep 17 00:00:00 2001 From: Scott González Date: Tue, 30 Aug 2011 20:45:48 -0400 Subject: Autocomplete: Fixed setting of valueMethod for textareas. Fixes #7674 - Autocomplete doesn't work with textareas. --- tests/unit/autocomplete/autocomplete.html | 1 + tests/unit/autocomplete/autocomplete_events.js | 173 ++++++++++--------------- ui/jquery.ui.autocomplete.js | 2 +- 3 files changed, 71 insertions(+), 105 deletions(-) diff --git a/tests/unit/autocomplete/autocomplete.html b/tests/unit/autocomplete/autocomplete.html index 8dc86c621..e5987350b 100644 --- a/tests/unit/autocomplete/autocomplete.html +++ b/tests/unit/autocomplete/autocomplete.html @@ -39,6 +39,7 @@
+ diff --git a/tests/unit/autocomplete/autocomplete_events.js b/tests/unit/autocomplete/autocomplete_events.js index c6d42ddcc..6813cfa71 100644 --- a/tests/unit/autocomplete/autocomplete_events.js +++ b/tests/unit/autocomplete/autocomplete_events.js @@ -4,110 +4,75 @@ module( "autocomplete: events" ); var data = [ "Clojure", "COBOL", "ColdFusion", "Java", "JavaScript", "Scala", "Scheme" ]; -asyncTest( "all events", function() { - expect( 13 ); - var element = $( "#autocomplete" ) - .autocomplete({ - autoFocus: false, - delay: 0, - source: data, - search: function( event ) { - equal( event.originalEvent.type, "keydown", "search originalEvent" ); - }, - response: function( event, ui ) { - deepEqual( ui.content, [ - { label: "Clojure", value: "Clojure" }, - { label: "Java", value: "Java" }, - { label: "JavaScript", value: "JavaScript" } - ], "response ui.content" ); - ui.content.splice( 0, 1 ); - }, - open: function( event ) { - ok( menu.is( ":visible" ), "menu open on open" ); - }, - focus: function( event, ui ) { - equal( event.originalEvent.type, "menufocus", "focus originalEvent" ); - deepEqual( ui.item, { label: "Java", value: "Java" }, "focus ui.item" ); - }, - close: function( event ) { - equal( event.originalEvent.type, "menuselect", "close originalEvent" ); - ok( menu.is( ":hidden" ), "menu closed on close" ); - }, - select: function( event, ui ) { - equal( event.originalEvent.type, "menuselect", "select originalEvent" ); - deepEqual( ui.item, { label: "Java", value: "Java" }, "select ui.item" ); - }, - change: function( event, ui ) { - equal( event.originalEvent.type, "blur", "change originalEvent" ); - deepEqual( ui.item, { label: "Java", value: "Java" }, "chnage ui.item" ); - ok( menu.is( ":hidden" ), "menu closed on change" ); - start(); - } - }), - menu = element.autocomplete( "widget" ); - - element.focus().val( "j" ).keydown(); - setTimeout(function() { - ok( menu.is( ":visible" ), "menu is visible after delay" ); - element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); - element.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - // blurring through jQuery causes a bug in IE 6 which causes the - // autocompletechange event to occur twice - element[0].blur(); - }, 50 ); -}); - -asyncTest( "all events - contenteditable", function() { - expect( 13 ); - var element = $( "#autocomplete-contenteditable" ) - .autocomplete({ - autoFocus: false, - delay: 0, - source: data, - search: function( event ) { - equal( event.originalEvent.type, "keydown", "search originalEvent" ); - }, - response: function( event, ui ) { - deepEqual( ui.content, [ - { label: "Clojure", value: "Clojure" }, - { label: "Java", value: "Java" }, - { label: "JavaScript", value: "JavaScript" } - ], "response ui.content" ); - ui.content.splice( 0, 1 ); - }, - open: function( event ) { - ok( menu.is( ":visible" ), "menu open on open" ); - }, - focus: function( event, ui ) { - equal( event.originalEvent.type, "menufocus", "focus originalEvent" ); - deepEqual( ui.item, { label: "Java", value: "Java" }, "focus ui.item" ); - }, - close: function( event ) { - equal( event.originalEvent.type, "menuselect", "close originalEvent" ); - ok( menu.is( ":hidden" ), "menu closed on close" ); - }, - select: function( event, ui ) { - equal( event.originalEvent.type, "menuselect", "select originalEvent" ); - deepEqual( ui.item, { label: "Java", value: "Java" }, "select ui.item" ); - }, - change: function( event, ui ) { - equal( event.originalEvent.type, "blur", "change originalEvent" ); - deepEqual( ui.item, { label: "Java", value: "Java" }, "chnage ui.item" ); - ok( menu.is( ":hidden" ), "menu closed on change" ); - start(); - } - }), - menu = element.autocomplete( "widget" ); - - element.focus().text( "j" ).keydown(); - setTimeout(function() { - ok( menu.is( ":visible" ), "menu is visible after delay" ); - element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); - element.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); - // TODO: blurring through jQuery causes a bug in IE 6 which causes the - // autocompletechange event to occur twice - element[0].blur(); - }, 50 ); +$.each([ + { + type: "input", + selector: "#autocomplete", + valueMethod: "val" + }, + { + type: "textarea", + selector: "#autocomplete-textarea", + valueMethod: "val" + }, + { + type: "contenteditable", + selector: "#autocomplete-contenteditable", + valueMethod: "text" + } +], function( i, settings ) { + asyncTest( "all events - " + settings.type, function() { + expect( 13 ); + var element = $( settings.selector ) + .autocomplete({ + autoFocus: false, + delay: 0, + source: data, + search: function( event ) { + equal( event.originalEvent.type, "keydown", "search originalEvent" ); + }, + response: function( event, ui ) { + deepEqual( ui.content, [ + { label: "Clojure", value: "Clojure" }, + { label: "Java", value: "Java" }, + { label: "JavaScript", value: "JavaScript" } + ], "response ui.content" ); + ui.content.splice( 0, 1 ); + }, + open: function( event ) { + ok( menu.is( ":visible" ), "menu open on open" ); + }, + focus: function( event, ui ) { + equal( event.originalEvent.type, "menufocus", "focus originalEvent" ); + deepEqual( ui.item, { label: "Java", value: "Java" }, "focus ui.item" ); + }, + close: function( event ) { + equal( event.originalEvent.type, "menuselect", "close originalEvent" ); + ok( menu.is( ":hidden" ), "menu closed on close" ); + }, + select: function( event, ui ) { + equal( event.originalEvent.type, "menuselect", "select originalEvent" ); + deepEqual( ui.item, { label: "Java", value: "Java" }, "select ui.item" ); + }, + change: function( event, ui ) { + equal( event.originalEvent.type, "blur", "change originalEvent" ); + deepEqual( ui.item, { label: "Java", value: "Java" }, "chnage ui.item" ); + ok( menu.is( ":hidden" ), "menu closed on change" ); + start(); + } + }), + menu = element.autocomplete( "widget" ); + + element.focus()[ settings.valueMethod ]( "j" ).keydown(); + setTimeout(function() { + ok( menu.is( ":visible" ), "menu is visible after delay" ); + element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + element.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + // blurring through jQuery causes a bug in IE 6 which causes the + // autocompletechange event to occur twice + element[0].blur(); + }, 50 ); + }); }); asyncTest( "change without selection", function() { diff --git a/ui/jquery.ui.autocomplete.js b/ui/jquery.ui.autocomplete.js index 3e0163682..b871715ba 100644 --- a/ui/jquery.ui.autocomplete.js +++ b/ui/jquery.ui.autocomplete.js @@ -51,7 +51,7 @@ $.widget( "ui.autocomplete", { suppressKeyPress, suppressInput; - this.valueMethod = this.element[ this.element.is( "input" ) ? "val" : "text" ]; + this.valueMethod = this.element[ this.element.is( "input,textarea" ) ? "val" : "text" ]; this.element .addClass( "ui-autocomplete-input" ) -- cgit v1.2.3 From 02c821da6e10bbdd31424949d73a1c2c603108fe Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Mon, 5 Sep 2011 17:59:36 +0200 Subject: Popup: Missing semicolon. Can't use :ui-button selected if button isn't loaded. --- ui/jquery.ui.popup.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/jquery.ui.popup.js b/ui/jquery.ui.popup.js index 508209a55..8e5cf198c 100644 --- a/ui/jquery.ui.popup.js +++ b/ui/jquery.ui.popup.js @@ -45,13 +45,13 @@ $.widget( "ui.popup", { .attr( "aria-owns", this.element.attr( "id" ) ); this.element - .addClass( "ui-popup" ) + .addClass( "ui-popup" ); this.close(); this._bind(this.options.trigger, { keydown: function( event ) { // prevent space-to-open to scroll the page, only happens for anchor ui.button - if ( this.options.trigger.is( "a:ui-button" ) && event.keyCode == $.ui.keyCode.SPACE ) { + if ( $.ui.button && this.options.trigger.is( "a:ui-button" ) && event.keyCode == $.ui.keyCode.SPACE ) { event.preventDefault(); } // TODO handle SPACE to open popup? only when not handled by ui.button -- cgit v1.2.3 From 08450c3b2dfa652c7866653af93566c9bfa2f2cb Mon Sep 17 00:00:00 2001 From: Scott González Date: Tue, 6 Sep 2011 11:00:42 -0400 Subject: Button: Fixed RTL detection to default to LTR. Fixes #7697 - Buttonset: Incorrect corners for disconnected elements. --- ui/jquery.ui.button.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/jquery.ui.button.js b/ui/jquery.ui.button.js index 89c52d007..1d9393d37 100644 --- a/ui/jquery.ui.button.js +++ b/ui/jquery.ui.button.js @@ -379,7 +379,7 @@ $.widget( "ui.buttonset", { }, refresh: function() { - var ltr = this.element.css( "direction" ) === "ltr"; + var rtl = this.element.css( "direction" ) === "rtl"; this.buttons = this.element.find( this.options.items ) .filter( ":ui-button" ) @@ -393,10 +393,10 @@ $.widget( "ui.buttonset", { }) .removeClass( "ui-corner-all ui-corner-left ui-corner-right" ) .filter( ":first" ) - .addClass( ltr ? "ui-corner-left" : "ui-corner-right" ) + .addClass( rtl ? "ui-corner-right" : "ui-corner-left" ) .end() .filter( ":last" ) - .addClass( ltr ? "ui-corner-right" : "ui-corner-left" ) + .addClass( rtl ? "ui-corner-left" : "ui-corner-right" ) .end() .end(); }, -- cgit v1.2.3 From c1cda180a93a6c0a63cf21a68dacb54233e03d03 Mon Sep 17 00:00:00 2001 From: Scott González Date: Tue, 6 Sep 2011 13:01:01 -0400 Subject: Tabs: Find panels using aria-controls instead of index for remove method. Fixes #7698 - Panels do not sort when a tab is sorted which can cause a mismatch error when a tab is removed. --- ui/jquery.ui.tabs.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ui/jquery.ui.tabs.js b/ui/jquery.ui.tabs.js index d4c5f6b69..a1bf72cb1 100644 --- a/ui/jquery.ui.tabs.js +++ b/ui/jquery.ui.tabs.js @@ -792,11 +792,14 @@ if ( $.uiBackCompat !== false ) { index = this._getIndex( index ); var options = this.options, tab = this.lis.eq( index ).remove(), - panel = this.panels.eq( index ).remove(); + panel = this._getPanelForTab( tab.find( "a[aria-controls]" ) ).remove(); // If selected tab was removed focus tab to the right or // in case the last tab was removed the tab to the left. - if ( tab.hasClass( "ui-tabs-active" ) && this.anchors.length > 1) { + // We check for more than 2 tabs, because if there are only 2, + // then when we remove this tab, there will only be one tab left + // so we don't need to detect which tab to activate. + if ( tab.hasClass( "ui-tabs-active" ) && this.anchors.length > 2 ) { this._activate( index + ( index + 1 < this.anchors.length ? 1 : -1 ) ); } -- cgit v1.2.3 From 4387d19030820077ac408e373bc135807e6a6002 Mon Sep 17 00:00:00 2001 From: Scott González Date: Fri, 9 Sep 2011 19:24:10 -0400 Subject: Spinner: Default min and max options to null. --- tests/unit/spinner/spinner_core.js | 20 +++++++++++++------- tests/unit/spinner/spinner_defaults.js | 4 ++-- ui/jquery.ui.spinner.js | 8 ++++---- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/tests/unit/spinner/spinner_core.js b/tests/unit/spinner/spinner_core.js index 57b6b3320..34a79bb16 100644 --- a/tests/unit/spinner/spinner_core.js +++ b/tests/unit/spinner/spinner_core.js @@ -149,22 +149,28 @@ test( "reading HTML5 attributes", function() { }); test( "ARIA attributes", function() { - expect( 7 ); + expect( 9 ); var element = $( "#spin" ).val( 2 ).spinner({ min: -5, max: 5 }); equal( element.attr( "role" ), "spinbutton", "role" ); - equal( element.attr( "aria-valuemin" ), -5, "aria-valuemin" ); - equal( element.attr( "aria-valuemax" ), 5, "aria-valuemax" ); - equal( element.attr( "aria-valuenow" ), 2, "aria-valuenow" ); + equal( element.attr( "aria-valuemin" ), "-5", "aria-valuemin" ); + equal( element.attr( "aria-valuemax" ), "5", "aria-valuemax" ); + equal( element.attr( "aria-valuenow" ), "2", "aria-valuenow" ); element.spinner( "stepUp" ); - equal( element.attr( "aria-valuenow" ), 3, "stepUp 1 step changes aria-valuenow" ); + equal( element.attr( "aria-valuenow" ), "3", "stepUp 1 step changes aria-valuenow" ); element.spinner( "option", { min: -10, max: 10 } ); - equal( element.attr( "aria-valuemin" ), -10, "min option changed aria-valuemin changes" ); - equal( element.attr( "aria-valuemax" ), 10, "max option changed aria-valuemax changes" ); + equal( element.attr( "aria-valuemin" ), "-10", "min option changed aria-valuemin changes" ); + equal( element.attr( "aria-valuemax" ), "10", "max option changed aria-valuemax changes" ); + + element.spinner( "option", "min", null ); + equal( element.attr( "aria-valuemin" ), undefined, "aria-valuemin not set when no min" ); + + element.spinner( "option", "max", null ); + equal( element.attr( "aria-valuemax" ), undefined, "aria-valuemax not set when no max" ); }); test( "focus text field when pressing button", function() { diff --git a/tests/unit/spinner/spinner_defaults.js b/tests/unit/spinner/spinner_defaults.js index f155a658e..3321f8733 100644 --- a/tests/unit/spinner/spinner_defaults.js +++ b/tests/unit/spinner/spinner_defaults.js @@ -2,8 +2,8 @@ commonWidgetTests( "spinner", { defaults: { disabled: false, incremental: true, - max: Number.MAX_VALUE, - min: -Number.MAX_VALUE, + max: null, + min: null, numberFormat: null, page: 10, step: 1, diff --git a/ui/jquery.ui.spinner.js b/ui/jquery.ui.spinner.js index a5c25cd34..97ee20e54 100644 --- a/ui/jquery.ui.spinner.js +++ b/ui/jquery.ui.spinner.js @@ -30,8 +30,8 @@ $.widget( "ui.spinner", { widgetEventPrefix: "spin", options: { incremental: true, - max: Number.MAX_VALUE, - min: -Number.MAX_VALUE, + max: null, + min: null, numberFormat: null, page: 10, step: 1, @@ -247,11 +247,11 @@ $.widget( "ui.spinner", { _trimValue: function( value ) { var options = this.options; - if ( value > options.max) { + if ( options.max != null && value > options.max) { return options.max; } - if ( value < options.min ) { + if ( options.min != null && value < options.min ) { return options.min; } -- cgit v1.2.3 From 7216c08b2fd9ad5e3cb90500f2b13bed6339f2ba Mon Sep 17 00:00:00 2001 From: Scott González Date: Fri, 9 Sep 2011 20:08:51 -0400 Subject: Spinner: Added ability to specify custom incremental function. --- tests/unit/spinner/spinner_options.js | 103 +++++++++++++++++++++------------- ui/jquery.ui.spinner.js | 12 +++- 2 files changed, 74 insertions(+), 41 deletions(-) diff --git a/tests/unit/spinner/spinner_options.js b/tests/unit/spinner/spinner_options.js index 647455fe5..48bdf96a9 100644 --- a/tests/unit/spinner/spinner_options.js +++ b/tests/unit/spinner/spinner_options.js @@ -2,6 +2,71 @@ module( "spinner: options" ); +test( "incremental, false", function() { + expect( 100 ); + + var i, diff, + prev = 0, + element = $( "#spin" ).val( prev ).spinner({ + incremental: false, + spin: function( event, ui ) { + equal( ui.value - prev, 1 ); + prev = ui.value; + } + }); + + for ( i = 0; i < 100; i++ ) { + element.simulate( "keydown", { keyCode: $.ui.keyCode.UP } ); + } +}); + +test( "incremental, true", function() { + expect( 100 ); + + function fill( num, val ) { + return $.map( new Array( num ), function() { + return val; + }); + } + + var i, diff, + prev = 0, + expected = [].concat( fill( 18, 1 ), fill( 37, 2 ), fill( 14, 3 ), + fill( 9, 4 ), fill( 6, 5 ), fill( 5, 6 ), fill ( 5, 7 ), + fill( 4, 8 ), fill( 2, 9 ) ), + element = $( "#spin" ).val( prev ).spinner({ + incremental: true, + spin: function( event, ui ) { + equal( ui.value - prev, expected[ i ] ); + prev = ui.value; + } + }); + + for ( i = 0; i < 100; i++ ) { + element.simulate( "keydown", { keyCode: $.ui.keyCode.UP } ); + } +}); + +test( "incremental, function", function() { + expect( 100 ); + + var i, + prev = 0, + element = $( "#spin" ).val( prev ).spinner({ + incremental: function( i ) { + return i; + }, + spin: function( event, ui ) { + equal( ui.value - prev, i + 1 ); + prev = ui.value; + } + }); + + for ( i = 0; i < 100; i++ ) { + element.simulate( "keydown", { keyCode: $.ui.keyCode.UP } ); + } +}); + test( "numberFormat, number", function() { expect( 2 ); var element = $( "#spin" ).val( 0 ).spinner({ numberFormat: "n" }); @@ -26,44 +91,6 @@ test( "numberFormat, currency", function() { equal( element.val(), "$1.00", "formatted after step" ); }); -/* TODO figure out how to test this properly -test("incremental - false (default)", function() { - var el = $("#spin").spinner({ incremental:false }); - - for ( var i = 1 ; i<=120 ; i++ ) { - el.simulate("keydown",{keyCode:$.ui.keyCode.UP}); - } - el.simulate("keyup",{keyCode:$.ui.keyCode.UP}); - - equals(el.val(), 120, "incremental false - keydown 120 times"); - - for ( var i = 1 ; i<=210 ; i++ ) { - el.simulate("keydown",{keyCode:$.ui.keyCode.DOWN}); - } - el.simulate("keyup",{keyCode:$.ui.keyCode.DOWN}); - - equals(el.val(), -90, "incremental false - keydown 210 times"); -}); - -test("incremental - true (default)", function() { - var el = $("#spin").spinner(); - - for ( var i = 1 ; i<=120 ; i++ ) { - el.simulate("keydown",{keyCode:$.ui.keyCode.UP}); - } - el.simulate("keyup",{keyCode:$.ui.keyCode.UP}); - - equals(el.val(), 300, "incremental true - keydown 120 times (100+20*10)"); - - for ( var i = 1 ; i<=210 ; i++ ) { - el.simulate("keydown",{keyCode:$.ui.keyCode.DOWN}); - } - el.simulate("keyup",{keyCode:$.ui.keyCode.DOWN}); - - equals(el.val(), -1800, "incremental true - keydown 210 times (300-100-100*10-10*100)"); -}); -*/ - test( "max", function() { expect( 3 ); var element = $( "#spin" ).val( 1000 ).spinner({ max: 100 }); diff --git a/ui/jquery.ui.spinner.js b/ui/jquery.ui.spinner.js index 97ee20e54..a7fb30cc3 100644 --- a/ui/jquery.ui.spinner.js +++ b/ui/jquery.ui.spinner.js @@ -233,9 +233,15 @@ $.widget( "ui.spinner", { }, _increment: function( i ) { - return this.options.incremental ? - Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 ) : - 1; + var incremental = this.options.incremental; + + if ( incremental ) { + return $.isFunction( incremental ) ? + incremental( i ) : + Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 ); + } + + return 1; }, _precision: function( num ) { -- cgit v1.2.3 From 94317d7aa4ed439cb825d006fb461145a6d2aa5d Mon Sep 17 00:00:00 2001 From: kborchers Date: Mon, 12 Sep 2011 08:43:49 -0500 Subject: Menu: Added autoCollapse as the default and added a unit test --- tests/unit/menu/menu_events.js | 19 ++++++++++++++++++ ui/jquery.ui.menu.js | 45 +++++++++++++++++++++++++++--------------- 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/tests/unit/menu/menu_events.js b/tests/unit/menu/menu_events.js index 19ac11c68..ab691b782 100644 --- a/tests/unit/menu/menu_events.js +++ b/tests/unit/menu/menu_events.js @@ -41,6 +41,25 @@ test( "handle blur: click", function() { $("#remove").remove(); }); +asyncTest( "handle submenu auto collapse: mouseleave", function() { + expect( 4 ); + var $menu = $( "#menu2" ).menu(); + + $menu.find( "li:nth-child(7)" ).trigger( "mouseover" ); + setTimeout(function() { + equal( $menu.find( "ul[aria-expanded='true']" ).length, 1, "first submenu expanded" ); + $menu.find( "li:nth-child(7) li:first" ).trigger( "mouseover" ); + setTimeout(function() { + equal( $menu.find( "ul[aria-expanded='true']" ).length, 2, "second submenu expanded" ); + $menu.find( "ul[aria-expanded='true']:first" ).trigger( "mouseleave" ); + equal( $menu.find( "ul[aria-expanded='true']" ).length, 1, "second submenu collapsed" ); + $menu.trigger( "mouseleave" ); + equal( $menu.find( "ul[aria-expanded='true']" ).length, 0, "first submenu collapsed" ); + start(); + }, 400); + }, 200); +}); + test("handle keyboard navigation on menu without scroll and without submenus", function() { expect(12); var element = $('#menu1').menu({ diff --git a/ui/jquery.ui.menu.js b/ui/jquery.ui.menu.js index 27e76d909..549eb5fae 100644 --- a/ui/jquery.ui.menu.js +++ b/ui/jquery.ui.menu.js @@ -62,6 +62,8 @@ $.widget( "ui.menu", { target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" ); this.focus( event, target ); }, + "mouseleave": "_mouseleave", + "mouseleave .ui-menu": "_mouseleave", "mouseout .ui-menu-item": "blur", "focus": function( event ) { this.focus( event, $( event.target ).children( ".ui-menu-item:first" ) ); @@ -346,21 +348,30 @@ $.widget( "ui.menu", { }, collapseAll: function( event ) { - this.element - .find( "ul" ) - .hide() - .attr( "aria-hidden", "true" ) - .attr( "aria-expanded", "false" ) - .end() - .find( "a.ui-state-active" ) - .removeClass( "ui-state-active" ); + var currentMenu = false; + if ( event ) { + var target = $( event.target ); + if ( target.is( "ui.menu" ) ) { + currentMenu = target; + } else if ( target.closest( ".ui-menu" ).length ) { + currentMenu = target.closest( ".ui-menu" ); + } + } - this.blur( event ); - this.activeMenu = this.element; + this._close( currentMenu ); + + if( !currentMenu ) { + this.blur( event ); + this.activeMenu = this.element; + } }, - _close: function() { - this.active.parent() + _close: function( startMenu ) { + if( !startMenu ) { + startMenu = this.active ? this.active.parent() : this.element; + } + + startMenu .find( "ul" ) .hide() .attr( "aria-hidden", "true" ) @@ -373,10 +384,7 @@ $.widget( "ui.menu", { collapse: function( event ) { var newItem = this.active && this.active.parents("li:not(.ui-menubar-item)").first(); if ( newItem && newItem.length ) { - this.active.parent() - .attr("aria-hidden", "true") - .attr("aria-expanded", "false") - .hide(); + this._close(); this.focus( event, newItem ); return true; } @@ -486,6 +494,11 @@ $.widget( "ui.menu", { return this.element.height() < this.element.prop( "scrollHeight" ); }, + _mouseleave: function( event ) { + this.collapseAll( event ); + this.blur(); + }, + select: function( event ) { // save active reference before collapseAll triggers blur var ui = { -- cgit v1.2.3 From af76ad1c82625521b94bfc8bf967d9ca4f44da37 Mon Sep 17 00:00:00 2001 From: kborchers Date: Mon, 12 Sep 2011 13:30:41 -0500 Subject: Datepicker: Added additional check to checkExternalClick to work when clicking in another datepicker and removed old fix. Fixes #7686 - infinite loop when onclose event shows a second calendar --- ui/jquery.ui.datepicker.js | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/ui/jquery.ui.datepicker.js b/ui/jquery.ui.datepicker.js index 0b6fb2218..e09dc5a50 100644 --- a/ui/jquery.ui.datepicker.js +++ b/ui/jquery.ui.datepicker.js @@ -636,10 +636,10 @@ $.extend(Datepicker.prototype, { return; var inst = $.datepicker._getInst(input); if ($.datepicker._curInst && $.datepicker._curInst != inst) { - if ( $.datepicker._datepickerShowing ) { - $.datepicker._triggerOnClose($.datepicker._curInst); - } $.datepicker._curInst.dpDiv.stop(true, true); + if ( inst && $.datepicker._datepickerShowing ) { + $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] ); + } } var beforeShow = $.datepicker._get(inst, 'beforeShow'); var beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {}; @@ -790,14 +790,6 @@ $.extend(Datepicker.prototype, { return [position.left, position.top]; }, - /* Trigger custom callback of onClose. */ - _triggerOnClose: function(inst) { - var onClose = this._get(inst, 'onClose'); - if (onClose) - onClose.apply((inst.input ? inst.input[0] : null), - [(inst.input ? inst.input.val() : ''), inst]); - }, - /* Hide the date picker from view. @param input element - the input field attached to the date picker */ _hideDatepicker: function(input) { @@ -820,8 +812,11 @@ $.extend(Datepicker.prototype, { (showAnim == 'fadeIn' ? 'fadeOut' : 'hide'))]((showAnim ? duration : null), postProcess); if (!showAnim) postProcess(); - $.datepicker._triggerOnClose(inst); this._datepickerShowing = false; + var onClose = this._get(inst, 'onClose'); + if (onClose) + onClose.apply((inst.input ? inst.input[0] : null), + [(inst.input ? inst.input.val() : ''), inst]); this._lastInput = null; if (this._inDialog) { this._dialogInput.css({ position: 'absolute', left: '0', top: '-100px' }); @@ -843,12 +838,16 @@ $.extend(Datepicker.prototype, { _checkExternalClick: function(event) { if (!$.datepicker._curInst) return; - var $target = $(event.target); - if ($target[0].id != $.datepicker._mainDivId && + + var $target = $(event.target), + inst = $.datepicker._getInst($target[0]); + + if ( ( ( $target[0].id != $.datepicker._mainDivId && $target.parents('#' + $.datepicker._mainDivId).length == 0 && !$target.hasClass($.datepicker.markerClassName) && !$target.hasClass($.datepicker._triggerClass) && - $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI)) + $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) || + ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst != inst ) ) $.datepicker._hideDatepicker(); }, -- cgit v1.2.3 From 609e1f87f4b242b1f30ccff75d72a863cb1fdb8e Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Mon, 12 Sep 2011 23:19:19 +0200 Subject: Menu: Replace regular bind call with _bind --- ui/jquery.ui.menu.js | 188 +++++++++++++++++++++++++-------------------------- 1 file changed, 94 insertions(+), 94 deletions(-) diff --git a/ui/jquery.ui.menu.js b/ui/jquery.ui.menu.js index 27e76d909..c900f4218 100644 --- a/ui/jquery.ui.menu.js +++ b/ui/jquery.ui.menu.js @@ -71,111 +71,111 @@ $.widget( "ui.menu", { this.refresh(); - this.element.attr( "tabIndex", 0 ).bind( "keydown.menu", function( event ) { - if ( self.options.disabled ) { - return; - } - switch ( event.keyCode ) { - case $.ui.keyCode.PAGE_UP: - self.previousPage( event ); - event.preventDefault(); - event.stopImmediatePropagation(); - break; - case $.ui.keyCode.PAGE_DOWN: - self.nextPage( event ); - event.preventDefault(); - event.stopImmediatePropagation(); - break; - case $.ui.keyCode.HOME: - self._move( "first", "first", event ); - event.preventDefault(); - event.stopImmediatePropagation(); - break; - case $.ui.keyCode.END: - self._move( "last", "last", event ); - event.preventDefault(); - event.stopImmediatePropagation(); - break; - case $.ui.keyCode.UP: - self.previous( event ); - event.preventDefault(); - event.stopImmediatePropagation(); - break; - case $.ui.keyCode.DOWN: - self.next( event ); - event.preventDefault(); - event.stopImmediatePropagation(); - break; - case $.ui.keyCode.LEFT: - if (self.collapse( event )) { + this.element.attr( "tabIndex", 0 ); + this._bind({ + "keydown": function( event ) { + switch ( event.keyCode ) { + case $.ui.keyCode.PAGE_UP: + self.previousPage( event ); + event.preventDefault(); event.stopImmediatePropagation(); - } - event.preventDefault(); - break; - case $.ui.keyCode.RIGHT: - if (self.expand( event )) { + break; + case $.ui.keyCode.PAGE_DOWN: + self.nextPage( event ); + event.preventDefault(); event.stopImmediatePropagation(); - } - event.preventDefault(); - break; - case $.ui.keyCode.ENTER: - if ( self.active.children( "a[aria-haspopup='true']" ).length ) { - if ( self.expand( event ) ) { - event.stopImmediatePropagation(); - } - } - else { - self.select( event ); + break; + case $.ui.keyCode.HOME: + self._move( "first", "first", event ); + event.preventDefault(); event.stopImmediatePropagation(); - } - event.preventDefault(); - break; - case $.ui.keyCode.ESCAPE: - if ( self.collapse( event ) ) { + break; + case $.ui.keyCode.END: + self._move( "last", "last", event ); + event.preventDefault(); event.stopImmediatePropagation(); - } - event.preventDefault(); - break; - default: - event.stopPropagation(); - clearTimeout( self.filterTimer ); - var match, - prev = self.previousFilter || "", - character = String.fromCharCode( event.keyCode ), - skip = false; - - if (character == prev) { - skip = true; - } else { - character = prev + character; - } - function escape( value ) { - return value.replace( /[-[\]{}()*+?.,\\^$|#\s]/g , "\\$&" ); - } - match = self.activeMenu.children( ".ui-menu-item" ).filter( function() { - return new RegExp("^" + escape(character), "i") - .test( $( this ).children( "a" ).text() ); - }); - match = skip && match.index(self.active.next()) != -1 ? self.active.nextAll(".ui-menu-item") : match; - if ( !match.length ) { - character = String.fromCharCode(event.keyCode); - match = self.activeMenu.children(".ui-menu-item").filter( function() { + break; + case $.ui.keyCode.UP: + self.previous( event ); + event.preventDefault(); + event.stopImmediatePropagation(); + break; + case $.ui.keyCode.DOWN: + self.next( event ); + event.preventDefault(); + event.stopImmediatePropagation(); + break; + case $.ui.keyCode.LEFT: + if (self.collapse( event )) { + event.stopImmediatePropagation(); + } + event.preventDefault(); + break; + case $.ui.keyCode.RIGHT: + if (self.expand( event )) { + event.stopImmediatePropagation(); + } + event.preventDefault(); + break; + case $.ui.keyCode.ENTER: + if ( self.active.children( "a[aria-haspopup='true']" ).length ) { + if ( self.expand( event ) ) { + event.stopImmediatePropagation(); + } + } + else { + self.select( event ); + event.stopImmediatePropagation(); + } + event.preventDefault(); + break; + case $.ui.keyCode.ESCAPE: + if ( self.collapse( event ) ) { + event.stopImmediatePropagation(); + } + event.preventDefault(); + break; + default: + event.stopPropagation(); + clearTimeout( self.filterTimer ); + var match, + prev = self.previousFilter || "", + character = String.fromCharCode( event.keyCode ), + skip = false; + + if (character == prev) { + skip = true; + } else { + character = prev + character; + } + function escape( value ) { + return value.replace( /[-[\]{}()*+?.,\\^$|#\s]/g , "\\$&" ); + } + match = self.activeMenu.children( ".ui-menu-item" ).filter( function() { return new RegExp("^" + escape(character), "i") .test( $( this ).children( "a" ).text() ); }); - } - if ( match.length ) { - self.focus( event, match ); - if (match.length > 1) { - self.previousFilter = character; - self.filterTimer = setTimeout( function() { + match = skip && match.index(self.active.next()) != -1 ? self.active.nextAll(".ui-menu-item") : match; + if ( !match.length ) { + character = String.fromCharCode(event.keyCode); + match = self.activeMenu.children(".ui-menu-item").filter( function() { + return new RegExp("^" + escape(character), "i") + .test( $( this ).children( "a" ).text() ); + }); + } + if ( match.length ) { + self.focus( event, match ); + if (match.length > 1) { + self.previousFilter = character; + self.filterTimer = setTimeout( function() { + delete self.previousFilter; + }, 1000 ); + } else { delete self.previousFilter; - }, 1000 ); + } } else { delete self.previousFilter; } - } else { - delete self.previousFilter; } } }); -- cgit v1.2.3 From d12180d1a5ae5f07f112aaeebbfc295f2fe104d8 Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Mon, 12 Sep 2011 23:23:54 +0200 Subject: Widget: Tests code cleanup --- tests/unit/widget/widget_core.js | 34 +++++++++++++++++----------------- tests/unit/widget/widget_extend.js | 5 ++--- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/tests/unit/widget/widget_core.js b/tests/unit/widget/widget_core.js index 41ae8ffb4..0c4142539 100644 --- a/tests/unit/widget/widget_core.js +++ b/tests/unit/widget/widget_core.js @@ -571,23 +571,23 @@ test( ".widget() - overriden", function() { test( "._bind() to element (default)", function() { expect( 12 ); - var self; + var that; $.widget( "ui.testWidget", { _create: function() { - self = this; + that = this; this._bind({ keyup: this.keyup, keydown: "keydown" }); }, keyup: function( event ) { - equals( self, this ); - equals( self.element[0], event.currentTarget ); + equals( that, this ); + equals( that.element[0], event.currentTarget ); equals( "keyup", event.type ); }, keydown: function( event ) { - equals( self, this ); - equals( self.element[0], event.currentTarget ); + equals( that, this ); + equals( that.element[0], event.currentTarget ); equals( "keydown", event.type ); } }); @@ -611,23 +611,23 @@ test( "._bind() to element (default)", function() { test( "._bind() to descendent", function() { expect( 12 ); - var self; + var that; $.widget( "ui.testWidget", { _create: function() { - self = this; + that = this; this._bind( this.element.find( "strong" ), { keyup: this.keyup, keydown: "keydown" }); }, keyup: function( event ) { - equals( self, this ); - equals( self.element.find( "strong" )[0], event.currentTarget ); + equals( that, this ); + equals( that.element.find( "strong" )[0], event.currentTarget ); equals( "keyup", event.type ); }, keydown: function(event) { - equals( self, this ); - equals( self.element.find( "strong" )[0], event.currentTarget ); + equals( that, this ); + equals( that.element.find( "strong" )[0], event.currentTarget ); equals( "keydown", event.type ); } }); @@ -987,31 +987,31 @@ test( "._trigger() - instance as element", function() { $( "#widget" ).testWidget().remove(); }); }); - + test( "auto-destroy - .remove() on parent", function() { shouldDestroy( true, function() { $( "#widget" ).testWidget().parent().remove(); }); }); - + test( "auto-destroy - .remove() on child", function() { shouldDestroy( false, function() { $( "#widget" ).testWidget().children().remove(); }); }); - + test( "auto-destroy - .empty()", function() { shouldDestroy( false, function() { $( "#widget" ).testWidget().empty(); }); }); - + test( "auto-destroy - .empty() on parent", function() { shouldDestroy( true, function() { $( "#widget" ).testWidget().parent().empty(); }); }); - + test( "auto-destroy - .detach()", function() { shouldDestroy( false, function() { $( "#widget" ).testWidget().detach(); diff --git a/tests/unit/widget/widget_extend.js b/tests/unit/widget/widget_extend.js index fb78ecfb7..90e686e18 100644 --- a/tests/unit/widget/widget_extend.js +++ b/tests/unit/widget/widget_extend.js @@ -6,7 +6,6 @@ test( "$.widget.extend()", function() { optionsCopy = { xnumber2: 1, xstring2: "x", xxx: "newstring" }, merged = { xnumber1: 5, xnumber2: 1, xstring1: "peter", xstring2: "x", xxx: "newstring" }, deep1 = { foo: { bar: true } }, - deep1copy = { foo: { bar: true } }, deep2 = { foo: { baz: true }, foo2: document }, deep2copy = { foo: { baz: true }, foo2: document }, deepmerged = { foo: { bar: true, baz: true }, foo2: document }, @@ -93,10 +92,10 @@ test( "$.widget.extend()", function() { deepEqual( defaults, defaultsCopy, "Check if not modified: options1 must not be modified" ); deepEqual( options1, options1Copy, "Check if not modified: options1 must not be modified" ); deepEqual( options2, options2Copy, "Check if not modified: options2 must not be modified" ); - + var input = { key: [ 1, 2, 3 ] - } + }; var output = $.widget.extend( {}, input ); deepEqual( input, output, "don't clone arrays" ); input.key[0] = 10; -- cgit v1.2.3 From 2a6ca3fb394f2caee6ad92c4dfc76ac66553cd46 Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Mon, 12 Sep 2011 23:37:14 +0200 Subject: Widget: Add a _delay method. Will be used in various places to replace setTimeout with custom binding (mostly getting rid of var self/that) --- tests/unit/widget/widget_core.js | 24 ++++++++++++++++++++++++ ui/jquery.ui.widget.js | 9 +++++++++ 2 files changed, 33 insertions(+) diff --git a/tests/unit/widget/widget_core.js b/tests/unit/widget/widget_core.js index 0c4142539..0b272a0d5 100644 --- a/tests/unit/widget/widget_core.js +++ b/tests/unit/widget/widget_core.js @@ -1040,4 +1040,28 @@ test( "redefine", function() { equal( $.ui.testWidget.foo, "bar", "static properties remain" ); }); +asyncTest( "_delay", function() { + expect( 4 ); + var order = 0, + that; + $.widget( "ui.testWidget", { + defaultElement: null, + _create: function() { + that = this; + this._delay(function() { + strictEqual( this, that ); + equal( order, 1 ); + start(); + }, 500); + this._delay("callback"); + }, + callback: function() { + strictEqual( this, that ); + equal( order, 0 ); + order += 1; + } + }); + $( "#widget" ).testWidget(); +}); + }( jQuery ) ); diff --git a/ui/jquery.ui.widget.js b/ui/jquery.ui.widget.js index 5b7942600..729e14cf9 100644 --- a/ui/jquery.ui.widget.js +++ b/ui/jquery.ui.widget.js @@ -333,6 +333,15 @@ $.Widget.prototype = { }); }, + _delay: function( handler, delay ) { + function handlerProxy() { + return ( typeof handler === "string" ? instance[ handler ] : handler ) + .apply( instance, arguments ); + } + var instance = this; + setTimeout( handlerProxy, delay || 0 ); + }, + _hoverable: function( element ) { this.hoverable = this.hoverable.add( element ); this._bind( element, { -- cgit v1.2.3 From 30482cd04b1fe2d5c4c1e29b624eb44828942de4 Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Mon, 12 Sep 2011 23:40:45 +0200 Subject: Widget: Get rid of `var self` --- ui/jquery.ui.widget.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/jquery.ui.widget.js b/ui/jquery.ui.widget.js index 729e14cf9..55b6eda5d 100644 --- a/ui/jquery.ui.widget.js +++ b/ui/jquery.ui.widget.js @@ -270,9 +270,9 @@ $.Widget.prototype = { return this; }, _setOptions: function( options ) { - var self = this; + var that = this; $.each( options, function( key, value ) { - self._setOption( key, value ); + that._setOption( key, value ); }); return this; -- cgit v1.2.3 From 3a0340f4ee2d343cdebeb398da10c2a71a948a9f Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Mon, 12 Sep 2011 23:47:09 +0200 Subject: Widget: return timer value from _delay --- tests/unit/widget/widget_core.js | 8 +++++--- ui/jquery.ui.widget.js | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/unit/widget/widget_core.js b/tests/unit/widget/widget_core.js index 0b272a0d5..0510da4b4 100644 --- a/tests/unit/widget/widget_core.js +++ b/tests/unit/widget/widget_core.js @@ -1041,19 +1041,21 @@ test( "redefine", function() { }); asyncTest( "_delay", function() { - expect( 4 ); + expect( 6 ); var order = 0, that; $.widget( "ui.testWidget", { defaultElement: null, _create: function() { that = this; - this._delay(function() { + var timer = this._delay(function() { strictEqual( this, that ); equal( order, 1 ); start(); }, 500); - this._delay("callback"); + ok( timer !== undefined ); + timer = this._delay("callback"); + ok( timer !== undefined ); }, callback: function() { strictEqual( this, that ); diff --git a/ui/jquery.ui.widget.js b/ui/jquery.ui.widget.js index 55b6eda5d..31328a455 100644 --- a/ui/jquery.ui.widget.js +++ b/ui/jquery.ui.widget.js @@ -339,7 +339,7 @@ $.Widget.prototype = { .apply( instance, arguments ); } var instance = this; - setTimeout( handlerProxy, delay || 0 ); + return setTimeout( handlerProxy, delay || 0 ); }, _hoverable: function( element ) { -- cgit v1.2.3 From bf26bf1ac4b2be791c2f283a60453fc59ee389bb Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Mon, 12 Sep 2011 23:52:17 +0200 Subject: Menu: Get rid of `var self`, replacing with `that` or calls to _delay --- ui/jquery.ui.menu.js | 88 ++++++++++++++++++++++++---------------------------- 1 file changed, 41 insertions(+), 47 deletions(-) diff --git a/ui/jquery.ui.menu.js b/ui/jquery.ui.menu.js index c900f4218..050112db5 100644 --- a/ui/jquery.ui.menu.js +++ b/ui/jquery.ui.menu.js @@ -26,7 +26,6 @@ $.widget( "ui.menu", { } }, _create: function() { - var self = this; this.activeMenu = this.element; this.menuId = this.element.attr( "id" ) || "ui-menu-" + idIncrement++; if ( this.element.find( ".ui-icon" ).length ) { @@ -40,11 +39,11 @@ $.widget( "ui.menu", { }) // need to catch all clicks on disabled menu // not possible through _bind - .bind( "click.menu", function( event ) { - if ( self.options.disabled ) { + .bind( "click.menu", $.proxy( function( event ) { + if ( this.options.disabled ) { event.preventDefault(); } - }); + }, this)); this._bind({ "click .ui-menu-item:has(a)": function( event ) { event.stopImmediatePropagation(); @@ -76,70 +75,70 @@ $.widget( "ui.menu", { "keydown": function( event ) { switch ( event.keyCode ) { case $.ui.keyCode.PAGE_UP: - self.previousPage( event ); + this.previousPage( event ); event.preventDefault(); event.stopImmediatePropagation(); break; case $.ui.keyCode.PAGE_DOWN: - self.nextPage( event ); + this.nextPage( event ); event.preventDefault(); event.stopImmediatePropagation(); break; case $.ui.keyCode.HOME: - self._move( "first", "first", event ); + this._move( "first", "first", event ); event.preventDefault(); event.stopImmediatePropagation(); break; case $.ui.keyCode.END: - self._move( "last", "last", event ); + this._move( "last", "last", event ); event.preventDefault(); event.stopImmediatePropagation(); break; case $.ui.keyCode.UP: - self.previous( event ); + this.previous( event ); event.preventDefault(); event.stopImmediatePropagation(); break; case $.ui.keyCode.DOWN: - self.next( event ); + this.next( event ); event.preventDefault(); event.stopImmediatePropagation(); break; case $.ui.keyCode.LEFT: - if (self.collapse( event )) { + if (this.collapse( event )) { event.stopImmediatePropagation(); } event.preventDefault(); break; case $.ui.keyCode.RIGHT: - if (self.expand( event )) { + if (this.expand( event )) { event.stopImmediatePropagation(); } event.preventDefault(); break; case $.ui.keyCode.ENTER: - if ( self.active.children( "a[aria-haspopup='true']" ).length ) { - if ( self.expand( event ) ) { + if ( this.active.children( "a[aria-haspopup='true']" ).length ) { + if ( this.expand( event ) ) { event.stopImmediatePropagation(); } } else { - self.select( event ); + this.select( event ); event.stopImmediatePropagation(); } event.preventDefault(); break; case $.ui.keyCode.ESCAPE: - if ( self.collapse( event ) ) { + if ( this.collapse( event ) ) { event.stopImmediatePropagation(); } event.preventDefault(); break; default: event.stopPropagation(); - clearTimeout( self.filterTimer ); + clearTimeout( this.filterTimer ); var match, - prev = self.previousFilter || "", + prev = this.previousFilter || "", character = String.fromCharCode( event.keyCode ), skip = false; @@ -151,30 +150,30 @@ $.widget( "ui.menu", { function escape( value ) { return value.replace( /[-[\]{}()*+?.,\\^$|#\s]/g , "\\$&" ); } - match = self.activeMenu.children( ".ui-menu-item" ).filter( function() { + match = this.activeMenu.children( ".ui-menu-item" ).filter( function() { return new RegExp("^" + escape(character), "i") .test( $( this ).children( "a" ).text() ); }); - match = skip && match.index(self.active.next()) != -1 ? self.active.nextAll(".ui-menu-item") : match; + match = skip && match.index(this.active.next()) != -1 ? this.active.nextAll(".ui-menu-item") : match; if ( !match.length ) { character = String.fromCharCode(event.keyCode); - match = self.activeMenu.children(".ui-menu-item").filter( function() { + match = this.activeMenu.children(".ui-menu-item").filter( function() { return new RegExp("^" + escape(character), "i") .test( $( this ).children( "a" ).text() ); }); } if ( match.length ) { - self.focus( event, match ); + this.focus( event, match ); if (match.length > 1) { - self.previousFilter = character; - self.filterTimer = setTimeout( function() { - delete self.previousFilter; + this.previousFilter = character; + this.filterTimer = this._delay( function() { + delete this.previousFilter; }, 1000 ); } else { - delete self.previousFilter; + delete this.previousFilter; } } else { - delete self.previousFilter; + delete this.previousFilter; } } } @@ -219,7 +218,7 @@ $.widget( "ui.menu", { }, refresh: function() { - var self = this, + var that = this, // initialize nested menus submenus = this.element.find( "ul:not(.ui-menu)" ) @@ -239,7 +238,7 @@ $.widget( "ui.menu", { .attr( "tabIndex", -1 ) .attr( "role", "menuitem" ) .attr( "id", function( i ) { - return self.element.attr( "id" ) + "-" + i; + return that.element.attr( "id" ) + "-" + i; }); submenus.each( function() { @@ -253,9 +252,6 @@ $.widget( "ui.menu", { }, focus: function( event, item ) { - var nested, - self = this; - this.blur( event ); if ( this._hasScroll() ) { @@ -277,18 +273,18 @@ $.widget( "ui.menu", { .children( "a" ) .addClass( "ui-state-focus" ) .end(); - self.element.attr( "aria-activedescendant", self.active.children("a").attr("id") ); + this.element.attr( "aria-activedescendant", this.active.children("a").attr("id") ); // highlight active parent menu item, if any this.active.parent().closest(".ui-menu-item").children("a:first").addClass("ui-state-active"); - self.timer = setTimeout( function() { - self._close(); - }, self.delay ); + this.timer = this._delay( function() { + this._close(); + }, this.delay ); - nested = $( ">ul", item ); + var nested = $( ">ul", item ); if ( nested.length && ( /^mouse/.test( event.type ) ) ) { - self._startOpening(nested); + this._startOpening(nested); } this.activeMenu = item.parent(); @@ -317,11 +313,10 @@ $.widget( "ui.menu", { return; } - var self = this; - self.timer = setTimeout( function() { - self._close(); - self._open( submenu ); - }, self.delay ); + this.timer = this._delay( function() { + this._close(); + this._open( submenu ); + }, this.delay ); }, _open: function( submenu ) { @@ -383,15 +378,14 @@ $.widget( "ui.menu", { }, expand: function( event ) { - var self = this, - newItem = this.active && this.active.children("ul").children("li").first(); + var newItem = this.active && this.active.children("ul").children("li").first(); if ( newItem && newItem.length ) { this._open( newItem.parent() ); //timeout so Firefox will not hide activedescendant change in expanding submenu from AT - setTimeout( function() { - self.focus( event, newItem ); + this._delay( function() { + this.focus( event, newItem ); }, 20 ); return true; } -- cgit v1.2.3 From e1ec6f8ebb509b636840dfad11aa062c9877beac Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Tue, 13 Sep 2011 00:24:43 +0200 Subject: Menu: Refactor to get rid of var that. Cleanup some odd formattings and unneeded temp vars --- tests/visual/menu/menu.html | 12 ++++++------ ui/jquery.ui.menu.js | 40 +++++++++++++++++++--------------------- 2 files changed, 25 insertions(+), 27 deletions(-) diff --git a/tests/visual/menu/menu.html b/tests/visual/menu/menu.html index 5720d04d9..195488184 100644 --- a/tests/visual/menu/menu.html +++ b/tests/visual/menu/menu.html @@ -16,7 +16,7 @@ right: 10, top: 10 }).appendTo(document.body).themeswitcher(); - + function create() { menus.menu({ select: function(event, ui) { @@ -24,8 +24,8 @@ } }); } - - var menus = $("#menu1, #menu2, #menu3, #menu4"); + + var menus = $("#menu1, #menu2, #menu3, .menu4"); create(); $("#toggle-destroy").toggle(function() { @@ -41,11 +41,11 @@ - + - + + + +
Log:
@@ -182,4 +280,4 @@ - + \ No newline at end of file diff --git a/ui/jquery.ui.menu.js b/ui/jquery.ui.menu.js index 9cb6afe32..455a12184 100644 --- a/ui/jquery.ui.menu.js +++ b/ui/jquery.ui.menu.js @@ -20,6 +20,7 @@ $.widget( "ui.menu", { defaultElement: "
    ", delay: 150, options: { + items: "ul", position: { my: "left top", at: "right top" @@ -194,7 +195,7 @@ $.widget( "ui.menu", { //destroy (sub)menus this.element .removeAttr( "aria-activedescendant" ) - .find( "ul" ) + .find( ".ui-menu" ) .andSelf() .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) .removeAttr( "role" ) @@ -221,7 +222,7 @@ $.widget( "ui.menu", { refresh: function() { // initialize nested menus - var submenus = this.element.find( "ul:not(.ui-menu)" ) + var submenus = this.element.find( this.options.items + ":not( .ui-menu )" ) .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) .attr( "role", "menu" ) .hide() @@ -230,7 +231,7 @@ $.widget( "ui.menu", { // don't refresh list items that are already adapted var menuId = this.menuId; - submenus.add( this.element ).children( "li:not(.ui-menu-item):has(a)" ) + submenus.add( this.element ).children( ":not( .ui-menu-item ):has( a )" ) .addClass( "ui-menu-item" ) .attr( "role", "presentation" ) .children( "a" ) @@ -273,16 +274,16 @@ $.widget( "ui.menu", { .children( "a" ) .addClass( "ui-state-focus" ) .end(); - this.element.attr( "aria-activedescendant", this.active.children("a").attr("id") ); + this.element.attr( "aria-activedescendant", this.active.children( "a" ).attr( "id" ) ); // highlight active parent menu item, if any - this.active.parent().closest(".ui-menu-item").children("a:first").addClass("ui-state-active"); + this.active.parent().closest( ".ui-menu-item" ).children( "a:first" ).addClass( "ui-state-active" ); this.timer = this._delay( function() { this._close(); }, this.delay ); - var nested = $( ">ul", item ); + var nested = $( "> .ui-menu", item ); if ( nested.length && ( /^mouse/.test( event.type ) ) ) { this._startOpening(nested); } @@ -353,19 +354,19 @@ $.widget( "ui.menu", { this._close( currentMenu ); - if( !currentMenu ) { + if ( !currentMenu ) { this.blur( event ); this.activeMenu = this.element; } }, _close: function( startMenu ) { - if( !startMenu ) { + if ( !startMenu ) { startMenu = this.active ? this.active.parent() : this.element; } startMenu - .find( "ul" ) + .find( ".ui-menu" ) .hide() .attr( "aria-hidden", "true" ) .attr( "aria-expanded", "false" ) @@ -375,7 +376,7 @@ $.widget( "ui.menu", { }, collapse: function( event ) { - var newItem = this.active && this.active.parents("li:not(.ui-menubar-item)").first(); + var newItem = this.active && this.active.parent().closest( ".ui-menu-item", this.element ); if ( newItem && newItem.length ) { this._close(); this.focus( event, newItem ); @@ -384,7 +385,7 @@ $.widget( "ui.menu", { }, expand: function( event ) { - var newItem = this.active && this.active.children("ul").children("li").first(); + var newItem = this.active && this.active.children( ".ui-menu " ).children( ".ui-menu-item" ).first(); if ( newItem && newItem.length ) { this._open( newItem.parent() ); -- cgit v1.2.3 From 8274f081e08b6e9dd69686ced17c4413dcc044c6 Mon Sep 17 00:00:00 2001 From: Scott González Date: Fri, 16 Sep 2011 11:33:26 -0400 Subject: Position demo: Updated sizes of elements. --- demos/position/default.html | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/demos/position/default.html b/demos/position/default.html index f7cba888d..f5caf3bc1 100644 --- a/demos/position/default.html +++ b/demos/position/default.html @@ -14,6 +14,7 @@ + + + +
    + Log In +
    +
    + + +
    +
    + + +
    +
    + +
    +
    +
    + +
    + +

    A link to a login form that opens as a popup. Open and close animations have been used.

    + +
    + + + + diff --git a/demos/popup/index.html b/demos/popup/index.html index e69365c98..961585268 100644 --- a/demos/popup/index.html +++ b/demos/popup/index.html @@ -10,6 +10,7 @@

    Examples

    diff --git a/ui/jquery.ui.popup.js b/ui/jquery.ui.popup.js index 15349bc23..487a53eea 100644 --- a/ui/jquery.ui.popup.js +++ b/ui/jquery.ui.popup.js @@ -22,7 +22,9 @@ $.widget( "ui.popup", { position: { my: "left top", at: "left bottom" - } + }, + show: "slideDown", + hide: "fadeOut" }, _create: function() { if ( !this.options.trigger ) { @@ -45,8 +47,9 @@ $.widget( "ui.popup", { .attr( "aria-owns", this.element.attr( "id" ) ); this.element - .addClass( "ui-popup" ); - this.close(); + .addClass( "ui-popup" ) + this._beforeClose(); + this.element.hide(); this._bind(this.options.trigger, { keydown: function( event ) { @@ -159,8 +162,8 @@ $.widget( "ui.popup", { of: this.options.trigger }, this.options.position ); + this._show( this.element, this.options.show ); this.element - .show() .attr( "aria-hidden", "false" ) .attr( "aria-expanded", "true" ) .position( position ); @@ -190,10 +193,8 @@ $.widget( "ui.popup", { }, close: function( event ) { - this.element - .hide() - .attr( "aria-hidden", "true" ) - .attr( "aria-expanded", "false" ); + this._beforeClose(); + this._hide( this.element, this.options.hide ); this.options.trigger.attr( "tabindex" , 0 ); if ( this.removeTabIndex ) { @@ -201,6 +202,12 @@ $.widget( "ui.popup", { } this.isOpen = false; this._trigger( "close", event ); + }, + + _beforeClose: function() { + this.element + .attr( "aria-hidden", "true" ) + .attr( "aria-expanded", "false" ); } }); -- cgit v1.2.3 From a3866bf057a8ef1d72f07de6fc12c2d9e4e4bb6f Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Wed, 21 Sep 2011 22:48:55 +0200 Subject: Popup: Use duration:fast for default animations. Also fix two missing semicolons. --- ui/jquery.ui.popup.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/ui/jquery.ui.popup.js b/ui/jquery.ui.popup.js index 487a53eea..4ef1e2c29 100644 --- a/ui/jquery.ui.popup.js +++ b/ui/jquery.ui.popup.js @@ -23,8 +23,14 @@ $.widget( "ui.popup", { my: "left top", at: "left bottom" }, - show: "slideDown", - hide: "fadeOut" + show: { + effect: "slideDown", + duration: "fast" + }, + hide: { + effect: "fadeOut", + duration: "fast" + } }, _create: function() { if ( !this.options.trigger ) { @@ -47,7 +53,7 @@ $.widget( "ui.popup", { .attr( "aria-owns", this.element.attr( "id" ) ); this.element - .addClass( "ui-popup" ) + .addClass( "ui-popup" ); this._beforeClose(); this.element.hide(); @@ -134,7 +140,7 @@ $.widget( "ui.popup", { this.close( event ); } } - }) + }); }, _destroy: function() { @@ -203,7 +209,7 @@ $.widget( "ui.popup", { this.isOpen = false; this._trigger( "close", event ); }, - + _beforeClose: function() { this.element .attr( "aria-hidden", "true" ) -- cgit v1.2.3 From cb372b7c2022f0827a5aeab117f0a21ff7cb8193 Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Wed, 21 Sep 2011 22:54:29 +0200 Subject: Popup: Make menu dependency actually optional, cleanup demos --- demos/popup/animation.html | 12 ------------ demos/popup/default.html | 12 ------------ ui/jquery.ui.popup.js | 7 ++++--- 3 files changed, 4 insertions(+), 27 deletions(-) diff --git a/demos/popup/animation.html b/demos/popup/animation.html index 3d5f50583..d14a12cd7 100644 --- a/demos/popup/animation.html +++ b/demos/popup/animation.html @@ -9,7 +9,6 @@ - @@ -43,17 +42,6 @@