mirror of
https://github.com/jquery/jquery-ui.git
synced 2024-10-05 01:44:18 +00:00
Tabs: Deprecate url method; use aria-controls instead of title to specify panels. Fixes #7132 Tabs: Deprecate url method; use aria-controls instead of title to specify panels
This commit is contained in:
parent
f6e7b6c9f6
commit
1e2d3145ff
@ -14,7 +14,8 @@
|
|||||||
$( "#tabs" ).tabs({
|
$( "#tabs" ).tabs({
|
||||||
ajaxOptions: {
|
ajaxOptions: {
|
||||||
error: function( xhr, status, index, anchor ) {
|
error: function( xhr, status, index, anchor ) {
|
||||||
$( anchor.hash ).html(
|
var selector = $( anchor ).attr( "aria-controls" );
|
||||||
|
$( selector ).html(
|
||||||
"Couldn't load this tab. We'll try to fix this as soon as possible. " +
|
"Couldn't load this tab. We'll try to fix this as soon as possible. " +
|
||||||
"If this wouldn't be a demo." );
|
"If this wouldn't be a demo." );
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,19 @@
|
|||||||
(function( $ ) {
|
(function( $ ) {
|
||||||
|
|
||||||
|
module("tabs (deprecated): core");
|
||||||
|
|
||||||
|
test( "#4581 - title attribute for remote tabs does not support foreign languages", function() {
|
||||||
|
expect( 1 );
|
||||||
|
|
||||||
|
$( "#tabs2" ).tabs({
|
||||||
|
selected: 3,
|
||||||
|
beforeload: function( event, ui ) {
|
||||||
|
event.preventDefault();
|
||||||
|
equal( ui.panel.id, "∫ßáö_Սե", "proper title" );
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
module("tabs (deprecated): options");
|
module("tabs (deprecated): options");
|
||||||
|
|
||||||
test('ajaxOptions', function() {
|
test('ajaxOptions', function() {
|
||||||
@ -148,4 +162,14 @@ test('length', function() {
|
|||||||
equals(el.tabs('length'), $('ul a', el).length, ' should return length');
|
equals(el.tabs('length'), $('ul a', el).length, ' should return length');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('url', function() {
|
||||||
|
el = $('#tabs2').tabs();
|
||||||
|
var tab = el.find('a:eq(3)'),
|
||||||
|
url = tab.attr('href');
|
||||||
|
|
||||||
|
el.tabs('url', 3, "data/test2.html");
|
||||||
|
equals(tab.attr('href'), 'data/test2.html', 'Url was updated');
|
||||||
|
tab.attr('href', url );
|
||||||
|
});
|
||||||
|
|
||||||
}( jQuery ) );
|
}( jQuery ) );
|
||||||
|
@ -191,8 +191,4 @@ test('load', function() {
|
|||||||
ok(false, "missing test - untested code is broken code.");
|
ok(false, "missing test - untested code is broken code.");
|
||||||
});
|
});
|
||||||
|
|
||||||
test('url', function() {
|
|
||||||
ok(false, "missing test - untested code is broken code.");
|
|
||||||
});
|
|
||||||
|
|
||||||
})(jQuery);
|
})(jQuery);
|
||||||
|
@ -42,21 +42,29 @@ test('#3627 - Ajax tab with url containing a fragment identifier fails to load',
|
|||||||
// http://dev.jqueryui.com/ticket/3627
|
// http://dev.jqueryui.com/ticket/3627
|
||||||
expect(1);
|
expect(1);
|
||||||
|
|
||||||
el = $('#tabs2').tabs();
|
el = $('#tabs2').tabs({
|
||||||
|
selected: 2,
|
||||||
ok(/test.html$/.test( $('a:eq(2)', el).data('load.tabs') ), 'should ignore fragment identifier');
|
beforeload: function( event, ui ) {
|
||||||
|
event.preventDefault();
|
||||||
|
ok(/test.html$/.test( ui.settings.url ), 'should ignore fragment identifier');
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('#4033 - IE expands hash to full url and misinterprets tab as ajax', function() {
|
test('#4033 - IE expands hash to full url and misinterprets tab as ajax', function() {
|
||||||
// http://dev.jqueryui.com/ticket/4033
|
// http://dev.jqueryui.com/ticket/4033
|
||||||
expect(1);
|
expect(1);
|
||||||
|
|
||||||
el = $('<div><ul><li><a href="#tab">Tab</a></li></ul><div id="tab"></div></div>')
|
el = $('<div><ul><li><a href="#tab">Tab</a></li></ul><div id="tab"></div></div>');
|
||||||
.appendTo('#main').tabs();
|
el.appendTo('#main');
|
||||||
|
el.tabs({
|
||||||
|
beforeload: function( event, ui ) {
|
||||||
|
event.preventDefault();
|
||||||
|
ok( false, 'should not be an ajax tab');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
equals($('a', el).data('load.tabs'), undefined, 'should not create ajax tab');
|
equals($('a', el).attr('aria-controls'), '#tab', 'aria-contorls attribute is correct');
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('#5893 - Sublist in the tab list are considered as tab', function() {
|
test('#5893 - Sublist in the tab list are considered as tab', function() {
|
||||||
@ -68,19 +76,6 @@ test('#5893 - Sublist in the tab list are considered as tab', function() {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
asyncTest( "#4581 - title attribute for remote tabs does not support foreign languages", function() {
|
|
||||||
expect( 1 );
|
|
||||||
|
|
||||||
$( "#tabs2" ).tabs({
|
|
||||||
selected: 3,
|
|
||||||
load: function( event, ui ) {
|
|
||||||
equal( ui.panel.id, "∫ßáö_Սե", "proper title" );
|
|
||||||
start();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
test('#6710 - selectors are global', function() {
|
test('#6710 - selectors are global', function() {
|
||||||
// http://bugs.jqueryui.com/ticket/6710
|
// http://bugs.jqueryui.com/ticket/6710
|
||||||
expect(1);
|
expect(1);
|
||||||
|
87
ui/jquery.ui.tabs.js
vendored
87
ui/jquery.ui.tabs.js
vendored
@ -99,15 +99,16 @@ $.widget( "ui.tabs", {
|
|||||||
this.lis.removeClass( "ui-tabs-selected ui-state-active" );
|
this.lis.removeClass( "ui-tabs-selected ui-state-active" );
|
||||||
// check for length avoids error when initializing empty list
|
// check for length avoids error when initializing empty list
|
||||||
if ( o.selected >= 0 && this.anchors.length ) {
|
if ( o.selected >= 0 && this.anchors.length ) {
|
||||||
var temp = self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) )
|
var tab = self.anchors[ o.selected ],
|
||||||
.removeClass( "ui-tabs-hide" );
|
panel = self.element.find( self._sanitizeSelector( $( tab ).attr( "aria-controls" ) ) );
|
||||||
|
|
||||||
|
panel.removeClass( "ui-tabs-hide" );
|
||||||
|
|
||||||
this.lis.eq( o.selected ).addClass( "ui-tabs-selected ui-state-active" );
|
this.lis.eq( o.selected ).addClass( "ui-tabs-selected ui-state-active" );
|
||||||
|
|
||||||
// seems to be expected behavior that the show callback is fired
|
// seems to be expected behavior that the show callback is fired
|
||||||
self.element.queue( "tabs", function() {
|
self.element.queue( "tabs", function() {
|
||||||
self._trigger( "show", null,
|
self._trigger( "show", null, self._ui( tab, panel[ 0 ] ) );
|
||||||
self._ui( self.anchors[ o.selected ], self.element.find( self._sanitizeSelector( self.anchors[ o.selected ].hash ) )[ 0 ] ) );
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.load( o.selected );
|
this.load( o.selected );
|
||||||
@ -133,7 +134,7 @@ $.widget( "ui.tabs", {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_tabId: function( a ) {
|
_tabId: function( a ) {
|
||||||
return a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF-]/g, "" ) ||
|
return ( $( a ).attr( "aria-controls" ) || "" ).replace( /^#/ , "" ) ||
|
||||||
this.options.idPrefix + getNextTabId();
|
this.options.idPrefix + getNextTabId();
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -165,7 +166,7 @@ $.widget( "ui.tabs", {
|
|||||||
|
|
||||||
// Remove panels that we created that are missing their tab
|
// Remove panels that we created that are missing their tab
|
||||||
this.element.find(".ui-tabs-panel:data(destroy.tabs)").each( function( index, panel ) {
|
this.element.find(".ui-tabs-panel:data(destroy.tabs)").each( function( index, panel ) {
|
||||||
var anchor = self.anchors.filter( "[href$='#" + panel.id + "']");
|
var anchor = self.anchors.filter( "[aria-controls='#" + panel.id + "']");
|
||||||
if ( !anchor.length ) {
|
if ( !anchor.length ) {
|
||||||
$( panel ).remove();
|
$( panel ).remove();
|
||||||
}
|
}
|
||||||
@ -224,14 +225,17 @@ $.widget( "ui.tabs", {
|
|||||||
this.panels = $( [] );
|
this.panels = $( [] );
|
||||||
|
|
||||||
this.anchors.each(function( i, a ) {
|
this.anchors.each(function( i, a ) {
|
||||||
var href = $( a ).attr( "href" );
|
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
|
// 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.
|
// 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
|
// Same consideration applies for an added tab with a fragment identifier
|
||||||
// since a[href=#fragment-identifier] does unexpectedly not match.
|
// since a[href=#fragment-identifier] does unexpectedly not match.
|
||||||
// Thus normalize href attribute...
|
// Thus normalize href attribute...
|
||||||
var hrefBase = href.split( "#" )[ 0 ],
|
|
||||||
baseEl;
|
|
||||||
if ( hrefBase && ( hrefBase === location.toString().split( "#" )[ 0 ] ||
|
if ( hrefBase && ( hrefBase === location.toString().split( "#" )[ 0 ] ||
|
||||||
( baseEl = $( "base" )[ 0 ]) && hrefBase === baseEl.href ) ) {
|
( baseEl = $( "base" )[ 0 ]) && hrefBase === baseEl.href ) ) {
|
||||||
href = a.hash;
|
href = a.hash;
|
||||||
@ -240,32 +244,30 @@ $.widget( "ui.tabs", {
|
|||||||
|
|
||||||
// inline tab
|
// inline tab
|
||||||
if ( fragmentId.test( href ) ) {
|
if ( fragmentId.test( href ) ) {
|
||||||
self.panels = self.panels.add( self.element.find( self._sanitizeSelector( href ) ) );
|
selector = href;
|
||||||
|
panel = self.element.find( self._sanitizeSelector( selector ) );
|
||||||
// remote tab
|
// remote tab
|
||||||
// prevent loading the page itself if href is just "#"
|
// prevent loading the page itself if href is just "#"
|
||||||
} else if ( href && href !== "#" ) {
|
} else if ( href && href !== "#" ) {
|
||||||
// required for restore on destroy
|
|
||||||
$.data( a, "href.tabs", href );
|
|
||||||
|
|
||||||
// TODO until #3808 is fixed strip fragment identifier from url
|
|
||||||
// (IE fails to load from such url)
|
|
||||||
$.data( a, "load.tabs", href.replace( /#.*$/, "" ) );
|
|
||||||
|
|
||||||
var id = self._tabId( a );
|
var id = self._tabId( a );
|
||||||
a.href = "#" + id;
|
selector = "#" + id;
|
||||||
var $panel = self.element.find( "#" + id );
|
panel = self.element.find( selector );
|
||||||
if ( !$panel.length ) {
|
if ( !panel.length ) {
|
||||||
$panel = $( self.options.panelTemplate )
|
panel = $( self.options.panelTemplate )
|
||||||
.attr( "id", id )
|
.attr( "id", id )
|
||||||
.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
|
.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
|
||||||
|
.data( "destroy.tabs", true )
|
||||||
.insertAfter( self.panels[ i - 1 ] || self.list );
|
.insertAfter( self.panels[ i - 1 ] || self.list );
|
||||||
$panel.data( "destroy.tabs", true );
|
|
||||||
}
|
}
|
||||||
self.panels = self.panels.add( $panel );
|
|
||||||
// invalid tab href
|
// invalid tab href
|
||||||
} else {
|
} else {
|
||||||
self.options.disabled.push( i );
|
self.options.disabled.push( i );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( panel.length) {
|
||||||
|
self.panels = self.panels.add( panel );
|
||||||
|
}
|
||||||
|
$( a ).attr( "aria-controls", selector );
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -348,9 +350,9 @@ $.widget( "ui.tabs", {
|
|||||||
var self = this,
|
var self = this,
|
||||||
o = this.options,
|
o = this.options,
|
||||||
el = event.currentTarget,
|
el = event.currentTarget,
|
||||||
$li = $(el).closest( "li" ),
|
$li = $( el ).closest( "li" ),
|
||||||
$hide = self.panels.filter( ":not(.ui-tabs-hide)" ),
|
$hide = self.panels.filter( ":not(.ui-tabs-hide)" ),
|
||||||
$show = self.element.find( self._sanitizeSelector( el.hash ) );
|
$show = self.element.find( self._sanitizeSelector( $( el ).attr( "aria-controls" ) ) );
|
||||||
|
|
||||||
// tab is already selected, but not collapsible
|
// tab is already selected, but not collapsible
|
||||||
if ( ( $li.hasClass( "ui-tabs-selected" ) && !o.collapsible ) ||
|
if ( ( $li.hasClass( "ui-tabs-selected" ) && !o.collapsible ) ||
|
||||||
@ -455,10 +457,6 @@ $.widget( "ui.tabs", {
|
|||||||
this.list.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" );
|
this.list.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" );
|
||||||
|
|
||||||
this.anchors.each(function() {
|
this.anchors.each(function() {
|
||||||
var href = $.data( this, "href.tabs" );
|
|
||||||
if ( href ) {
|
|
||||||
this.href = href;
|
|
||||||
}
|
|
||||||
var $this = $( this ).unbind( ".tabs" );
|
var $this = $( this ).unbind( ".tabs" );
|
||||||
$.each( [ "href", "load" ], function( i, prefix ) {
|
$.each( [ "href", "load" ], function( i, prefix ) {
|
||||||
$this.removeData( prefix + ".tabs" );
|
$this.removeData( prefix + ".tabs" );
|
||||||
@ -558,8 +556,11 @@ $.widget( "ui.tabs", {
|
|||||||
var self = this,
|
var self = this,
|
||||||
o = this.options,
|
o = this.options,
|
||||||
a = this.anchors.eq( index )[ 0 ],
|
a = this.anchors.eq( index )[ 0 ],
|
||||||
url = $.data( a, "load.tabs" ),
|
panel = self.element.find( self._sanitizeSelector( $( a ).attr( "aria-controls" ) ) ),
|
||||||
eventData = self._ui( self.anchors[ index ], self.panels[ index ] );
|
// TODO until #3808 is fixed strip fragment identifier from url
|
||||||
|
// (IE fails to load from such url)
|
||||||
|
url = $( a ).attr( "href" ).replace( /#.*$/, "" ),
|
||||||
|
eventData = self._ui( a, panel[ 0 ] );
|
||||||
|
|
||||||
if ( this.xhr ) {
|
if ( this.xhr ) {
|
||||||
this.xhr.abort();
|
this.xhr.abort();
|
||||||
@ -585,7 +586,7 @@ $.widget( "ui.tabs", {
|
|||||||
|
|
||||||
this.xhr
|
this.xhr
|
||||||
.success( function( response ) {
|
.success( function( response ) {
|
||||||
self.element.find( self._sanitizeSelector( a.hash ) ).html( response );
|
panel.html( response );
|
||||||
})
|
})
|
||||||
.complete( function( jqXHR, status ) {
|
.complete( function( jqXHR, status ) {
|
||||||
if ( status === "abort" ) {
|
if ( status === "abort" ) {
|
||||||
@ -609,13 +610,9 @@ $.widget( "ui.tabs", {
|
|||||||
// last, so that load event is fired before show...
|
// last, so that load event is fired before show...
|
||||||
self.element.dequeue( "tabs" );
|
self.element.dequeue( "tabs" );
|
||||||
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
url: function( index, url ) {
|
|
||||||
this.anchors.eq( index ).data( "load.tabs", url );
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$.extend( $.ui.tabs, {
|
$.extend( $.ui.tabs, {
|
||||||
@ -861,6 +858,22 @@ if ( $.uiBackCompat !== false ) {
|
|||||||
return this.anchors.length;
|
return this.anchors.length;
|
||||||
};
|
};
|
||||||
}( jQuery, jQuery.ui.tabs.prototype ) );
|
}( jQuery, jQuery.ui.tabs.prototype ) );
|
||||||
|
|
||||||
|
// url method
|
||||||
|
(function( $, prototype ) {
|
||||||
|
prototype.url = function( index, url ) {
|
||||||
|
this.anchors.eq( index ).attr( "href", url );
|
||||||
|
};
|
||||||
|
}( jQuery, jQuery.ui.tabs.prototype ) );
|
||||||
|
|
||||||
|
// _tabId method
|
||||||
|
(function( $, prototype ) {
|
||||||
|
var _tabId = prototype._tabId;
|
||||||
|
prototype._tabId = function( a ) {
|
||||||
|
return a.title && a.title.replace( /\s/g, "_" ).replace( /[^\w\u00c0-\uFFFF-]/g, "" ) ||
|
||||||
|
_tabId.apply( this, arguments );
|
||||||
|
};
|
||||||
|
}( jQuery, jQuery.ui.tabs.prototype ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
})( jQuery );
|
})( jQuery );
|
||||||
|
Loading…
Reference in New Issue
Block a user