diff options
31 files changed, 470 insertions, 270 deletions
diff --git a/build/tasks/testswarm.js b/build/tasks/testswarm.js index 118887ca6..c0244ebad 100644 --- a/build/tasks/testswarm.js +++ b/build/tasks/testswarm.js @@ -63,7 +63,7 @@ grunt.registerTask( "testswarm", function( commit, configFile ) { grunt.registerTask( "testswarm-multi-jquery", function( commit, configFile ) { var allTests = {}; - "1.6 1.6.1 1.6.3 1.6.4 1.7 1.7.1 1.7.2 git".split(" ").forEach(function( version ) { + "1.6 1.6.1 1.6.2 1.6.3 1.6.4 1.7 1.7.1 1.7.2 git".split(" ").forEach(function( version ) { for ( var test in tests ) { allTests[ test + "-" + version ] = tests[ test ] + "?nojshint=true&jquery=" + version; } diff --git a/demos/menu/topalignmenu.html b/demos/menu/topalignmenu.html index 62373ba9d..a6ac11520 100644 --- a/demos/menu/topalignmenu.html +++ b/demos/menu/topalignmenu.html @@ -13,7 +13,10 @@ <script> $(function() { $( "#menu" ).menu({ - position: { of: "ul:has(a.ui-state-focus):last" } + position: { of: "ul:has(a.ui-state-focus):last" }, + icons: { + submenu: "ui-icon-carat-1-e" + } }); }); </script> diff --git a/demos/spinner/currency.html b/demos/spinner/currency.html index 348666143..a52f187c1 100644 --- a/demos/spinner/currency.html +++ b/demos/spinner/currency.html @@ -5,7 +5,7 @@ <title>jQuery UI Spinner - Default functionality</title> <link rel="stylesheet" href="../../themes/base/jquery.ui.all.css"> <script src="../../jquery-1.7.2.js"></script> - <script src="../../external/jquery.mousewheel-3.0.4.js"></script> + <script src="../../external/jquery.mousewheel.js"></script> <script src="../../external/globalize.js"></script> <script src="../../external/globalize.culture.de-DE.js"></script> <script src="../../external/globalize.culture.ja-JP.js"></script> @@ -52,7 +52,7 @@ <div class="demo-description"> -<p>Example of a donation form, with currency selection and amout spinner.</p> +<p>Example of a donation form, with currency selection and amount spinner.</p> </div><!-- End demo-description --> </body> diff --git a/demos/spinner/decimal.html b/demos/spinner/decimal.html index 0af4c520c..87e413da8 100644 --- a/demos/spinner/decimal.html +++ b/demos/spinner/decimal.html @@ -5,7 +5,7 @@ <title>jQuery UI Spinner - Decimal</title> <link rel="stylesheet" href="../../themes/base/jquery.ui.all.css"> <script src="../../jquery-1.7.2.js"></script> - <script src="../../external/jquery.mousewheel-3.0.4.js"></script> + <script src="../../external/jquery.mousewheel.js"></script> <script src="../../external/globalize.js"></script> <script src="../../external/globalize.culture.de-DE.js"></script> <script src="../../external/globalize.culture.ja-JP.js"></script> diff --git a/demos/spinner/default.html b/demos/spinner/default.html index 1827724b9..b857a9095 100644 --- a/demos/spinner/default.html +++ b/demos/spinner/default.html @@ -5,7 +5,7 @@ <title>jQuery UI Spinner - Default functionality</title> <link rel="stylesheet" href="../../themes/base/jquery.ui.all.css"> <script src="../../jquery-1.7.2.js"></script> - <script src="../../external/jquery.mousewheel-3.0.4.js"></script> + <script src="../../external/jquery.mousewheel.js"></script> <script src="../../ui/jquery.ui.core.js"></script> <script src="../../ui/jquery.ui.widget.js"></script> <script src="../../ui/jquery.ui.button.js"></script> diff --git a/demos/spinner/latlong.html b/demos/spinner/latlong.html index f4292c56a..eafbd257f 100644 --- a/demos/spinner/latlong.html +++ b/demos/spinner/latlong.html @@ -6,7 +6,7 @@ <link rel="stylesheet" href="../../themes/base/jquery.ui.all.css"> <script src="http://maps.google.com/maps/api/js?sensor=false"></script> <script src="../../jquery-1.7.2.js"></script> - <script src="../../external/jquery.mousewheel-3.0.4.js"></script> + <script src="../../external/jquery.mousewheel.js"></script> <script src="../../ui/jquery.ui.core.js"></script> <script src="../../ui/jquery.ui.widget.js"></script> <script src="../../ui/jquery.ui.button.js"></script> diff --git a/demos/spinner/overflow.html b/demos/spinner/overflow.html index 312853ddb..17d1ca30b 100644 --- a/demos/spinner/overflow.html +++ b/demos/spinner/overflow.html @@ -5,7 +5,7 @@ <title>jQuery UI Spinner - Overflow</title> <link rel="stylesheet" href="../../themes/base/jquery.ui.all.css"> <script src="../../jquery-1.7.2.js"></script> - <script src="../../external/jquery.mousewheel-3.0.4.js"></script> + <script src="../../external/jquery.mousewheel.js"></script> <script src="../../ui/jquery.ui.core.js"></script> <script src="../../ui/jquery.ui.widget.js"></script> <script src="../../ui/jquery.ui.button.js"></script> diff --git a/demos/spinner/time.html b/demos/spinner/time.html index 8f8088486..a45a801d5 100644 --- a/demos/spinner/time.html +++ b/demos/spinner/time.html @@ -5,7 +5,7 @@ <title>jQuery UI Spinner - Time</title> <link rel="stylesheet" href="../../themes/base/jquery.ui.all.css"> <script src="../../jquery-1.7.2.js"></script> - <script src="../../external/jquery.mousewheel-3.0.4.js"></script> + <script src="../../external/jquery.mousewheel.js"></script> <script src="../../external/globalize.js"></script> <script src="../../external/globalize.culture.de-DE.js"></script> <script src="../../ui/jquery.ui.core.js"></script> diff --git a/external/jquery.mousewheel-3.0.4.js b/external/jquery.mousewheel.js index dbf8f4b0f..808e12b89 100644 --- a/external/jquery.mousewheel-3.0.4.js +++ b/external/jquery.mousewheel.js @@ -1,12 +1,12 @@ -/*! Copyright (c) 2010 Brandon Aaron (http://brandonaaron.net)
+/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net)
* Licensed under the MIT License (LICENSE.txt).
*
* Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
* Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
* Thanks to: Seamus Leahy for adding deltaX and deltaY
*
- * Version: 3.0.4
- *
+ * Version: 3.0.6
+ *
* Requires: 1.2.2+
*/
@@ -14,6 +14,12 @@ var types = ['DOMMouseScroll', 'mousewheel'];
+if ($.event.fixHooks) {
+ for ( var i=types.length; i; ) {
+ $.event.fixHooks[ types[--i] ] = $.event.mouseHooks;
+ }
+}
+
$.event.special.mousewheel = {
setup: function() {
if ( this.addEventListener ) {
@@ -24,7 +30,7 @@ $.event.special.mousewheel = { this.onmousewheel = handler;
}
},
-
+
teardown: function() {
if ( this.removeEventListener ) {
for ( var i=types.length; i; ) {
@@ -40,7 +46,7 @@ $.fn.extend({ mousewheel: function(fn) {
return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel");
},
-
+
unmousewheel: function(fn) {
return this.unbind("mousewheel", fn);
}
@@ -51,28 +57,28 @@ function handler(event) { var orgEvent = event || window.event, args = [].slice.call( arguments, 1 ), delta = 0, returnValue = true, deltaX = 0, deltaY = 0;
event = $.event.fix(orgEvent);
event.type = "mousewheel";
-
+
// Old school scrollwheel delta
- if ( event.wheelDelta ) { delta = event.wheelDelta/120; }
- if ( event.detail ) { delta = -event.detail/3; }
-
+ if ( orgEvent.wheelDelta ) { delta = orgEvent.wheelDelta/120; }
+ if ( orgEvent.detail ) { delta = -orgEvent.detail/3; }
+
// New school multidimensional scroll (touchpads) deltas
deltaY = delta;
-
+
// Gecko
if ( orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
deltaY = 0;
deltaX = -1*delta;
}
-
+
// Webkit
if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY/120; }
if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = -1*orgEvent.wheelDeltaX/120; }
-
+
// Add event and delta to the front of the arguments
args.unshift(event, delta, deltaX, deltaY);
-
- return $.event.handle.apply(this, args);
+
+ return ($.event.dispatch || $.event.handle).apply(this, args);
}
})(jQuery);
\ No newline at end of file diff --git a/external/qunit.css b/external/qunit.css index 5684a4485..257b224ff 100644 --- a/external/qunit.css +++ b/external/qunit.css @@ -1,5 +1,5 @@ /** - * QUnit v1.8.0 - A JavaScript Unit Testing Framework + * QUnit v1.9.0 - A JavaScript Unit Testing Framework * * http://docs.jquery.com/QUnit * @@ -38,10 +38,10 @@ line-height: 1em; font-weight: normal; - border-radius: 15px 15px 0 0; - -moz-border-radius: 15px 15px 0 0; - -webkit-border-top-right-radius: 15px; - -webkit-border-top-left-radius: 15px; + border-radius: 5px 5px 0 0; + -moz-border-radius: 5px 5px 0 0; + -webkit-border-top-right-radius: 5px; + -webkit-border-top-left-radius: 5px; } #qunit-header a { @@ -54,9 +54,9 @@ color: #fff; } -#qunit-header label { +#qunit-testrunner-toolbar label { display: inline-block; - padding-left: 0.5em; + padding: 0 .5em 0 .1em; } #qunit-banner { @@ -113,13 +113,9 @@ background-color: #fff; - border-radius: 15px; - -moz-border-radius: 15px; - -webkit-border-radius: 15px; - - box-shadow: inset 0px 2px 13px #999; - -moz-box-shadow: inset 0px 2px 13px #999; - -webkit-box-shadow: inset 0px 2px 13px #999; + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; } #qunit-tests table { @@ -162,8 +158,7 @@ #qunit-tests b.failed { color: #710909; } #qunit-tests li li { - margin: 0.5em; - padding: 0.4em 0.5em 0.4em 0.5em; + padding: 5px; background-color: #fff; border-bottom: none; list-style-position: inside; @@ -172,9 +167,9 @@ /*** Passing Styles */ #qunit-tests li li.pass { - color: #5E740B; + color: #3c510c; background-color: #fff; - border-left: 26px solid #C6E746; + border-left: 10px solid #C6E746; } #qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; } @@ -190,15 +185,15 @@ #qunit-tests li li.fail { color: #710909; background-color: #fff; - border-left: 26px solid #EE5757; + border-left: 10px solid #EE5757; white-space: pre; } #qunit-tests > li:last-child { - border-radius: 0 0 15px 15px; - -moz-border-radius: 0 0 15px 15px; - -webkit-border-bottom-right-radius: 15px; - -webkit-border-bottom-left-radius: 15px; + border-radius: 0 0 5px 5px; + -moz-border-radius: 0 0 5px 5px; + -webkit-border-bottom-right-radius: 5px; + -webkit-border-bottom-left-radius: 5px; } #qunit-tests .fail { color: #000000; background-color: #EE5757; } diff --git a/external/qunit.js b/external/qunit.js index c1570c252..9efedcb44 100644 --- a/external/qunit.js +++ b/external/qunit.js @@ -1,5 +1,5 @@ /** - * QUnit v1.8.0 - A JavaScript Unit Testing Framework + * QUnit v1.9.0 - A JavaScript Unit Testing Framework * * http://docs.jquery.com/QUnit * @@ -403,6 +403,8 @@ QUnit = { QUnit.assert = { /** * Asserts rough true-ish result. + * @name ok + * @function * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" ); */ ok: function( result, msg ) { @@ -437,36 +439,59 @@ QUnit.assert = { /** * Assert that the first two arguments are equal, with an optional message. * Prints out both actual and expected values. + * @name equal + * @function * @example equal( format( "Received {0} bytes.", 2), "Received 2 bytes.", "format() replaces {0} with next argument" ); */ equal: function( actual, expected, message ) { QUnit.push( expected == actual, actual, expected, message ); }, + /** + * @name notEqual + * @function + */ notEqual: function( actual, expected, message ) { QUnit.push( expected != actual, actual, expected, message ); }, + /** + * @name deepEqual + * @function + */ deepEqual: function( actual, expected, message ) { QUnit.push( QUnit.equiv(actual, expected), actual, expected, message ); }, + /** + * @name notDeepEqual + * @function + */ notDeepEqual: function( actual, expected, message ) { QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message ); }, + /** + * @name strictEqual + * @function + */ strictEqual: function( actual, expected, message ) { QUnit.push( expected === actual, actual, expected, message ); }, + /** + * @name notStrictEqual + * @function + */ notStrictEqual: function( actual, expected, message ) { QUnit.push( expected !== actual, actual, expected, message ); }, - raises: function( block, expected, message ) { + throws: function( block, expected, message ) { var actual, ok = false; + // 'expected' is optional if ( typeof expected === "string" ) { message = expected; expected = null; @@ -494,18 +519,29 @@ QUnit.assert = { } else if ( expected.call( {}, actual ) === true ) { ok = true; } - } - QUnit.push( ok, actual, null, message ); + QUnit.push( ok, actual, null, message ); + } else { + QUnit.pushFailure( message, null, 'No exception was thrown.' ); + } } }; -// @deprecated: Kept assertion helpers in root for backwards compatibility +/** + * @deprecate since 1.8.0 + * Kept assertion helpers in root for backwards compatibility + */ extend( QUnit, QUnit.assert ); /** - * @deprecated: Kept for backwards compatibility - * next step: remove entirely + * @deprecated since 1.9.0 + * Kept global "raises()" for backwards compatibility + */ +QUnit.raises = QUnit.assert.throws; + +/** + * @deprecated since 1.0.0, replaced with error pushes since 1.3.0 + * Kept to avoid TypeErrors for undefined methods. */ QUnit.equals = function() { QUnit.push( false, false, false, "QUnit.equals has been deprecated since 2009 (e88049a0), use QUnit.equal instead" ); @@ -549,7 +585,20 @@ config = { // when enabled, all tests must call expect() requireExpects: false, - urlConfig: [ "noglobals", "notrycatch" ], + // add checkboxes that are persisted in the query-string + // when enabled, the id is set to `true` as a `QUnit.config` property + urlConfig: [ + { + id: "noglobals", + label: "Check for Globals", + tooltip: "Enabling this will test if any test introduces new properties on the `window` object. Stored as query-strings." + }, + { + id: "notrycatch", + label: "No try-catch", + tooltip: "Enabling this will run tests outside of a try-catch block. Makes debugging exceptions in IE reasonable. Stored as query-strings." + } + ], // logging callback queues begin: [], @@ -770,7 +819,7 @@ extend( QUnit, { }); }, - pushFailure: function( message, source ) { + pushFailure: function( message, source, actual ) { if ( !config.current ) { throw new Error( "pushFailure() assertion outside test context, was " + sourceFromStacktrace(2) ); } @@ -781,15 +830,23 @@ extend( QUnit, { message: message }; - message = escapeInnerText(message ) || "error"; + message = escapeInnerText( message ) || "error"; message = "<span class='test-message'>" + message + "</span>"; output = message; + output += "<table>"; + + if ( actual ) { + output += "<tr class='test-actual'><th>Result: </th><td><pre>" + escapeInnerText( actual ) + "</pre></td></tr>"; + } + if ( source ) { details.source = source; - output += "<table><tr class='test-source'><th>Source: </th><td><pre>" + escapeInnerText( source ) + "</pre></td></tr></table>"; + output += "<tr class='test-source'><th>Source: </th><td><pre>" + escapeInnerText( source ) + "</pre></td></tr>"; } + output += "</table>"; + runLoggingCallbacks( "log", QUnit, details ); config.current.assertions.push({ @@ -859,7 +916,7 @@ QUnit.load = function() { runLoggingCallbacks( "begin", QUnit, {} ); // Initialize the config, saving the execution queue - var banner, filter, i, label, len, main, ol, toolbar, userAgent, val, + var banner, filter, i, label, len, main, ol, toolbar, userAgent, val, urlConfigCheckboxes, urlConfigHtml = "", oldconfig = extend( {}, config ); @@ -872,8 +929,15 @@ QUnit.load = function() { for ( i = 0; i < len; i++ ) { val = config.urlConfig[i]; - config[val] = QUnit.urlParams[val]; - urlConfigHtml += "<label><input name='" + val + "' type='checkbox'" + ( config[val] ? " checked='checked'" : "" ) + ">" + val + "</label>"; + if ( typeof val === "string" ) { + val = { + id: val, + label: val, + tooltip: "[no tooltip available]" + }; + } + config[ val.id ] = QUnit.urlParams[ val.id ]; + urlConfigHtml += "<input id='qunit-urlconfig-" + val.id + "' name='" + val.id + "' type='checkbox'" + ( config[ val.id ] ? " checked='checked'" : "" ) + " title='" + val.tooltip + "'><label for='qunit-urlconfig-" + val.id + "' title='" + val.tooltip + "'>" + val.label + "</label>"; } // `userAgent` initialized at top of scope @@ -885,12 +949,7 @@ QUnit.load = function() { // `banner` initialized at top of scope banner = id( "qunit-header" ); if ( banner ) { - banner.innerHTML = "<a href='" + QUnit.url({ filter: undefined }) + "'>" + banner.innerHTML + "</a> " + urlConfigHtml; - addEvent( banner, "change", function( event ) { - var params = {}; - params[ event.target.name ] = event.target.checked ? true : undefined; - window.location = QUnit.url( params ); - }); + banner.innerHTML = "<a href='" + QUnit.url({ filter: undefined, module: undefined, testNumber: undefined }) + "'>" + banner.innerHTML + "</a> "; } // `toolbar` initialized at top of scope @@ -931,8 +990,18 @@ QUnit.load = function() { // `label` initialized at top of scope label = document.createElement( "label" ); label.setAttribute( "for", "qunit-filter-pass" ); + label.setAttribute( "title", "Only show tests and assertons that fail. Stored in sessionStorage." ); label.innerHTML = "Hide passed tests"; toolbar.appendChild( label ); + + urlConfigCheckboxes = document.createElement( 'span' ); + urlConfigCheckboxes.innerHTML = urlConfigHtml; + addEvent( urlConfigCheckboxes, "change", function( event ) { + var params = {}; + params[ event.target.name ] = event.target.checked ? true : undefined; + window.location = QUnit.url( params ); + }); + toolbar.appendChild( urlConfigCheckboxes ); } // `main` initialized at top of scope @@ -1051,14 +1120,14 @@ function done() { function validTest( test ) { var include, filter = config.filter && config.filter.toLowerCase(), - module = config.module, + module = config.module && config.module.toLowerCase(), fullName = (test.module + ": " + test.testName).toLowerCase(); if ( config.testNumber ) { return test.testNumber === config.testNumber; } - if ( module && test.module !== module ) { + if ( module && ( !test.module || test.module.toLowerCase() !== module ) ) { return false; } diff --git a/tests/unit/dialog/dialog_tickets.js b/tests/unit/dialog/dialog_tickets.js index 201ea3a87..5c3277c2f 100644 --- a/tests/unit/dialog/dialog_tickets.js +++ b/tests/unit/dialog/dialog_tickets.js @@ -10,7 +10,7 @@ asyncTest( "#3123: Prevent tabbing out of modal dialogs", function() { var el = $( "<div><input id='t3123-first'><input id='t3123-last'></div>" ).dialog({ modal: true }), inputs = el.find( "input" ), - widget = el.dialog( "widget" ); + widget = el.dialog( "widget" )[ 0 ]; function checkTab() { ok( $.contains( widget, document.activeElement ), "Tab key event moved focus within the modal" ); diff --git a/tests/unit/menu/menu.html b/tests/unit/menu/menu.html index c58b9fc65..ed376232e 100644 --- a/tests/unit/menu/menu.html +++ b/tests/unit/menu/menu.html @@ -44,11 +44,7 @@ </head> <body> -<h1 id="qunit-header">jQuery UI Menu Test Suite</h1> -<h2 id="qunit-banner"></h2> -<div id="qunit-testrunner-toolbar"></div> -<h2 id="qunit-userAgent"></h2> -<ol id="qunit-tests"></ol> +<div id="qunit">jQuery UI Menu Test Suite</div> <div id="qunit-fixture"> <ul class="foo" id="menu1"> diff --git a/tests/unit/menu/menu_common.js b/tests/unit/menu/menu_common.js index 07295f1af..4a89a947a 100644 --- a/tests/unit/menu/menu_common.js +++ b/tests/unit/menu/menu_common.js @@ -1,6 +1,9 @@ TestHelpers.commonWidgetTests( "menu", { defaults: { disabled: false, + icons: { + submenu: "ui-icon-carat-1-e" + }, menus: "ul", position: { my: "left top", diff --git a/tests/unit/menu/menu_methods.js b/tests/unit/menu/menu_methods.js index 0835f61ec..510ddb1d7 100644 --- a/tests/unit/menu/menu_methods.js +++ b/tests/unit/menu/menu_methods.js @@ -44,6 +44,30 @@ test( "refresh", function() { equal( element.find( ".ui-menu-item" ).length, 5, "Incorrect number of menu items" ); }); +// TODO: test focus method + +// TODO: test blur method + +// TODO: test collapseAll method + +// TODO: test collapse method + +// TODO: test expand method + +// TODO: test next method + +// TODO: test prev method + +// TODO: test isFirstItem method + +// TODO: test isLastItem method + +// TODO: test nextPage method + +// TODO: test prevPage method + +// TODO: test select method + test( "destroy", function() { expect( 4 ); domEqual( "#menu1", function() { diff --git a/tests/unit/menu/menu_options.js b/tests/unit/menu/menu_options.js index 27c2fabb3..a8b029201 100644 --- a/tests/unit/menu/menu_options.js +++ b/tests/unit/menu/menu_options.js @@ -18,7 +18,7 @@ test( "{ disabled: true }", function() { log(); } }); - ok( element.is( ".ui-state-disabled" ), "Missing ui-state-disabled class" ); + ok( element.hasClass( "ui-state-disabled" ), "Missing ui-state-disabled class" ); log( "click", true ); click( element, "1" ); log( "afterclick" ); @@ -33,14 +33,34 @@ test( "{ disabled: false }", function() { log(); } }); - ok( element.not( ".ui-state-disabled" ), "Has ui-state-disabled class" ); + ok( !element.hasClass( "ui-state-disabled" ), "Has ui-state-disabled class" ); log( "click", true ); click( element, "1" ); log( "afterclick" ); equal( logOutput(), "click,1,afterclick", "Click order not valid." ); }); -test( "{ role: 'menu' } ", function () { +test( "{ icons: default }", function() { + expect( 1 ); + var element = $( "#menu2" ).menu(); + equal( element.find( ".ui-menu-icon" ).attr( "class" ), "ui-menu-icon ui-icon ui-icon-carat-1-e" ); +}); + +test( "{ icons: { submenu: 'custom' } }", function() { + expect( 1 ); + var element = $( "#menu2" ).menu({ + icons: { + submenu: "custom-class" + } + }); + equal( element.find( ".ui-menu-icon" ).attr( "class" ), "ui-menu-icon ui-icon custom-class" ); +}); + +// TODO: test menus option + +// TODO: test position option + +test( "{ role: 'menu' } ", function() { var element = $( "#menu1" ).menu(), items = element.find( "li" ); expect( 2 + 5 * items.length ); @@ -55,16 +75,37 @@ test( "{ role: 'menu' } ", function () { }); }); -test( "{ role: 'listbox' } ", function () { +test( "{ role: 'listbox' } ", function() { var element = $( "#menu1" ).menu({ role: "listbox" }), items = element.find( "li" ); - expect( 2 + items.length ); + expect( 2 + 5 * items.length ); equal( element.attr( "role" ), "listbox" ); ok( items.length > 0, "number of menu items" ); items.each(function( item ) { + ok( $( this ).hasClass( "ui-menu-item" ), "menu item ("+ item + ") class for item" ); + equal( $( this ).attr( "role" ), "presentation", "menu item ("+ item + ") role" ); equal( $( "a", this ).attr( "role" ), "option", "menu item ("+ item + ") role" ); + ok( $( "a", this ).hasClass( "ui-corner-all" ), "a element class for menu item ("+ item + ")" ); + equal( $( "a", this ).attr( "tabindex" ), "-1", "a element tabindex for menu item ("+ item + ")" ); + }); +}); + +test( "{ role: null }", function() { + var element = $( "#menu1" ).menu({ + role: null + }), + items = element.find( "li" ); + expect( 2 + 5 * items.length ); + strictEqual( element.attr( "role" ), undefined ); + ok( items.length > 0, "number of menu items" ); + items.each(function( item ) { + ok( $( this ).hasClass( "ui-menu-item" ), "menu item ("+ item + ") class for item" ); + equal( $( this ).attr( "role" ), "presentation", "menu item ("+ item + ") role" ); + equal( $( "a", this ).attr( "role" ), undefined, "menu item ("+ item + ") role" ); + ok( $( "a", this ).hasClass( "ui-corner-all" ), "a element class for menu item ("+ item + ")" ); + equal( $( "a", this ).attr( "tabindex" ), "-1", "a element tabindex for menu item ("+ item + ")" ); }); }); diff --git a/tests/unit/spinner/spinner.html b/tests/unit/spinner/spinner.html index b7f4a532a..1d09bbc38 100644 --- a/tests/unit/spinner/spinner.html +++ b/tests/unit/spinner/spinner.html @@ -5,7 +5,7 @@ <title>jQuery UI Spinner Test Suite</title> <script src="../../jquery.js"></script> - <script src="../../../external/jquery.mousewheel-3.0.4.js"></script> + <script src="../../../external/jquery.mousewheel.js"></script> <script src="../../../external/globalize.js"></script> <script src="../../../external/globalize.culture.ja-JP.js"></script> <link rel="stylesheet" href="../../../external/qunit.css"> diff --git a/tests/unit/spinner/spinner_common.js b/tests/unit/spinner/spinner_common.js index 4f05b1e63..b494e3ca3 100644 --- a/tests/unit/spinner/spinner_common.js +++ b/tests/unit/spinner/spinner_common.js @@ -2,6 +2,10 @@ TestHelpers.commonWidgetTests( "spinner", { defaults: { culture: null, disabled: false, + icons: { + down: "ui-icon-triangle-1-s", + up: "ui-icon-triangle-1-n" + }, incremental: true, max: null, min: null, diff --git a/tests/unit/spinner/spinner_options.js b/tests/unit/spinner/spinner_options.js index e21852630..1f6646a33 100644 --- a/tests/unit/spinner/spinner_options.js +++ b/tests/unit/spinner/spinner_options.js @@ -6,6 +6,25 @@ module( "spinner: options" ); // culture is tested after numberFormat, since it depends on numberFormat +test( "icons: default ", function() { + expect( 2 ); + var element = $( "#spin" ).val( 0 ).spinner().spinner( "widget" ); + equal( element.find( ".ui-icon:first" ).attr( "class" ), "ui-icon ui-icon-triangle-1-n" ); + equal( element.find( ".ui-icon:last" ).attr( "class" ), "ui-icon ui-icon-triangle-1-s" ); +}); + +test( "icons: custom ", function() { + expect( 2 ); + var element = $( "#spin" ).val( 0 ).spinner({ + icons: { + down: "custom-down", + up: "custom-up" + } + }).spinner( "widget" ); + equal( element.find( ".ui-icon:first" ).attr( "class" ), "ui-icon custom-up" ); + equal( element.find( ".ui-icon:last" ).attr( "class" ), "ui-icon custom-down" ); +}); + test( "incremental, false", function() { expect( 100 ); diff --git a/tests/unit/tabs/tabs_core.js b/tests/unit/tabs/tabs_core.js index fd9cc7d63..f1a2d72c1 100644 --- a/tests/unit/tabs/tabs_core.js +++ b/tests/unit/tabs/tabs_core.js @@ -118,8 +118,24 @@ test( "accessibility", function() { equal( tabs.eq( 2 ).attr( "aria-disabled" ), "true", "disabled tab has aria-disabled=true" ); equal( panels.eq( 2 ).attr( "aria-expanded" ), "false", "inactive panel has aria-expanded=false" ); equal( panels.eq( 2 ).attr( "aria-hidden" ), "true", "inactive panel has aria-hidden=true" ); +}); - // TODO: aria-live and aria-busy tests for ajax tabs +asyncTest( "accessibility - ajax", function() { + expect( 4 ); + var element = $( "#tabs2" ).tabs(), + tab = element.find( ".ui-tabs-nav li" ).eq( 3 ), + panel = $( "#custom-id" ); + + equal( panel.attr( "aria-live" ), "polite", "remote panel has aria-live" ); + equal( panel.attr( "aria-busy" ), null, "does not have aria-busy on init" ); + element.tabs( "option", "active", 3 ); + equal( panel.attr( "aria-busy" ), "true", "panel has aria-busy during load" ); + element.one( "tabsload", function() { + setTimeout(function() { + equal( panel.attr( "aria-busy" ), null, "panel does not have aria-busy after load" ); + start(); + }, 1 ); + }); }); asyncTest( "keyboard support - LEFT, RIGHT, UP, DOWN, HOME, END, SPACE, ENTER", function() { diff --git a/tests/unit/tabs/tabs_options.js b/tests/unit/tabs/tabs_options.js index eed5b99d8..5a90ff895 100644 --- a/tests/unit/tabs/tabs_options.js +++ b/tests/unit/tabs/tabs_options.js @@ -280,6 +280,54 @@ test( "{ heightStyle: 'fill' } with multiple siblings", function() { equalHeight( element, 335 ); }); -// TODO: add animation tests +test( "hide and show: false", function() { + expect( 3 ); + var element = $( "#tabs1" ).tabs({ + show: false, + hide: false + }), + widget = element.data( "tabs" ), + panels = element.find( ".ui-tabs-panel" ); + widget._show = function() { + ok( false, "_show() called" ); + }; + widget._hide = function() { + ok( false, "_hide() called" ); + }; + + ok( panels.eq( 0 ).is( ":visible" ), "first panel visible" ); + element.tabs( "option", "active", 1 ); + ok( panels.eq( 0 ).is( ":hidden" ), "first panel hidden" ); + ok( panels.eq( 1 ).is( ":visible" ), "second panel visible" ); +}); + +asyncTest( "hide and show - animation", function() { + expect( 5 ); + var element = $( "#tabs1" ).tabs({ + show: "drop", + hide: 2000 + }), + widget = element.data( "tabs" ), + panels = element.find( ".ui-tabs-panel" ); + widget._show = function( element, options, callback ) { + strictEqual( element[ 0 ], panels[ 1 ], "correct element in _show()" ); + equal( options, "drop", "correct options in _show()" ); + setTimeout(function() { + callback(); + }, 1 ); + }; + widget._hide = function( element, options, callback ) { + strictEqual( element[ 0 ], panels[ 0 ], "correct element in _hide()" ); + equal( options, 2000, "correct options in _hide()" ); + setTimeout(function() { + callback(); + start(); + }, 1 ); + }; + + ok( panels.eq( 0 ).is( ":visible" ), "first panel visible" ); + element.tabs( "option", "active", 1 ); +}); + }( jQuery ) ); diff --git a/tests/unit/testsuite.js b/tests/unit/testsuite.js index 99694a83e..26f46138a 100644 --- a/tests/unit/testsuite.js +++ b/tests/unit/testsuite.js @@ -12,7 +12,12 @@ function includeScript( url ) { QUnit.config.requireExpects = true; -QUnit.config.urlConfig.push( "min" ); +QUnit.config.urlConfig.push({ + id: "min", + label: "Minified source", + tooltip: "Load minified source files instead of the regular unminified ones." +}); + TestHelpers.loadResources = QUnit.urlParams.min ? function() { // TODO: proper include with theme images @@ -28,7 +33,12 @@ TestHelpers.loadResources = QUnit.urlParams.min ? }); }; -QUnit.config.urlConfig.push( "nojshint" ); +QUnit.config.urlConfig.push({ + id: "nojshint", + label: "Skip JSHint", + tooltip: "Skip running JSHint, e.g. within TestSwarm, where Jenkins runs it already" +}); + var jshintLoaded = false; TestHelpers.testJshint = function( module ) { if ( QUnit.urlParams.nojshint ) { diff --git a/tests/unit/widget/widget_core.js b/tests/unit/widget/widget_core.js index 0296b9e4f..5efd91268 100644 --- a/tests/unit/widget/widget_core.js +++ b/tests/unit/widget/widget_core.js @@ -83,7 +83,7 @@ test( "custom selector expression", function() { var elem = $( "<div>" ).appendTo( "#qunit-fixture" ); $.widget( "ui.testWidget", {} ); elem.testWidget(); - deepEqual( $( ":ui-testWidget" )[0], elem[0] ); + deepEqual( $( ":ui-testwidget" )[0], elem[0] ); elem.testWidget( "destroy" ); }); diff --git a/tests/visual/menu/menu.html b/tests/visual/menu/menu.html index 5bda32eae..205cb10c9 100644 --- a/tests/visual/menu/menu.html +++ b/tests/visual/menu/menu.html @@ -26,7 +26,8 @@ $( "#menu6" ).menu({ menus: ".menuElement", - select: logger + select: logger, + icon: "ui-icon-carat-1-s" }); }); </script> @@ -212,7 +213,7 @@ </blockquote> </div> -<h2>Menu with custom markup, multi-line items</h2> +<h2>Menu with custom markup, multi-line items and a custom submenu icon</h2> <div class="menuElement" id="menu6"> <div class="address-item"> <a href="#"> diff --git a/ui/jquery.ui.core.js b/ui/jquery.ui.core.js index ad0ab25d7..3e102f181 100644 --- a/ui/jquery.ui.core.js +++ b/ui/jquery.ui.core.js @@ -216,9 +216,16 @@ function visible( element ) { } $.extend( $.expr[ ":" ], { - data: function( elem, i, match ) { - return !!$.data( elem, match[ 3 ] ); - }, + data: $.expr.createPseudo ? + $.expr.createPseudo(function( dataName ) { + return function( elem ) { + return !!$.data( elem, dataName ); + }; + }) : + // support: jQuery <1.8 + function( elem, i, match ) { + return !!$.data( elem, match[ 3 ] ); + }, focusable: function( element ) { return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); diff --git a/ui/jquery.ui.dialog.js b/ui/jquery.ui.dialog.js index 818363d0b..85e4b3e2b 100644 --- a/ui/jquery.ui.dialog.js +++ b/ui/jquery.ui.dialog.js @@ -316,7 +316,7 @@ $.widget("ui.dialog", { return; } - var tabbables = $( ":tabbable", this ), + var tabbables = $( ":tabbable", uiDialog ), first = tabbables.filter( ":first" ), last = tabbables.filter( ":last" ); diff --git a/ui/jquery.ui.effect.js b/ui/jquery.ui.effect.js index da3c70b7c..7cabe5849 100644 --- a/ui/jquery.ui.effect.js +++ b/ui/jquery.ui.effect.js @@ -20,15 +20,15 @@ $.effects = { /*! * jQuery Color Animations - * http://jquery.org/ + * http://jquery.com/ * - * Copyright 2012 John Resig + * Copyright 2012 jQuery Foundation and other contributors * Dual licensed under the MIT or GPL Version 2 licenses. * http://jquery.org/license */ (function( jQuery, undefined ) { -var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color outlineColor".split(" "), + var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor".split(" "), // plusequals test for += 100 -= 100 rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, @@ -47,14 +47,15 @@ var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightCo re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/, parse: function( execResult ) { return [ - 2.55 * execResult[1], - 2.55 * execResult[2], - 2.55 * execResult[3], + execResult[ 1 ] * 2.55, + execResult[ 2 ] * 2.55, + execResult[ 3 ] * 2.55, execResult[ 4 ] ]; } }, { - re: /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/, + // this regex ignores A-F because it's compared against an already lowercased string + re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/, parse: function( execResult ) { return [ parseInt( execResult[ 1 ], 16 ), @@ -63,7 +64,8 @@ var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightCo ]; } }, { - re: /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/, + // this regex ignores A-F because it's compared against an already lowercased string + re: /#([a-f0-9])([a-f0-9])([a-f0-9])/, parse: function( execResult ) { return [ parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), @@ -76,10 +78,10 @@ var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightCo space: "hsla", parse: function( execResult ) { return [ - execResult[1], - execResult[2] / 100, - execResult[3] / 100, - execResult[4] + execResult[ 1 ], + execResult[ 2 ] / 100, + execResult[ 3 ] / 100, + execResult[ 4 ] ]; } }], @@ -90,47 +92,35 @@ var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightCo }, spaces = { rgba: { - cache: "_rgba", props: { red: { idx: 0, - type: "byte", - empty: true + type: "byte" }, green: { idx: 1, - type: "byte", - empty: true + type: "byte" }, blue: { idx: 2, - type: "byte", - empty: true - }, - alpha: { - idx: 3, - type: "percent", - def: 1 + type: "byte" } } }, + hsla: { - cache: "_hsla", props: { hue: { idx: 0, - type: "degrees", - empty: true + type: "degrees" }, saturation: { idx: 1, - type: "percent", - empty: true + type: "percent" }, lightness: { idx: 2, - type: "percent", - empty: true + type: "percent" } } } @@ -138,11 +128,9 @@ var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightCo propTypes = { "byte": { floor: true, - min: 0, max: 255 }, "percent": { - min: 0, max: 1 }, "degrees": { @@ -152,40 +140,54 @@ var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightCo }, support = color.support = {}, + // element for support tests + supportElem = jQuery( "<p>" )[ 0 ], + // colors = jQuery.Color.names colors, // local aliases of functions called often each = jQuery.each; -spaces.hsla.props.alpha = spaces.rgba.props.alpha; +// determine rgba support immediately +supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; +support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; -function clamp( value, prop, alwaysAllowEmpty ) { - var type = propTypes[ prop.type ] || {}, - allowEmpty = alwaysAllowEmpty || prop.empty; +// define cache name and alpha properties +// for rgba and hsla spaces +each( spaces, function( spaceName, space ) { + space.cache = "_" + spaceName; + space.props.alpha = { + idx: 3, + type: "percent", + def: 1 + }; +}); - if ( allowEmpty && value == null ) { - return null; - } - if ( prop.def && value == null ) { - return prop.def; - } - if ( type.floor ) { - value = ~~value; - } else { - value = parseFloat( value ); +function clamp( value, prop, allowEmpty ) { + var type = propTypes[ prop.type ] || {}; + + if ( value == null ) { + return (allowEmpty || !prop.def) ? null : prop.def; } - if ( value == null || isNaN( value ) ) { + + // ~~ is an short way of doing floor for positive numbers + value = type.floor ? ~~value : parseFloat( value ); + + // IE will pass in empty strings as value for alpha, + // which will hit this case + if ( isNaN( value ) ) { return prop.def; } + if ( type.mod ) { - value %= type.mod; - // -10 -> 350 - return value < 0 ? type.mod + value : value; + // we add mod before modding to make sure that negatives values + // get converted properly: -10 -> 350 + return (value + type.mod) % type.mod; } // for now all property types without mod have min and max - return type.min > value ? type.min : type.max < value ? type.max : value; + return 0 > value ? 0 : type.max < value ? type.max : value; } function stringParse( string ) { @@ -195,19 +197,17 @@ function stringParse( string ) { string = string.toLowerCase(); each( stringParsers, function( i, parser ) { - var match = parser.re.exec( string ), + var parsed, + match = parser.re.exec( string ), values = match && parser.parse( match ), - parsed, - spaceName = parser.space || "rgba", - cache = spaces[ spaceName ].cache; - + spaceName = parser.space || "rgba"; if ( values ) { parsed = inst[ spaceName ]( values ); // if this was an rgba parse the assignment might happen twice // oh well.... - inst[ cache ] = parsed[ cache ]; + inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; rgba = inst._rgba = parsed._rgba; // exit each( stringParsers ) here because we matched @@ -216,11 +216,11 @@ function stringParse( string ) { }); // Found a stringParser that handled it - if ( rgba.length !== 0 ) { + if ( rgba.length ) { // if this came from a parsed string, force "transparent" when alpha is 0 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) - if ( Math.max.apply( Math, rgba ) === 0 ) { + if ( rgba.join() === "0,0,0,0" ) { jQuery.extend( rgba, colors.transparent ); } return inst; @@ -280,7 +280,7 @@ color.fn = jQuery.extend( color.prototype, { // if the value was null, we don't need to copy it // if the key was alpha, we don't need to copy it either - if ( red[ key ] == null || key === "alpha") { + if ( key === "alpha" || red[ key ] == null ) { return; } inst[ cache ] = space.to( inst._rgba ); @@ -298,13 +298,13 @@ color.fn = jQuery.extend( color.prototype, { is: function( compare ) { var is = color( compare ), same = true, - myself = this; + inst = this; each( spaces, function( _, space ) { - var isCache = is[ space.cache ], - localCache; + var localCache, + isCache = is[ space.cache ]; if (isCache) { - localCache = myself[ space.cache ] || space.to && space.to( myself._rgba ) || []; + localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; each( space.props, function( _, prop ) { if ( isCache[ prop.idx ] != null ) { same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); @@ -330,7 +330,8 @@ color.fn = jQuery.extend( color.prototype, { var end = color( other ), spaceName = end._space(), space = spaces[ spaceName ], - start = this[ space.cache ] || space.to( this._rgba ), + startColor = this.alpha() === 0 ? color( "transparent" ) : this, + start = startColor[ space.cache ] || space.to( startColor._rgba ), result = start.slice(); end = end[ space.cache ]; @@ -355,7 +356,7 @@ color.fn = jQuery.extend( color.prototype, { startValue -= type.mod; } } - result[ prop.idx ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); + result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); } }); return this[ spaceName ]( result ); @@ -385,7 +386,7 @@ color.fn = jQuery.extend( color.prototype, { prefix = "rgb("; } - return prefix + rgba.join(",") + ")"; + return prefix + rgba.join() + ")"; }, toHslaString: function() { var prefix = "hsla(", @@ -405,7 +406,7 @@ color.fn = jQuery.extend( color.prototype, { hsla.pop(); prefix = "hsl("; } - return prefix + hsla.join(",") + ")"; + return prefix + hsla.join() + ")"; }, toHexString: function( includeAlpha ) { var rgba = this._rgba.slice(), @@ -429,12 +430,12 @@ color.fn = jQuery.extend( color.prototype, { color.fn.parse.prototype = color.fn; // hsla conversions adapted from: -// http://www.google.com/codesearch/p#OAMlx_jo-ck/src/third_party/WebKit/Source/WebCore/inspector/front-end/Color.js&d=7&l=193 +// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 function hue2rgb( p, q, h ) { h = ( h + 1 ) % 1; if ( h * 6 < 1 ) { - return p + (q - p) * 6 * h; + return p + (q - p) * h * 6; } if ( h * 2 < 1) { return q; @@ -518,10 +519,10 @@ each( spaces, function( spaceName, space ) { return this[ cache ].slice(); } - var type = jQuery.type( value ), + var ret, + type = jQuery.type( value ), arr = ( type === "array" || type === "object" ) ? value : arguments, - local = this[ cache ].slice(), - ret; + local = this[ cache ].slice(); each( props, function( key, prop ) { var val = arr[ type === "object" ? key : prop.idx ]; @@ -548,7 +549,7 @@ each( spaces, function( spaceName, space ) { } color.fn[ key ] = function( value ) { var vtype = jQuery.type( value ), - fn = ( key === 'alpha' ? ( this._hsla ? 'hsla' : 'rgba' ) : spaceName ), + fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ), local = this[ fn ](), cur = local[ prop.idx ], match; @@ -582,13 +583,12 @@ each( stepHooks, function( i, hook ) { set: function( elem, value ) { var parsed, backgroundColor, curElem; - if ( jQuery.type( value ) !== 'string' || ( parsed = stringParse( value ) ) ) - { + if ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) { value = color( parsed || value ); if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { curElem = hook === "backgroundColor" ? elem.parentNode : elem; do { - backgroundColor = jQuery.curCSS( curElem, "backgroundColor" ); + backgroundColor = jQuery.css( curElem, "backgroundColor" ); } while ( ( backgroundColor === "" || backgroundColor === "transparent" ) && ( curElem = curElem.parentNode ) && @@ -619,63 +619,31 @@ each( stepHooks, function( i, hook ) { }; }); -// detect rgba support -jQuery(function() { - var div = document.createElement( "div" ), - div_style = div.style; - - div_style.cssText = "background-color:rgba(1,1,1,.5)"; - support.rgba = div_style.backgroundColor.indexOf( "rgba" ) > -1; -}); - -// Some named colors to work with -// From Interface by Stefan Petre -// http://interface.eyecon.ro/ +// Basic color names only. +// Usage of any of the other color names requires adding yourself or including +// jquery.color.svg-names.js. colors = jQuery.Color.names = { + // 4.1. Basic color keywords aqua: "#00ffff", - azure: "#f0ffff", - beige: "#f5f5dc", black: "#000000", blue: "#0000ff", - brown: "#a52a2a", - cyan: "#00ffff", - darkblue: "#00008b", - darkcyan: "#008b8b", - darkgrey: "#a9a9a9", - darkgreen: "#006400", - darkkhaki: "#bdb76b", - darkmagenta: "#8b008b", - darkolivegreen: "#556b2f", - darkorange: "#ff8c00", - darkorchid: "#9932cc", - darkred: "#8b0000", - darksalmon: "#e9967a", - darkviolet: "#9400d3", fuchsia: "#ff00ff", - gold: "#ffd700", + gray: "#808080", green: "#008000", - indigo: "#4b0082", - khaki: "#f0e68c", - lightblue: "#add8e6", - lightcyan: "#e0ffff", - lightgreen: "#90ee90", - lightgrey: "#d3d3d3", - lightpink: "#ffb6c1", - lightyellow: "#ffffe0", lime: "#00ff00", - magenta: "#ff00ff", maroon: "#800000", navy: "#000080", olive: "#808000", - orange: "#ffa500", - pink: "#ffc0cb", purple: "#800080", - violet: "#800080", red: "#ff0000", silver: "#c0c0c0", + teal: "#008080", white: "#ffffff", yellow: "#ffff00", + + // 4.2.3. ‘transparent’ color keyword transparent: [ null, null, null, 0 ], + _default: "#ffffff" }; @@ -893,9 +861,19 @@ $.extend( $.effects, { // Restores a set of previously saved properties from a data storage restore: function( element, set ) { - for( var i=0; i < set.length; i++ ) { + var val, i; + for( i=0; i < set.length; i++ ) { if ( set[ i ] !== null ) { - element.css( set[ i ], element.data( dataSpace + set[ i ] ) ); + val = element.data( dataSpace + set[ i ] ); + // support: jQuery 1.6.2 + // http://bugs.jquery.com/ticket/9917 + // jQuery 1.6.2 incorrectly returns undefined for any falsy value. + // We can't differentiate between "" and 0 here, so we just assume + // empty string since it's likely to be a more common value... + if ( val === undefined ) { + val = ""; + } + element.css( set[ i ], val ); } } }, diff --git a/ui/jquery.ui.menu.js b/ui/jquery.ui.menu.js index 758676199..75cfac40b 100644 --- a/ui/jquery.ui.menu.js +++ b/ui/jquery.ui.menu.js @@ -15,13 +15,16 @@ */ (function( $, undefined ) { -var currentEventTarget = null; +var mouseHandled = false; $.widget( "ui.menu", { version: "@VERSION", defaultElement: "<ul>", delay: 300, options: { + icons: { + submenu: "ui-icon-carat-1-e" + }, menus: "ul", position: { my: "left top", @@ -70,23 +73,13 @@ $.widget( "ui.menu", { }, "click .ui-menu-item:has(a)": function( event ) { var target = $( event.target ); - if ( target[0] !== currentEventTarget ) { - currentEventTarget = target[0]; - // TODO: What are we trying to accomplish with this check? - // Clicking a menu item twice results in a select event with - // an empty ui.item. - target.one( "click" + this.eventNamespace, function( event ) { - currentEventTarget = null; - }); - // Don't select disabled menu items - if ( !target.closest( ".ui-menu-item" ).is( ".ui-state-disabled" ) ) { - this.select( event ); - // Redirect focus to the menu with a delay for firefox - this._delay(function() { - if ( !this.element.is(":focus") ) { - this.element.focus(); - } - }, 20 ); + if ( !mouseHandled && target.closest( ".ui-menu-item" ).not( ".ui-state-disabled" ).length ) { + mouseHandled = true; + + this.select( event ); + // Redirect focus to the menu + if ( !this.element.is(":focus") ) { + this.element.focus(); } } }, @@ -100,26 +93,10 @@ $.widget( "ui.menu", { mouseleave: "collapseAll", "mouseleave .ui-menu": "collapseAll", focus: function( event ) { - var menuTop, - menu = this.element, - // Default to focusing the first item - item = menu.children( ".ui-menu-item" ).eq( 0 ); - // If there's already an active item, keep it active - if ( this.active ) { - item = this.active; - // If there's no active item and the menu is scrolled, - // then find the first visible item - } else if ( this._hasScroll() ) { - menuTop = menu.offset().top; - menu.children().each(function() { - var currentItem = $( this ); - if ( currentItem.offset().top - menuTop >= 0 ) { - item = currentItem; - return false; - } - }); - } + // If not, activate the first item + var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 ); + this.focus( event, item ); }, blur: function( event ) { @@ -140,6 +117,9 @@ $.widget( "ui.menu", { if ( !$( event.target ).closest( ".ui-menu" ).length ) { this.collapseAll( event ); } + + // Reset the mouseHandled flag + mouseHandled = false; } }); }, @@ -179,13 +159,10 @@ $.widget( "ui.menu", { // Destroy menu dividers this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" ); - - // Unbind currentEventTarget click event handler - this._off( $( currentEventTarget ), "click" ); }, _keydown: function( event ) { - var match, prev, character, skip, + var match, prev, character, skip, regex, preventDefault = true; function escape( value ) { @@ -240,9 +217,9 @@ $.widget( "ui.menu", { character = prev + character; } + regex = new RegExp( "^" + escape( character ), "i" ); match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { - return new RegExp( "^" + escape( character ), "i" ) - .test( $( this ).children( "a" ).text() ); + return regex.test( $( this ).children( "a" ).text() ); }); match = skip && match.index( this.active.next() ) !== -1 ? this.active.nextAll( ".ui-menu-item" ) : @@ -252,9 +229,9 @@ $.widget( "ui.menu", { // to move down the menu to the first item that starts with that character if ( !match.length ) { character = String.fromCharCode( event.keyCode ); + regex = new RegExp( "^" + escape( character ), "i" ); match = this.activeMenu.children( ".ui-menu-item" ).filter(function() { - return new RegExp( "^" + escape( character ), "i" ) - .test( $( this ).children( "a" ).text() ); + return regex.test( $( this ).children( "a" ).text() ); }); } @@ -291,6 +268,7 @@ $.widget( "ui.menu", { refresh: function() { // Initialize nested menus var menus, + icon = this.options.icons.submenu, submenus = this.element.find( this.options.menus + ":not(.ui-menu)" ) .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) .hide() @@ -303,7 +281,7 @@ $.widget( "ui.menu", { // Don't refresh list items that are already adapted menus = submenus.add( this.element ); - menus.children( ":not( .ui-menu-item ):has( a )" ) + menus.children( ":not(.ui-menu-item):has(a)" ) .addClass( "ui-menu-item" ) .attr( "role", "presentation" ) .children( "a" ) @@ -330,7 +308,7 @@ $.widget( "ui.menu", { var menu = $( this ), item = menu.prev( "a" ), submenuCarat = $( "<span>" ) - .addClass( "ui-menu-icon ui-icon ui-icon-carat-1-e" ) + .addClass( "ui-menu-icon ui-icon " + icon ) .data( "ui-menu-submenu-carat", true ); item @@ -436,10 +414,7 @@ $.widget( "ui.menu", { _open: function( submenu ) { var position = $.extend({ of: this.active - }, $.type( this.options.position ) === "function" ? - this.options.position( this.active ) : - this.options.position - ); + }, this.options.position ); clearTimeout( this.timer ); this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) ) @@ -495,7 +470,6 @@ $.widget( "ui.menu", { if ( newItem && newItem.length ) { this._close(); this.focus( event, newItem ); - return true; } }, @@ -512,8 +486,7 @@ $.widget( "ui.menu", { // Delay so Firefox will not hide activedescendant change in expanding submenu from AT this._delay(function() { this.focus( event, newItem ); - }, 20 ); - return true; + }); } }, @@ -608,7 +581,8 @@ $.widget( "ui.menu", { select: function( event ) { // Save active reference before collapseAll triggers blur var ui = { - item: this.active + // Selecting a menu item removes the active item causing multiple clicks to be missing an item + item: this.active || $( event.target ).closest( ".ui-menu-item" ) }; this.collapseAll( event, true ); this._trigger( "select", event, ui ); diff --git a/ui/jquery.ui.sortable.js b/ui/jquery.ui.sortable.js index 7e5875200..db24fed38 100644 --- a/ui/jquery.ui.sortable.js +++ b/ui/jquery.ui.sortable.js @@ -1030,6 +1030,8 @@ $.widget("ui.sortable", $.ui.mouse, { for (var i=0; i < delayedTriggers.length; i++) { delayedTriggers[i].call(this, event); }; //Trigger all delayed events this._trigger("stop", event, this._uiHash()); } + + this.fromOutside = false; return false; } diff --git a/ui/jquery.ui.spinner.js b/ui/jquery.ui.spinner.js index 6acb3693e..ead3b17be 100644 --- a/ui/jquery.ui.spinner.js +++ b/ui/jquery.ui.spinner.js @@ -32,6 +32,10 @@ $.widget( "ui.spinner", { widgetEventPrefix: "spin", options: { culture: null, + icons: { + down: "ui-icon-triangle-1-s", + up: "ui-icon-triangle-1-n" + }, incremental: true, max: null, min: null, @@ -244,10 +248,10 @@ $.widget( "ui.spinner", { _buttonHtml: function() { return "" + "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" + - "<span class='ui-icon ui-icon-triangle-1-n'>▲</span>" + + "<span class='ui-icon " + this.options.icons.up + "'>▲</span>" + "</a>" + "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" + - "<span class='ui-icon ui-icon-triangle-1-s'>▼</span>" + + "<span class='ui-icon " + this.options.icons.down + "'>▼</span>" + "</a>"; }, diff --git a/ui/jquery.ui.widget.js b/ui/jquery.ui.widget.js index 628b63bb0..b5dfaa344 100644 --- a/ui/jquery.ui.widget.js +++ b/ui/jquery.ui.widget.js @@ -36,7 +36,7 @@ $.widget = function( name, base, prototype ) { } // create selector for plugin - $.expr[ ":" ][ fullName ] = function( elem ) { + $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { return !!$.data( elem, fullName ); }; |