mirror of
https://github.com/jquery/jquery-ui.git
synced 2024-11-21 11:04:24 +00:00
Tabs: Use CSS.escape
for sanitizing selectors
The previous private `_sanitizeSelector` API was not correctly escaping backslashes and is now removed. The native API should always be correct. Closes gh-2307
This commit is contained in:
parent
ebdcd0d866
commit
af8adca548
@ -84,6 +84,37 @@ QUnit.test( "non-tab list items", function( assert ) {
|
|||||||
"first actual tab is active" );
|
"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 ) {
|
QUnit.test( "aria-controls", function( assert ) {
|
||||||
assert.expect( 7 );
|
assert.expect( 7 );
|
||||||
var element = $( "#tabs1" ).tabs(),
|
var element = $( "#tabs1" ).tabs(),
|
||||||
|
@ -58,8 +58,7 @@ return $.extend( helper, {
|
|||||||
var expected = $.makeArray( arguments ).slice( 2 ),
|
var expected = $.makeArray( arguments ).slice( 2 ),
|
||||||
actual = tabs.find( ".ui-tabs-nav li" ).map( function() {
|
actual = tabs.find( ".ui-tabs-nav li" ).map( function() {
|
||||||
var tab = $( this ),
|
var tab = $( this ),
|
||||||
panel = $( $.ui.tabs.prototype._sanitizeSelector(
|
panel = $( "#" + CSS.escape( tab.attr( "aria-controls" ) ) ),
|
||||||
"#" + tab.attr( "aria-controls" ) ) ),
|
|
||||||
tabIsActive = tab.hasClass( "ui-state-active" ),
|
tabIsActive = tab.hasClass( "ui-state-active" ),
|
||||||
panelIsActive = panel.css( "display" ) !== "none";
|
panelIsActive = panel.css( "display" ) !== "none";
|
||||||
|
|
||||||
|
@ -121,14 +121,14 @@ $.widget( "ui.tabs", {
|
|||||||
_initialActive: function() {
|
_initialActive: function() {
|
||||||
var active = this.options.active,
|
var active = this.options.active,
|
||||||
collapsible = this.options.collapsible,
|
collapsible = this.options.collapsible,
|
||||||
locationHash = location.hash.substring( 1 );
|
locationHashDecoded = decodeURIComponent( location.hash.substring( 1 ) );
|
||||||
|
|
||||||
if ( active === null ) {
|
if ( active === null ) {
|
||||||
|
|
||||||
// check the fragment identifier in the URL
|
// check the fragment identifier in the URL
|
||||||
if ( locationHash ) {
|
if ( locationHashDecoded ) {
|
||||||
this.tabs.each( function( i, tab ) {
|
this.tabs.each( function( i, tab ) {
|
||||||
if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
|
if ( $( tab ).attr( "aria-controls" ) === locationHashDecoded ) {
|
||||||
active = i;
|
active = i;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -312,10 +312,6 @@ $.widget( "ui.tabs", {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_sanitizeSelector: function( hash ) {
|
|
||||||
return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
|
|
||||||
},
|
|
||||||
|
|
||||||
refresh: function() {
|
refresh: function() {
|
||||||
var options = this.options,
|
var options = this.options,
|
||||||
lis = this.tablist.children( ":has(a[href])" );
|
lis = this.tablist.children( ":has(a[href])" );
|
||||||
@ -434,9 +430,9 @@ $.widget( "ui.tabs", {
|
|||||||
|
|
||||||
// Inline tab
|
// Inline tab
|
||||||
if ( that._isLocal( anchor ) ) {
|
if ( that._isLocal( anchor ) ) {
|
||||||
selector = anchor.hash;
|
selector = decodeURIComponent( anchor.hash );
|
||||||
panelId = selector.substring( 1 );
|
panelId = selector.substring( 1 );
|
||||||
panel = that.element.find( that._sanitizeSelector( selector ) );
|
panel = that.element.find( "#" + CSS.escape( panelId ) );
|
||||||
|
|
||||||
// remote tab
|
// remote tab
|
||||||
} else {
|
} else {
|
||||||
@ -874,7 +870,7 @@ $.widget( "ui.tabs", {
|
|||||||
|
|
||||||
_getPanelForTab: function( tab ) {
|
_getPanelForTab: function( tab ) {
|
||||||
var id = $( tab ).attr( "aria-controls" );
|
var id = $( tab ).attr( "aria-controls" );
|
||||||
return this.element.find( this._sanitizeSelector( "#" + id ) );
|
return this.element.find( "#" + CSS.escape( id ) );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user