Skip to content

Commit b91fbab

Browse files
committed
Tabs: Support URL-based credentials
When credentials are provided directly in the URL, e.g.: https://username:password@www.example.com/ `location.href` strips out the auth part, but anchor links contain them, making our `isLocal` computation broken. This fixes it by only looking at `origin`, `pathname` & `search`. Fixes gh-2213
1 parent 44de3d3 commit b91fbab

File tree

2 files changed

+39
-20
lines changed

2 files changed

+39
-20
lines changed

tests/unit/tabs/core.js

+26
Original file line numberDiff line numberDiff line change
@@ -747,4 +747,30 @@ QUnit.test( "extra listeners created when tabs are added/removed (trac-15136)",
747747
"No extra listeners after removing all the extra tabs" );
748748
} );
749749

750+
QUnit.test( "URL-based auth with local tabs (gh-2213)", function( assert ) {
751+
assert.expect( 1 );
752+
753+
var origAjax = $.ajax,
754+
element = $( "#tabs1" ),
755+
anchor = element.find( "a[href='#fragment-3']" ),
756+
url = new URL( anchor.prop( "href" ) );
757+
758+
try {
759+
$.ajax = function() {
760+
throw new Error( "Unexpected AJAX call; all tabs are local!" );
761+
};
762+
763+
anchor.attr( "href", url.protocol + "//username:password@" + url.host +
764+
url.pathname + url.search + url.hash );
765+
766+
element.tabs();
767+
anchor.trigger( "click" );
768+
769+
assert.strictEqual( element.tabs( "option", "active" ), 2,
770+
"should set the active option" );
771+
} finally {
772+
$.ajax = origAjax;
773+
}
774+
} );
775+
750776
} );

ui/widgets/tabs.js

+13-20
Original file line numberDiff line numberDiff line change
@@ -61,26 +61,19 @@ $.widget( "ui.tabs", {
6161
load: null
6262
},
6363

64-
_isLocal: ( function() {
65-
var rhash = /#.*$/;
66-
67-
return function( anchor ) {
68-
var anchorUrl, locationUrl;
69-
70-
anchorUrl = anchor.href.replace( rhash, "" );
71-
locationUrl = location.href.replace( rhash, "" );
72-
73-
// Decoding may throw an error if the URL isn't UTF-8 (#9518)
74-
try {
75-
anchorUrl = decodeURIComponent( anchorUrl );
76-
} catch ( _error ) {}
77-
try {
78-
locationUrl = decodeURIComponent( locationUrl );
79-
} catch ( _error ) {}
80-
81-
return anchor.hash.length > 1 && anchorUrl === locationUrl;
82-
};
83-
} )(),
64+
_isLocal: function( anchor ) {
65+
var anchorUrl = new URL( anchor.href ),
66+
locationUrl = new URL( location.href );
67+
68+
return anchor.hash.length > 1 &&
69+
70+
// `href` may contain a hash but also username & password;
71+
// we want to ignore them, so we check the three fields
72+
// below instead.
73+
anchorUrl.origin === locationUrl.origin &&
74+
anchorUrl.pathname === locationUrl.pathname &&
75+
anchorUrl.search === locationUrl.search;
76+
},
8477

8578
_create: function() {
8679
var that = this,

0 commit comments

Comments
 (0)