From d4318a5f4c216e1184b6e90c17214b6e6cfbb0fb Mon Sep 17 00:00:00 2001 From: Scott González Date: Mon, 14 May 2012 14:40:06 -0400 Subject: Tabs: Replaced fx option with show and hide options. Fixes #8319 - Tabs: Deprecate fx option. --- tests/unit/tabs/tabs_common.js | 3 ++- tests/unit/tabs/tabs_common_deprecated.js | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'tests/unit') diff --git a/tests/unit/tabs/tabs_common.js b/tests/unit/tabs/tabs_common.js index 7ffb05da4..b98ff3575 100644 --- a/tests/unit/tabs/tabs_common.js +++ b/tests/unit/tabs/tabs_common.js @@ -4,7 +4,8 @@ TestHelpers.commonWidgetTests( "tabs", { collapsible: false, disabled: false, event: "click", - fx: null, + hide: null, + show: null, // callbacks activate: null, diff --git a/tests/unit/tabs/tabs_common_deprecated.js b/tests/unit/tabs/tabs_common_deprecated.js index fdcff21b3..718ae8272 100644 --- a/tests/unit/tabs/tabs_common_deprecated.js +++ b/tests/unit/tabs/tabs_common_deprecated.js @@ -7,9 +7,11 @@ TestHelpers.commonWidgetTests( "tabs", { cookie: null, disabled: false, event: "click", + hide: null, fx: null, idPrefix: "ui-tabs-", panelTemplate: "
", + // show: null, // conflicts with old show callback spinner: "Loading…", tabTemplate: "
  • #{label}
  • ", -- cgit v1.2.3 From b2a51a589ab4742c1146e9f3088822d706d85e4c Mon Sep 17 00:00:00 2001 From: "Yi, EungJun" Date: Sun, 6 May 2012 12:12:00 +0900 Subject: Draggable tests: Fixed typo. --- tests/unit/draggable/draggable_events.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests/unit') diff --git a/tests/unit/draggable/draggable_events.js b/tests/unit/draggable/draggable_events.js index 85ba824d8..2b2104ed4 100644 --- a/tests/unit/draggable/draggable_events.js +++ b/tests/unit/draggable/draggable_events.js @@ -5,7 +5,7 @@ module("draggable: events"); -test("callbacks occurance count", function() { +test("callbacks occurrence count", function() { expect(3); -- cgit v1.2.3 From c0f6b0ccdf69c705a03e30778ae318e0cd8a0625 Mon Sep 17 00:00:00 2001 From: Scott González Date: Tue, 15 May 2012 16:43:47 -0400 Subject: Tests: Cleaned up index pages. Fixes #7374 - Broken link to Static and Visual tests (Index of Static and Visual tests do not exist). --- tests/index.css | 21 ++++++++++++ tests/index.html | 35 ++++++++++++------- tests/index.js | 10 ++++++ tests/unit/index.html | 34 ++----------------- tests/visual/index.html | 90 +++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 146 insertions(+), 44 deletions(-) create mode 100644 tests/index.css create mode 100644 tests/index.js create mode 100644 tests/visual/index.html (limited to 'tests/unit') diff --git a/tests/index.css b/tests/index.css new file mode 100644 index 000000000..2034cfba5 --- /dev/null +++ b/tests/index.css @@ -0,0 +1,21 @@ +body { + font-size: 62.5%; +} +.ui-widget-header { + padding: 0.2em 0.5em; + margin: 0; +} +.ui-widget-content { + padding: 1em; + margin-bottom: 1em; +} +p { + margin: 0; +} +ul { + margin: 0; + list-style: none; +} +li { + line-height: 2em; +} diff --git a/tests/index.html b/tests/index.html index 3c66bf38f..d4b3f4a8d 100644 --- a/tests/index.html +++ b/tests/index.html @@ -1,22 +1,33 @@ - + - + jQuery UI Tests - - - - + + + + + -

    jQuery UI Tests

    +
    +

    jQuery UI Tests

    +
    +

    Unit Tests

    +

    Unit tests exist for all functionality in jQuery UI. + The unit tests can be run locally (some tests require a web server with PHP) + to ensure proper functionality before committing changes. + The unit tests are also run on TestSwarm + for every commit.

    -

    Static Tests

    - -

    Unit Tests

    - -

    Visual Tests

    +

    Visual Tests

    +

    Visual tests only exist in cases where we can't verify proper functionality + with unit tests. These may be either purely visual or just hard to automate. + Most visual tests will provide a description of what is happening on the page + and what to look for.

    +
    +
    diff --git a/tests/index.js b/tests/index.js new file mode 100644 index 000000000..26c07498f --- /dev/null +++ b/tests/index.js @@ -0,0 +1,10 @@ +$(function() { + +$( "#main" ) + .addClass( "ui-widget" ) + .find( "h1, h2" ) + .addClass( "ui-widget-header ui-corner-top" ) + .next() + .addClass( "ui-widget-content ui-corner-bottom" ); + +}); diff --git a/tests/unit/index.html b/tests/unit/index.html index b73ede29c..e2dd9069a 100644 --- a/tests/unit/index.html +++ b/tests/unit/index.html @@ -6,39 +6,9 @@ - - + - + diff --git a/tests/visual/index.html b/tests/visual/index.html new file mode 100644 index 000000000..4e524cdcc --- /dev/null +++ b/tests/visual/index.html @@ -0,0 +1,90 @@ + + + + + jQuery UI Visual Tests + + + + + + + + + +
    +

    jQuery UI Visual Tests

    +
    +

    Accordion

    + + +

    addClass

    + + +

    Button

    + + +

    Dialog

    + + +

    Effects

    + + +

    Menu

    + + +

    Position

    + + +

    Tooltip

    + + +

    Compound

    + + +

    General

    + +
    +
    + + + -- cgit v1.2.3 From f4b2d7a4115814b64ff291e3518fe15f2dfbe390 Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Tue, 15 May 2012 14:07:35 +0200 Subject: Autocomplete: ARIA live region as extension, adding a messages option. Fixes #7840 - Autocomplete: popup results not read by screen-readers --- demos/autocomplete/multiple-remote.html | 3 +- demos/autocomplete/multiple.html | 5 +-- tests/unit/autocomplete/autocomplete_common.js | 4 +++ tests/unit/menu/menu_common.js | 1 + ui/jquery.ui.autocomplete.js | 48 +++++++++++++++++++++----- ui/jquery.ui.menu.js | 26 +++++++++----- 6 files changed, 68 insertions(+), 19 deletions(-) (limited to 'tests/unit') diff --git a/demos/autocomplete/multiple-remote.html b/demos/autocomplete/multiple-remote.html index 378e449d5..00d739967 100644 --- a/demos/autocomplete/multiple-remote.html +++ b/demos/autocomplete/multiple-remote.html @@ -47,7 +47,8 @@ } }, focus: function() { - // prevent value inserted on focus + // prevent value inserted on focus, update liveRegion instead + $( this ).data( "autocomplete" ).liveRegion.text( ui.item.label ); return false; }, select: function( event, ui ) { diff --git a/demos/autocomplete/multiple.html b/demos/autocomplete/multiple.html index e3f84b65d..3d1326591 100644 --- a/demos/autocomplete/multiple.html +++ b/demos/autocomplete/multiple.html @@ -59,8 +59,9 @@ response( $.ui.autocomplete.filter( availableTags, extractLast( request.term ) ) ); }, - focus: function() { - // prevent value inserted on focus + focus: function( event, ui ) { + // prevent value inserted on focus, update liveRegion instead + $( this ).data( "autocomplete" ).liveRegion.text( ui.item.label ); return false; }, select: function( event, ui ) { diff --git a/tests/unit/autocomplete/autocomplete_common.js b/tests/unit/autocomplete/autocomplete_common.js index c090ce4df..e1d24ef8d 100644 --- a/tests/unit/autocomplete/autocomplete_common.js +++ b/tests/unit/autocomplete/autocomplete_common.js @@ -4,6 +4,10 @@ TestHelpers.commonWidgetTests( "autocomplete", { autoFocus: false, delay: 300, disabled: false, + messages: { + noResults: "No search results.", + results: $.ui.autocomplete.prototype.options.messages.results + }, minLength: 1, position: { my: "left top", diff --git a/tests/unit/menu/menu_common.js b/tests/unit/menu/menu_common.js index ddcdbebf2..07295f1af 100644 --- a/tests/unit/menu/menu_common.js +++ b/tests/unit/menu/menu_common.js @@ -6,6 +6,7 @@ TestHelpers.commonWidgetTests( "menu", { my: "left top", at: "right top" }, + role: "menu", // callbacks blur: null, diff --git a/ui/jquery.ui.autocomplete.js b/ui/jquery.ui.autocomplete.js index fab9691a3..fa15bc278 100644 --- a/ui/jquery.ui.autocomplete.js +++ b/ui/jquery.ui.autocomplete.js @@ -60,13 +60,7 @@ $.widget( "ui.autocomplete", { this.element .addClass( "ui-autocomplete-input" ) - .attr( "autocomplete", "off" ) - // TODO verify these actually work as intended - .attr({ - role: "textbox", - "aria-autocomplete": "list", - "aria-haspopup": "true" - }); + .attr( "autocomplete", "off" ); this._bind({ keydown: function( event ) { @@ -188,7 +182,9 @@ $.widget( "ui.autocomplete", { .appendTo( this.document.find( this.options.appendTo || "body" )[0] ) .menu({ // custom key handling for now - input: $() + input: $(), + // disable ARIA support, the live region takes care of that + role: null }) .zIndex( this.element.zIndex() + 1 ) .hide() @@ -532,4 +528,40 @@ $.extend( $.ui.autocomplete, { } }); + +// live region extension, adding a `messages` option +$.widget( "ui.autocomplete", $.ui.autocomplete, { + options: { + messages: { + noResults: "No search results.", + results: function(amount) { + return amount + ( amount > 1 ? " results are" : " result is" ) + " available, use up and down arrow keys to navigate."; + } + } + }, + _create: function() { + this._super(); + this.liveRegion = $( "", { + role: "status", + "aria-live": "polite" + }) + .addClass( "ui-helper-hidden-accessible" ) + .insertAfter( this.element ); + }, + __response: function( content ) { + var message; + this._superApply( arguments ); + if ( this.options.disabled || this.cancelSearch) { + return; + } + if ( content && content.length ) { + message = this.options.messages.results( content.length ); + } else { + message = this.options.messages.noResults; + } + this.liveRegion.text( message ); + } +}); + + }( jQuery )); diff --git a/ui/jquery.ui.menu.js b/ui/jquery.ui.menu.js index 7704521fb..36f7e1de4 100644 --- a/ui/jquery.ui.menu.js +++ b/ui/jquery.ui.menu.js @@ -26,6 +26,7 @@ $.widget( "ui.menu", { my: "left top", at: "right top" }, + role: "menu", // callbacks blur: null, @@ -42,7 +43,7 @@ $.widget( "ui.menu", { .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) .attr({ id: this.menuId, - role: "menu", + role: this.options.role, tabIndex: 0 }) // need to catch all clicks on disabled menu @@ -267,7 +268,7 @@ $.widget( "ui.menu", { .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" ) .hide() .attr({ - role: "menu", + role: this.options.role, "aria-hidden": "true", "aria-expanded": "false" }); @@ -281,7 +282,7 @@ $.widget( "ui.menu", { .children( "a" ) .addClass( "ui-corner-all" ) .attr( "tabIndex", -1 ) - .attr( "role", "menuitem" ) + .attr( "role", this._itemRole() ) .attr( "id", function( i ) { return menuId + "-" + i; }); @@ -302,8 +303,15 @@ $.widget( "ui.menu", { }); }, + _itemRole: function() { + return { + menu: "menuitem", + listbox: "option" + }[ this.options.role ]; + }, + focus: function( event, item ) { - var nested, borderTop, paddingTop, offset, scroll, elementHeight, itemHeight; + var nested, borderTop, paddingTop, offset, scroll, elementHeight, itemHeight, focused; this.blur( event, event && event.type === "focus" ); if ( this._hasScroll() ) { @@ -322,10 +330,12 @@ $.widget( "ui.menu", { } this.active = item.first(); - this.element.attr( "aria-activedescendant", - this.active.children( "a" ) - .addClass( "ui-state-focus" ) - .attr( "id" ) ); + focused = this.active.children( "a" ).addClass( "ui-state-focus" ); + // only update aria-activedescendant if there's a role + // otherwise we assume focus is managed elsewhere + if ( this.options.role ) { + this.element.attr( "aria-activedescendant", focused.attr( "id" ) ); + } // highlight active parent menu item, if any this.active.parent().closest( ".ui-menu-item" ).children( "a:first" ).addClass( "ui-state-active" ); -- cgit v1.2.3 From 627d27fea23f1fb50db6c9ad8a2ff264505a0f3e Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Fri, 18 May 2012 16:04:54 +0200 Subject: Menu: Tests for role option --- tests/unit/menu/menu_core.js | 13 ------------- tests/unit/menu/menu_options.js | 26 ++++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 13 deletions(-) (limited to 'tests/unit') diff --git a/tests/unit/menu/menu_core.js b/tests/unit/menu/menu_core.js index f2de7ef1a..68b625687 100644 --- a/tests/unit/menu/menu_core.js +++ b/tests/unit/menu/menu_core.js @@ -26,17 +26,4 @@ test("accessibility", function () { equal( menu.attr("aria-activedescendant"), "menu1-4", "aria attribute, generated id"); }); -test("items class and role", function () { - var menu = $('#menu1').menu(); - expect(1 + 5 * $("li",menu).length); - ok( ($("li",menu).length > 0 ), "number of menu items"); - $("li",menu).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"), "menuitem", "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 + ") "); - }); -}); - })(jQuery); diff --git a/tests/unit/menu/menu_options.js b/tests/unit/menu/menu_options.js index e651fd2d1..306f575ea 100644 --- a/tests/unit/menu/menu_options.js +++ b/tests/unit/menu/menu_options.js @@ -38,4 +38,30 @@ test( "{ disabled: false }", function() { equal( $("#log").html(), "afterclick,1,click,", "Click order not valid."); }); +test("{ role: 'menu' } ", function () { + var menu = $('#menu1').menu(); + expect(2 + 5 * $("li", menu).length); + equal( menu.attr( "role" ), "menu" ); + ok( $("li", menu).length > 0, "number of menu items"); + $("li", menu).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"), "menuitem", "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: 'listbox' } ", function () { + var menu = $('#menu1').menu({ + role: "listbox" + }); + expect(2 + $("li", menu).length); + equal( menu.attr( "role" ), "listbox" ); + ok( ($("li", menu).length > 0 ), "number of menu items"); + $("li", menu).each(function(item) { + equal( $("a", this).attr("role"), "option", "menu item ("+ item + ") role"); + }); +}); + })(jQuery); -- cgit v1.2.3 From c54986457279db18bce5ae3858142906f786855e Mon Sep 17 00:00:00 2001 From: Scott González Date: Fri, 18 May 2012 11:31:01 -0400 Subject: Tests: Use versioned jQuery files in index files. --- tests/index.html | 2 +- tests/unit/index.html | 2 +- tests/visual/index.html | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'tests/unit') diff --git a/tests/index.html b/tests/index.html index d4b3f4a8d..d5e364ad6 100644 --- a/tests/index.html +++ b/tests/index.html @@ -6,7 +6,7 @@ - + diff --git a/tests/unit/index.html b/tests/unit/index.html index e2dd9069a..33a326370 100644 --- a/tests/unit/index.html +++ b/tests/unit/index.html @@ -7,7 +7,7 @@ - + diff --git a/tests/visual/index.html b/tests/visual/index.html index 1f9a5954f..46615a3a4 100644 --- a/tests/visual/index.html +++ b/tests/visual/index.html @@ -7,7 +7,7 @@ - + -- cgit v1.2.3 From 5c9d9f9e9dc852ea37b7acc8c6a758f1901aa6a6 Mon Sep 17 00:00:00 2001 From: Scott González Date: Fri, 18 May 2012 16:11:14 -0400 Subject: Tabs: Pass the list item instead of the anchor in events; move aria-controls from the anchor to the list item. --- tests/unit/tabs/tabs.html | 2 +- tests/unit/tabs/tabs_core.js | 13 ++--- tests/unit/tabs/tabs_deprecated.html | 2 +- tests/unit/tabs/tabs_deprecated.js | 61 ++++++++++++----------- tests/unit/tabs/tabs_events.js | 28 ++++++----- tests/unit/tabs/tabs_methods.js | 22 ++++++--- tests/unit/tabs/tabs_options.js | 18 +++---- tests/unit/tabs/tabs_test_helpers.js | 2 +- ui/jquery.ui.tabs.js | 95 +++++++++++++++++++++--------------- 9 files changed, 136 insertions(+), 107 deletions(-) (limited to 'tests/unit') diff --git a/tests/unit/tabs/tabs.html b/tests/unit/tabs/tabs.html index b961c60f3..b9fa507d8 100644 --- a/tests/unit/tabs/tabs.html +++ b/tests/unit/tabs/tabs.html @@ -57,7 +57,7 @@
  • 1
  • 2
  • 3
  • -
  • 4
  • +
  • 4
  • 5
  • diff --git a/tests/unit/tabs/tabs_core.js b/tests/unit/tabs/tabs_core.js index b9bd81987..fb3c306e6 100644 --- a/tests/unit/tabs/tabs_core.js +++ b/tests/unit/tabs/tabs_core.js @@ -47,14 +47,15 @@ test( "disconnected from DOM", function() { test( "aria-controls", function() { expect( 7 ); var element = $( "#tabs1" ).tabs(), - tabs = element.find( ".ui-tabs-nav a" ); + tabs = element.find( ".ui-tabs-nav li" ); tabs.each(function() { - var tab = $( this ); - equal( tab.prop( "hash" ).substring( 1 ), tab.attr( "aria-controls" ) ); + var tab = $( this ), + anchor = tab.find( ".ui-tabs-anchor" ); + equal( anchor.prop( "hash" ).substring( 1 ), tab.attr( "aria-controls" ) ); }); element = $( "#tabs2" ).tabs(); - tabs = element.find( ".ui-tabs-nav a" ); + tabs = element.find( ".ui-tabs-nav li" ); equal( tabs.eq( 0 ).attr( "aria-controls" ), "colon:test" ); equal( tabs.eq( 1 ).attr( "aria-controls" ), "inline-style" ); ok( /^ui-tabs-\d+$/.test( tabs.eq( 2 ).attr( "aria-controls" ) ), "generated id" ); @@ -86,11 +87,11 @@ test( "#4033 - IE expands hash to full url and misinterprets tab as ajax", funct element.tabs({ beforeLoad: function( event, ui ) { event.preventDefault(); - ok( false, 'should not be an ajax tab'); + ok( false, "should not be an ajax tab" ); } }); - equal( element.find( ".ui-tabs-nav a" ).attr( "aria-controls" ), "tab", "aria-contorls attribute is correct" ); + equal( element.find( ".ui-tabs-nav li" ).attr( "aria-controls" ), "tab", "aria-contorls attribute is correct" ); state( element, 1 ); }); diff --git a/tests/unit/tabs/tabs_deprecated.html b/tests/unit/tabs/tabs_deprecated.html index 09afc91b4..e58382efb 100644 --- a/tests/unit/tabs/tabs_deprecated.html +++ b/tests/unit/tabs/tabs_deprecated.html @@ -56,7 +56,7 @@
  • 1
  • 2
  • 3
  • -
  • 4
  • +
  • 4
  • 5
  • diff --git a/tests/unit/tabs/tabs_deprecated.js b/tests/unit/tabs/tabs_deprecated.js index 66768b866..351433348 100644 --- a/tests/unit/tabs/tabs_deprecated.js +++ b/tests/unit/tabs/tabs_deprecated.js @@ -107,11 +107,11 @@ test( "tabTemplate + panelTemplate", function() { }); element.tabs( "add", "#new", "New" ); tab = element.find( ".ui-tabs-nav li" ).last(); - anchor = tab.find( "a" ); + anchor = tab.find( ".ui-tabs-anchor" ); equal( tab.text(), "New", "label" ); ok( tab.hasClass( "customTab" ), "tab custom class" ); equal( anchor.attr( "href" ), "http://example.com/#new", "href" ); - equal( anchor.attr( "aria-controls" ), "new", "aria-controls" ); + equal( tab.attr( "aria-controls" ), "new", "aria-controls" ); ok( element.find( "#new" ).hasClass( "customPanel" ), "panel custom class" ); }); @@ -210,7 +210,7 @@ test( "selected", function() { equal( element.tabs( "option", "selected" ), 0 ); state( element, 1, 0, 0 ); - element.find( ".ui-tabs-nav a" ).eq( 1 ).click(); + element.find( ".ui-tabs-nav .ui-tabs-anchor" ).eq( 1 ).click(); equal( element.tabs( "option", "selected" ), 1 ); state( element, 0, 1, 0 ); @@ -226,17 +226,18 @@ module( "tabs (deprecated): events" ); asyncTest( "load", function() { expect( 15 ); - var tab, panelId, panel, + var tab, anchor, panelId, panel, element = $( "#tabs2" ); // init element.one( "tabsload", function( event, ui ) { - tab = element.find( ".ui-tabs-nav a" ).eq( 2 ); + tab = element.find( ".ui-tabs-nav li" ).eq( 2 ); + anchor = tab.find( ".ui-tabs-anchor" ); panelId = tab.attr( "aria-controls" ); panel = $( "#" + panelId ); ok( !( "originalEvent" in event ), "originalEvent" ); - strictEqual( ui.tab, tab[ 0 ], "tab" ); + strictEqual( ui.tab, anchor[ 0 ], "tab" ); strictEqual( ui.panel, panel[ 0 ], "panel" ); equal( $( ui.panel ).find( "p" ).length, 1, "panel html" ); state( element, 0, 0, 1, 0, 0 ); @@ -247,12 +248,13 @@ asyncTest( "load", function() { function tabsload1() { // .option() element.one( "tabsload", function( event, ui ) { - tab = element.find( ".ui-tabs-nav a" ).eq( 3 ); + tab = element.find( ".ui-tabs-nav li" ).eq( 3 ); + anchor = tab.find( ".ui-tabs-anchor" ); panelId = tab.attr( "aria-controls" ); panel = $( "#" + panelId ); ok( !( "originalEvent" in event ), "originalEvent" ); - strictEqual( ui.tab, tab[ 0 ], "tab" ); + strictEqual( ui.tab, anchor[ 0 ], "tab" ); strictEqual( ui.panel, panel[ 0 ], "panel" ); equal( $( ui.panel ).find( "p" ).length, 1, "panel html" ); state( element, 0, 0, 0, 1, 0 ); @@ -264,18 +266,19 @@ asyncTest( "load", function() { function tabsload2() { // click, change panel content element.one( "tabsload", function( event, ui ) { - tab = element.find( ".ui-tabs-nav a" ).eq( 4 ); + tab = element.find( ".ui-tabs-nav li" ).eq( 4 ); + anchor = tab.find( ".ui-tabs-anchor" ); panelId = tab.attr( "aria-controls" ); panel = $( "#" + panelId ); equal( event.originalEvent.type, "click", "originalEvent" ); - strictEqual( ui.tab, tab[ 0 ], "tab" ); + strictEqual( ui.tab, anchor[ 0 ], "tab" ); strictEqual( ui.panel, panel[ 0 ], "panel" ); equal( $( ui.panel ).find( "p" ).length, 1, "panel html" ); state( element, 0, 0, 0, 0, 1 ); start(); }); - element.find( ".ui-tabs-nav a" ).eq( 4 ).click(); + element.find( ".ui-tabs-nav .ui-tabs-anchor" ).eq( 4 ).click(); } }); @@ -285,7 +288,7 @@ test( "enable", function() { var element = $( "#tabs1" ).tabs({ disabled: [ 0, 1 ], enable: function( event, ui ) { - equal( ui.tab, element.find( ".ui-tabs-nav a" )[ 1 ], "ui.tab" ); + equal( ui.tab, element.find( ".ui-tabs-nav .ui-tabs-anchor" )[ 1 ], "ui.tab" ); equal( ui.panel, element.find( ".ui-tabs-panel" )[ 1 ], "ui.panel" ); equal( ui.index, 1, "ui.index" ); } @@ -300,7 +303,7 @@ test( "disable", function() { var element = $( "#tabs1" ).tabs({ disable: function( event, ui ) { - equal( ui.tab, element.find( ".ui-tabs-nav a" )[ 1 ], "ui.tab" ); + equal( ui.tab, element.find( ".ui-tabs-nav .ui-tabs-anchor" )[ 1 ], "ui.tab" ); equal( ui.panel, element.find( ".ui-tabs-panel" )[ 1 ], "ui.panel" ); equal( ui.index, 1, "ui.index" ); } @@ -318,13 +321,13 @@ test( "show", function() { active: false, collapsible: true }), - tabs = element.find( ".ui-tabs-nav a" ), + anchors = element.find( ".ui-tabs-nav .ui-tabs-anchor" ), panels = element.find( ".ui-tabs-panel" ); // from collapsed element.one( "tabsshow", function( event, ui ) { ok( !( "originalEvent" in event ), "originalEvent" ); - strictEqual( ui.tab, tabs[ 0 ], "ui.tab" ); + strictEqual( ui.tab, anchors[ 0 ], "ui.tab" ); strictEqual( ui.panel, panels[ 0 ], "ui.panel" ); equal( ui.index, 0, "ui.index" ); state( element, 1, 0, 0 ); @@ -335,12 +338,12 @@ test( "show", function() { // switching tabs element.one( "tabsshow", function( event, ui ) { equal( event.originalEvent.type, "click", "originalEvent" ); - strictEqual( ui.tab, tabs[ 1 ], "ui.tab" ); + strictEqual( ui.tab, anchors[ 1 ], "ui.tab" ); strictEqual( ui.panel, panels[ 1 ], "ui.panel" ); equal( ui.index, 1, "ui.index" ); state( element, 0, 1, 0 ); }); - tabs.eq( 1 ).click(); + anchors.eq( 1 ).click(); state( element, 0, 1, 0 ); // collapsing @@ -358,13 +361,13 @@ test( "select", function() { active: false, collapsible: true }), - tabs = element.find( ".ui-tabs-nav a" ), + anchors = element.find( ".ui-tabs-nav .ui-tabs-anchor" ), panels = element.find( ".ui-tabs-panel" ); // from collapsed element.one( "tabsselect", function( event, ui ) { ok( !( "originalEvent" in event ), "originalEvent" ); - strictEqual( ui.tab, tabs[ 0 ], "ui.tab" ); + strictEqual( ui.tab, anchors[ 0 ], "ui.tab" ); strictEqual( ui.panel, panels[ 0 ], "ui.panel" ); equal( ui.index, 0, "ui.index" ); state( element, 0, 0, 0 ); @@ -375,12 +378,12 @@ test( "select", function() { // switching tabs element.one( "tabsselect", function( event, ui ) { equal( event.originalEvent.type, "click", "originalEvent" ); - strictEqual( ui.tab, tabs[ 1 ], "ui.tab" ); + strictEqual( ui.tab, anchors[ 1 ], "ui.tab" ); strictEqual( ui.panel, panels[ 1 ], "ui.panel" ); equal( ui.index, 1, "ui.index" ); state( element, 1, 0, 0 ); }); - tabs.eq( 1 ).click(); + anchors.eq( 1 ).click(); state( element, 0, 1, 0 ); // collapsing @@ -414,11 +417,11 @@ test( "add", function() { element.tabs( "add", "#new", "New" ); state( element, 1, 0, 0, 0 ); tab = element.find( ".ui-tabs-nav li" ).last(); - anchor = tab.find( "a" ); + anchor = tab.find( ".ui-tabs-anchor" ); equal( tab.text(), "New", "label" ); equal( stripLeadingSlash( anchor[0].pathname ), stripLeadingSlash( location.pathname ), "href pathname" ); equal( anchor[0].hash, "#new", "href hash" ); - equal( anchor.attr( "aria-controls" ), "new", "aria-controls" ); + equal( tab.attr( "aria-controls" ), "new", "aria-controls" ); ok( !tab.hasClass( "ui-state-hover" ), "not hovered" ); anchor.simulate( "mouseover" ); ok( tab.hasClass( "ui-state-hover" ), "hovered" ); @@ -429,17 +432,17 @@ test( "add", function() { element.one( "tabsadd", function( event, ui ) { equal( ui.index, 1, "ui.index" ); equal( $( ui.tab ).text(), "New Remote", "ui.tab" ); - equal( ui.panel.id, $( ui.tab ).attr( "aria-controls" ), "ui.panel" ); + equal( ui.panel.id, $( ui.tab ).closest( "li" ).attr( "aria-controls" ), "ui.panel" ); }); element.tabs( "add", "data/test.html", "New Remote", 1 ); state( element, 0, 0, 0, 0, 1 ); tab = element.find( ".ui-tabs-nav li" ).eq( 1 ); - anchor = tab.find( "a" ); + anchor = tab.find( ".ui-tabs-anchor" ); equal( tab.text(), "New Remote", "label" ); equal( stripLeadingSlash( stripLeadingSlash( anchor[0].pathname.replace( stripLeadingSlash( location.pathname ).split( "/" ).slice( 0, -1 ).join( "/" ), "" ) ) ), "data/test.html", "href" ); - ok( /^ui-tabs-\d+$/.test( anchor.attr( "aria-controls" ) ), "aria controls" ); + ok( /^ui-tabs-\d+$/.test( tab.attr( "aria-controls" ) ), "aria controls" ); ok( !tab.hasClass( "ui-state-hover" ), "not hovered" ); anchor.simulate( "mouseover" ); ok( tab.hasClass( "ui-state-hover" ), "hovered" ); @@ -560,10 +563,10 @@ test( "url", function() { expect( 2 ); var element = $( "#tabs2" ).tabs(), - tab = element.find( "a" ).eq( 3 ); + anchor = element.find( ".ui-tabs-anchor" ).eq( 3 ); element.tabs( "url", 3, "data/test2.html" ); - equal( tab.attr( "href" ), "data/test2.html", "href was updated" ); + equal( anchor.attr( "href" ), "data/test2.html", "href was updated" ); element.one( "tabsbeforeload", function( event, ui ) { equal( ui.ajaxSettings.url, "data/test2.html", "ajaxSettings.url" ); event.preventDefault(); @@ -582,7 +585,7 @@ asyncTest( "abort", function() { }); }); // prevent IE from caching the request, so that it won't resolve before we call abort - element.find( ".ui-tabs-nav li:eq(2) a" ).attr( "href", function( href ) { + element.find( ".ui-tabs-nav li:eq(2) .ui-tabs-anchor" ).attr( "href", function( href ) { return href + "?" + (+ new Date()); }); element.tabs( "option", "active", 2 ); diff --git a/tests/unit/tabs/tabs_events.js b/tests/unit/tabs/tabs_events.js index f33686581..57011bdad 100644 --- a/tests/unit/tabs/tabs_events.js +++ b/tests/unit/tabs/tabs_events.js @@ -8,7 +8,7 @@ test( "create", function() { expect( 10 ); var element = $( "#tabs1" ), - tabs = element.find( "ul a" ), + tabs = element.find( "ul li" ), panels = element.children( "div" ); element.tabs({ @@ -50,7 +50,8 @@ test( "beforeActivate", function() { active: false, collapsible: true }), - tabs = element.find( ".ui-tabs-nav a" ), + tabs = element.find( ".ui-tabs-nav li" ), + anchors = tabs.find( ".ui-tabs-anchor" ), panels = element.find( ".ui-tabs-panel" ); // from collapsed @@ -80,7 +81,7 @@ test( "beforeActivate", function() { strictEqual( ui.newPanel[ 0 ], panels[ 1 ], "newPanel" ); state( element, 1, 0, 0 ); }); - tabs.eq( 1 ).click(); + anchors.eq( 1 ).click(); state( element, 0, 1, 0 ); // collapsing @@ -120,7 +121,8 @@ test( "activate", function() { active: false, collapsible: true }), - tabs = element.find( ".ui-tabs-nav a" ), + tabs = element.find( ".ui-tabs-nav li" ), + anchors = element.find( ".ui-tabs-anchor" ), panels = element.find( ".ui-tabs-panel" ); // from collapsed @@ -150,7 +152,7 @@ test( "activate", function() { strictEqual( ui.newPanel[ 0 ], panels[ 1 ], "newPanel" ); state( element, 0, 1, 0 ); }); - tabs.eq( 1 ).click(); + anchors.eq( 1 ).click(); state( element, 0, 1, 0 ); // collapsing @@ -186,7 +188,7 @@ test( "beforeLoad", function() { // init element.one( "tabsbeforeload", function( event, ui ) { - tab = element.find( ".ui-tabs-nav a" ).eq( 2 ); + tab = element.find( ".ui-tabs-nav li" ).eq( 2 ); panelId = tab.attr( "aria-controls" ); panel = $( "#" + panelId ); @@ -208,7 +210,7 @@ test( "beforeLoad", function() { // .option() element.one( "tabsbeforeload", function( event, ui ) { - tab = element.find( ".ui-tabs-nav a" ).eq( 2 ); + tab = element.find( ".ui-tabs-nav li" ).eq( 2 ); panelId = tab.attr( "aria-controls" ); panel = $( "#" + panelId ); @@ -230,7 +232,7 @@ test( "beforeLoad", function() { // click, change panel content element.one( "tabsbeforeload", function( event, ui ) { - tab = element.find( ".ui-tabs-nav a" ).eq( 3 ); + tab = element.find( ".ui-tabs-nav li" ).eq( 3 ); panelId = tab.attr( "aria-controls" ); panel = $( "#" + panelId ); @@ -245,7 +247,7 @@ test( "beforeLoad", function() { event.preventDefault(); state( element, 0, 0, 1, 0, 0 ); }); - element.find( ".ui-tabs-nav a" ).eq( 3 ).click(); + element.find( ".ui-tabs-nav .ui-tabs-anchor" ).eq( 3 ).click(); state( element, 0, 0, 0, 1, 0 ); // .toLowerCase() is needed to convert

    to

    in old IEs equal( panel.html().toLowerCase(), "

    testing

    ", "panel html after" ); @@ -260,7 +262,7 @@ if ( $.uiBackCompat === false ) { // init element.one( "tabsload", function( event, ui ) { - tab = element.find( ".ui-tabs-nav a" ).eq( 2 ); + tab = element.find( ".ui-tabs-nav li" ).eq( 2 ); panelId = tab.attr( "aria-controls" ); panel = $( "#" + panelId ); @@ -278,7 +280,7 @@ if ( $.uiBackCompat === false ) { function tabsload1() { // .option() element.one( "tabsload", function( event, ui ) { - tab = element.find( ".ui-tabs-nav a" ).eq( 3 ); + tab = element.find( ".ui-tabs-nav li" ).eq( 3 ); panelId = tab.attr( "aria-controls" ); panel = $( "#" + panelId ); @@ -297,7 +299,7 @@ if ( $.uiBackCompat === false ) { function tabsload2() { // click, change panel content element.one( "tabsload", function( event, ui ) { - tab = element.find( ".ui-tabs-nav a" ).eq( 4 ); + tab = element.find( ".ui-tabs-nav li" ).eq( 4 ); panelId = tab.attr( "aria-controls" ); panel = $( "#" + panelId ); @@ -310,7 +312,7 @@ if ( $.uiBackCompat === false ) { state( element, 0, 0, 0, 0, 1 ); start(); }); - element.find( ".ui-tabs-nav a" ).eq( 4 ).click(); + element.find( ".ui-tabs-nav .ui-tabs-anchor" ).eq( 4 ).click(); } }); } diff --git a/tests/unit/tabs/tabs_methods.js b/tests/unit/tabs/tabs_methods.js index 0837995e6..ed3e73745 100644 --- a/tests/unit/tabs/tabs_methods.js +++ b/tests/unit/tabs/tabs_methods.js @@ -97,7 +97,7 @@ test( "refresh", function() { element.tabs( "refresh" ); state( element, 1, 0, 0, 0 ); disabled( element, [ 1 ] ); - equal( element.find( "#" + $( "#newTab a" ).attr( "aria-controls" ) ).length, 1, + equal( element.find( "#" + $( "#newTab" ).attr( "aria-controls" ) ).length, 1, "panel added for remote tab" ); // remove all tabs @@ -156,7 +156,7 @@ asyncTest( "load", function() { // load content of inactive tab // useful for preloading content with custom caching element.one( "tabsbeforeload", function( event, ui ) { - var tab = element.find( ".ui-tabs-nav a" ).eq( 3 ), + var tab = element.find( ".ui-tabs-nav li" ).eq( 3 ), panelId = tab.attr( "aria-controls" ), panel = $( "#" + panelId ); @@ -171,13 +171,17 @@ asyncTest( "load", function() { // TODO: remove wrapping in 2.0 var uiTab = $( ui.tab ), uiPanel = $( ui.panel ), - tab = element.find( ".ui-tabs-nav a" ).eq( 3 ), + tab = element.find( ".ui-tabs-nav li" ).eq( 3 ), panelId = tab.attr( "aria-controls" ), panel = $( "#" + panelId ); ok( !( "originalEvent" in event ), "originalEvent" ); equal( uiTab.length, 1, "tab length" ); - strictEqual( uiTab[ 0 ], tab[ 0 ], "tab" ); + if ( $.uiBackCompat === false ) { + strictEqual( uiTab[ 0 ], tab[ 0 ], "tab" ); + } else { + strictEqual( uiTab[ 0 ], tab.find( ".ui-tabs-anchor" )[ 0 ], "tab" ); + } equal( uiPanel.length, 1, "panel length" ); strictEqual( uiPanel[ 0 ], panel[ 0 ], "panel" ); equal( uiPanel.find( "p" ).length, 1, "panel html" ); @@ -203,7 +207,7 @@ asyncTest( "load", function() { function tabsload2() { // reload content of active tab element.one( "tabsbeforeload", function( event, ui ) { - var tab = element.find( ".ui-tabs-nav a" ).eq( 3 ), + var tab = element.find( ".ui-tabs-nav li" ).eq( 3 ), panelId = tab.attr( "aria-controls" ), panel = $( "#" + panelId ); @@ -218,13 +222,17 @@ asyncTest( "load", function() { // TODO: remove wrapping in 2.0 var uiTab = $( ui.tab ), uiPanel = $( ui.panel ), - tab = element.find( ".ui-tabs-nav a" ).eq( 3 ), + tab = element.find( ".ui-tabs-nav li" ).eq( 3 ), panelId = tab.attr( "aria-controls" ), panel = $( "#" + panelId ); ok( !( "originalEvent" in event ), "originalEvent" ); equal( uiTab.length, 1, "tab length" ); - strictEqual( uiTab[ 0 ], tab[ 0 ], "tab" ); + if ( $.uiBackCompat === false ) { + strictEqual( uiTab[ 0 ], tab[ 0 ], "tab" ); + } else { + strictEqual( uiTab[ 0 ], tab.find( ".ui-tabs-anchor" )[ 0 ], "tab" ); + } equal( uiPanel.length, 1, "panel length" ); strictEqual( uiPanel[ 0 ], panel[ 0 ], "panel" ); state( element, 0, 0, 0, 1, 0 ); diff --git a/tests/unit/tabs/tabs_options.js b/tests/unit/tabs/tabs_options.js index ae9e7bdc6..df6827c57 100644 --- a/tests/unit/tabs/tabs_options.js +++ b/tests/unit/tabs/tabs_options.js @@ -57,7 +57,7 @@ test( "{ active: Number }", function() { equal( element.tabs( "option", "active" ), 0 ); state( element, 1, 0, 0 ); - element.find( ".ui-tabs-nav a" ).eq( 1 ).click(); + element.find( ".ui-tabs-nav .ui-tabs-anchor" ).eq( 1 ).click(); equal( element.tabs( "option", "active" ), 1 ); state( element, 0, 1, 0 ); @@ -110,7 +110,7 @@ test( "{ collapsible: false }", function() { equal( element.tabs( "option", "active" ), 1 ); state( element, 0, 1, 0 ); - element.find( ".ui-state-active a" ).eq( 1 ).click(); + element.find( ".ui-state-active .ui-tabs-anchor" ).eq( 1 ).click(); equal( element.tabs( "option", "active" ), 1 ); state( element, 0, 1, 0 ); }); @@ -131,7 +131,7 @@ test( "{ collapsible: true }", function() { equal( element.tabs( "option", "active" ), 1 ); state( element, 0, 1, 0 ); - element.find( ".ui-state-active a" ).click(); + element.find( ".ui-state-active .ui-tabs-anchor" ).click(); equal( element.tabs( "option", "active" ), false ); state( element, 0, 0, 0 ); }); @@ -173,7 +173,7 @@ test( "{ event: null }", function() { state( element, 0, 1, 0 ); // ensure default click handler isn't bound - element.find( ".ui-tabs-nav a" ).eq( 2 ).click(); + element.find( ".ui-tabs-nav .ui-tabs-anchor" ).eq( 2 ).click(); equal( element.tabs( "option", "active" ), 1 ); state( element, 0, 1, 0 ); }); @@ -186,27 +186,27 @@ test( "{ event: custom }", function() { }); state( element, 1, 0, 0 ); - element.find( ".ui-tabs-nav a" ).eq( 1 ).trigger( "custom1" ); + element.find( ".ui-tabs-nav .ui-tabs-anchor" ).eq( 1 ).trigger( "custom1" ); equal( element.tabs( "option", "active" ), 1 ); state( element, 0, 1, 0 ); // ensure default click handler isn't bound - element.find( ".ui-tabs-nav a" ).eq( 2 ).trigger( "click" ); + element.find( ".ui-tabs-nav .ui-tabs-anchor" ).eq( 2 ).trigger( "click" ); equal( element.tabs( "option", "active" ), 1 ); state( element, 0, 1, 0 ); - element.find( ".ui-tabs-nav a" ).eq( 2 ).trigger( "custom2" ); + element.find( ".ui-tabs-nav .ui-tabs-anchor" ).eq( 2 ).trigger( "custom2" ); equal( element.tabs( "option", "active" ), 2 ); state( element, 0, 0, 1 ); element.tabs( "option", "event", "custom3" ); // ensure old event handlers are unbound - element.find( ".ui-tabs-nav a" ).eq( 1 ).trigger( "custom1" ); + element.find( ".ui-tabs-nav .ui-tabs-anchor" ).eq( 1 ).trigger( "custom1" ); equal( element.tabs( "option", "active" ), 2 ); state( element, 0, 0, 1 ); - element.find( ".ui-tabs-nav a" ).eq( 1 ).trigger( "custom3" ); + element.find( ".ui-tabs-nav .ui-tabs-anchor" ).eq( 1 ).trigger( "custom3" ); equal( element.tabs( "option", "active" ), 1 ); state( element, 0, 1, 0 ); }); diff --git a/tests/unit/tabs/tabs_test_helpers.js b/tests/unit/tabs/tabs_test_helpers.js index 9f592c074..508043943 100644 --- a/tests/unit/tabs/tabs_test_helpers.js +++ b/tests/unit/tabs/tabs_test_helpers.js @@ -43,7 +43,7 @@ TestHelpers.tabs = { actual = tabs.find( ".ui-tabs-nav li" ).map(function() { var tab = $( this ), panel = $( $.ui.tabs.prototype._sanitizeSelector( - "#" + tab.find( "a" ).attr( "aria-controls" ) ) ), + "#" + tab.attr( "aria-controls" ) ) ), tabIsActive = tab.hasClass( "ui-state-active" ), panelIsActive = panel.css( "display" ) !== "none"; diff --git a/ui/jquery.ui.tabs.js b/ui/jquery.ui.tabs.js index 23c6ed58d..c0490e48e 100644 --- a/ui/jquery.ui.tabs.js +++ b/ui/jquery.ui.tabs.js @@ -59,8 +59,8 @@ $.widget( "ui.tabs", { if ( active === null ) { // check the fragment identifier in the URL if ( location.hash ) { - that.anchors.each(function( i, tab ) { - if ( tab.hash === location.hash ) { + that.anchors.each(function( i, anchor ) { + if ( anchor.hash === location.hash ) { active = i; return false; } @@ -152,8 +152,8 @@ $.widget( "ui.tabs", { } }, - _tabId: function( a ) { - return $( a ).attr( "aria-controls" ) || "ui-tabs-" + getNextTabId(); + _tabId: function( tab ) { + return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId(); }, _sanitizeSelector: function( hash ) { @@ -187,7 +187,7 @@ $.widget( "ui.tabs", { // was active, active tab still exists } else { // make sure active index is correct - options.active = this.anchors.index( this.active ); + options.active = this.lis.index( this.active ); } }, @@ -197,6 +197,7 @@ $.widget( "ui.tabs", { this.element.toggleClass( "ui-tabs-collapsible", options.collapsible ); this.list.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ); this.lis.addClass( "ui-state-default ui-corner-top" ); + this.anchors.addClass( "ui-tabs-anchor" ); this.panels.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ); this._setupDisabled( options.disabled ); @@ -219,7 +220,8 @@ $.widget( "ui.tabs", { this.panels = $(); this.anchors.each(function( i, a ) { - var selector, panel, id; + var selector, panel, id, + tab = $( a ).closest( "li" ); // inline tab if ( isLocal( a ) ) { @@ -227,7 +229,7 @@ $.widget( "ui.tabs", { panel = that.element.find( that._sanitizeSelector( selector ) ); // remote tab } else { - id = that._tabId( a ); + id = that._tabId( tab ); selector = "#" + id; panel = that.element.find( selector ); if ( !panel.length ) { @@ -239,7 +241,7 @@ $.widget( "ui.tabs", { if ( panel.length) { that.panels = that.panels.add( panel ); } - $( a ).attr( "aria-controls", selector.substring( 1 ) ); + tab.attr( "aria-controls", selector.substring( 1 ) ); }); }, @@ -294,16 +296,16 @@ $.widget( "ui.tabs", { var that = this, options = that.options, active = that.active, - clicked = $( event.currentTarget ), - clickedIsActive = clicked[ 0 ] === active[ 0 ], + anchor = $( event.currentTarget ), + tab = anchor.closest( "li" ), + clickedIsActive = tab[ 0 ] === active[ 0 ], collapsing = clickedIsActive && options.collapsible, - toShow = collapsing ? $() : that._getPanelForTab( clicked ), + toShow = collapsing ? $() : that._getPanelForTab( tab ), toHide = !active.length ? $() : that._getPanelForTab( active ), - tab = clicked.closest( "li" ), eventData = { oldTab: active, oldPanel: toHide, - newTab: collapsing ? $() : clicked, + newTab: collapsing ? $() : tab, newPanel: toShow }; @@ -318,13 +320,13 @@ $.widget( "ui.tabs", { ( clickedIsActive && !options.collapsible ) || // allow canceling activation ( that._trigger( "beforeActivate", event, eventData ) === false ) ) { - clicked[ 0 ].blur(); + anchor[ 0 ].blur(); return; } - options.active = collapsing ? false : that.anchors.index( clicked ); + options.active = collapsing ? false : that.lis.index( tab ); - that.active = clickedIsActive ? $() : clicked; + that.active = clickedIsActive ? $() : tab; if ( that.xhr ) { that.xhr.abort(); } @@ -335,8 +337,8 @@ $.widget( "ui.tabs", { if ( toShow.length ) { // TODO make passing in node possible - that.load( that.anchors.index( clicked ), event ); - clicked[ 0 ].blur(); + that.load( that.lis.index( tab ), event ); + anchor[ 0 ].blur(); } that._toggle( event, eventData ); }, @@ -379,31 +381,39 @@ $.widget( "ui.tabs", { }, _activate: function( index ) { - var active = this._findActive( index )[ 0 ]; + var anchor, + active = this._findActive( index ); // trying to activate the already active panel - if ( active === this.active[ 0 ] ) { + if ( active[ 0 ] === this.active[ 0 ] ) { return; } // trying to collapse, simulate a click on the current active header - active = active || this.active[ 0 ]; + if ( !active.length ) { + active = this.active; + } + anchor = active.find( ".ui-tabs-anchor" )[ 0 ]; this._eventHandler({ - target: active, - currentTarget: active, + target: anchor, + currentTarget: anchor, preventDefault: $.noop }); }, _findActive: function( selector ) { - return typeof selector === "number" ? this.anchors.eq( selector ) : - typeof selector === "string" ? this.anchors.filter( "[href$='" + selector + "']" ) : $(); + if ( typeof selector === "number" ) { + return this.lis.eq( selector ); + } + if ( typeof selector === "string" ) { + return this.anchors.filter( "[href$='" + selector + "']" ).closest( "li" ); + } + return $(); }, _getIndex: function( index ) { // meta-function to give users option to provide a href string instead of a numerical index. - // also sanitizes numerical indexes to valid values. if ( typeof index === "string" ) { index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) ); } @@ -421,6 +431,7 @@ $.widget( "ui.tabs", { this.list.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ); this.anchors + .removeClass( "ui-tabs-anchor" ) .unbind( ".tabs" ) .removeData( "href.tabs" ) .removeData( "load.tabs" ); @@ -493,10 +504,11 @@ $.widget( "ui.tabs", { load: function( index, event ) { index = this._getIndex( index ); var that = this, - anchor = this.anchors.eq( index ), - panel = that._getPanelForTab( anchor ), + tab = this.lis.eq( index ), + anchor = tab.find( ".ui-tabs-anchor" ), + panel = that._getPanelForTab( tab ), eventData = { - tab: anchor, + tab: tab, panel: panel }; @@ -517,7 +529,7 @@ $.widget( "ui.tabs", { // jQuery <1.8 returns false if the request is canceled in beforeSend, // but as of 1.8, $.ajax() always returns a jqXHR object. if ( this.xhr && this.xhr.statusText !== "canceled" ) { - this.lis.eq( index ).addClass( "ui-tabs-loading" ); + tab.addClass( "ui-tabs-loading" ); this.xhr .success(function( response ) { @@ -536,7 +548,7 @@ $.widget( "ui.tabs", { that.panels.stop( false, true ); } - that.lis.eq( index ).removeClass( "ui-tabs-loading" ); + tab.removeClass( "ui-tabs-loading" ); if ( jqXHR === that.xhr ) { delete that.xhr; @@ -723,10 +735,10 @@ if ( $.uiBackCompat !== false ) { .replace( /#\{label\}/g, label ) ), id = !url.indexOf( "#" ) ? url.replace( "#", "" ) : - this._tabId( li.find( "a" )[ 0 ] ); + this._tabId( li ); li.addClass( "ui-state-default ui-corner-top" ).data( "ui-tabs-destroy", true ); - li.find( "a" ).attr( "aria-controls", id ); + li.attr( "aria-controls", id ); doInsertAfter = index >= this.lis.length; @@ -769,7 +781,7 @@ if ( $.uiBackCompat !== false ) { index = this._getIndex( index ); var options = this.options, tab = this.lis.eq( index ).remove(), - panel = this._getPanelForTab( tab.find( "a[aria-controls]" ) ).remove(); + panel = this._getPanelForTab( tab ).remove(); // If selected tab was removed focus tab to the right or // in case the last tab was removed the tab to the left. @@ -808,8 +820,10 @@ if ( $.uiBackCompat !== false ) { idPrefix: "ui-tabs-" }, - _tabId: function( a ) { - return $( a ).attr( "aria-controls" ) || + _tabId: function( tab ) { + var a = tab.is( "li" ) ? tab.find( "a[href]" ) : tab; + a = a[0]; + return $( a ).closest( "li" ).attr( "aria-controls" ) || a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF\-]/g, "" ) || this.options.idPrefix + getNextTabId(); } @@ -875,7 +889,8 @@ if ( $.uiBackCompat !== false ) { this._super(); if ( this.options.active !== false ) { this._trigger( "show", null, this._ui( - this.active[ 0 ], this._getPanelForTab( this.active )[ 0 ] ) ); + this.active.find( ".ui-tabs-anchor" )[ 0 ], + this._getPanelForTab( this.active )[ 0 ] ) ); } }, _trigger: function( type, event, data ) { @@ -885,13 +900,13 @@ if ( $.uiBackCompat !== false ) { } if ( type === "beforeActivate" && data.newTab.length ) { ret = this._super( "select", event, { - tab: data.newTab[ 0], + tab: data.newTab.find( ".ui-tabs-anchor" )[ 0], panel: data.newPanel[ 0 ], index: data.newTab.closest( "li" ).index() }); } else if ( type === "activate" && data.newTab.length ) { ret = this._super( "show", event, { - tab: data.newTab[ 0 ], + tab: data.newTab.find( ".ui-tabs-anchor" )[ 0 ], panel: data.newPanel[ 0 ], index: data.newTab.closest( "li" ).index() }); @@ -973,7 +988,7 @@ if ( $.uiBackCompat !== false ) { var _data = $.extend( {}, data ); if ( type === "load" ) { _data.panel = _data.panel[ 0 ]; - _data.tab = _data.tab[ 0 ]; + _data.tab = _data.tab.find( ".ui-tabs-anchor" )[ 0 ]; } return this._super( type, event, _data ); } -- cgit v1.2.3 From 9de4da9d107767ad51315328bb73c7b20afd2994 Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Mon, 21 May 2012 16:27:04 +0200 Subject: Menu: Extend test for destroy method --- tests/unit/menu/menu_methods.js | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'tests/unit') diff --git a/tests/unit/menu/menu_methods.js b/tests/unit/menu/menu_methods.js index 6ad7bc134..fc4fce4f1 100644 --- a/tests/unit/menu/menu_methods.js +++ b/tests/unit/menu/menu_methods.js @@ -42,6 +42,12 @@ test("destroy", function() { domEqual("#menu1", function() { $("#menu1").menu().menu("destroy"); }); + domEqual("#menu5", function() { + $("#menu5").menu().menu("destroy"); + }); + domEqual("#menu6", function() { + $("#menu6").menu().menu("destroy"); + }); }); -- cgit v1.2.3 From 9ac52deaa271d3162e3d24724faf03f0b92ba3df Mon Sep 17 00:00:00 2001 From: Scott González Date: Mon, 21 May 2012 12:02:28 -0400 Subject: Don't use :radio selector. --- tests/unit/button/button_core.js | 6 +++--- tests/unit/button/button_tickets.js | 2 +- ui/jquery.ui.button.js | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'tests/unit') diff --git a/tests/unit/button/button_core.js b/tests/unit/button/button_core.js index 0d93ecedf..c274a8473 100644 --- a/tests/unit/button/button_core.js +++ b/tests/unit/button/button_core.js @@ -34,7 +34,7 @@ function assert(noForm, form1, form2) { } test("radio groups", function() { - $(":radio").button(); + $("input[type=radio]").button(); assert(":eq(0)", ":eq(1)", ":eq(2)"); // click outside of forms @@ -61,7 +61,7 @@ test("buttonset", function() { var set = $("#radio1").buttonset(); ok( set.is(".ui-buttonset") ); deepEqual( set.children(".ui-button").length, 3 ); - deepEqual( set.children("input:radio.ui-helper-hidden-accessible").length, 3 ); + deepEqual( set.children("input[type=radio].ui-helper-hidden-accessible").length, 3 ); ok( set.children("label:eq(0)").is(".ui-button.ui-corner-left:not(.ui-corner-all)") ); ok( set.children("label:eq(1)").is(".ui-button:not(.ui-corner-all)") ); ok( set.children("label:eq(2)").is(".ui-button.ui-corner-right:not(.ui-corner-all)") ); @@ -76,7 +76,7 @@ test("buttonset (rtl)", function() { set = $("#radio1").buttonset(); ok( set.is(".ui-buttonset") ); deepEqual( set.children(".ui-button").length, 3 ); - deepEqual( set.children("input:radio.ui-helper-hidden-accessible").length, 3 ); + deepEqual( set.children("input[type=radio].ui-helper-hidden-accessible").length, 3 ); ok( set.children("label:eq(0)").is(".ui-button.ui-corner-right:not(.ui-corner-all)") ); ok( set.children("label:eq(1)").is(".ui-button:not(.ui-corner-all)") ); ok( set.children("label:eq(2)").is(".ui-button.ui-corner-left:not(.ui-corner-all)") ); diff --git a/tests/unit/button/button_tickets.js b/tests/unit/button/button_tickets.js index 624d16716..43bfdb833 100644 --- a/tests/unit/button/button_tickets.js +++ b/tests/unit/button/button_tickets.js @@ -7,7 +7,7 @@ module( "button: tickets" ); test( "#5946 - buttonset should ignore buttons that are not :visible", function() { $( "#radio01" ).next().andSelf().hide(); - var set = $( "#radio0" ).buttonset({ items: ":radio:visible" }); + var set = $( "#radio0" ).buttonset({ items: "input[type=radio]:visible" }); ok( set.find( "label:eq(0)" ).is( ":not(.ui-button):not(.ui-corner-left)" ) ); ok( set.find( "label:eq(1)" ).is( ".ui-button.ui-corner-left" ) ); }); diff --git a/ui/jquery.ui.button.js b/ui/jquery.ui.button.js index f84d748cf..bd0af9408 100644 --- a/ui/jquery.ui.button.js +++ b/ui/jquery.ui.button.js @@ -216,7 +216,7 @@ $.widget( "ui.button", { if ( this.element.is(":checkbox") ) { this.type = "checkbox"; - } else if ( this.element.is(":radio") ) { + } else if ( this.element.is("[type=radio]") ) { this.type = "radio"; } else if ( this.element.is("input") ) { this.type = "input"; @@ -358,7 +358,7 @@ $.ui.button.version = "@VERSION"; $.widget( "ui.buttonset", { options: { - items: ":button, :submit, :reset, :checkbox, :radio, a, :data(button)" + items: ":button, :submit, :reset, :checkbox, [type=radio], a, :data(button)" }, _create: function() { -- cgit v1.2.3 From e6f21410ff4e2e88ed5f44c872451e8030898178 Mon Sep 17 00:00:00 2001 From: Scott González Date: Mon, 21 May 2012 12:47:15 -0400 Subject: Don't use :checkbox selector. --- tests/unit/button/button_tickets.js | 10 +++++----- ui/jquery.ui.button.js | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'tests/unit') diff --git a/tests/unit/button/button_tickets.js b/tests/unit/button/button_tickets.js index 43bfdb833..fe0d82fd6 100644 --- a/tests/unit/button/button_tickets.js +++ b/tests/unit/button/button_tickets.js @@ -30,23 +30,23 @@ test( "#6711 Checkbox/Radiobutton do not Show Focused State when using Keyboard test( "#7092 - button creation that requires a matching label does not find label in all cases", function() { var group = $( "" ); - group.find( "input:checkbox" ).button(); + group.find( "input[type=checkbox]" ).button(); ok( group.find( "label" ).is( ".ui-button" ) ); group = $( "" ); - group.filter( "input:checkbox" ).button(); + group.filter( "input[type=checkbox]" ).button(); ok( group.filter( "label" ).is( ".ui-button" ) ); group = $( "" ); - group.find( "input:checkbox" ).button(); + group.find( "input[type=checkbox]" ).button(); ok( group.filter( "label" ).is( ".ui-button" ) ); group = $( "" ); - group.find( "input:checkbox" ).button(); + group.find( "input[type=checkbox]" ).button(); ok( group.find( "label" ).is( ".ui-button" ) ); group = $( "" ); - group.filter( "input:checkbox" ).button(); + group.filter( "input[type=checkbox]" ).button(); ok( group.find( "label" ).is( ".ui-button" ) ); }); diff --git a/ui/jquery.ui.button.js b/ui/jquery.ui.button.js index bd0af9408..44dbc68db 100644 --- a/ui/jquery.ui.button.js +++ b/ui/jquery.ui.button.js @@ -214,7 +214,7 @@ $.widget( "ui.button", { _determineButtonType: function() { var ancestor, labelSelector, checked; - if ( this.element.is(":checkbox") ) { + if ( this.element.is("[type=checkbox]") ) { this.type = "checkbox"; } else if ( this.element.is("[type=radio]") ) { this.type = "radio"; @@ -358,7 +358,7 @@ $.ui.button.version = "@VERSION"; $.widget( "ui.buttonset", { options: { - items: ":button, :submit, :reset, :checkbox, [type=radio], a, :data(button)" + items: ":button, :submit, :reset, [type=checkbox], [type=radio], a, :data(button)" }, _create: function() { -- cgit v1.2.3 From 51863d5a71f50c86b1757a1a0840d7571f6a0ef7 Mon Sep 17 00:00:00 2001 From: Scott González Date: Mon, 21 May 2012 14:49:49 -0400 Subject: Don't use :input selector. --- demos/position/default.html | 2 +- tests/unit/draggable/draggable_common.js | 2 +- tests/unit/draggable/draggable_options.js | 8 ++++---- tests/unit/resizable/resizable_common.js | 2 +- tests/unit/selectable/selectable_common.js | 2 +- tests/unit/slider/slider_common.js | 2 +- tests/unit/sortable/sortable_common.js | 2 +- tests/unit/sortable/sortable_options.js | 2 +- tests/visual/position/position.html | 2 +- ui/jquery.ui.mouse.js | 2 +- 10 files changed, 13 insertions(+), 13 deletions(-) (limited to 'tests/unit') diff --git a/demos/position/default.html b/demos/position/default.html index 01137be62..35004b993 100644 --- a/demos/position/default.html +++ b/demos/position/default.html @@ -55,7 +55,7 @@ $( ".positionable" ).css( "opacity", 0.5 ); - $( ":input" ).bind( "click keyup change", position ); + $( "select, input" ).bind( "click keyup change", position ); $( "#parent" ).draggable({ drag: position diff --git a/tests/unit/draggable/draggable_common.js b/tests/unit/draggable/draggable_common.js index b47b139cd..64f8ce4a3 100644 --- a/tests/unit/draggable/draggable_common.js +++ b/tests/unit/draggable/draggable_common.js @@ -3,7 +3,7 @@ TestHelpers.commonWidgetTests( "draggable", { addClasses: true, appendTo: "parent", axis: false, - cancel: ":input,option", + cancel: "input,textarea,button,select,option", connectToSortable: false, containment: false, cursor: "auto", diff --git a/tests/unit/draggable/draggable_options.js b/tests/unit/draggable/draggable_options.js index 464e025dd..ea4611d69 100644 --- a/tests/unit/draggable/draggable_options.js +++ b/tests/unit/draggable/draggable_options.js @@ -106,15 +106,15 @@ test("{ axis: ? }, unexpected", function() { }); }); -test("{ cancel: ':input,option' }, default", function() { +test("{ cancel: 'input,textarea,button,select,option' }, default", function() { $('
    ').appendTo('#main'); - el = $("#draggable-option-cancel-default").draggable({ cancel: ":input,option" }); + el = $("#draggable-option-cancel-default").draggable({ cancel: "input,textarea,button,select,option" }); drag("#draggable-option-cancel-default", 50, 50); moved(50, 50); - el = $("#draggable-option-cancel-default").draggable({ cancel: ":input,option" }); - drag("#draggable-option-cancel-default :input", 50, 50); + el = $("#draggable-option-cancel-default").draggable({ cancel: "input,textarea,button,select,option" }); + drag("#draggable-option-cancel-default input", 50, 50); moved(0, 0); el.draggable("destroy"); diff --git a/tests/unit/resizable/resizable_common.js b/tests/unit/resizable/resizable_common.js index 617cdd2ad..119f5bd0e 100644 --- a/tests/unit/resizable/resizable_common.js +++ b/tests/unit/resizable/resizable_common.js @@ -6,7 +6,7 @@ TestHelpers.commonWidgetTests('resizable', { animateEasing: 'swing', aspectRatio: false, autoHide: false, - cancel: ':input,option', + cancel: 'input,textarea,button,select,option', containment: false, delay: 0, disabled: false, diff --git a/tests/unit/selectable/selectable_common.js b/tests/unit/selectable/selectable_common.js index 27714d0ae..885e79401 100644 --- a/tests/unit/selectable/selectable_common.js +++ b/tests/unit/selectable/selectable_common.js @@ -2,7 +2,7 @@ TestHelpers.commonWidgetTests('selectable', { defaults: { appendTo: 'body', autoRefresh: true, - cancel: ':input,option', + cancel: 'input,textarea,button,select,option', delay: 0, disabled: false, distance: 0, diff --git a/tests/unit/slider/slider_common.js b/tests/unit/slider/slider_common.js index 8a0b347f3..ccf793549 100644 --- a/tests/unit/slider/slider_common.js +++ b/tests/unit/slider/slider_common.js @@ -1,7 +1,7 @@ TestHelpers.commonWidgetTests( "slider", { defaults: { animate: false, - cancel: ':input,option', + cancel: 'input,textarea,button,select,option', delay: 0, disabled: false, distance: 0, diff --git a/tests/unit/sortable/sortable_common.js b/tests/unit/sortable/sortable_common.js index b5fc05a5d..ae21f7dd2 100644 --- a/tests/unit/sortable/sortable_common.js +++ b/tests/unit/sortable/sortable_common.js @@ -2,7 +2,7 @@ TestHelpers.commonWidgetTests( "sortable", { defaults: { appendTo: "parent", axis: false, - cancel: ":input,option", + cancel: "input,textarea,button,select,option", connectWith: false, containment: false, cursor: "auto", diff --git a/tests/unit/sortable/sortable_options.js b/tests/unit/sortable/sortable_options.js index 507d5dcfa..a043e68fe 100644 --- a/tests/unit/sortable/sortable_options.js +++ b/tests/unit/sortable/sortable_options.js @@ -29,7 +29,7 @@ test("{ axis: ? }, unexpected", function() { ok(false, "missing test - untested code is broken code."); }); -test("{ cancel: ':input,button' }, default", function() { +test("{ cancel: 'input,textarea,button,select,option' }, default", function() { ok(false, "missing test - untested code is broken code."); }); diff --git a/tests/visual/position/position.html b/tests/visual/position/position.html index 2fbe8e95d..545dc6993 100644 --- a/tests/visual/position/position.html +++ b/tests/visual/position/position.html @@ -64,7 +64,7 @@ position(); }); - $( ":input" ).bind( "click keyup change", function() { position(); } ); + $( "select, input" ).bind( "click keyup change", function() { position(); } ); position(); }); diff --git a/ui/jquery.ui.mouse.js b/ui/jquery.ui.mouse.js index eaa953ad0..e2e06897c 100644 --- a/ui/jquery.ui.mouse.js +++ b/ui/jquery.ui.mouse.js @@ -20,7 +20,7 @@ $( document ).mouseup( function( e ) { $.widget("ui.mouse", { version: "@VERSION", options: { - cancel: ':input,option', + cancel: 'input,textarea,button,select,option', distance: 1, delay: 0 }, -- cgit v1.2.3 From 1f1613852cb6116cd71a6600d737099fc2d55d2a Mon Sep 17 00:00:00 2001 From: TJ VanToll Date: Mon, 21 May 2012 21:52:48 -0400 Subject: Button: Corrected default label applied to submit buttons. Fixed #8337: Submit inputs don't automatically set label option. --- tests/unit/button/button_options.js | 4 ++++ ui/jquery.ui.button.js | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'tests/unit') diff --git a/tests/unit/button/button_options.js b/tests/unit/button/button_options.js index 9ef4a19db..3dd361ac9 100644 --- a/tests/unit/button/button_options.js +++ b/tests/unit/button/button_options.js @@ -53,6 +53,7 @@ test("text false with icon", function() { test("label, default", function() { $("#button").button(); deepEqual( $("#button").text(), "Label" ); + deepEqual( $( "#button").button( "option", "label" ), "Label" ); $("#button").button("destroy"); }); @@ -62,12 +63,14 @@ test("label", function() { label: "xxx" }); deepEqual( $("#button").text(), "xxx" ); + deepEqual( $("#button").button( "option", "label" ), "xxx" ); $("#button").button("destroy"); }); test("label default with input type submit", function() { deepEqual( $("#submit").button().val(), "Label" ); + deepEqual( $("#submit").button( "option", "label" ), "Label" ); }); test("label with input type submit", function() { @@ -75,6 +78,7 @@ test("label with input type submit", function() { label: "xxx" }).val(); deepEqual( label, "xxx" ); + deepEqual( $("#submit").button( "option", "label" ), "xxx" ); }); test("icons", function() { diff --git a/ui/jquery.ui.button.js b/ui/jquery.ui.button.js index 772ad4d6f..810191775 100644 --- a/ui/jquery.ui.button.js +++ b/ui/jquery.ui.button.js @@ -73,7 +73,7 @@ $.widget( "ui.button", { focusClass = "ui-state-focus"; if ( options.label === null ) { - options.label = this.buttonElement.html(); + options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html()); } this.buttonElement -- cgit v1.2.3 From 9dcd0e0eb824a4000692b6ce6d864056339ac498 Mon Sep 17 00:00:00 2001 From: Jörn Zaefferer Date: Tue, 22 May 2012 16:01:40 +0200 Subject: Menu: Handle SPACE same as ENTER, select items or opening submenus --- tests/unit/menu/menu_events.js | 16 ++++++++++++++-- ui/jquery.ui.menu.js | 22 +++++++++++++++------- 2 files changed, 29 insertions(+), 9 deletions(-) (limited to 'tests/unit') diff --git a/tests/unit/menu/menu_events.js b/tests/unit/menu/menu_events.js index 4cb083240..643da4a26 100644 --- a/tests/unit/menu/menu_events.js +++ b/tests/unit/menu/menu_events.js @@ -208,7 +208,7 @@ test("handle keyboard navigation on menu without scroll and without submenus", f }); asyncTest("handle keyboard navigation on menu without scroll and with submenus", function() { - expect(14); + expect(16); var element = $('#menu2').menu({ select: function(event, ui) { log($(ui.item[0]).text()); @@ -290,11 +290,23 @@ asyncTest("handle keyboard navigation on menu without scroll and with submenus", equal( $("#log").html(), "4,keydown,", "Keydown ESCAPE (close submenu)"); log("keydown",true); - element.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + element.simulate( "keydown", { keyCode: $.ui.keyCode.SPACE } ); setTimeout( menukeyboard4, 50 ); } function menukeyboard4() { + equal( $("#log").html(), "0,keydown,", "Keydown SPACE (open submenu)"); + + log("keydown",true); + element.simulate( "keydown", { keyCode: $.ui.keyCode.ESCAPE } ); + equal( $("#log").html(), "4,keydown,", "Keydown ESCAPE (close submenu)"); + + log("keydown",true); + element.simulate( "keydown", { keyCode: $.ui.keyCode.ENTER } ); + setTimeout( menukeyboard5, 50 ); + } + + function menukeyboard5() { equal( $("#log").html(), "0,keydown,", "Keydown ENTER (open submenu)"); log("keydown",true); diff --git a/ui/jquery.ui.menu.js b/ui/jquery.ui.menu.js index d3c32e3a0..1bfd76716 100644 --- a/ui/jquery.ui.menu.js +++ b/ui/jquery.ui.menu.js @@ -202,13 +202,11 @@ $.widget( "ui.menu", { event.preventDefault(); break; case $.ui.keyCode.ENTER: - if ( !this.active.is( ".ui-state-disabled" ) ) { - if ( this.active.children( "a[aria-haspopup='true']" ).length ) { - this.expand( event ); - } else { - this.select( event ); - } - } + this._activate( event ); + event.preventDefault(); + break; + case $.ui.keyCode.SPACE: + this._activate( event ); event.preventDefault(); break; case $.ui.keyCode.ESCAPE: @@ -260,6 +258,16 @@ $.widget( "ui.menu", { } }, + _activate: function( event ) { + if ( !this.active.is( ".ui-state-disabled" ) ) { + if ( this.active.children( "a[aria-haspopup='true']" ).length ) { + this.expand( event ); + } else { + this.select( event ); + } + } + }, + refresh: function() { // initialize nested menus var menus, -- cgit v1.2.3 From d7359beee6f8103e997959efd4f070245e9d3225 Mon Sep 17 00:00:00 2001 From: Scott González Date: Tue, 22 May 2012 10:09:08 -0400 Subject: Autocomplete: Added tests for live region. --- tests/unit/autocomplete/autocomplete_core.js | 37 ++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'tests/unit') diff --git a/tests/unit/autocomplete/autocomplete_core.js b/tests/unit/autocomplete/autocomplete_core.js index daeea0972..f0ad36a57 100644 --- a/tests/unit/autocomplete/autocomplete_core.js +++ b/tests/unit/autocomplete/autocomplete_core.js @@ -152,4 +152,41 @@ asyncTest( "handle race condition", function() { } }); +test( "ARIA", function() { + expect( 7 ); + var element = $( "#autocomplete" ).autocomplete({ + source: [ "java", "javascript" ] + }), + liveRegion = element.data( "ui-autocomplete" ).liveRegion; + + equal( liveRegion.text(), "", "Empty live region on create" ); + + element.autocomplete( "search", "j" ); + equal( liveRegion.text(), "2 results are available, use up and down arrow keys to navigate.", + "Live region for multiple values" ); + + element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + equal( liveRegion.text(), "2 results are available, use up and down arrow keys to navigate.", + "Live region not changed on focus" ); + + element.one( "autocompletefocus", function( event ) { + event.preventDefault(); + }); + element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + equal( liveRegion.text(), "javascript", + "Live region updated when default focus is prevented" ); + + element.autocomplete( "search", "javas" ); + equal( liveRegion.text(), "1 result is available, use up and down arrow keys to navigate.", + "Live region for one value" ); + + element.autocomplete( "search", "z" ); + equal( liveRegion.text(), "No search results.", + "Live region for no values" ); + + element.autocomplete( "search", "j" ); + equal( liveRegion.text(), "2 results are available, use up and down arrow keys to navigate.", + "Live region for multiple values" ); +}); + }( jQuery ) ); -- cgit v1.2.3 From b6cc9dd870836b94d6f82729d56e592c548f24ea Mon Sep 17 00:00:00 2001 From: Scott González Date: Tue, 22 May 2012 11:06:44 -0400 Subject: Tooltip: Handle multiple aria-describedby values. --- tests/unit/tooltip/tooltip.html | 1 + tests/unit/tooltip/tooltip_core.js | 20 ++++++++++++++++---- tests/unit/tooltip/tooltip_events.js | 2 +- tests/unit/tooltip/tooltip_methods.js | 6 +++--- tests/unit/tooltip/tooltip_options.js | 16 ++++++++-------- ui/jquery.ui.tooltip.js | 33 +++++++++++++++++++++++++++++---- 6 files changed, 58 insertions(+), 20 deletions(-) (limited to 'tests/unit') diff --git a/tests/unit/tooltip/tooltip.html b/tests/unit/tooltip/tooltip.html index d20ba8578..f6e60b367 100644 --- a/tests/unit/tooltip/tooltip.html +++ b/tests/unit/tooltip/tooltip.html @@ -41,6 +41,7 @@
    anchor + aria-describedby span
    diff --git a/tests/unit/tooltip/tooltip_core.js b/tests/unit/tooltip/tooltip_core.js index e2569fb01..e25eb3c13 100644 --- a/tests/unit/tooltip/tooltip_core.js +++ b/tests/unit/tooltip/tooltip_core.js @@ -3,7 +3,7 @@ module( "tooltip: core" ); test( "markup structure", function() { - expect( 6 ); + expect( 7 ); var element = $( "#tooltipped1" ).tooltip(), tooltip = $( ".ui-tooltip" ); @@ -11,8 +11,9 @@ test( "markup structure", function() { equal( tooltip.length, 0, "no tooltip on init" ); element.tooltip( "open" ); - tooltip = $( "#" + element.attr( "aria-describedby" ) ); + tooltip = $( "#" + element.data( "ui-tooltip-id" ) ); equal( tooltip.length, 1, "tooltip exists" ); + equal( element.attr( "aria-describedby"), tooltip.attr( "id" ), "aria-describedby" ); ok( tooltip.hasClass( "ui-tooltip" ), "tooltip is .ui-tooltip" ); equal( tooltip.length, 1, ".ui-tooltip exists" ); equal( tooltip.find( ".ui-tooltip-content" ).length, 1, @@ -20,8 +21,19 @@ test( "markup structure", function() { }); test( "accessibility", function() { - // TODO: add tests - expect( 0 ); + // TODO: full tests + expect( 2 ); + + var tooltipId, + element = $( "#multiple-describedby" ).tooltip(); + + element.tooltip( "open" ); + tooltipId = element.data( "ui-tooltip-id" ); + equal( element.attr( "aria-describedby" ), "fixture-span " + tooltipId, + "multiple describedby when open" ); + element.tooltip( "close" ); + equal( element.attr( "aria-describedby" ), "fixture-span", + "correct describedby when closed" ); }); }( jQuery ) ); diff --git a/tests/unit/tooltip/tooltip_events.js b/tests/unit/tooltip/tooltip_events.js index b1ce92fb2..fc5f1acc5 100644 --- a/tests/unit/tooltip/tooltip_events.js +++ b/tests/unit/tooltip/tooltip_events.js @@ -11,7 +11,7 @@ test( "programmatic triggers", function() { tooltip = ui.tooltip; ok( !( "originalEvent" in event ), "open" ); strictEqual( ui.tooltip[0], - $( "#" + element.attr( "aria-describedby" ) )[0], "ui.tooltip" ); + $( "#" + element.data( "ui-tooltip-id" ) )[0], "ui.tooltip" ); }); element.tooltip( "open" ); diff --git a/tests/unit/tooltip/tooltip_methods.js b/tests/unit/tooltip/tooltip_methods.js index eaab1c0d1..1b8cd2bf2 100644 --- a/tests/unit/tooltip/tooltip_methods.js +++ b/tests/unit/tooltip/tooltip_methods.js @@ -21,7 +21,7 @@ test( "open/close", function() { equal( $( ".ui-tooltip" ).length, 0, "no tooltip on init" ); element.tooltip( "open" ); - tooltip = $( "#" + element.attr( "aria-describedby" ) ); + tooltip = $( "#" + element.data( "ui-tooltip-id" ) ); ok( tooltip.is( ":visible" ) ); element.tooltip( "close" ); @@ -37,7 +37,7 @@ test( "enable/disable", function() { equal( $( ".ui-tooltip" ).length, 0, "no tooltip on init" ); element.tooltip( "open" ); - tooltip = $( "#" + element.attr( "aria-describedby" ) ); + tooltip = $( "#" + element.data( "ui-tooltip-id" ) ); ok( tooltip.is( ":visible" ) ); element.tooltip( "disable" ); @@ -51,7 +51,7 @@ test( "enable/disable", function() { equal( element.attr( "title" ), "anchortitle", "title restored on enable" ); element.tooltip( "open" ); - tooltip = $( "#" + element.attr( "aria-describedby" ) ); + tooltip = $( "#" + element.data( "ui-tooltip-id" ) ); ok( tooltip.is( ":visible" ) ); $.fx.off = false; }); diff --git a/tests/unit/tooltip/tooltip_options.js b/tests/unit/tooltip/tooltip_options.js index 4f994f8de..a4ef9f472 100644 --- a/tests/unit/tooltip/tooltip_options.js +++ b/tests/unit/tooltip/tooltip_options.js @@ -4,7 +4,7 @@ module( "tooltip: options" ); test( "content: default", function() { var element = $( "#tooltipped1" ).tooltip().tooltip( "open" ); - deepEqual( $( "#" + element.attr( "aria-describedby" ) ).text(), "anchortitle" ); + deepEqual( $( "#" + element.data( "ui-tooltip-id" ) ).text(), "anchortitle" ); }); test( "content: return string", function() { @@ -13,7 +13,7 @@ test( "content: return string", function() { return "customstring"; } }).tooltip( "open" ); - deepEqual( $( "#" + element.attr( "aria-describedby" ) ).text(), "customstring" ); + deepEqual( $( "#" + element.data( "ui-tooltip-id" ) ).text(), "customstring" ); }); test( "content: return jQuery", function() { @@ -22,7 +22,7 @@ test( "content: return jQuery", function() { return $( "
    " ).html( "customstring" ); } }).tooltip( "open" ); - deepEqual( $( "#" + element.attr( "aria-describedby" ) ).text(), "customstring" ); + deepEqual( $( "#" + element.data( "ui-tooltip-id" ) ).text(), "customstring" ); }); asyncTest( "content: sync + async callback", function() { @@ -30,11 +30,11 @@ asyncTest( "content: sync + async callback", function() { var element = $( "#tooltipped1" ).tooltip({ content: function( response ) { setTimeout(function() { - deepEqual( $( "#" + element.attr("aria-describedby") ).text(), "loading..." ); + deepEqual( $( "#" + element.data("ui-tooltip-id") ).text(), "loading..." ); response( "customstring2" ); setTimeout(function() { - deepEqual( $( "#" + element.attr("aria-describedby") ).text(), "customstring2" ); + deepEqual( $( "#" + element.data("ui-tooltip-id") ).text(), "customstring2" ); start(); }, 13 ); }, 13 ); @@ -53,12 +53,12 @@ test( "items", function() { event = $.Event( "mouseenter" ); event.target = $( "#fixture-span" )[ 0 ]; element.tooltip( "open", event ); - deepEqual( $( "#" + $( "#fixture-span" ).attr( "aria-describedby" ) ).text(), "title-text" ); + deepEqual( $( "#" + $( "#fixture-span" ).data( "ui-tooltip-id" ) ).text(), "title-text" ); // make sure default [title] doesn't get used event.target = $( "#tooltipped1" )[ 0 ]; element.tooltip( "open", event ); - deepEqual( $( "#tooltipped1" ).attr( "aria-describedby" ), undefined ); + deepEqual( $( "#tooltipped1" ).data( "ui-tooltip-id" ), undefined ); element.tooltip( "destroy" ); }); @@ -68,7 +68,7 @@ test( "tooltipClass", function() { var element = $( "#tooltipped1" ).tooltip({ tooltipClass: "custom" }).tooltip( "open" ); - ok( $( "#" + element.attr( "aria-describedby" ) ).hasClass( "custom" ) ); + ok( $( "#" + element.data( "ui-tooltip-id" ) ).hasClass( "custom" ) ); }); }( jQuery ) ); diff --git a/ui/jquery.ui.tooltip.js b/ui/jquery.ui.tooltip.js index 47a377bfd..1d6cd32a8 100644 --- a/ui/jquery.ui.tooltip.js +++ b/ui/jquery.ui.tooltip.js @@ -14,6 +14,31 @@ var increments = 0; +function addDescribedBy( elem, id ) { + var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ); + describedby.push( id ); + elem + .data( "ui-tooltip-id", id ) + .attr( "aria-describedby", $.trim( describedby.join( " " ) ) ); +} + +function removeDescribedBy( elem ) { + var id = elem.data( "ui-tooltip-id" ), + describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ), + index = $.inArray( id, describedby ); + if ( index !== -1 ) { + describedby.splice( index, 1 ); + } + + elem.removeData( "ui-tooltip-id" ); + describedby = $.trim( describedby.join( " " ) ); + if ( describedby ) { + elem.attr( "aria-describedby", describedby ); + } else { + elem.removeAttr( "aria-describedby" ); + } +} + $.widget( "ui.tooltip", { version: "@VERSION", options: { @@ -93,7 +118,7 @@ $.widget( "ui.tooltip", { .closest( this.options.items ); // if aria-describedby exists, then the tooltip is already open - if ( !target.length || target.attr( "aria-describedby" ) ) { + if ( !target.length || target.data( "ui-tooltip-id" ) ) { return; } @@ -143,7 +168,7 @@ $.widget( "ui.tooltip", { var tooltip = this._find( target ); if ( !tooltip.length ) { tooltip = this._tooltip( target ); - target.attr( "aria-describedby", tooltip.attr( "id" ) ); + addDescribedBy( target, tooltip.attr( "id" ) ); } tooltip.find( ".ui-tooltip-content" ).html( content ); tooltip @@ -195,7 +220,7 @@ $.widget( "ui.tooltip", { target.attr( "title", target.data( "ui-tooltip-title" ) ); } - target.removeAttr( "aria-describedby" ); + removeDescribedBy( target ); tooltip.stop( true ); this._hide( tooltip, this.options.hide, function() { @@ -232,7 +257,7 @@ $.widget( "ui.tooltip", { }, _find: function( target ) { - var id = target.attr( "aria-describedby" ); + var id = target.data( "ui-tooltip-id" ); return id ? $( "#" + id ) : $(); }, -- cgit v1.2.3 From 1339c1850f394b7200497f2de6e0d7dd13673b59 Mon Sep 17 00:00:00 2001 From: Scott González Date: Tue, 22 May 2012 12:54:09 -0400 Subject: Tooltip tests: Added accessibility tests. --- tests/unit/tooltip/tooltip_core.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'tests/unit') diff --git a/tests/unit/tooltip/tooltip_core.js b/tests/unit/tooltip/tooltip_core.js index e25eb3c13..1c8817aa8 100644 --- a/tests/unit/tooltip/tooltip_core.js +++ b/tests/unit/tooltip/tooltip_core.js @@ -21,19 +21,24 @@ test( "markup structure", function() { }); test( "accessibility", function() { - // TODO: full tests - expect( 2 ); + expect( 5 ); var tooltipId, + tooltip, element = $( "#multiple-describedby" ).tooltip(); element.tooltip( "open" ); tooltipId = element.data( "ui-tooltip-id" ); + tooltip = $( "#" + tooltipId ); + equal( tooltip.attr( "role" ), "tooltip", "role" ); equal( element.attr( "aria-describedby" ), "fixture-span " + tooltipId, "multiple describedby when open" ); + // strictEqual to distinguish between .removeAttr( "title" ) and .attr( "title", "" ) + strictEqual( element.attr( "title" ), undefined, "no title when open" ); element.tooltip( "close" ); equal( element.attr( "aria-describedby" ), "fixture-span", "correct describedby when closed" ); + equal( element.attr( "title" ), "...", "title restored when closed" ); }); }( jQuery ) ); -- cgit v1.2.3 From c275ebe09b967ab834646be9e0c73f2ff468bdac Mon Sep 17 00:00:00 2001 From: kborchers Date: Tue, 22 May 2012 23:52:59 -0500 Subject: Menu Tests: Remove unused unit tests and add new unit tests to improve coverage. --- tests/unit/menu/menu.html | 2 +- tests/unit/menu/menu_events.js | 123 +++++++++++++++++++++++++++++------------ 2 files changed, 88 insertions(+), 37 deletions(-) (limited to 'tests/unit') diff --git a/tests/unit/menu/menu.html b/tests/unit/menu/menu.html index fca45697f..62585d863 100644 --- a/tests/unit/menu/menu.html +++ b/tests/unit/menu/menu.html @@ -63,7 +63,7 @@
  • Aberdeen
  • Ada
  • Adamsville
  • -
  • Addyston
  • +
  • Addyston
  • Delphi