@@ -96,16 +96,16 @@ $.widget( "ui.tabs", {
96
96
this . lis . removeClass ( "ui-tabs-selected ui-state-active" ) ;
97
97
// check for length avoids error when initializing empty list
98
98
if ( o . active >= 0 && this . anchors . length ) {
99
- var tab = self . anchors [ o . active ] ,
100
- panel = self . element . find ( self . _sanitizeSelector ( $ ( tab ) . attr ( "aria-controls" ) ) ) ;
99
+ this . active = this . _findActive ( o . active ) ;
100
+ var panel = self . element . find ( self . _sanitizeSelector ( this . active . attr ( "aria-controls" ) ) ) ;
101
101
102
102
panel . removeClass ( "ui-tabs-hide" ) ;
103
103
104
104
this . lis . eq ( o . active ) . addClass ( "ui-tabs-selected ui-state-active" ) ;
105
105
106
106
// seems to be expected behavior that the activate callback is fired
107
107
self . element . queue ( "tabs" , function ( ) {
108
- self . _trigger ( "activate" , null , self . _ui ( tab , panel [ 0 ] ) ) ;
108
+ self . _trigger ( "activate" , null , self . _ui ( self . active [ 0 ] , panel [ 0 ] ) ) ;
109
109
} ) ;
110
110
111
111
this . load ( o . active ) ;
@@ -120,10 +120,9 @@ $.widget( "ui.tabs", {
120
120
121
121
_setOption : function ( key , value ) {
122
122
if ( key == "active" ) {
123
- if ( this . options . collapsible && value == this . options . active ) {
124
- return ;
125
- }
126
- this . select ( value ) ;
123
+ // _activate() will handle invalid values and update this.option
124
+ this . _activate ( value ) ;
125
+ return
127
126
} else {
128
127
this . options [ key ] = value ;
129
128
this . refresh ( ) ;
@@ -350,10 +349,10 @@ $.widget( "ui.tabs", {
350
349
event . preventDefault ( ) ;
351
350
var self = this ,
352
351
o = this . options ,
353
- el = event . currentTarget ,
354
- $li = $ ( el ) . closest ( "li" ) ,
352
+ clicked = $ ( event . currentTarget ) ,
353
+ $li = clicked . closest ( "li" ) ,
355
354
$hide = self . panels . filter ( ":not(.ui-tabs-hide)" ) ,
356
- $show = self . element . find ( self . _sanitizeSelector ( $ ( el ) . attr ( "aria-controls" ) ) ) ;
355
+ $show = self . element . find ( self . _sanitizeSelector ( clicked . attr ( "aria-controls" ) ) ) ;
357
356
358
357
// tab is already selected, but not collapsible
359
358
if ( ( $li . hasClass ( "ui-tabs-selected" ) && ! o . collapsible ) ||
@@ -364,12 +363,14 @@ $.widget( "ui.tabs", {
364
363
// tab is already loading
365
364
$li . hasClass ( "ui-state-processing" ) ||
366
365
// allow canceling by beforeActivate event
367
- self . _trigger ( "beforeActivate" , event , self . _ui ( el , $show [ 0 ] ) ) === false ) {
368
- el . blur ( ) ;
366
+ self . _trigger ( "beforeActivate" , event , self . _ui ( clicked [ 0 ] , $show [ 0 ] ) ) === false ) {
367
+ clicked [ 0 ] . blur ( ) ;
369
368
return ;
370
369
}
371
370
372
- o . active = self . anchors . index ( el ) ;
371
+ o . active = self . anchors . index ( clicked ) ;
372
+
373
+ self . active = clicked ;
373
374
374
375
if ( self . xhr ) {
375
376
self . xhr . abort ( ) ;
@@ -379,30 +380,31 @@ $.widget( "ui.tabs", {
379
380
if ( o . collapsible ) {
380
381
if ( $li . hasClass ( "ui-tabs-selected" ) ) {
381
382
o . active = - 1 ;
383
+ self . active = null ;
382
384
383
385
if ( o . cookie ) {
384
386
self . _cookie ( o . active , o . cookie ) ;
385
387
}
386
388
387
389
self . element . queue ( "tabs" , function ( ) {
388
- self . _hideTab ( el , $hide ) ;
390
+ self . _hideTab ( clicked , $hide ) ;
389
391
} ) . dequeue ( "tabs" ) ;
390
392
391
- el . blur ( ) ;
393
+ clicked [ 0 ] . blur ( ) ;
392
394
return ;
393
395
} else if ( ! $hide . length ) {
394
396
if ( o . cookie ) {
395
397
self . _cookie ( o . active , o . cookie ) ;
396
398
}
397
399
398
400
self . element . queue ( "tabs" , function ( ) {
399
- self . _showTab ( el , $show , event ) ;
401
+ self . _showTab ( clicked , $show , event ) ;
400
402
} ) ;
401
403
402
404
// TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171
403
- self . load ( self . anchors . index ( el ) ) ;
405
+ self . load ( self . anchors . index ( clicked ) ) ;
404
406
405
- el . blur ( ) ;
407
+ clicked [ 0 ] . blur ( ) ;
406
408
return ;
407
409
}
408
410
}
@@ -415,14 +417,14 @@ $.widget( "ui.tabs", {
415
417
if ( $show . length ) {
416
418
if ( $hide . length ) {
417
419
self . element . queue ( "tabs" , function ( ) {
418
- self . _hideTab ( el , $hide ) ;
420
+ self . _hideTab ( clicked , $hide ) ;
419
421
} ) ;
420
422
}
421
423
self . element . queue ( "tabs" , function ( ) {
422
- self . _showTab ( el , $show , event ) ;
424
+ self . _showTab ( clicked , $show , event ) ;
423
425
} ) ;
424
426
425
- self . load ( self . anchors . index ( el ) ) ;
427
+ self . load ( self . anchors . index ( clicked ) ) ;
426
428
} else {
427
429
throw "jQuery UI Tabs: Mismatching fragment identifier." ;
428
430
}
@@ -432,8 +434,31 @@ $.widget( "ui.tabs", {
432
434
// in modern browsers; blur() removes focus from address bar in Firefox
433
435
// which can become a usability
434
436
if ( $ . browser . msie ) {
435
- el . blur ( ) ;
437
+ clicked [ 0 ] . blur ( ) ;
438
+ }
439
+ } ,
440
+
441
+ _activate : function ( index ) {
442
+ var active = this . _findActive ( index ) [ 0 ] ;
443
+
444
+ // trying to activate the already active panel
445
+ if ( this . active && active === this . active [ 0 ] ) {
446
+ return ;
436
447
}
448
+
449
+ // trying to collapse, simulate a click on the current active header
450
+ active = active || this . active ;
451
+
452
+ this . _eventHandler ( {
453
+ target : active ,
454
+ currentTarget : active ,
455
+ preventDefault : $ . noop
456
+ } ) ;
457
+ } ,
458
+
459
+ _findActive : function ( selector ) {
460
+ return typeof selector === "number" ? this . anchors . eq ( selector ) :
461
+ typeof selector === "string" ? this . anchors . filter ( "[href$='" + selector + "']" ) : $ ( ) ;
437
462
} ,
438
463
439
464
_getIndex : function ( index ) {
@@ -539,19 +564,6 @@ $.widget( "ui.tabs", {
539
564
return this ;
540
565
} ,
541
566
542
- select : function ( index ) {
543
- index = this . _getIndex ( index ) ;
544
- if ( index == - 1 ) {
545
- if ( this . options . collapsible && this . options . active != - 1 ) {
546
- index = this . options . active ;
547
- } else {
548
- return this ;
549
- }
550
- }
551
- this . anchors . eq ( index ) . trigger ( this . options . event + ".tabs" ) ;
552
- return this ;
553
- } ,
554
-
555
567
load : function ( index ) {
556
568
index = this . _getIndex ( index ) ;
557
569
var self = this ,
@@ -834,7 +846,7 @@ if ( $.uiBackCompat !== false ) {
834
846
// If selected tab was removed focus tab to the right or
835
847
// in case the last tab was removed the tab to the left.
836
848
if ( $li . hasClass ( "ui-tabs-selected" ) && this . anchors . length > 1 ) {
837
- this . select ( index + ( index + 1 < this . anchors . length ? 1 : - 1 ) ) ;
849
+ this . _activate ( index + ( index + 1 < this . anchors . length ? 1 : - 1 ) ) ;
838
850
}
839
851
840
852
o . disabled = $ . map (
@@ -947,6 +959,21 @@ if ( $.uiBackCompat !== false ) {
947
959
}
948
960
} ;
949
961
} ( jQuery , jQuery . ui . tabs . prototype ) ) ;
962
+
963
+ // select method
964
+ ( function ( $ , prototype ) {
965
+ prototype . select = function ( index ) {
966
+ index = this . _getIndex ( index ) ;
967
+ if ( index == - 1 ) {
968
+ if ( this . options . collapsible && this . options . selected != - 1 ) {
969
+ index = this . options . selected ;
970
+ } else {
971
+ return ;
972
+ }
973
+ }
974
+ this . anchors . eq ( index ) . trigger ( this . options . event + ".tabs" ) ;
975
+ } ;
976
+ } ( jQuery , jQuery . ui . tabs . prototype ) ) ;
950
977
}
951
978
952
979
} ) ( jQuery ) ;
0 commit comments