From 18a3b539882835ecc78ed976a7d9e830c128fd96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Scott=20Gonz=C3=A1lez?= Date: Thu, 11 Aug 2011 16:48:58 -0400 Subject: [PATCH] Tabs: Fixed detection of local vs. remote tabs. Fixes #4941 - Mishandling of base tag. Fixes #4836 - Self refering href only partially detected. --- tests/unit/tabs/tabs_core.js | 2 +- ui/jquery.ui.tabs.js | 50 +++++++++++++++--------------------- 2 files changed, 21 insertions(+), 31 deletions(-) diff --git a/tests/unit/tabs/tabs_core.js b/tests/unit/tabs/tabs_core.js index 98cb617ec..e7c1ee576 100644 --- a/tests/unit/tabs/tabs_core.js +++ b/tests/unit/tabs/tabs_core.js @@ -48,7 +48,7 @@ test( "aria-controls", function() { tabs = element.find( ".ui-tabs-nav a" ); tabs.each(function() { var tab = $( this ); - equal( tab.attr( "href" ).substring( 1 ), tab.attr( "aria-controls" ) ); + equal( tab.prop( "hash" ).substring( 1 ), tab.attr( "aria-controls" ) ); }); element = $( "#tabs2" ).tabs(); diff --git a/ui/jquery.ui.tabs.js b/ui/jquery.ui.tabs.js index 62bab2d9f..b6f178ed9 100644 --- a/ui/jquery.ui.tabs.js +++ b/ui/jquery.ui.tabs.js @@ -18,6 +18,19 @@ function getNextTabId() { return ++tabId; } +var isLocal = (function() { + var rhash = /#.*$/, + currentPage = location.href.replace( rhash, "" ); + + return function( anchor ) { + // clone the node to work around IE 6 not normalizing the href property + // if it's manually set, i.e., a.href = "#foo" kills the normalization + anchor = anchor.cloneNode(); + return anchor.hash.length > 1 && + anchor.href.replace( rhash, "" ) === currentPage; + }; +})(); + $.widget( "ui.tabs", { version: "@VERSION", options: { @@ -197,8 +210,7 @@ $.widget( "ui.tabs", { }, _processTabs: function() { - var self = this, - fragmentId = /^#.+/; // Safari 2 reports '#' for an empty hash + var self = this; this.list = this.element.find( "ol,ul" ).eq( 0 ); this.lis = $( " > li:has(a[href])", this.list ); @@ -208,30 +220,14 @@ $.widget( "ui.tabs", { this.panels = $( [] ); this.anchors.each(function( i, a ) { - var href = $( a ).attr( "href" ), - hrefBase = href.split( "#" )[ 0 ], - selector, - panel, - baseEl; - - // For dynamically created HTML that contains a hash as href IE < 8 expands - // such href to the full page url with hash and then misinterprets tab as ajax. - // Same consideration applies for an added tab with a fragment identifier - // since a[href=#fragment-identifier] does unexpectedly not match. - // Thus normalize href attribute... - if ( hrefBase && ( hrefBase === location.toString().split( "#" )[ 0 ] || - ( baseEl = $( "base" )[ 0 ]) && hrefBase === baseEl.href ) ) { - href = a.hash; - a.href = href; - } + var selector, panel; // inline tab - if ( fragmentId.test( href ) ) { - selector = href; + if ( isLocal( a ) ) { + selector = a.hash; panel = self.element.find( self._sanitizeSelector( selector ) ); // remote tab - // prevent loading the page itself if href is just "#" - } else if ( href && href !== "#" ) { + } else { var id = self._tabId( a ); selector = "#" + id; panel = self.element.find( selector ); @@ -239,9 +235,6 @@ $.widget( "ui.tabs", { panel = self._createPanel( id ); panel.insertAfter( self.panels[ i - 1 ] || self.list ); } - // invalid tab href - } else { - self.options.disabled.push( i ); } if ( panel.length) { @@ -525,21 +518,18 @@ $.widget( "ui.tabs", { options = this.options, anchor = this.anchors.eq( index ), panel = self._getPanelForTab( anchor ), - // TODO until #3808 is fixed strip fragment identifier from url - // (IE fails to load from such url) - url = anchor.attr( "href" ).replace( /#.*$/, "" ), eventData = { tab: anchor, panel: panel }; // not remote - if ( !url ) { + if ( isLocal( anchor[ 0 ] ) ) { return; } this.xhr = $.ajax({ - url: url, + url: anchor.attr( "href" ), beforeSend: function( jqXHR, settings ) { return self._trigger( "beforeLoad", event, $.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) );