@@ -99,15 +99,16 @@ $.widget( "ui.tabs", {
99
99
this . lis . removeClass ( "ui-tabs-selected ui-state-active" ) ;
100
100
// check for length avoids error when initializing empty list
101
101
if ( o . selected >= 0 && this . anchors . length ) {
102
- var temp = self . element . find ( self . _sanitizeSelector ( self . anchors [ o . selected ] . hash ) )
103
- . removeClass ( "ui-tabs-hide" ) ;
102
+ var tab = self . anchors [ o . selected ] ,
103
+ panel = self . element . find ( self . _sanitizeSelector ( $ ( tab ) . attr ( "aria-controls" ) ) ) ;
104
+
105
+ panel . removeClass ( "ui-tabs-hide" ) ;
104
106
105
107
this . lis . eq ( o . selected ) . addClass ( "ui-tabs-selected ui-state-active" ) ;
106
108
107
109
// seems to be expected behavior that the show callback is fired
108
110
self . element . queue ( "tabs" , function ( ) {
109
- self . _trigger ( "show" , null ,
110
- self . _ui ( self . anchors [ o . selected ] , self . element . find ( self . _sanitizeSelector ( self . anchors [ o . selected ] . hash ) ) [ 0 ] ) ) ;
111
+ self . _trigger ( "show" , null , self . _ui ( tab , panel [ 0 ] ) ) ;
111
112
} ) ;
112
113
113
114
this . load ( o . selected ) ;
@@ -133,7 +134,7 @@ $.widget( "ui.tabs", {
133
134
} ,
134
135
135
136
_tabId : function ( a ) {
136
- return a . title && a . title . replace ( / \s / g , "_ " ) . replace ( / [ ^ \w \u00c0 - \uFFFF - ] / g , "" ) ||
137
+ return ( $ ( a ) . attr ( "aria-controls" ) || " " ) . replace ( / ^ # / , "" ) ||
137
138
this . options . idPrefix + getNextTabId ( ) ;
138
139
} ,
139
140
@@ -165,7 +166,7 @@ $.widget( "ui.tabs", {
165
166
166
167
// Remove panels that we created that are missing their tab
167
168
this . element . find ( ".ui-tabs-panel:data(destroy.tabs)" ) . each ( function ( index , panel ) {
168
- var anchor = self . anchors . filter ( "[href$ ='#" + panel . id + "']" ) ;
169
+ var anchor = self . anchors . filter ( "[aria-controls ='#" + panel . id + "']" ) ;
169
170
if ( ! anchor . length ) {
170
171
$ ( panel ) . remove ( ) ;
171
172
}
@@ -224,14 +225,17 @@ $.widget( "ui.tabs", {
224
225
this . panels = $ ( [ ] ) ;
225
226
226
227
this . anchors . each ( function ( i , a ) {
227
- var href = $ ( a ) . attr ( "href" ) ;
228
+ var href = $ ( a ) . attr ( "href" ) ,
229
+ hrefBase = href . split ( "#" ) [ 0 ] ,
230
+ selector ,
231
+ panel ,
232
+ baseEl ;
233
+
228
234
// For dynamically created HTML that contains a hash as href IE < 8 expands
229
235
// such href to the full page url with hash and then misinterprets tab as ajax.
230
236
// Same consideration applies for an added tab with a fragment identifier
231
237
// since a[href=#fragment-identifier] does unexpectedly not match.
232
238
// Thus normalize href attribute...
233
- var hrefBase = href . split ( "#" ) [ 0 ] ,
234
- baseEl ;
235
239
if ( hrefBase && ( hrefBase === location . toString ( ) . split ( "#" ) [ 0 ] ||
236
240
( baseEl = $ ( "base" ) [ 0 ] ) && hrefBase === baseEl . href ) ) {
237
241
href = a . hash ;
@@ -240,32 +244,30 @@ $.widget( "ui.tabs", {
240
244
241
245
// inline tab
242
246
if ( fragmentId . test ( href ) ) {
243
- self . panels = self . panels . add ( self . element . find ( self . _sanitizeSelector ( href ) ) ) ;
247
+ selector = href ;
248
+ panel = self . element . find ( self . _sanitizeSelector ( selector ) ) ;
244
249
// remote tab
245
250
// prevent loading the page itself if href is just "#"
246
251
} else if ( href && href !== "#" ) {
247
- // required for restore on destroy
248
- $ . data ( a , "href.tabs" , href ) ;
249
-
250
- // TODO until #3808 is fixed strip fragment identifier from url
251
- // (IE fails to load from such url)
252
- $ . data ( a , "load.tabs" , href . replace ( / # .* $ / , "" ) ) ;
253
-
254
252
var id = self . _tabId ( a ) ;
255
- a . href = "#" + id ;
256
- var $ panel = self . element . find ( "#" + id ) ;
257
- if ( ! $ panel. length ) {
258
- $ panel = $ ( self . options . panelTemplate )
253
+ selector = "#" + id ;
254
+ panel = self . element . find ( selector ) ;
255
+ if ( ! panel . length ) {
256
+ panel = $ ( self . options . panelTemplate )
259
257
. attr ( "id" , id )
260
258
. addClass ( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
259
+ . data ( "destroy.tabs" , true )
261
260
. insertAfter ( self . panels [ i - 1 ] || self . list ) ;
262
- $panel . data ( "destroy.tabs" , true ) ;
263
261
}
264
- self . panels = self . panels . add ( $panel ) ;
265
262
// invalid tab href
266
263
} else {
267
264
self . options . disabled . push ( i ) ;
268
265
}
266
+
267
+ if ( panel . length ) {
268
+ self . panels = self . panels . add ( panel ) ;
269
+ }
270
+ $ ( a ) . attr ( "aria-controls" , selector ) ;
269
271
} ) ;
270
272
} ,
271
273
@@ -348,9 +350,9 @@ $.widget( "ui.tabs", {
348
350
var self = this ,
349
351
o = this . options ,
350
352
el = event . currentTarget ,
351
- $li = $ ( el ) . closest ( "li" ) ,
353
+ $li = $ ( el ) . closest ( "li" ) ,
352
354
$hide = self . panels . filter ( ":not(.ui-tabs-hide)" ) ,
353
- $show = self . element . find ( self . _sanitizeSelector ( el . hash ) ) ;
355
+ $show = self . element . find ( self . _sanitizeSelector ( $ ( el ) . attr ( "aria-controls" ) ) ) ;
354
356
355
357
// tab is already selected, but not collapsible
356
358
if ( ( $li . hasClass ( "ui-tabs-selected" ) && ! o . collapsible ) ||
@@ -455,10 +457,6 @@ $.widget( "ui.tabs", {
455
457
this . list . removeClass ( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ) ;
456
458
457
459
this . anchors . each ( function ( ) {
458
- var href = $ . data ( this , "href.tabs" ) ;
459
- if ( href ) {
460
- this . href = href ;
461
- }
462
460
var $this = $ ( this ) . unbind ( ".tabs" ) ;
463
461
$ . each ( [ "href" , "load" ] , function ( i , prefix ) {
464
462
$this . removeData ( prefix + ".tabs" ) ;
@@ -558,8 +556,11 @@ $.widget( "ui.tabs", {
558
556
var self = this ,
559
557
o = this . options ,
560
558
a = this . anchors . eq ( index ) [ 0 ] ,
561
- url = $ . data ( a , "load.tabs" ) ,
562
- eventData = self . _ui ( self . anchors [ index ] , self . panels [ index ] ) ;
559
+ panel = self . element . find ( self . _sanitizeSelector ( $ ( a ) . attr ( "aria-controls" ) ) ) ,
560
+ // TODO until #3808 is fixed strip fragment identifier from url
561
+ // (IE fails to load from such url)
562
+ url = $ ( a ) . attr ( "href" ) . replace ( / # .* $ / , "" ) ,
563
+ eventData = self . _ui ( a , panel [ 0 ] ) ;
563
564
564
565
if ( this . xhr ) {
565
566
this . xhr . abort ( ) ;
@@ -585,7 +586,7 @@ $.widget( "ui.tabs", {
585
586
586
587
this . xhr
587
588
. success ( function ( response ) {
588
- self . element . find ( self . _sanitizeSelector ( a . hash ) ) . html ( response ) ;
589
+ panel . html ( response ) ;
589
590
} )
590
591
. complete ( function ( jqXHR , status ) {
591
592
if ( status === "abort" ) {
@@ -609,13 +610,9 @@ $.widget( "ui.tabs", {
609
610
// last, so that load event is fired before show...
610
611
self . element . dequeue ( "tabs" ) ;
611
612
612
- return this ;
613
- } ,
614
-
615
- url : function ( index , url ) {
616
- this . anchors . eq ( index ) . data ( "load.tabs" , url ) ;
617
613
return this ;
618
614
}
615
+
619
616
} ) ;
620
617
621
618
$ . extend ( $ . ui . tabs , {
@@ -861,6 +858,22 @@ if ( $.uiBackCompat !== false ) {
861
858
return this . anchors . length ;
862
859
} ;
863
860
} ( jQuery , jQuery . ui . tabs . prototype ) ) ;
861
+
862
+ // url method
863
+ ( function ( $ , prototype ) {
864
+ prototype . url = function ( index , url ) {
865
+ this . anchors . eq ( index ) . attr ( "href" , url ) ;
866
+ } ;
867
+ } ( jQuery , jQuery . ui . tabs . prototype ) ) ;
868
+
869
+ // _tabId method
870
+ ( function ( $ , prototype ) {
871
+ var _tabId = prototype . _tabId ;
872
+ prototype . _tabId = function ( a ) {
873
+ return a . title && a . title . replace ( / \s / g, "_" ) . replace ( / [ ^ \w \u00c0 - \uFFFF - ] / g, "" ) ||
874
+ _tabId . apply ( this , arguments ) ;
875
+ } ;
876
+ } ( jQuery , jQuery . ui . tabs . prototype ) ) ;
864
877
}
865
878
866
879
} ) ( jQuery ) ;
0 commit comments