From: Scott González Date: Fri, 18 May 2012 20:11:14 +0000 (-0400) Subject: Tabs: Pass the list item instead of the anchor in events; move aria-controls from... X-Git-Tag: 1.9.0-beta.1~157 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=5c9d9f9e9dc852ea37b7acc8c6a758f1901aa6a6;p=jquery-ui.git Tabs: Pass the list item instead of the anchor in events; move aria-controls from the anchor to the list item. --- 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 ); }