"first actual tab is active" );
} );
+QUnit.test( "ID escaping backslashes", function( assert ) {
+ assert.expect( 5 );
+
+ location.hash = "#fragment\b-2";
+
+ var element = $( "#tabs1" )
+ .find( "a[href='#fragment-2']" )
+ .attr( "href", "#fragment\b-2" )
+ .end()
+ .find( "#fragment-2" )
+ .attr( "id", "fragment\b-2" )
+ .end()
+ .tabs();
+ var tabs = element.find( ".ui-tabs-nav li" );
+ var anchors = tabs.find( ".ui-tabs-anchor" );
+ var panels = element.find( ".ui-tabs-panel" );
+
+ assert.strictEqual( element.tabs( "option", "active" ), 1,
+ "should set the active option" );
+
+ assert.strictEqual( anchors.length, 3, "should decorate all anchors" );
+ assert.strictEqual( panels.length, 3, "should decorate all panels" );
+
+ assert.strictEqual( panels.eq( 1 ).attr( "aria-labelledby" ), anchors.eq( 1 ).attr( "id" ),
+ "panel 2 aria-labelledby equals anchor 2 id" );
+ assert.strictEqual( tabs.eq( 1 ).attr( "aria-controls" ), "fragment\b-2",
+ "tab 2 aria-controls" );
+
+ location.hash = "";
+} );
+
QUnit.test( "aria-controls", function( assert ) {
assert.expect( 7 );
var element = $( "#tabs1" ).tabs(),
var expected = $.makeArray( arguments ).slice( 2 ),
actual = tabs.find( ".ui-tabs-nav li" ).map( function() {
var tab = $( this ),
- panel = $( $.ui.tabs.prototype._sanitizeSelector(
- "#" + tab.attr( "aria-controls" ) ) ),
+ panel = $( "#" + CSS.escape( tab.attr( "aria-controls" ) ) ),
tabIsActive = tab.hasClass( "ui-state-active" ),
panelIsActive = panel.css( "display" ) !== "none";
_initialActive: function() {
var active = this.options.active,
collapsible = this.options.collapsible,
- locationHash = location.hash.substring( 1 );
+ locationHashDecoded = decodeURIComponent( location.hash.substring( 1 ) );
if ( active === null ) {
// check the fragment identifier in the URL
- if ( locationHash ) {
+ if ( locationHashDecoded ) {
this.tabs.each( function( i, tab ) {
- if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
+ if ( $( tab ).attr( "aria-controls" ) === locationHashDecoded ) {
active = i;
return false;
}
}
},
- _sanitizeSelector: function( hash ) {
- return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
- },
-
refresh: function() {
var options = this.options,
lis = this.tablist.children( ":has(a[href])" );
// Inline tab
if ( that._isLocal( anchor ) ) {
- selector = anchor.hash;
+ selector = decodeURIComponent( anchor.hash );
panelId = selector.substring( 1 );
- panel = that.element.find( that._sanitizeSelector( selector ) );
+ panel = that.element.find( "#" + CSS.escape( panelId ) );
// remote tab
} else {
_getPanelForTab: function( tab ) {
var id = $( tab ).attr( "aria-controls" );
- return this.element.find( this._sanitizeSelector( "#" + id ) );
+ return this.element.find( "#" + CSS.escape( id ) );
}
} );