2016-04-01 13:17:09 +00:00
/ *
*
2019-01-17 13:05:03 +00:00
* ( c ) Copyright Ascensio System SIA 2010 - 2019
2016-04-01 13:17:09 +00:00
*
* This program is a free software product . You can redistribute it and / or
* modify it under the terms of the GNU Affero General Public License ( AGPL )
* version 3 as published by the Free Software Foundation . In accordance with
* Section 7 ( a ) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non - infringement
* of any third - party rights .
*
* This program is distributed WITHOUT ANY WARRANTY ; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . For
* details , see the GNU AGPL at : http : //www.gnu.org/licenses/agpl-3.0.html
*
2019-01-17 13:00:34 +00:00
* You can contact Ascensio System SIA at 20 A - 12 Ernesta Birznieka - Upisha
* street , Riga , Latvia , EU , LV - 1050.
2016-04-01 13:17:09 +00:00
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices , as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7 ( b ) of the License you must retain the original Product
* logo when distributing the program . Pursuant to Section 7 ( e ) we decline to
* grant you any rights under trademark law for use of our trademarks .
*
* All the Product ' s GUI elements , including illustrations and icon sets , as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution - ShareAlike 4.0 International . See the License
* terms at http : //creativecommons.org/licenses/by-sa/4.0/legalcode
*
* /
2016-03-11 00:48:53 +00:00
/ * *
* TabBar . js
*
* Created by Maxim Kadushkin on 28 March 2014
2018-03-01 12:16:38 +00:00
* Copyright ( c ) 2018 Ascensio System SIA . All rights reserved .
2016-03-11 00:48:53 +00:00
*
* /
define ( [
'common/main/lib/component/BaseView' ,
'common/main/lib/component/Tab'
] , function ( ) {
'use strict' ;
var Events = {
bind : function ( ) {
if ( ! this . o ) this . o = $ ( { } ) ;
this . o . on . apply ( this . o , arguments ) ;
} ,
unbind : function ( ) {
if ( this . o ) this . o . off . apply ( this . o , arguments ) ;
} ,
trigger : function ( ) {
if ( ! this . o ) this . o = $ ( { } ) ;
this . o . trigger . apply ( this . o , arguments ) ;
}
} ;
var StateManager = function ( options ) {
this . initialize . call ( this , options ) ;
} ;
_ . extend ( StateManager . prototype , Events ) ;
StateManager . prototype . initialize = function ( options ) {
this . bar = options . bar ;
} ;
StateManager . prototype . attach = function ( tab ) {
2019-08-30 13:34:11 +00:00
tab . changeState = $ . proxy ( function ( select ) {
if ( select ) {
tab . toggleClass ( 'selected' ) ;
2019-09-03 11:09:22 +00:00
var selectTab = _ . find ( this . bar . selectTabs , function ( item ) { return item . sheetindex === tab . sheetindex ; } ) ;
if ( selectTab ) {
this . bar . selectTabs = _ . without ( this . bar . selectTabs , selectTab ) ;
} else {
this . bar . selectTabs . push ( tab ) ;
}
2019-08-30 13:34:11 +00:00
} else {
if ( ! tab . isSelected ( ) ) {
this . bar . $el . find ( 'ul > li.selected' ) . removeClass ( 'selected' ) ;
tab . addClass ( 'selected' ) ;
2019-09-03 11:09:22 +00:00
this . bar . selectTabs . length = 0 ;
this . bar . selectTabs . push ( tab ) ;
2019-08-30 13:34:11 +00:00
}
this . trigger ( 'tab:change' , tab ) ;
this . bar . $el . find ( 'ul > li.active' ) . removeClass ( 'active' ) ;
tab . activate ( ) ;
2016-03-11 00:48:53 +00:00
2019-08-30 13:34:11 +00:00
this . bar . trigger ( 'tab:changed' , this . bar , this . bar . tabs . indexOf ( tab ) , tab ) ;
}
2016-03-11 00:48:53 +00:00
} , this ) ;
var dragHelper = new ( function ( ) {
return {
bounds : [ ] ,
drag : undefined ,
calculateBounds : function ( ) {
var me = this ,
length = me . bar . tabs . length ,
barBounds = me . bar . $bar . get ( 0 ) . getBoundingClientRect ( ) ;
2019-11-08 14:13:38 +00:00
me . leftBorder = barBounds . left ;
me . rightBorder = barBounds . right ;
2016-03-11 00:48:53 +00:00
if ( barBounds ) {
me . bounds = [ ] ;
me . scrollLeft = me . bar . $bar . scrollLeft ( ) ;
me . bar . scrollX = this . scrollLeft ;
for ( var i = 0 ; i < length ; ++ i ) {
this . bounds . push ( me . bar . tabs [ i ] . $el . get ( 0 ) . getBoundingClientRect ( ) ) ;
}
2019-11-01 11:15:46 +00:00
me . lastTabRight = me . bounds [ length - 1 ] . right ;
2016-03-11 00:48:53 +00:00
me . tabBarLeft = me . bounds [ 0 ] . left ;
me . tabBarRight = me . bounds [ length - 1 ] . right ;
me . tabBarRight = Math . min ( me . tabBarRight , barBounds . right - 1 ) ;
}
} ,
2019-10-01 08:49:43 +00:00
setHookTabs : function ( e , bar , tabs ) {
var me = this ;
function dragComplete ( ) {
if ( ! _ . isUndefined ( me . drag ) ) {
bar . dragging = false ;
bar . $el . find ( 'li.mousemove' ) . removeClass ( 'mousemove right' ) ;
var arrSelectIndex = [ ] ;
tabs . forEach ( function ( item ) {
arrSelectIndex . push ( item . sheetindex ) ;
} ) ;
if ( ! _ . isUndefined ( me . drag . place ) ) {
me . bar . trigger ( 'tab:move' , arrSelectIndex , me . drag . place ) ;
me . bar . $bar . scrollLeft ( me . scrollLeft ) ;
me . bar . scrollX = undefined ;
} else {
me . bar . trigger ( 'tab:move' , arrSelectIndex ) ;
me . bar . $bar . scrollLeft ( me . scrollLeft ) ;
me . bar . scrollX = undefined ;
}
me . drag = undefined ;
2019-12-12 11:35:57 +00:00
me . bar . trigger ( 'tab:drop' , this ) ;
2019-10-01 08:49:43 +00:00
}
}
function dragMove ( event ) {
if ( ! _ . isUndefined ( me . drag ) ) {
me . drag . moveX = event . clientX * Common . Utils . zoom ( ) ;
2019-11-08 14:13:38 +00:00
if ( me . drag . moveX < me . leftBorder ) {
me . scrollLeft -= 20 ;
me . bar . $bar . scrollLeft ( me . scrollLeft ) ;
me . calculateBounds ( ) ;
} else if ( me . drag . moveX < me . tabBarRight && me . drag . moveX > me . tabBarLeft ) {
2019-10-23 10:50:40 +00:00
var name = $ ( event . target ) . parent ( ) . data ( 'label' ) ,
2019-10-31 13:36:43 +00:00
currentTab = _ . findIndex ( bar . tabs , { label : name } ) ;
2019-11-08 14:13:38 +00:00
if ( currentTab === - 1 ) {
bar . $el . find ( 'li.mousemove' ) . removeClass ( 'mousemove right' ) ;
me . drag . place = undefined ;
} else if ( me . bounds [ currentTab ] . left - me . scrollLeft >= me . tabBarLeft ) {
2019-10-31 13:36:43 +00:00
me . drag . place = currentTab ;
2019-11-01 11:15:46 +00:00
$ ( event . target ) . parent ( ) . parent ( ) . find ( 'li.mousemove' ) . removeClass ( 'mousemove right' ) ;
$ ( event . target ) . parent ( ) . addClass ( 'mousemove' ) ;
2019-10-01 08:49:43 +00:00
}
2019-11-08 14:13:38 +00:00
} else if ( me . drag . moveX > me . lastTabRight && Math . abs ( me . tabBarRight - me . bounds [ me . bar . tabs . length - 1 ] . right ) < 1 ) { //move to end of list, right border of the right tab is visible
2019-11-01 11:15:46 +00:00
bar . $el . find ( 'li.mousemove' ) . removeClass ( 'mousemove right' ) ;
bar . tabs [ bar . tabs . length - 1 ] . $el . addClass ( 'mousemove right' ) ;
me . drag . place = bar . tabs . length ;
2019-11-08 14:13:38 +00:00
} else if ( me . drag . moveX - me . rightBorder > 3 ) {
me . scrollLeft += 20 ;
me . bar . $bar . scrollLeft ( me . scrollLeft ) ;
me . calculateBounds ( ) ;
}
2019-10-01 08:49:43 +00:00
}
}
if ( ! _ . isUndefined ( bar ) && ! _ . isUndefined ( tabs ) && bar . tabs . length > 1 ) {
me . bar = bar ;
me . drag = { tabs : tabs } ;
bar . dragging = true ;
this . calculateBounds ( ) ;
$ ( document ) . on ( 'mousemove.tabbar' , dragMove ) ;
$ ( document ) . on ( 'mouseup.tabbar' , function ( e ) {
dragComplete ( e ) ;
$ ( document ) . off ( 'mouseup.tabbar' ) ;
$ ( document ) . off ( 'mousemove.tabbar' , dragMove ) ;
} ) ;
2019-12-12 11:35:57 +00:00
this . bar . trigger ( 'tab:drag' , this . bar . selectTabs ) ;
2019-10-01 08:49:43 +00:00
}
2016-03-11 00:48:53 +00:00
}
}
} ) ;
tab . $el . on ( {
2019-08-30 13:34:11 +00:00
click : $ . proxy ( function ( event ) {
2019-09-02 10:52:16 +00:00
if ( ! tab . disabled ) {
if ( event . ctrlKey || event . metaKey ) {
2019-10-29 12:05:32 +00:00
if ( ! tab . isActive ( ) ) {
tab . changeState ( true ) ;
}
2019-08-30 13:34:11 +00:00
} else if ( event . shiftKey ) {
this . bar . $el . find ( 'ul > li.selected' ) . removeClass ( 'selected' ) ;
2019-09-03 11:09:22 +00:00
this . bar . selectTabs . length = 0 ;
2019-08-30 13:34:11 +00:00
var $active = this . bar . $el . find ( 'ul > li.active' ) ,
indexAct = $active . index ( ) ,
2019-09-03 11:09:22 +00:00
indexCur = this . bar . tabs . indexOf ( tab ) ;
2019-08-30 13:34:11 +00:00
var startIndex = ( indexCur > indexAct ) ? indexAct : indexCur ,
endIndex = ( indexCur > indexAct ) ? indexCur : indexAct ;
2019-09-02 10:52:16 +00:00
for ( var i = startIndex ; i <= endIndex ; i ++ ) {
2019-08-30 13:34:11 +00:00
this . bar . tabs [ i ] . changeState ( true ) ;
}
2019-09-02 10:52:16 +00:00
} else if ( ! tab . $el . hasClass ( 'active' ) ) {
2019-09-06 10:07:47 +00:00
if ( this . bar . tabs . length === this . bar . selectTabs . length ) {
this . bar . $el . find ( 'ul > li.selected' ) . removeClass ( 'selected' ) ;
this . bar . selectTabs . length = 0 ;
}
2019-09-02 10:52:16 +00:00
if ( tab . control == 'manual' ) {
this . bar . trigger ( 'tab:manual' , this . bar , this . bar . tabs . indexOf ( tab ) , tab ) ;
} else {
tab . changeState ( ) ;
}
2016-03-11 00:48:53 +00:00
}
}
2017-09-14 12:07:04 +00:00
! tab . disabled && Common . NotificationCenter . trigger ( 'edit:complete' , this . bar ) ;
2016-03-11 00:48:53 +00:00
} , this ) ,
dblclick : $ . proxy ( function ( ) {
this . trigger ( 'tab:dblclick' , this , this . tabs . indexOf ( tab ) , tab ) ;
} , this . bar ) ,
contextmenu : $ . proxy ( function ( ) {
2019-09-06 10:07:47 +00:00
this . trigger ( 'tab:contextmenu' , this , this . tabs . indexOf ( tab ) , tab , this . selectTabs ) ;
2016-03-11 00:48:53 +00:00
} , this . bar ) ,
mousedown : $ . proxy ( function ( e ) {
2020-02-13 09:09:05 +00:00
if ( ( 3 !== e . which ) && ! e . ctrlKey && ! e . metaKey && ! e . shiftKey ) {
var lockDrag = tab . isLockTheDrag ;
this . bar . selectTabs . forEach ( function ( item ) {
if ( item . isLockTheDrag ) {
lockDrag = true ;
}
} ) ;
this . bar . $el . find ( 'ul > li > span' ) . attr ( 'draggable' , ! lockDrag ) ;
2020-01-24 11:26:16 +00:00
tab . changeState ( ) ;
2020-02-13 09:09:05 +00:00
} else {
this . bar . $el . find ( 'ul > li > span' ) . attr ( 'draggable' , 'false' ) ;
}
2019-12-24 07:52:37 +00:00
this . bar . trigger ( 'tab:drag' , this . bar . selectTabs ) ;
2016-03-11 00:48:53 +00:00
} , this )
} ) ;
2019-12-24 07:52:37 +00:00
tab . $el . children ( ) . on (
{ dragstart : $ . proxy ( function ( e ) {
var event = e . originalEvent ,
img = document . createElement ( 'div' ) ;
event . dataTransfer . setDragImage ( img , 0 , 0 ) ;
event . dataTransfer . effectAllowed = 'move' ;
2020-01-13 08:36:22 +00:00
this . bar . trigger ( 'tab:dragstart' , event . dataTransfer , this . bar . selectTabs ) ;
} , this ) ,
dragenter : $ . proxy ( function ( e ) {
this . bar . $el . find ( '.mousemove' ) . removeClass ( 'mousemove right' ) ;
$ ( e . currentTarget ) . parent ( ) . addClass ( 'mousemove' ) ;
2019-12-24 07:52:37 +00:00
} , this ) ,
dragover : $ . proxy ( function ( e ) {
var event = e . originalEvent ;
if ( event . preventDefault ) {
event . preventDefault ( ) ; // Necessary. Allows us to drop.
}
event . dataTransfer . dropEffect = 'move' ;
2020-02-13 09:09:05 +00:00
this . bar . $el . find ( '.mousemove' ) . removeClass ( 'mousemove right' ) ;
2020-01-24 11:26:16 +00:00
$ ( e . currentTarget ) . parent ( ) . addClass ( 'mousemove' ) ;
2019-12-24 07:52:37 +00:00
return false ;
} , this ) ,
2020-01-24 11:26:16 +00:00
dragleave : $ . proxy ( function ( e ) {
$ ( e . currentTarget ) . parent ( ) . removeClass ( 'mousemove right' ) ;
} , this ) ,
2020-01-13 08:36:22 +00:00
dragend : $ . proxy ( function ( e ) {
2020-02-18 11:43:56 +00:00
var event = e . originalEvent ;
var data = event . dataTransfer . getData ( 'status' ) ;
if ( event . dataTransfer . dropEffect === 'move' ) {
this . bar . trigger ( 'tab:dragend' , true ) ;
} else {
this . bar . trigger ( 'tab:dragend' , false ) ;
}
2020-01-13 08:36:22 +00:00
this . bar . $el . find ( '.mousemove' ) . removeClass ( 'mousemove right' ) ;
} , this ) ,
drop : $ . proxy ( function ( e ) {
var event = e . originalEvent ,
index = $ ( event . currentTarget ) . data ( 'index' ) ;
this . bar . $el . find ( '.mousemove' ) . removeClass ( 'mousemove right' ) ;
this . bar . trigger ( 'tab:drop' , event . dataTransfer , index ) ;
2020-02-18 11:43:56 +00:00
event . stopPropagation ( ) ;
2020-01-13 08:36:22 +00:00
} , this )
2019-12-24 07:52:37 +00:00
} ) ;
2016-03-11 00:48:53 +00:00
} ;
StateManager . prototype . detach = function ( tab ) {
tab . $el . off ( ) ;
} ;
Common . UI . TabBar = Common . UI . BaseView . extend ( {
config : {
placement : 'top' ,
items : [ ] ,
draggable : false
} ,
tabs : [ ] ,
2020-01-13 08:36:22 +00:00
template : _ . template ( '<ul id="statusbar_bottom" class="nav nav-tabs <%= placement %>"/>' ) ,
2019-09-03 11:09:22 +00:00
selectTabs : [ ] ,
2016-03-11 00:48:53 +00:00
initialize : function ( options ) {
_ . extend ( this . config , options ) ;
Common . UI . BaseView . prototype . initialize . call ( this , options ) ;
this . saved = [ ] ;
} ,
render : function ( ) {
this . $el . html ( this . template ( this . config ) ) ;
this . $bar = this . $el . find ( 'ul' ) ;
var addEvent = function ( elem , type , fn ) {
elem . addEventListener ? elem . addEventListener ( type , fn , false ) : elem . attachEvent ( "on" + type , fn ) ;
} ;
var eventname = ( /Firefox/i . test ( navigator . userAgent ) ) ? 'DOMMouseScroll' : 'mousewheel' ;
addEvent ( this . $bar [ 0 ] , eventname , _ . bind ( this . _onMouseWheel , this ) ) ;
2019-12-24 07:52:37 +00:00
addEvent ( this . $bar [ 0 ] , 'dragstart' , _ . bind ( function ( event ) {
event . dataTransfer . effectAllowed = 'move' ;
} , this ) ) ;
addEvent ( this . $bar [ 0 ] , 'dragover' , _ . bind ( function ( event ) {
if ( event . preventDefault ) {
event . preventDefault ( ) ; // Necessary. Allows us to drop.
}
event . dataTransfer . dropEffect = 'move' ;
2020-01-13 08:36:22 +00:00
this . tabs [ this . tabs . length - 1 ] . $el . addClass ( 'mousemove right' ) ;
2019-12-24 07:52:37 +00:00
return false ;
} , this ) ) ;
2020-01-24 11:26:16 +00:00
addEvent ( this . $bar [ 0 ] , 'dragleave' , _ . bind ( function ( event ) {
this . tabs [ this . tabs . length - 1 ] . $el . removeClass ( 'mousemove right' ) ;
} , this ) ) ;
addEvent ( this . $bar [ 0 ] , 'drop' , _ . bind ( function ( event ) {
var index = this . tabs . length ;
this . $el . find ( '.mousemove' ) . removeClass ( 'mousemove right' ) ;
this . trigger ( 'tab:drop' , event . dataTransfer , index ) ;
2020-02-18 11:43:56 +00:00
event . stopPropagation ( ) ;
2020-01-24 11:26:16 +00:00
} , this ) ) ;
2016-03-11 00:48:53 +00:00
this . manager = new StateManager ( { bar : this } ) ;
this . insert ( - 1 , this . config . items ) ;
this . insert ( - 1 , this . saved ) ;
delete this . saved ;
2017-10-24 14:44:11 +00:00
Common . Gateway . on ( 'processmouse' , _ . bind ( this . onProcessMouse , this ) ) ;
2016-03-11 00:48:53 +00:00
this . rendered = true ;
return this ;
} ,
_onMouseWheel : function ( e ) {
var hidden = this . checkInvisible ( true ) ,
forward = ( ( e . detail && - e . detail ) || e . wheelDelta ) > 0 ;
if ( forward ) {
if ( hidden . last ) {
this . setTabVisible ( 'forward' ) ;
}
} else {
if ( hidden . first ) {
this . setTabVisible ( 'backward' ) ;
}
}
} ,
2017-10-24 14:44:11 +00:00
onProcessMouse : function ( data ) {
2017-11-07 14:10:25 +00:00
if ( data . type == 'mouseup' && this . dragging ) {
2017-10-24 14:44:11 +00:00
var tab = this . getActive ( true ) ;
if ( tab )
tab . mouseup ( ) ;
}
} ,
2016-03-11 00:48:53 +00:00
add : function ( tabs ) {
return this . insert ( - 1 , tabs ) > 0 ;
} ,
insert : function ( index , tabs ) {
var count = 0 ;
if ( tabs ) {
if ( ! ( tabs instanceof Array ) ) tabs = [ tabs ] ;
if ( tabs . length ) {
count = tabs . length ;
if ( this . rendered ) {
var me = this , tab ;
if ( index < 0 || index > me . tabs . length ) {
for ( var i = 0 ; i < tabs . length ; i ++ ) {
tab = new Common . UI . Tab ( tabs [ i ] ) ;
me . $bar . append ( tab . render ( ) . $el ) ;
me . tabs . push ( tab ) ;
me . manager . attach ( tab ) ;
2019-09-03 11:09:22 +00:00
if ( tab . isActive ( ) ) {
me . selectTabs . length = 0 ;
me . selectTabs . push ( tab ) ;
}
2016-03-11 00:48:53 +00:00
}
} else {
for ( i = tabs . length ; i -- > 0 ; ) {
tab = new Common . UI . Tab ( tabs [ i ] ) ;
if ( index === 0 ) {
me . $bar . prepend ( tab . render ( ) . $el ) ;
me . tabs . unshift ( tab ) ;
} else {
me . $bar . find ( 'li:nth-child(' + index + ')' ) . before ( tab . render ( ) . $el ) ;
me . tabs . splice ( index , 0 , tab ) ;
}
2019-09-03 11:09:22 +00:00
if ( tab . isActive ( ) ) {
me . selectTabs . length = 0 ;
me . selectTabs . push ( tab ) ;
}
2016-03-11 00:48:53 +00:00
me . manager . attach ( tab ) ;
}
}
} else {
this . saved . push ( tabs )
}
this . checkInvisible ( ) ;
}
}
return count ;
} ,
remove : function ( index ) {
if ( index >= 0 && index < this . tabs . length ) {
var tab = this . tabs . splice ( index , 1 ) [ 0 ] ;
this . manager . detach ( tab ) ;
tab . $el . remove ( ) ;
this . checkInvisible ( ) ;
}
} ,
empty : function ( suppress ) {
var me = this ;
this . tabs . forEach ( function ( tab ) {
me . manager . detach ( tab ) ;
} ) ;
this . $bar . empty ( ) ;
me . tabs = [ ] ;
this . checkInvisible ( suppress ) ;
} ,
setActive : function ( t ) {
if ( t instanceof Common . UI . Tab ) {
tab = t ;
} else
if ( typeof t == 'number' ) {
if ( t >= 0 && t < this . tabs . length ) {
var tab = this . tabs [ t ] ;
}
}
if ( tab && tab . control != 'manual' && ! tab . disabled && ! tab . $el . hasClass ( 'active' ) ) {
tab . changeState ( ) ;
}
this . checkInvisible ( ) ;
} ,
2019-09-06 10:07:47 +00:00
setSelectAll : function ( isSelect ) {
var me = this ;
me . selectTabs . length = 0 ;
if ( isSelect ) {
me . tabs . forEach ( function ( tab ) {
if ( ! tab . isSelected ( ) ) {
tab . addClass ( 'selected' ) ;
}
me . selectTabs . push ( tab ) ;
} ) ;
} else {
me . tabs . forEach ( function ( tab ) {
if ( tab . isActive ( ) ) {
me . selectTabs . push ( tab ) ;
} else if ( tab . isSelected ( ) ) {
tab . removeClass ( 'selected' ) ;
}
} ) ;
}
} ,
2016-03-11 00:48:53 +00:00
getActive : function ( iselem ) {
return iselem ? this . $bar . find ( '> li.active' ) : this . $bar . find ( '> li.active' ) . index ( ) ;
} ,
getAt : function ( index ) {
return ( index >= 0 && index < this . tabs . length ) ? this . tabs [ index ] : undefined ;
} ,
getCount : function ( ) {
return this . tabs . length ;
} ,
addClass : function ( cls ) {
if ( cls . length && ! this . $bar . hasClass ( cls ) )
this . $bar . addClass ( cls ) ;
} ,
removeClass : function ( cls ) {
if ( cls . length && this . $bar . hasClass ( cls ) )
this . $bar . removeClass ( cls ) ;
} ,
hasClass : function ( cls ) {
return this . $bar . hasClass ( cls ) ;
} ,
setTabVisible : function ( index , suppress ) {
if ( index <= 0 || index == 'first' ) {
this . $bar . scrollLeft ( 0 ) ;
this . checkInvisible ( suppress ) ;
} else if ( index >= ( this . tabs . length - 1 ) || index == 'last' ) {
var tab = this . tabs [ this . tabs . length - 1 ] . $el ;
this . $bar . scrollLeft ( this . $bar . scrollLeft ( ) + ( tab . position ( ) . left + parseInt ( tab . css ( 'width' ) ) - this . $bar . width ( ) ) + 1 ) ;
this . checkInvisible ( suppress ) ;
} else {
var rightbound = this . $bar . width ( ) ,
tab , right , left ;
if ( index == 'forward' ) {
for ( var i = 0 ; i < this . tabs . length ; i ++ ) {
tab = this . tabs [ i ] . $el ;
right = tab . position ( ) . left + parseInt ( tab . css ( 'width' ) ) ;
if ( right > rightbound ) {
this . $bar . scrollLeft ( this . $bar . scrollLeft ( ) + ( right - rightbound ) + 20 ) ;
this . checkInvisible ( suppress ) ;
break ;
}
}
} else if ( index == 'backward' ) {
for ( i = this . tabs . length ; i -- > 0 ; ) {
tab = this . tabs [ i ] . $el ;
left = tab . position ( ) . left ;
if ( left < 0 ) {
this . $bar . scrollLeft ( this . $bar . scrollLeft ( ) + left - 26 ) ;
this . checkInvisible ( suppress ) ;
break ;
}
}
} else if ( typeof index == 'number' ) {
tab = this . tabs [ index ] . $el ;
left = tab . position ( ) . left ;
right = left + parseInt ( tab . css ( 'width' ) ) ;
if ( left < 0 ) {
this . $bar . scrollLeft ( this . $bar . scrollLeft ( ) + left - 26 ) ;
this . checkInvisible ( suppress ) ;
} else if ( right > rightbound ) {
this . $bar . scrollLeft ( this . $bar . scrollLeft ( ) + ( right - rightbound ) + 20 ) ;
this . checkInvisible ( suppress ) ;
}
}
}
} ,
checkInvisible : function ( suppress ) {
var result = {
first : ! this . isTabVisible ( 0 ) ,
last : ! this . isTabVisible ( this . tabs . length - 1 )
} ;
! suppress && this . fireEvent ( 'tab:invisible' , this , result ) ;
return result ;
} ,
hasInvisible : function ( ) {
var _left _bound _ = this . $bar . offset ( ) . left ,
_right _bound _ = _left _bound _ + this . $bar . width ( ) ;
for ( var i = this . tabs . length ; i -- > 0 ; ) {
if ( ! this . isTabVisible ( i , _left _bound _ , _right _bound _ ) ) {
return true ;
}
}
return false ;
} ,
isTabVisible : function ( index ) {
var leftbound = arguments [ 1 ] || this . $bar . offset ( ) . left ,
rightbound = arguments [ 2 ] || ( leftbound + this . $bar . width ( ) ) ,
left , right , tab , rect ;
if ( index < this . tabs . length && index >= 0 ) {
tab = this . tabs [ index ] . $el ;
rect = tab . get ( 0 ) . getBoundingClientRect ( ) ;
left = rect . left ;
right = rect . right ;
//left = tab.position().left;
//right = left + tab.width();
2019-10-09 12:14:02 +00:00
return ! ( left < leftbound ) && ! ( right - rightbound > 0.1 ) ;
2016-03-11 00:48:53 +00:00
}
return false ;
}
} ) ;
} ) ;