2011-05-25 16:54:46 -04:00
/ * * * * * * B E G I N L I C E N S E B L O C K * * * * *
* Version : MPL 1.1 / GPL 2.0 / LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 ( the "License" ) ; you may not use this file except in compliance with
* the License . You may obtain a copy of the License at
* http : //www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis ,
* WITHOUT WARRANTY OF ANY KIND , either express or implied . See the License
* for the specific language governing rights and limitations under the
* License .
*
* The Original Code is the Tree Style Tab .
*
2012-10-13 14:31:06 -04:00
* The Initial Developer of the Original Code is YUKI "Piro" Hiroshi .
2012-01-02 05:52:51 -05:00
* Portions created by the Initial Developer are Copyright ( C ) 2011 - 2012
2011-05-25 16:54:46 -04:00
* the Initial Developer . All Rights Reserved .
*
2012-10-13 14:31:06 -04:00
* Contributor ( s ) : YUKI "Piro" Hiroshi < piro . outsider . reflex @ gmail . com >
2011-05-25 16:54:46 -04:00
*
* Alternatively , the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later ( the "GPL" ) , or
* the GNU Lesser General Public License Version 2.1 or later ( the "LGPL" ) ,
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above . If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL , and not to allow others to
* use your version of this file under the terms of the MPL , indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL . If you do not delete
* the provisions above , a recipient may use your version of this file under
* the terms of any one of the MPL , the GPL or the LGPL .
*
* * * * * * END LICENSE BLOCK * * * * * * /
const EXPORTED _SYMBOLS = [ 'TreeStyleTabBrowser' ] ;
const Cc = Components . classes ;
const Ci = Components . interfaces ;
2012-09-17 11:31:48 -04:00
Components . utils . import ( 'resource://gre/modules/XPCOMUtils.jsm' ) ;
2012-11-11 08:48:42 -05:00
XPCOMUtils . defineLazyModuleGetter ( this , 'Services' , 'resource://gre/modules/Services.jsm' ) ;
XPCOMUtils . defineLazyModuleGetter ( this , 'utils' , 'resource://treestyletab-modules/utils.js' , 'TreeStyleTabUtils' ) ;
XPCOMUtils . defineLazyModuleGetter ( this , 'FullTooltipManager' , 'resource://treestyletab-modules/fullTooltip.js' ) ;
XPCOMUtils . defineLazyModuleGetter ( this , 'TabbarDNDObserver' , 'resource://treestyletab-modules/tabbarDNDObserver.js' ) ;
XPCOMUtils . defineLazyModuleGetter ( this , 'TabpanelDNDObserver' , 'resource://treestyletab-modules/tabpanelDNDObserver.js' ) ;
XPCOMUtils . defineLazyModuleGetter ( this , 'AutoHideBrowser' , 'resource://treestyletab-modules/autoHide.js' ) ;
2012-10-19 08:38:35 -04:00
2011-05-25 16:54:46 -04:00
Components . utils . import ( 'resource://treestyletab-modules/window.js' ) ;
function TreeStyleTabBrowser ( aWindowService , aTabBrowser )
2007-11-14 14:34:36 -05:00
{
2012-08-04 16:49:17 -04:00
this . id = Date . now ( ) + '-' + parseInt ( Math . random ( ) * 65000 ) ;
2011-05-25 16:54:46 -04:00
this . windowService = aWindowService ;
this . window = aWindowService . window ;
this . document = aWindowService . document ;
2007-11-14 14:34:36 -05:00
this . mTabBrowser = aTabBrowser ;
2011-05-25 16:54:46 -04:00
aTabBrowser . treeStyleTab = this ;
this . tabVisibilityChangedTabs = [ ] ;
this . updateTabsIndentWithDelayTabs = [ ] ;
2012-08-04 16:49:17 -04:00
this . deferredTasks = { } ;
this . tabVisibilityChangedTabs = [ ] ;
this . _updateFloatingTabbarReason = 0 ;
this . internallyTabMovingCount = 0 ;
this . subTreeMovingCount = 0 ;
this . subTreeChildrenMovingCount = 0 ;
this . _treeViewEnabled = true ;
2007-11-14 14:34:36 -05:00
}
TreeStyleTabBrowser . prototype = {
2011-05-25 16:54:46 -04:00
_ _proto _ _ : TreeStyleTabWindow . prototype ,
2011-01-21 23:21:39 -05:00
kMENUITEM _RELOADSUBTREE : 'context-item-reloadTabSubtree' ,
2009-07-06 05:21:06 -04:00
kMENUITEM _RELOADCHILDREN : 'context-item-reloadDescendantTabs' ,
2009-12-25 06:19:50 -05:00
kMENUITEM _REMOVESUBTREE : 'context-item-removeTabSubtree' ,
2007-11-26 10:07:10 -05:00
kMENUITEM _REMOVECHILDREN : 'context-item-removeDescendantTabs' ,
2010-12-08 06:34:42 -05:00
kMENUITEM _REMOVEALLTABSBUT : 'context-item-removeAllTabsButThisTree' ,
2007-11-17 01:05:23 -05:00
kMENUITEM _COLLAPSEEXPAND _SEPARATOR : 'context-separator-collapseExpandAll' ,
kMENUITEM _COLLAPSE : 'context-item-collapseAllSubtree' ,
kMENUITEM _EXPAND : 'context-item-expandAllSubtree' ,
kMENUITEM _AUTOHIDE _SEPARATOR : 'context-separator-toggleAutoHide' ,
kMENUITEM _AUTOHIDE : 'context-item-toggleAutoHide' ,
2008-02-22 12:55:35 -05:00
kMENUITEM _FIXED : 'context-item-toggleFixed' ,
2009-12-25 06:19:50 -05:00
kMENUITEM _BOOKMARKSUBTREE : 'context-item-bookmarkTabSubtree' ,
2011-01-21 23:21:39 -05:00
2007-11-14 14:34:36 -05:00
mTabBrowser : null ,
2011-05-26 13:31:44 -04:00
indent : - 1 ,
indentProp : 'margin' ,
indentTarget : 'left' ,
indentCSSProp : 'margin-left' ,
collapseTarget : 'top' ,
collapseCSSProp : 'margin-top' ,
screenPositionProp : 'screenY' ,
2012-08-29 16:28:03 -04:00
offsetProp : 'offsetY' ,
translateFunction : 'translateY' ,
2011-05-26 13:31:44 -04:00
sizeProp : 'height' ,
invertedScreenPositionProp : 'screenX' ,
invertedSizeProp : 'width' ,
startProp : 'top' ,
endProp : 'bottom' ,
2010-11-18 23:00:42 -05:00
2010-11-29 03:24:45 -05:00
maxTreeLevelPhisical : false ,
2011-12-13 02:32:42 -05:00
2011-12-13 23:30:29 -05:00
needRestoreTree : false ,
2007-11-14 14:34:36 -05:00
2011-01-21 23:21:39 -05:00
/* elements */
2007-11-17 07:59:48 -05:00
get browser ( )
{
return this . mTabBrowser ;
} ,
2007-11-14 14:34:36 -05:00
get container ( )
{
2009-09-02 22:05:25 -04:00
if ( ! this . _container ) {
2011-05-25 16:54:46 -04:00
this . _container = this . document . getElementById ( 'appcontent' ) ;
2009-09-02 22:05:25 -04:00
}
return this . _container ;
2007-11-14 14:34:36 -05:00
} ,
2009-09-02 22:05:25 -04:00
_container : null ,
2007-11-14 14:34:36 -05:00
2008-06-20 01:57:38 -04:00
get scrollBox ( )
{
2011-01-23 01:18:09 -05:00
return ( // Tab Mix Plus
2012-10-23 12:43:56 -04:00
utils . getTreePref ( 'compatibility.TMP' ) &&
2011-05-25 16:54:46 -04:00
this . document . getAnonymousElementByAttribute ( this . mTabBrowser . mTabContainer , 'class' , 'tabs-frame' )
2011-01-23 01:18:09 -05:00
) ||
this . mTabBrowser . mTabContainer . mTabstrip ;
2008-06-20 01:57:38 -04:00
} ,
2008-10-17 13:16:16 -04:00
get scrollBoxObject ( )
2008-06-20 01:57:38 -04:00
{
2011-03-18 17:06:04 -04:00
var node = this . scrollBox ;
if ( node . _scrollbox ) node = node . _scrollbox ;
return ( node . scrollBoxObject || node . boxObject )
2011-05-25 16:54:46 -04:00
. QueryInterface ( Ci . nsIScrollBoxObject ) ; // for Tab Mix Plus (ensure scrollbox-ed)
2008-06-20 01:57:38 -04:00
} ,
2010-03-23 15:10:53 -04:00
get splitter ( )
{
2011-05-25 17:23:02 -04:00
var d = this . document ;
return d . getAnonymousElementByAttribute ( this . mTabBrowser , 'class' , this . kSPLITTER ) ||
d . getAnonymousElementByAttribute ( this . mTabBrowser , 'id' , 'tabkit-splitter' ) ; // Tab Kit
2010-03-23 15:10:53 -04:00
} ,
2010-03-25 23:17:16 -04:00
get tabStripPlaceHolder ( )
{
return this . _tabStripPlaceHolder ;
} ,
2010-03-28 14:22:15 -04:00
set tabStripPlaceHolder ( value )
2010-03-25 23:17:16 -04:00
{
2010-03-25 23:32:38 -04:00
return ( this . _tabStripPlaceHolder = value ) ;
2010-03-25 23:17:16 -04:00
} ,
2011-01-21 23:21:39 -05:00
/* properties */
get maxTreeLevel ( )
2010-12-01 19:00:39 -05:00
{
2011-01-21 23:21:39 -05:00
return this . _maxTreeLevel ;
2010-12-01 19:00:39 -05:00
} ,
2011-01-21 23:21:39 -05:00
set maxTreeLevel ( aValue )
{
this . _maxTreeLevel = aValue ;
this . setTabbrowserAttribute ( this . kMAX _LEVEL , this . _maxTreeLevel || '0' ) ;
this . enableSubtreeIndent = this . _maxTreeLevel != 0 ;
return aValue ;
} ,
_maxTreeLevel : - 1 ,
2010-12-01 19:00:39 -05:00
2012-08-30 13:51:21 -04:00
get baseIndent ( ) {
return this . isVertical ? this . baseIndentVertical : this . baseIndentHorizontal ;
} ,
2011-01-21 23:21:39 -05:00
get enableSubtreeIndent ( )
2010-12-01 19:00:39 -05:00
{
2011-01-21 23:21:39 -05:00
return this . _enableSubtreeIndent ;
2010-12-01 19:00:39 -05:00
} ,
2011-01-21 23:21:39 -05:00
set enableSubtreeIndent ( aValue )
{
this . _enableSubtreeIndent = aValue ;
this . setTabbrowserAttribute ( this . kINDENTED , this . _enableSubtreeIndent ? 'true' : null ) ;
return aValue ;
} ,
_enableSubtreeIndent : true ,
2010-12-01 19:00:39 -05:00
2011-01-21 23:21:39 -05:00
get allowSubtreeCollapseExpand ( )
2007-11-17 00:20:26 -05:00
{
2011-01-21 23:21:39 -05:00
return this . _allowSubtreeCollapseExpand ;
} ,
set allowSubtreeCollapseExpand ( aValue )
{
this . _allowSubtreeCollapseExpand = aValue ;
this . setTabbrowserAttribute ( this . kALLOW _COLLAPSE , this . _allowSubtreeCollapseExpand ? 'true' : null ) ;
return aValue ;
2007-11-17 00:20:26 -05:00
} ,
2011-01-21 23:21:39 -05:00
_allowSubtreeCollapseExpand : true ,
2007-11-17 00:20:26 -05:00
2011-01-22 13:25:21 -05:00
get fixed ( )
{
var orient = this . isVertical ? 'vertical' : 'horizontal' ;
2011-05-25 16:54:46 -04:00
if ( ! this . windowService . preInitialized )
2012-10-23 12:43:56 -04:00
return utils . getTreePref ( 'tabbar.fixed.' + orient ) ;
2011-01-22 13:25:21 -05:00
var b = this . mTabBrowser ;
if ( ! b ) return false ;
return b . getAttribute ( this . kFIXED + '-' + orient ) == 'true' ;
} ,
set fixed ( aValue )
{
this . setTabbrowserAttribute ( this . kFIXED , aValue || null , this . mTabBrowser ) ;
return aValue ;
} ,
get isFixed ( ) // for backward compatibility
{
return this . fixed ;
} ,
2011-01-23 01:20:06 -05:00
get position ( ) /* PUBLIC API */
2011-01-22 10:46:29 -05:00
{
return (
// Don't touch to the <tabbrowser/> element before it is initialized by XBL constructor.
2011-05-25 16:54:46 -04:00
( this . windowService . preInitialized && this . browser . getAttribute ( this . kTABBAR _POSITION ) ) ||
2012-10-29 14:11:39 -04:00
this . base . position
2011-01-22 10:46:29 -05:00
) ;
} ,
set position ( aValue )
{
var position = String ( aValue ) . toLowerCase ( ) ;
if ( ! position || ! /^(top|bottom|left|right)$/ . test ( position ) )
position = 'top' ;
if ( position == this . position )
return position ;
2011-05-25 16:54:46 -04:00
if ( 'UndoTabService' in this . window && this . window . UndoTabService . isUndoable ( ) ) {
2011-01-22 10:46:29 -05:00
var current = this . position ;
var self = this ;
2011-05-25 16:54:46 -04:00
this . window . UndoTabService . doOperation (
2011-01-22 10:46:29 -05:00
function ( ) {
self . _changeTabbarPosition ( position ) ;
} ,
{
label : self . treeBundle . getString ( 'undo_changeTabbarPosition_label' ) ,
name : 'treestyletab-changeTabbarPosition-private' ,
data : {
oldPosition : current ,
newPosition : position ,
target : self . mTabBrowser . id
}
}
) ;
}
else {
this . _changeTabbarPosition ( position ) ;
}
return position ;
} ,
_changeTabbarPosition : function TSTBrowser _changeTabbarPosition ( aNewPosition )
{
2012-08-04 13:53:57 -04:00
if ( this . deferredTasks [ '_changeTabbarPosition' ] )
this . deferredTasks [ '_changeTabbarPosition' ] . cancel ( ) ;
2011-01-22 10:46:29 -05:00
var oldPosition = this . position ;
this . fireTabbarPositionEvent ( true , oldPosition , aNewPosition ) ;
this . initTabbar ( aNewPosition , oldPosition ) ;
2011-01-22 11:08:26 -05:00
this . reinitAllTabs ( ) ;
2011-01-22 10:46:29 -05:00
2011-05-25 16:54:46 -04:00
var self = this ;
2012-08-04 13:53:57 -04:00
( this . deferredTasks [ '_changeTabbarPosition' ] = this . Deferred . next ( function ( ) {
2011-05-25 16:54:46 -04:00
self . checkTabsIndentOverflow ( ) ;
self . fireTabbarPositionEvent ( false , oldPosition , aNewPosition ) ;
2012-08-04 13:53:57 -04:00
} ) ) . error ( this . defaultDeferredErrorHandler ) . next ( function ( ) {
delete self . deferredTasks [ '_changeTabbarPosition' ] ;
} ) ;
2011-01-22 10:46:29 -05:00
} ,
2007-11-17 00:20:26 -05:00
2011-01-21 23:21:39 -05:00
/* status getters */
2008-02-22 02:44:06 -05:00
2007-11-14 14:43:54 -05:00
get isVertical ( )
2007-11-14 14:34:36 -05:00
{
2011-05-25 16:54:46 -04:00
if ( ! this . windowService . preInitialized )
2011-01-22 10:46:29 -05:00
return [ 'left' , 'right' ] . indexOf ( this . position ) > - 1 ;
2010-09-13 00:57:53 -04:00
2007-11-14 14:34:36 -05:00
var b = this . mTabBrowser ;
if ( ! b ) return false ;
2011-01-22 09:43:55 -05:00
if ( b . hasAttribute ( this . kMODE ) )
return b . getAttribute ( this . kMODE ) == 'vertical' ;
2008-06-20 01:57:38 -04:00
var box = this . scrollBox || b . mTabContainer ;
2011-05-25 16:54:46 -04:00
return ( box . getAttribute ( 'orient' ) || this . window . getComputedStyle ( box , '' ) . getPropertyValue ( '-moz-box-orient' ) ) == 'vertical' ;
2007-11-14 14:34:36 -05:00
} ,
2012-01-29 05:54:02 -05:00
isFloating : true , // for backward compatibility (but this should be removed)
2010-03-25 23:17:16 -04:00
2011-01-23 01:20:06 -05:00
get ownerToolbar ( )
{
return this . evaluateXPath (
'ancestor-or-self::xul:toolbar[1]' ,
this . mTabBrowser . tabContainer ,
2011-04-06 01:02:00 -04:00
Ci . nsIDOMXPathResult . FIRST _ORDERED _NODE _TYPE
2011-01-23 01:20:06 -05:00
) . singleNodeValue ;
} ,
2010-11-24 11:14:36 -05:00
get canStackTabs ( )
{
2012-01-17 21:58:12 -05:00
return (
! this . isVertical &&
this . canCollapseSubtree ( ) &&
2012-10-23 12:43:56 -04:00
utils . getTreePref ( 'stackCollapsedTabs' )
2012-01-17 21:58:12 -05:00
) ;
2010-11-24 11:14:36 -05:00
} ,
2012-01-13 11:45:51 -05:00
get counterRole ( )
{
return this . isVertical ? this . counterRoleVertical : this . counterRoleHorizontal ;
} ,
2012-02-04 18:24:26 -05:00
get isDestroying ( )
{
return ! this . mTabBrowser || ! this . mTabBrowser . mTabContainer ;
} ,
2011-01-21 23:21:39 -05:00
/* utils */
/* get tab contents */
getTabLabel : function TSTBrowser _getTabLabel ( aTab )
{
2011-05-25 17:23:02 -04:00
var d = this . document ;
var label = d . getAnonymousElementByAttribute ( aTab , 'class' , 'tab-text-stack' ) || // Mac OS X
2011-01-21 23:21:39 -05:00
( // Tab Mix Plus
2012-10-23 12:43:56 -04:00
utils . getTreePref ( 'compatibility.TMP' ) &&
2011-05-25 17:23:02 -04:00
d . getAnonymousElementByAttribute ( aTab , 'class' , 'tab-text-container' )
2011-01-21 23:21:39 -05:00
) ||
2012-01-13 03:38:12 -05:00
d . getAnonymousElementByAttribute ( aTab , 'class' , 'tab-text tab-label' ) ;
2011-01-21 23:21:39 -05:00
return label ;
} ,
2010-11-24 11:14:36 -05:00
2011-01-21 23:21:39 -05:00
getTabClosebox : function TSTBrowser _getTabClosebox ( aTab )
{
2011-05-25 17:23:02 -04:00
var d = this . document ;
2011-01-21 23:21:39 -05:00
var close = ( // Tab Mix Plus
2012-10-23 12:43:56 -04:00
utils . getTreePref ( 'compatibility.TMP' ) &&
2011-05-25 17:23:02 -04:00
d . getAnonymousElementByAttribute ( aTab , 'class' , 'tab-close-button always-right' )
2011-01-21 23:21:39 -05:00
) ||
2011-05-25 17:23:02 -04:00
d . getAnonymousElementByAttribute ( aTab , 'class' , 'tab-close-button' ) ;
2011-01-21 23:21:39 -05:00
return close ;
} ,
2011-12-19 02:49:23 -05:00
getTabTwisty : function TSTBrowser _getTabTwisty ( aTab )
{
return this . document . getAnonymousElementByAttribute ( aTab , 'class' , this . kTWISTY ) ;
} ,
2012-02-04 06:28:30 -05:00
getTabTwistyAnchorNode : function TSTBrowser _getTabTwistyAnchorNode ( aTab )
{
return this . document . getAnonymousElementByAttribute ( aTab , 'class' , 'tab-icon' ) || // Tab Mix Plus
this . document . getAnonymousElementByAttribute ( aTab , 'class' , 'tab-throbber' ) ;
} ,
2011-01-21 23:21:39 -05:00
2011-12-13 09:21:31 -05:00
getTabFromTabbarEvent : function TSTBrowser _getTabFromTabbarEvent ( aEvent )
{
if (
! this . shouldDetectClickOnIndentSpaces ||
! this . getAncestorTabbarFromEvent ( aEvent ) ||
this . isEventFiredOnClickable ( aEvent ) ||
this . getSplitterFromEvent ( aEvent )
)
return null ;
2011-12-19 02:37:48 -05:00
return this . getTabFromCoordinate ( aEvent [ this . screenPositionProp ] ) ;
} ,
2012-01-29 05:54:02 -05:00
getTabFromCoordinate : function TSTBrowser _getTabFromCoordinate ( aCoordinate )
2011-12-19 02:37:48 -05:00
{
2011-12-13 09:21:31 -05:00
var tab = null ;
2012-09-23 02:43:49 -04:00
this . getTabs ( this . mTabBrowser ) . some ( function ( aTab ) {
2011-12-13 09:21:31 -05:00
var box = aTab . boxObject ;
2011-12-19 02:37:48 -05:00
if ( box [ this . screenPositionProp ] > aCoordinate ||
box [ this . screenPositionProp ] + box [ this . sizeProp ] < aCoordinate ) {
2011-12-13 09:21:31 -05:00
return false ;
}
tab = aTab ;
return true ;
} , this ) ;
return tab ;
} ,
getNextFocusedTab : function TSTBrowser _getNextFocusedTab ( aTab )
{
return this . getNextSiblingTab ( aTab ) ||
this . getPreviousVisibleTab ( aTab ) ;
} ,
2009-12-25 03:34:52 -05:00
isTabInViewport : function TSTBrowser _isTabInViewport ( aTab )
2007-11-14 14:34:36 -05:00
{
2011-05-25 16:54:46 -04:00
if ( ! this . windowService . preInitialized || ! aTab )
2010-09-13 00:57:53 -04:00
return false ;
2010-09-09 05:38:48 -04:00
if ( aTab . getAttribute ( 'pinned' ) == 'true' )
2010-09-09 05:02:26 -04:00
return true ;
2012-01-28 16:43:43 -05:00
var tabBox = this . getFutureBoxObject ( aTab ) ;
2008-06-20 01:57:38 -04:00
var barBox = this . scrollBox . boxObject ;
2012-01-28 16:43:43 -05:00
return (
tabBox . screenX >= barBox . screenX &&
tabBox . screenX + tabBox . width <= barBox . screenX + barBox . width &&
tabBox . screenY >= barBox . screenY &&
tabBox . screenY + tabBox . height <= barBox . screenY + barBox . height
) ;
2007-11-14 14:34:36 -05:00
} ,
2011-01-21 23:21:39 -05:00
2009-12-25 03:34:52 -05:00
isMultiRow : function TSTBrowser _isMultiRow ( )
2008-02-22 02:44:06 -05:00
{
2011-05-25 17:23:02 -04:00
var w = this . window ;
2012-10-23 12:43:56 -04:00
return ( 'tabberwocky' in w && utils . getTreePref ( 'compatibility.Tabberwocky' ) ) ?
2011-05-25 16:54:46 -04:00
( this . getPref ( 'tabberwocky.multirow' ) && ! this . isVertical ) :
2012-10-23 12:43:56 -04:00
( 'TabmixTabbar' in w && utils . getTreePref ( 'compatibility.TMP' ) ) ?
2011-05-25 17:23:02 -04:00
w . TabmixTabbar . isMultiRow :
2011-05-25 16:54:46 -04:00
false ;
2008-02-22 02:44:06 -05:00
} ,
2010-06-25 11:59:59 -04:00
2011-05-06 01:29:39 -04:00
positionPinnedTabs : function TSTBrowser _positionPinnedTabs ( aWidth , aHeight , aJustNow )
2010-06-25 11:59:59 -04:00
{
var b = this . mTabBrowser ;
var tabbar = b . tabContainer ;
2011-01-12 11:36:14 -05:00
if (
! tabbar ||
! tabbar . _positionPinnedTabs ||
! tabbar . boxObject . width
)
2010-12-06 23:46:38 -05:00
return ;
2011-11-29 15:01:56 -05:00
var count = this . pinnedTabsCount ;
if ( ! this . isVertical || ! count ) {
2010-12-06 23:46:38 -05:00
this . resetPinnedTabs ( ) ;
b . mTabContainer . _positionPinnedTabs ( ) ;
return ;
}
2011-04-26 12:00:18 -04:00
var tabbarPlaceHolderWidth = this . _tabStripPlaceHolder . boxObject . width ;
var tabbarWidth = this . tabStrip . boxObject . width ;
var maxWidth = tabbarPlaceHolderWidth || tabbarWidth ;
2011-01-12 11:36:14 -05:00
2012-10-23 12:43:56 -04:00
var faviconized = utils . getTreePref ( 'pinnedTab.faviconized' ) ;
2011-11-29 15:33:47 -05:00
var faviconizedSize = tabbar . childNodes [ 0 ] . boxObject . height ;
var width = faviconized ? faviconizedSize : maxWidth ;
var height = faviconizedSize ;
2012-05-01 14:38:39 -04:00
var maxCol = Math . max ( 1 , Math . floor ( maxWidth / width ) ) ;
2010-06-25 11:59:59 -04:00
var maxRow = Math . ceil ( count / maxCol ) ;
var col = 0 ;
var row = 0 ;
2011-04-26 12:00:18 -04:00
2011-10-30 01:52:56 -04:00
var baseX = this . tabStrip . boxObject . screenX - this . document . documentElement . boxObject . screenX ;
2011-07-29 01:44:31 -04:00
2011-10-24 06:54:16 -04:00
/ * *
* Hacks for Firefox 9 or olders .
* In a box with "direction: rtr" , we have to position tabs
* by margin - right , because the basic position becomes
* "top-right" instead of "top-left" .
* /
2011-10-30 01:52:56 -04:00
var needToInvertDirection = ! this . isGecko10OrLater && this . position == 'left' && b . getAttribute ( this . kINVERT _SCROLLBAR ) == 'true' ;
2011-04-07 12:42:00 -04:00
var remainder = maxWidth - ( maxCol * width ) ;
2011-10-24 06:54:16 -04:00
var shrunkenOffset = ( ( needToInvertDirection || this . position == 'right' ) && tabbarPlaceHolderWidth ) ?
2011-04-26 12:00:18 -04:00
tabbarWidth - tabbarPlaceHolderWidth :
0 ;
2011-07-29 01:44:31 -04:00
var removeFaviconizedClassPattern = new RegExp ( '\\s+' + this . kFAVICONIZED , 'g' ) ;
2010-06-25 12:14:49 -04:00
tabbar . style . MozMarginStart = '' ;
2011-01-12 09:37:31 -05:00
tabbar . style . setProperty ( 'margin-top' , ( height * maxRow ) + 'px' , 'important' ) ;
2011-03-18 17:06:04 -04:00
for ( let i = 0 ; i < count ; i ++ )
2010-06-25 11:59:59 -04:00
{
2011-07-29 01:44:31 -04:00
let item = tabbar . childNodes [ i ] ;
let style = item . style ;
2010-06-25 12:14:49 -04:00
style . MozMarginStart = '' ;
2011-05-06 01:29:39 -04:00
let transitionStyleBackup = style . transition || style . MozTransition || '' ;
if ( aJustNow )
style . MozTransition = style . transition = 'none' ;
2011-07-29 01:44:31 -04:00
let className = item . className . replace ( removeFaviconizedClassPattern , '' ) ;
if ( faviconized )
className += ' ' + this . kFAVICONIZED ;
if ( className != item . className )
item . className = className ;
2011-11-29 15:33:47 -05:00
style . maxWidth = style . width = width + 'px' ;
2011-10-24 06:54:16 -04:00
if ( needToInvertDirection ) {
2011-04-26 12:00:18 -04:00
let margin = ( width * ( maxCol - col - 1 ) ) + remainder + shrunkenOffset ;
2011-04-07 12:42:00 -04:00
style . setProperty ( 'margin-right' , margin + 'px' , 'important' ) ;
2011-10-24 06:54:16 -04:00
style . marginLeft = style . left = style . right = '' ;
2011-04-07 12:42:00 -04:00
}
else {
2011-04-26 12:00:18 -04:00
style . setProperty ( 'margin-left' , ( ( width * col ) + shrunkenOffset ) + 'px' , 'important' ) ;
2011-10-30 01:52:56 -04:00
style . left = baseX + 'px' ;
style . right = 'auto' ;
2011-04-07 12:42:00 -04:00
style . marginRight = '' ;
}
2011-05-06 01:29:39 -04:00
2010-06-25 12:14:49 -04:00
style . setProperty ( 'margin-top' , ( - height * ( maxRow - row ) ) + 'px' , 'important' ) ;
2011-10-24 06:54:16 -04:00
style . top = style . bottom = '' ;
2011-05-06 01:29:39 -04:00
2012-08-04 13:53:57 -04:00
if ( aJustNow ) {
let key = 'positionPinnedTabs_tab_' + parseInt ( Math . random ( ) * 65000 ) ;
( this . deferredTasks [ key ] = this . Deferred . next ( function ( ) { // "transition" must be cleared after the reflow.
2011-05-06 01:29:39 -04:00
style . MozTransition = style . transition = transitionStyleBackup ;
2012-08-04 13:53:57 -04:00
} ) ) . error ( this . defaultDeferredErrorHandler ) . next ( function ( ) {
delete self . deferredTasks [ key ] ;
} ) ;
}
2011-05-06 01:29:39 -04:00
2010-06-25 11:59:59 -04:00
col ++ ;
if ( col >= maxCol ) {
col = 0 ;
row ++ ;
}
}
} ,
2010-12-06 23:46:38 -05:00
positionPinnedTabsWithDelay : function TSTBrowser _positionPinnedTabsWithDelay ( )
{
2012-08-04 13:53:57 -04:00
if ( this . deferredTasks [ 'positionPinnedTabsWithDelay' ] )
2010-12-07 05:22:41 -05:00
return ;
2011-05-06 05:47:36 -04:00
var args = Array . slice ( arguments ) ;
2012-08-04 13:53:57 -04:00
var lastArgs = this . deferredTasks [ 'positionPinnedTabsWithDelay' ] ?
this . deferredTasks [ 'positionPinnedTabsWithDelay' ] . _ _treestyletab _ _args :
[ null , null , false ] ;
2011-05-06 05:47:36 -04:00
lastArgs [ 0 ] = lastArgs [ 0 ] || args [ 0 ] ;
lastArgs [ 1 ] = lastArgs [ 1 ] || args [ 1 ] ;
lastArgs [ 2 ] = lastArgs [ 2 ] || args [ 2 ] ;
2012-08-04 13:53:57 -04:00
var self = this ;
( this . deferredTasks [ 'positionPinnedTabsWithDelay' ] = this . Deferred . wait ( 0 ) . next ( function ( ) {
return self . Deferred . next ( function ( ) {
2011-03-18 17:06:04 -04:00
// do with delay again, after Firefox's reposition was completely finished.
2012-08-04 13:53:57 -04:00
self . positionPinnedTabs . apply ( self , lastArgs ) ;
} ) ;
} ) ) . error ( this . defaultDeferredErrorHandler ) . next ( function ( ) {
delete self . deferredTasks [ 'positionPinnedTabsWithDelay' ] ;
} ) ;
this . deferredTasks [ 'positionPinnedTabsWithDelay' ] . _ _treestyletab _ _args = lastArgs ;
2010-12-06 23:46:38 -05:00
} ,
2010-06-25 12:14:49 -04:00
2010-09-09 06:03:03 -04:00
resetPinnedTabs : function TSTBrowser _resetPinnedTabs ( )
2010-06-25 12:14:49 -04:00
{
var b = this . mTabBrowser ;
var tabbar = b . tabContainer ;
2010-09-09 06:03:03 -04:00
tabbar . style . MozMarginStart = tabbar . style . marginTop = '' ;
for ( var i = 0 , count = this . pinnedTabsCount ; i < count ; i ++ )
2010-06-25 12:14:49 -04:00
{
let style = tabbar . childNodes [ i ] . style ;
2011-11-29 15:33:47 -05:00
style . maxWidth = style . width = style . left = style . right =
2011-10-24 06:54:16 -04:00
style . MozMarginStart = style . marginLeft = style . marginRight = style . marginTop = '' ;
2010-06-25 12:14:49 -04:00
}
} ,
2010-11-24 18:37:26 -05:00
updateTabsZIndex : function TSTBrowser _updateTabsZIndex ( aStacked )
2010-11-24 11:14:36 -05:00
{
2012-09-23 02:43:49 -04:00
var tabs = this . getTabs ( this . mTabBrowser ) ;
2010-11-24 11:14:36 -05:00
var count = tabs . length ;
2012-02-04 16:31:03 -05:00
for ( let i = 0 ; i < count ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
let tab = tabs [ i ] ;
2012-02-04 13:15:38 -05:00
if ( aStacked )
2012-02-08 12:52:10 -05:00
tab . style . zIndex = count * 1000 - i ;
2012-02-04 13:15:38 -05:00
else
tab . style . zIndex = '' ;
}
2010-11-24 11:14:36 -05:00
} ,
2011-04-06 09:04:02 -04:00
2011-05-25 11:47:29 -04:00
fixTooNarrowTabbar : function TSTBrowser _fixTooNarrowTabbar ( )
2011-04-06 09:04:02 -04:00
{
/ * *
* The tab bar can become smaller than the actual size of the
* floating tab bar , and then , we cannot resize tab bar by
* dragging anymore . To avoid this problem , we have to enlarge
* the tab bar larger than the floating tab bar .
* /
if ( this . isVertical ) {
let key = this . autoHide . expanded ?
'tabbar.width' : 'tabbar.shrunkenWidth' ;
2012-10-23 12:43:56 -04:00
let width = utils . getTreePref ( key ) ;
2011-04-06 09:04:02 -04:00
let minWidth = this . scrollBox . boxObject . width
if ( minWidth > width ) {
this . setPrefForActiveWindow ( function ( ) {
2012-10-23 12:43:56 -04:00
utils . setTreePref ( key , minWidth ) ;
2011-04-06 09:04:02 -04:00
this . updateFloatingTabbar ( this . kTABBAR _UPDATE _BY _PREF _CHANGE ) ;
} ) ;
}
}
else {
2012-10-23 12:43:56 -04:00
let height = utils . getTreePref ( 'tabbar.height' ) ;
2011-04-06 09:04:02 -04:00
let minHeight = this . scrollBox . boxObject . height
if ( minHeight > height ) {
this . setPrefForActiveWindow ( function ( ) {
2012-10-23 12:43:56 -04:00
utils . setTreePref ( 'tabbar.height' , minHeight ) ;
2011-04-06 09:04:02 -04:00
this . updateFloatingTabbar ( this . kTABBAR _UPDATE _BY _PREF _CHANGE ) ;
} ) ;
}
}
} ,
2008-02-22 12:55:35 -05:00
2007-11-17 00:20:26 -05:00
/* initialize */
2008-12-01 03:30:36 -05:00
2009-12-25 03:34:52 -05:00
init : function TSTBrowser _init ( )
2007-11-14 14:34:36 -05:00
{
2010-02-03 08:43:39 -05:00
this . stopRendering ( ) ;
2011-05-25 17:23:02 -04:00
var w = this . window ;
2011-05-26 22:31:02 -04:00
var d = this . document ;
2007-11-17 00:20:26 -05:00
var b = this . mTabBrowser ;
2010-03-23 13:58:23 -04:00
b . tabContainer . treeStyleTab = this ;
2011-01-21 23:06:59 -05:00
2012-08-04 17:03:34 -04:00
this . tabsHash = { } ;
2011-01-21 10:01:19 -05:00
if ( b . tabContainer . parentNode . localName == 'toolbar' )
b . tabContainer . parentNode . classList . add ( this . kTABBAR _TOOLBAR ) ;
2007-11-14 14:34:36 -05:00
2011-12-19 05:20:14 -05:00
/ * *
* On secondary ( and later ) window , SSWindowStateBusy event can be fired
* before DOMContentLoad , on "domwindowopened" .
* /
this . needRestoreTree = w . _ _treestyletab _ _WindowStateBusy || false ;
delete w . _ _treestyletab _ _WindowStateBusy ;
2011-01-21 23:06:59 -05:00
this . _initTabbrowserExtraContents ( ) ;
2009-09-03 03:31:49 -04:00
2012-04-27 16:31:12 -04:00
var position = this . position ;
2010-11-30 05:05:00 -05:00
this . fireTabbarPositionEvent ( this . kEVENT _TYPE _TABBAR _POSITION _CHANGING , 'top' , position ) ; /* PUBLIC API */
2009-12-25 04:49:47 -05:00
2012-10-23 12:43:56 -04:00
this . setTabbrowserAttribute ( this . kFIXED + '-horizontal' , utils . getTreePref ( 'tabbar.fixed.horizontal' ) ? 'true' : null , b ) ;
this . setTabbrowserAttribute ( this . kFIXED + '-vertical' , utils . getTreePref ( 'tabbar.fixed.vertical' ) ? 'true' : null , b ) ;
2010-05-08 02:22:49 -04:00
2011-05-26 22:31:02 -04:00
/ * *
* < tabbrowser > has its custom background color for itself , but it
* prevents to make transparent background of the vertical tab bar .
2011-05-26 22:33:00 -04:00
* So , I re - define the background color of content area for
2011-05-26 22:31:02 -04:00
* < notificationbox > es via dynamically generated stylesheet .
* See :
* https : //bugzilla.mozilla.org/show_bug.cgi?id=558585
* http : //hg.mozilla.org/mozilla-central/rev/e90bdd97d168
* /
2012-01-13 11:30:06 -05:00
if ( b . style . backgroundColor ) {
2011-05-26 22:31:02 -04:00
let color = b . style . backgroundColor ;
let pi = d . createProcessingInstruction (
'xml-stylesheet' ,
'type="text/css" href="data:text/css,' + encodeURIComponent (
2012-10-12 13:24:02 -04:00
( '.tabbrowser-tabbox > tabpanels > notificationbox {\n' +
' background-color: %COLOR%;\n' +
2012-10-12 03:46:37 -04:00
'}' ) . replace ( /%COLOR%/ , color )
2011-05-26 22:31:02 -04:00
) + '"'
) ;
d . insertBefore ( pi , d . documentElement ) ;
b . style . backgroundColor = '' ;
}
2010-05-08 01:37:41 -04:00
this . initTabbar ( null , this . kTABBAR _TOP ) ;
2007-11-14 14:34:36 -05:00
2011-05-25 17:23:02 -04:00
w . addEventListener ( 'resize' , this , true ) ;
w . addEventListener ( 'beforecustomization' , this , true ) ;
w . addEventListener ( 'aftercustomization' , this , false ) ;
w . addEventListener ( 'customizationchange' , this , false ) ;
w . addEventListener ( this . kEVENT _TYPE _PRINT _PREVIEW _ENTERED , this , false ) ;
w . addEventListener ( this . kEVENT _TYPE _PRINT _PREVIEW _EXITED , this , false ) ;
2012-01-01 15:18:14 -05:00
w . addEventListener ( 'tabviewframeinitialized' , this , false ) ;
2011-11-29 06:36:49 -05:00
w . addEventListener ( this . kEVENT _TYPE _TAB _FOCUS _SWITCHING _END , this , false ) ;
2011-12-13 02:10:49 -05:00
w . addEventListener ( 'SSWindowStateBusy' , this , false ) ;
2010-03-28 14:22:15 -04:00
2010-12-20 07:04:21 -05:00
b . addEventListener ( 'nsDOMMultipleTabHandlerTabsClosing' , this , false ) ;
2009-12-25 22:26:40 -05:00
2011-05-25 17:23:02 -04:00
w [ 'piro.sakura.ne.jp' ] . tabsDragUtils . initTabBrowser ( b ) ;
2010-11-29 22:23:08 -05:00
2011-05-25 17:23:02 -04:00
w . TreeStyleTabWindowHelper . initTabbrowserMethods ( b ) ;
2011-01-21 23:06:59 -05:00
this . _initTabbrowserContextMenu ( ) ;
2011-05-25 17:23:02 -04:00
w . TreeStyleTabWindowHelper . updateTabDNDObserver ( b ) ;
2010-03-25 13:36:27 -04:00
2012-09-23 02:43:49 -04:00
this . getAllTabs ( b ) . forEach ( this . initTab , this ) ;
2007-11-14 14:34:36 -05:00
2011-01-21 23:06:59 -05:00
this . onPrefChange ( 'extensions.treestyletab.maxTreeLevel' ) ;
this . onPrefChange ( 'extensions.treestyletab.tabbar.style' ) ;
this . onPrefChange ( 'extensions.treestyletab.twisty.style' ) ;
this . onPrefChange ( 'extensions.treestyletab.showBorderForFirstTab' ) ;
this . onPrefChange ( 'extensions.treestyletab.tabbar.invertTabContents' ) ;
this . onPrefChange ( 'extensions.treestyletab.tabbar.invertClosebox' ) ;
this . onPrefChange ( 'extensions.treestyletab.tabbar.autoShow.mousemove' ) ;
2011-03-24 23:12:33 -04:00
this . onPrefChange ( 'extensions.treestyletab.tabbar.invertScrollbar' ) ;
2011-03-24 22:42:50 -04:00
this . onPrefChange ( 'extensions.treestyletab.tabbar.narrowScrollbar' ) ;
2011-01-21 23:06:59 -05:00
this . onPrefChange ( 'extensions.treestyletab.animation.enabled' ) ;
2007-11-14 14:34:36 -05:00
2012-09-17 11:31:48 -04:00
Services . obs . addObserver ( this , this . kTOPIC _INDENT _MODIFIED , false ) ;
Services . obs . addObserver ( this , this . kTOPIC _COLLAPSE _EXPAND _ALL , false ) ;
Services . obs . addObserver ( this , this . kTOPIC _CHANGE _TREEVIEW _AVAILABILITY , false ) ;
Services . obs . addObserver ( this , 'private-browsing-change-granted' , false ) ;
Services . obs . addObserver ( this , 'lightweight-theme-styling-update' , false ) ;
2011-01-21 23:06:59 -05:00
this . addPrefListener ( this ) ;
2007-11-14 14:34:36 -05:00
2011-05-25 11:47:29 -04:00
// Don't init these ovservers on this point to avoid needless initializations.
// this.tabbarDNDObserver;
// this.panelDNDObserver;
this . _readyToInitDNDObservers ( ) ;
// Init autohide service only if it have to be activated.
2011-05-25 11:52:28 -04:00
if ( this . isAutoHide )
2011-05-25 11:47:29 -04:00
this . autoHide ;
2011-01-21 23:06:59 -05:00
this . updateFloatingTabbar ( this . kTABBAR _UPDATE _BY _INITIALIZE ) ;
2011-04-06 09:04:02 -04:00
this . fixTooNarrowTabbar ( ) ;
2011-01-21 23:06:59 -05:00
this . fireTabbarPositionEvent ( false , 'top' , position ) ; /* PUBLIC API */
this . startRendering ( ) ;
2012-04-27 16:31:12 -04:00
2012-08-04 13:53:57 -04:00
if ( this . deferredTasks [ 'init' ] )
this . deferredTasks [ 'init' ] . cancel ( ) ;
2012-04-27 16:31:12 -04:00
var self = this ;
2012-08-04 13:53:57 -04:00
( this . deferredTasks [ 'init' ] = this . Deferred . next ( function ( ) {
2012-04-27 16:31:12 -04:00
// On Firefox 12 and later, this command is always enabled
// and the TabsOnTop can be enabled by <tabbrowser>.updateVisibility().
// So we have to reset TabsOnTop state on the startup.
var toggleTabsOnTop = d . getElementById ( 'cmd_ToggleTabsOnTop' ) ;
var TabsOnTop = 'TabsOnTop' in w ? w . TabsOnTop : null ;
if ( TabsOnTop && TabsOnTop . syncUI && toggleTabsOnTop && self . isVertical ) {
toggleTabsOnTop . setAttribute ( 'disabled' , true ) ;
if ( TabsOnTop . enabled && TabsOnTop . toggle )
TabsOnTop . toggle ( ) ;
}
2012-08-04 13:53:57 -04:00
} ) ) . error ( this . defaultDeferredErrorHandler ) . next ( function ( ) {
delete self . deferredTasks [ 'init' ] ;
2012-04-27 16:31:12 -04:00
} ) ;
2011-01-21 23:06:59 -05:00
} ,
_initTabbrowserExtraContents : function TSTBrowser _initTabbrowserExtraContents ( )
{
2011-05-25 17:23:02 -04:00
var d = this . document ;
2011-01-21 23:06:59 -05:00
var b = this . mTabBrowser ;
2011-05-25 17:23:02 -04:00
var toggler = d . getAnonymousElementByAttribute ( b , 'class' , this . kTABBAR _TOGGLER ) ;
2011-01-21 23:06:59 -05:00
if ( ! toggler ) {
2011-05-25 17:23:02 -04:00
toggler = d . createElement ( 'spacer' ) ;
2011-01-21 23:06:59 -05:00
toggler . setAttribute ( 'class' , this . kTABBAR _TOGGLER ) ;
toggler . setAttribute ( 'layer' , true ) ; // https://bugzilla.mozilla.org/show_bug.cgi?id=590468
b . mTabBox . insertBefore ( toggler , b . mTabBox . firstChild ) ;
if ( b . mTabDropIndicatorBar == toggler )
2011-05-25 17:23:02 -04:00
b . mTabDropIndicatorBar = d . getAnonymousElementByAttribute ( b , 'class' , 'tab-drop-indicator-bar' ) ;
2010-03-23 13:58:23 -04:00
}
2011-01-21 23:06:59 -05:00
2011-05-25 17:23:02 -04:00
var placeHolder = d . getAnonymousElementByAttribute ( b , 'anonid' , 'strip' ) ;
2011-01-21 23:06:59 -05:00
if ( ! placeHolder ) {
2011-05-25 17:23:02 -04:00
placeHolder = d . createElement ( 'hbox' ) ;
2011-01-21 23:06:59 -05:00
placeHolder . setAttribute ( 'anonid' , 'strip' ) ;
placeHolder . setAttribute ( 'class' , 'tabbrowser-strip ' + this . kTABBAR _PLACEHOLDER ) ;
placeHolder . setAttribute ( 'layer' , true ) ; // https://bugzilla.mozilla.org/show_bug.cgi?id=590468
b . mTabBox . insertBefore ( placeHolder , toggler . nextSibling ) ;
2010-03-23 13:58:23 -04:00
}
2011-01-21 23:06:59 -05:00
this . tabStripPlaceHolder = ( placeHolder != this . tabStrip ) ? placeHolder : null ;
} ,
_initTabbrowserContextMenu : function TSTBrowser _initTabbrowserContextMenu ( )
{
2011-05-25 17:23:02 -04:00
var w = this . window ;
var d = this . document ;
2011-01-21 23:06:59 -05:00
var b = this . mTabBrowser ;
2009-05-13 02:09:17 -04:00
2010-03-25 20:20:51 -04:00
var tabContextMenu = b . tabContextMenu ||
2011-05-25 17:23:02 -04:00
d . getAnonymousElementByAttribute ( b , 'anonid' , 'tabContextMenu' ) ;
2009-07-08 06:40:51 -04:00
tabContextMenu . addEventListener ( 'popupshowing' , this , false ) ;
2011-05-25 17:23:02 -04:00
if ( ! ( 'MultipleTabService' in w ) ) {
w . setTimeout ( function ( aSelf , aTabBrowser , aPopup ) {
2009-07-08 06:40:51 -04:00
let suffix = '-tabbrowser-' + ( aTabBrowser . id || 'instance-' + parseInt ( Math . random ( ) * 65000 ) ) ;
2012-02-04 16:31:03 -05:00
let ids = [
2012-02-04 13:15:38 -05:00
aSelf . kMENUITEM _RELOADSUBTREE ,
aSelf . kMENUITEM _RELOADCHILDREN ,
aSelf . kMENUITEM _REMOVESUBTREE ,
aSelf . kMENUITEM _REMOVECHILDREN ,
aSelf . kMENUITEM _REMOVEALLTABSBUT ,
aSelf . kMENUITEM _COLLAPSEEXPAND _SEPARATOR ,
aSelf . kMENUITEM _COLLAPSE ,
aSelf . kMENUITEM _EXPAND ,
aSelf . kMENUITEM _AUTOHIDE _SEPARATOR ,
aSelf . kMENUITEM _AUTOHIDE ,
aSelf . kMENUITEM _FIXED ,
aSelf . kMENUITEM _BOOKMARKSUBTREE
2012-02-04 16:31:03 -05:00
] ;
for ( let i = 0 , maxi = ids . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
let id = ids [ i ] ;
2012-02-04 13:15:38 -05:00
let item = d . getElementById ( id ) . cloneNode ( true ) ;
2009-07-08 06:40:51 -04:00
item . setAttribute ( 'id' , item . getAttribute ( 'id' ) + suffix ) ;
let refNode = void ( 0 ) ;
let insertAfter = item . getAttribute ( 'multipletab-insertafter' ) ;
if ( insertAfter ) {
try {
eval ( 'refNode = (' + insertAfter + ').nextSibling' ) ;
2009-05-12 12:56:39 -04:00
}
2009-07-08 06:40:51 -04:00
catch ( e ) {
2009-05-12 12:56:39 -04:00
}
2009-07-08 06:40:51 -04:00
}
let insertBefore = item . getAttribute ( 'multipletab-insertbefore' ) ;
if ( refNode === void ( 0 ) && insertBefore ) {
try {
eval ( 'refNode = ' + insertBefore ) ;
}
catch ( e ) {
}
}
aPopup . insertBefore ( item , refNode || null ) ;
2012-02-04 13:15:38 -05:00
}
2009-07-06 05:21:06 -04:00
tabContextMenu = null ;
2009-07-08 06:40:51 -04:00
} , 0 , this , b , tabContextMenu ) ;
2009-05-12 12:56:39 -04:00
}
2007-11-17 00:20:26 -05:00
2011-05-25 17:23:02 -04:00
var removeTabItem = d . getAnonymousElementByAttribute ( b , 'id' , 'context_closeTab' ) ;
2011-01-21 23:06:59 -05:00
if ( removeTabItem ) {
removeTabItem . setAttribute (
'oncommand' ,
removeTabItem . getAttribute ( 'oncommand' ) . replace (
/(tabbrowser\.removeTab\(([^\)]+)\))/ ,
'if (tabbrowser.treeStyleTab.warnAboutClosingTabSubtreeOf($2)) $1'
)
) ;
2009-12-18 01:08:42 -05:00
}
2007-11-14 14:34:36 -05:00
} ,
2011-01-21 23:06:59 -05:00
2011-11-30 12:59:46 -05:00
_initTooltipManager : function TSTBrowser _initTooltipManager ( )
{
if ( this . tooltipManager )
return ;
2012-11-11 08:48:42 -05:00
this . tooltipManager = new FullTooltipManager ( this ) ;
2011-11-30 12:59:46 -05:00
} ,
2011-05-25 11:47:29 -04:00
_readyToInitDNDObservers : function TSTBrowser _readyToInitDNDObservers ( )
{
2011-05-25 17:23:02 -04:00
var w = this . window ;
2011-05-25 11:47:29 -04:00
this . _DNDObserversInitialized = false ;
2011-05-25 17:23:02 -04:00
w . addEventListener ( 'mouseover' , this , true ) ;
w . addEventListener ( 'dragover' , this , true ) ;
2011-05-25 11:47:29 -04:00
} ,
_initDNDObservers : function TSTBrowser _initDNDObservers ( )
{
if ( this . _DNDObserversInitialized )
return ;
this . tabbarDNDObserver ;
this . panelDNDObserver ;
2011-05-25 17:23:02 -04:00
var w = this . window ;
2011-12-16 10:50:30 -05:00
w . removeEventListener ( 'mouseover' , this , true ) ;
w . removeEventListener ( 'dragover' , this , true ) ;
2011-05-25 11:47:29 -04:00
this . _DNDObserversInitialized = true ;
} ,
2009-12-25 03:34:52 -05:00
initTab : function TSTBrowser _initTab ( aTab )
2007-11-14 14:34:36 -05:00
{
2012-08-04 13:53:57 -04:00
if ( ! aTab . parentNode ) return ; // do nothing for closed tab!
2007-11-17 00:20:26 -05:00
if ( ! aTab . hasAttribute ( this . kID ) ) {
2011-05-25 16:54:46 -04:00
let id = this . getTabValue ( aTab , this . kID ) || this . makeNewId ( ) ;
2009-09-29 10:31:02 -04:00
aTab . setAttribute ( this . kID , id ) ;
2012-09-23 04:19:09 -04:00
aTab . setAttribute ( this . kID _NEW , id ) ;
2009-09-29 13:07:02 -04:00
aTab . setAttribute ( this . kSUBTREE _COLLAPSED , true ) ;
2010-11-30 02:45:03 -05:00
aTab . setAttribute ( this . kALLOW _COLLAPSE , true ) ;
2011-05-25 16:54:46 -04:00
let self = this ;
2012-08-04 13:53:57 -04:00
let key = 'initTab_' + id ;
if ( this . deferredTasks [ key ] )
this . deferredTasks [ key ] . cancel ( ) ;
( this . deferredTasks [ key ] = this . Deferred . next ( function ( ) {
2011-12-12 13:54:43 -05:00
// changed by someone!
2011-12-13 23:41:26 -05:00
if ( aTab . getAttribute ( self . kID ) != id )
2011-12-12 13:54:43 -05:00
return ;
2012-09-23 04:19:09 -04:00
aTab . removeAttribute ( this . kID _NEW ) ;
2011-05-25 16:54:46 -04:00
if ( ! self . getTabValue ( aTab , self . kID ) ) {
self . setTabValue ( aTab , self . kID , id ) ;
if ( ! ( id in self . tabsHash ) )
self . tabsHash [ id ] = aTab ;
2010-03-03 08:30:49 -05:00
}
2012-08-04 13:53:57 -04:00
} ) ) . error ( this . defaultDeferredErrorHandler ) . next ( function ( ) {
delete self . deferredTasks [ key ] ;
} ) ;
2010-03-24 11:38:08 -04:00
if ( ! ( id in this . tabsHash ) )
this . tabsHash [ id ] = aTab ;
2007-11-17 00:20:26 -05:00
}
2012-08-04 18:08:04 -04:00
else {
// if the tab is restored from session, it can be not-cached.
let id = aTab . getAttribute ( this . kID ) ;
if ( ! ( id in this . tabsHash ) )
this . tabsHash [ id ] = aTab ;
}
2007-11-17 00:20:26 -05:00
aTab . _ _treestyletab _ _linkedTabBrowser = this . mTabBrowser ;
2011-12-13 06:41:42 -05:00
/ * *
2012-08-05 09:38:06 -04:00
* XXX dirty hack ! ! ! there is no way to know when the tab is readied to be restored ...
2011-12-13 06:41:42 -05:00
* /
2012-08-05 09:38:06 -04:00
if ( ! aTab . linkedBrowser . _ _treestyletab _ _toBeRestored )
aTab . linkedBrowser . _ _treestyletab _ _toBeRestored = ! ! aTab . linkedBrowser . _ _SS _restoreState ;
2011-12-13 06:41:42 -05:00
var b = aTab . linkedBrowser ;
if ( ! b . _ _treestyletab _ _stop ) {
b . _ _treestyletab _ _stop = b . stop ;
b . stop = function TSTBrowser _stopHook ( ) {
try {
var stack = Components . stack ;
while ( stack )
{
2012-08-05 09:38:06 -04:00
if ( stack . name == 'sss_restoreHistoryPrecursor' ||
stack . name == 'ssi_restoreHistoryPrecursor' ) {
2011-12-13 08:59:45 -05:00
this . _ _treestyletab _ _toBeRestored = true ;
2011-12-13 06:41:42 -05:00
break ;
}
stack = stack . caller ;
}
}
catch ( e ) {
2011-12-13 09:00:44 -05:00
dump ( e + '\n' + e . stack + '\n' ) ;
2011-12-13 06:41:42 -05:00
}
return this . _ _treestyletab _ _stop . apply ( this , arguments ) ;
} ;
}
2007-11-17 00:20:26 -05:00
this . initTabAttributes ( aTab ) ;
this . initTabContents ( aTab ) ;
2011-12-05 05:31:12 -05:00
if ( ! aTab . hasAttribute ( this . kNEST ) )
2011-12-06 22:06:05 -05:00
aTab . setAttribute ( this . kNEST , 0 ) ;
2007-11-14 14:34:36 -05:00
} ,
2011-12-13 09:21:31 -05:00
isTabInitialized : function TSTBrowser _isTabInitialized ( aTab )
2009-12-25 04:15:25 -05:00
{
return aTab . getAttribute ( this . kID ) ;
} ,
2011-12-13 09:21:31 -05:00
ensureTabInitialized : function TSTBrowser _ensureTabInitialized ( aTab )
2009-03-31 14:25:49 -04:00
{
2009-12-25 04:15:25 -05:00
if ( ! aTab || this . isTabInitialized ( aTab ) ) return ;
2009-03-31 14:25:49 -04:00
this . initTab ( aTab ) ;
} ,
2011-12-13 09:21:31 -05:00
2009-12-25 03:34:52 -05:00
initTabAttributes : function TSTBrowser _initTabAttributes ( aTab )
2007-11-14 14:34:36 -05:00
{
2012-08-04 13:53:57 -04:00
if ( ! aTab . parentNode ) return ; // do nothing for closed tab!
2011-01-22 10:46:29 -05:00
var pos = this . position ;
2007-11-17 00:20:26 -05:00
if ( pos == 'left' || pos == 'right' ) {
aTab . setAttribute ( 'align' , 'stretch' ) ;
aTab . removeAttribute ( 'maxwidth' ) ;
aTab . removeAttribute ( 'minwidth' ) ;
aTab . removeAttribute ( 'width' ) ;
aTab . removeAttribute ( 'flex' ) ;
aTab . maxWidth = 65000 ;
aTab . minWidth = 0 ;
2012-10-23 12:43:56 -04:00
if ( utils . getTreePref ( 'compatibility.TMP' ) )
2009-12-15 03:33:03 -05:00
aTab . setAttribute ( 'dir' , 'ltr' ) ; // Tab Mix Plus
2007-11-17 00:20:26 -05:00
}
else {
aTab . removeAttribute ( 'align' ) ;
2010-11-26 00:03:09 -05:00
aTab . removeAttribute ( 'maxwidth' ) ;
aTab . removeAttribute ( 'minwidth' ) ;
2012-10-23 12:43:56 -04:00
if ( utils . getTreePref ( 'compatibility.TMP' ) )
2009-12-15 03:33:03 -05:00
aTab . removeAttribute ( 'dir' ) ; // Tab Mix Plus
2007-11-14 14:34:36 -05:00
}
} ,
2007-11-17 00:20:26 -05:00
2012-02-03 12:33:49 -05:00
initTabContents : function TSTBrowser _initTabContents ( aTab )
2007-11-14 14:34:36 -05:00
{
2012-08-04 13:53:57 -04:00
if ( ! aTab . parentNode ) return ; // do nothing for closed tab!
2011-05-25 17:23:02 -04:00
var d = this . document ;
2011-05-25 16:54:46 -04:00
2012-02-04 06:28:30 -05:00
var twisty = this . getTabTwisty ( aTab ) ;
var anchor = this . getTabTwistyAnchorNode ( aTab ) ;
if ( anchor && ! twisty ) {
2012-02-02 15:27:57 -05:00
twisty = d . createElement ( 'image' ) ;
twisty . setAttribute ( 'class' , this . kTWISTY ) ;
2012-02-04 06:28:30 -05:00
anchor . parentNode . appendChild ( twisty ) ;
2007-11-14 14:34:36 -05:00
}
2010-09-15 00:51:50 -04:00
var label = this . getTabLabel ( aTab ) ;
2011-05-25 17:23:02 -04:00
var counter = d . getAnonymousElementByAttribute ( aTab , 'class' , this . kCOUNTER _CONTAINER ) ;
2012-02-02 15:27:57 -05:00
if ( label && ! counter ) {
2011-05-25 17:23:02 -04:00
counter = d . createElement ( 'hbox' ) ;
2007-11-17 00:20:26 -05:00
counter . setAttribute ( 'class' , this . kCOUNTER _CONTAINER ) ;
2011-05-25 17:23:02 -04:00
let startParen = counter . appendChild ( d . createElement ( 'label' ) ) ;
2010-09-15 00:51:50 -04:00
startParen . setAttribute ( 'class' , this . kCOUNTER _PAREN ) ;
startParen . setAttribute ( 'value' , '(' ) ;
2010-01-31 23:06:09 -05:00
2011-05-25 17:23:02 -04:00
let counterLabel = counter . appendChild ( d . createElement ( 'label' ) ) ;
2010-09-15 00:51:50 -04:00
counterLabel . setAttribute ( 'class' , this . kCOUNTER ) ;
counterLabel . setAttribute ( 'value' , '0' ) ;
2010-01-31 23:06:09 -05:00
2011-05-25 17:23:02 -04:00
let endParen = counter . appendChild ( d . createElement ( 'label' ) ) ;
2010-09-15 00:51:50 -04:00
endParen . setAttribute ( 'class' , this . kCOUNTER _PAREN ) ;
endParen . setAttribute ( 'value' , ')' ) ;
2007-11-17 00:20:26 -05:00
2011-03-18 16:00:39 -04:00
/ * * X X X
* Insertion before an anonymous element breaks its "xbl:inherits" .
* For example , "xbl:inherits" of the closebox in a tab ( Tab Mix Plus
* defines it ) doesn 't work. So, I don' t use insertBefore ( ) .
* Instead , the counter will be rearranged by "ordinal" attribute
* given by initTabContentsOrder ( ) .
* /
// label.parentNode.insertBefore(counter, label.nextSibling);
label . parentNode . appendChild ( counter ) ;
2007-11-14 14:34:36 -05:00
}
2010-09-15 00:51:50 -04:00
2012-02-03 12:33:49 -05:00
this . initTabContentsOrder ( aTab , true ) ;
2007-11-14 14:34:36 -05:00
} ,
2012-02-02 15:27:57 -05:00
initTabContentsOrder : function TSTBrowser _initTabContentsOrder ( aTab , aForce )
2007-11-14 14:34:36 -05:00
{
2012-08-04 13:53:57 -04:00
if ( ! aTab . parentNode ) return ; // do nothing for closed tab!
2011-05-25 17:23:02 -04:00
var d = this . document ;
2011-05-25 16:54:46 -04:00
2012-02-04 06:28:30 -05:00
var namedNodes = {
label : this . getTabLabel ( aTab ) ,
close : this . getTabClosebox ( aTab ) ,
twistyAnchor : this . getTabTwistyAnchorNode ( aTab ) ,
twisty : this . getTabTwisty ( aTab ) ,
counter : d . getAnonymousElementByAttribute ( aTab , 'class' , this . kCOUNTER _CONTAINER )
} ;
2012-02-02 15:27:57 -05:00
2012-02-04 06:28:30 -05:00
namedNodes . closeAnchor = namedNodes . label ;
if ( namedNodes . closeAnchor . parentNode != namedNodes . close . parentNode ) {
let containerFinder = d . createRange ( ) ;
containerFinder . selectNode ( namedNodes . closeAnchor ) ;
containerFinder . setEndAfter ( namedNodes . close ) ;
let container = containerFinder . getCommonAncestor ( ) ;
while ( namedNodes . closeAnchor . parentNode != container )
{
namedNodes . closeAnchor = namedNodes . closeAnchor . parentNode ;
}
while ( namedNodes . close . parentNode != container )
{
namedNodes . close = namedNodes . close . parentNode ;
}
}
2009-04-28 00:11:22 -04:00
2012-02-04 06:28:30 -05:00
namedNodes . counterAnchor = namedNodes . label ;
2009-05-12 11:09:49 -04:00
2012-02-04 06:28:30 -05:00
var foundContainers = [ ] ;
2012-02-04 16:31:03 -05:00
var containers = [
2012-02-04 06:28:30 -05:00
namedNodes . twistyAnchor . parentNode ,
namedNodes . label . parentNode ,
namedNodes . counter . parentNode ,
namedNodes . closeAnchor . parentNode
2012-02-04 16:31:03 -05:00
] ;
for ( let i = 0 , maxi = containers . length ; i < maxi ; i ++ )
2012-02-04 06:28:30 -05:00
{
2012-02-04 16:31:03 -05:00
let container = containers [ i ] ;
2012-02-04 06:28:30 -05:00
if ( foundContainers . indexOf ( container ) > - 1 )
2012-02-04 13:15:38 -05:00
continue ;
2012-02-04 06:28:30 -05:00
this . initTabContentsOrderInternal ( container , namedNodes , aForce ) ;
foundContainers . push ( container ) ;
}
} ,
initTabContentsOrderInternal : function TSTBrowser _initTabContentsOrderInternal ( aContainer , aNamedNodes , aForce )
{
2012-02-04 11:02:02 -05:00
if ( this . window . getComputedStyle ( aContainer , '' ) . getPropertyValue ( '-moz-box-orient' ) == 'vertical' )
return ;
2012-02-04 06:28:30 -05:00
var nodes = Array . slice ( this . document . getAnonymousNodes ( aContainer ) || aContainer . childNodes ) ;
// reset order at first!
2012-02-04 16:31:03 -05:00
for ( let i = 0 , maxi = nodes . length ; i < maxi ; i ++ )
2012-02-04 06:28:30 -05:00
{
2012-02-04 16:31:03 -05:00
let node = nodes [ i ] ;
2012-02-04 06:28:30 -05:00
if ( node . getAttribute ( 'class' ) == 'informationaltab-thumbnail-container' )
continue ;
node . setAttribute ( 'ordinal' , i ) ;
}
2009-05-12 11:09:49 -04:00
2012-02-02 15:27:57 -05:00
// after that, rearrange contents
2012-02-04 06:28:30 -05:00
var index = nodes . indexOf ( aNamedNodes . close ) ;
if ( index > - 1 ) {
nodes . splice ( index , 1 ) ;
if ( this . mTabBrowser . getAttribute ( this . kCLOSEBOX _INVERTED ) == 'true' )
nodes . splice ( nodes . indexOf ( aNamedNodes . closeAnchor ) , 0 , aNamedNodes . close ) ;
else
nodes . splice ( nodes . indexOf ( aNamedNodes . closeAnchor ) + 1 , 0 , aNamedNodes . close ) ;
}
index = nodes . indexOf ( aNamedNodes . twisty ) ;
if ( index > - 1 ) {
nodes . splice ( index , 1 ) ;
nodes . splice ( nodes . indexOf ( aNamedNodes . twistyAnchor ) , 0 , aNamedNodes . twisty ) ;
2009-04-28 00:11:22 -04:00
}
2007-11-14 14:34:36 -05:00
2012-02-02 15:27:57 -05:00
if ( this . mTabBrowser . getAttribute ( this . kTAB _CONTENTS _INVERTED ) == 'true' )
2010-09-15 00:51:50 -04:00
nodes . reverse ( ) ;
2012-02-04 06:28:30 -05:00
// counter must rightside of the label!
index = nodes . indexOf ( aNamedNodes . counter ) ;
if ( index > - 1 ) {
nodes . splice ( index , 1 ) ;
nodes . splice ( nodes . indexOf ( aNamedNodes . counterAnchor ) + 1 , 0 , aNamedNodes . counter ) ;
2010-09-15 00:51:50 -04:00
}
2012-02-02 15:27:57 -05:00
var count = nodes . length ;
2012-02-04 06:28:30 -05:00
nodes . reverse ( ) ;
2012-02-04 16:31:03 -05:00
for ( let i = 0 , maxi = nodes . length ; i < maxi ; i ++ )
2012-02-04 06:28:30 -05:00
{
2012-02-04 16:31:03 -05:00
let node = nodes [ i ] ;
2012-02-04 06:28:30 -05:00
if ( node . getAttribute ( 'class' ) == 'informationaltab-thumbnail-container' )
continue ;
node . setAttribute ( 'ordinal' , ( count - i + 1 ) * 100 ) ;
}
2012-02-02 15:27:57 -05:00
if ( aForce ) {
/ * *
* After the order of contents are changed dynamically ,
* Gecko doesn ' t re - render them in the new order .
* Changing of "display" or "position" can fix this problem .
* /
2012-02-06 21:46:14 -05:00
let shouldHideTemporaryState = (
'TabmixTabbar' in this . window || // Tab Mix Plus
'InformationalTabService' in this . window // Informational Tab
) ;
2012-02-04 16:31:03 -05:00
for ( let i = 0 , maxi = nodes . length ; i < maxi ; i ++ )
2012-02-04 06:28:30 -05:00
{
2012-02-04 16:31:03 -05:00
let node = nodes [ i ] ;
2012-02-06 21:46:14 -05:00
if ( shouldHideTemporaryState )
node . style . visibility = 'hidden' ;
2012-02-04 06:28:30 -05:00
node . style . position = 'fixed' ;
}
2012-08-04 13:53:57 -04:00
let key = 'initTabContentsOrderInternal_' + parseInt ( Math . random ( ) * 65000 ) ;
( this . deferredTasks [ key ] = this . Deferred . wait ( 0.1 ) . next ( function ( ) {
2012-02-04 16:31:03 -05:00
for ( let i = 0 , maxi = nodes . length ; i < maxi ; i ++ )
2012-02-04 06:28:30 -05:00
{
2012-02-04 16:31:03 -05:00
let node = nodes [ i ] ;
2012-02-04 06:28:30 -05:00
node . style . position = '' ;
2012-02-06 21:46:14 -05:00
if ( shouldHideTemporaryState )
node . style . visibility = '' ;
2012-02-04 06:28:30 -05:00
}
2012-08-04 13:53:57 -04:00
} ) ) . error ( this . defaultDeferredErrorHandler ) . next ( function ( ) {
delete self . deferredTasks [ key ] ;
} ) ;
2012-02-02 15:27:57 -05:00
}
2007-11-14 14:34:36 -05:00
} ,
2008-03-03 04:21:33 -05:00
2010-12-06 11:11:34 -05:00
updateInvertedTabContentsOrder : function TSTBrowser _updateInvertedTabContentsOrder ( aTarget )
2008-03-03 04:21:33 -05:00
{
2011-05-25 16:54:46 -04:00
var self = this ;
2012-08-04 13:53:57 -04:00
let key = 'updateInvertedTabContentsOrder_' + parseInt ( Math . random ( ) * 65000 ) ;
( this . deferredTasks [ key ] = this . Deferred . next ( function ( ) {
2011-05-25 16:54:46 -04:00
var b = self . mTabBrowser ;
2010-12-06 11:11:34 -05:00
var tabs = ! aTarget ?
[ b . selectedTab ] :
( aTarget instanceof Ci . nsIDOMElement ) ?
[ aTarget ] :
( typeof aTarget == 'object' && 'length' in aTarget ) ?
Array . slice ( aTarget ) :
2012-09-23 02:43:49 -04:00
self . getAllTabs ( b ) ;
2012-02-04 16:31:03 -05:00
for ( let i = 0 , maxi = tabs . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-06 12:15:15 -05:00
self . initTabContentsOrder ( tabs [ i ] ) ;
2012-02-04 13:15:38 -05:00
}
2012-08-04 13:53:57 -04:00
} ) ) . error ( this . defaultDeferredErrorHandler ) . next ( function ( ) {
delete self . deferredTasks [ key ] ;
} ) ;
2008-03-03 04:21:33 -05:00
} ,
2008-03-08 03:57:17 -05:00
2010-05-08 01:37:41 -04:00
initTabbar : function TSTBrowser _initTabbar ( aNewPosition , aOldPosition )
2007-11-14 14:34:36 -05:00
{
2011-05-25 17:23:02 -04:00
var d = this . document ;
2011-05-25 16:54:46 -04:00
var b = this . mTabBrowser ;
2011-01-21 09:21:39 -05:00
if ( aNewPosition && typeof aNewPosition == 'string' )
aNewPosition = this . getPositionFlag ( aNewPosition ) ;
if ( aOldPosition && typeof aOldPosition == 'string' )
aOldPosition = this . getPositionFlag ( aOldPosition ) ;
2011-01-21 23:06:59 -05:00
this . _startListenTabbarEvents ( ) ;
2011-05-25 16:54:46 -04:00
this . window . TreeStyleTabWindowHelper . initTabbarMethods ( b ) ;
2011-01-21 23:06:59 -05:00
2009-12-21 00:45:07 -05:00
this . stopRendering ( ) ;
2011-01-22 10:46:29 -05:00
var pos = aNewPosition || this . getPositionFlag ( this . position ) ;
2008-10-17 11:47:45 -04:00
if ( b . getAttribute ( 'id' ) != 'content' &&
2012-10-23 12:43:56 -04:00
! utils . getTreePref ( 'tabbar.position.subbrowser.enabled' ) ) {
2010-02-03 08:43:39 -05:00
pos = this . kTABBAR _TOP ;
2007-11-14 14:34:36 -05:00
}
2010-02-03 08:43:39 -05:00
aOldPosition = aOldPosition || pos ;
// We have to use CSS property hack instead, because the stopRendering()
// doesn't effect on the first time of startup.
// * This hack works in a "stop"-"start" pair, so, people never see the side effect.
// * This hack works only when "ordinal" properties are modified.
// So, this is just for the case: "right" or "bottom" tab bar on the startup.
if (
pos != aOldPosition &&
(
( ( pos & this . kTABBAR _REGULAR ) && ( aOldPosition & this . kTABBAR _INVERTED ) ) ||
( ( pos & this . kTABBAR _INVERTED ) && ( aOldPosition & this . kTABBAR _REGULAR ) )
)
)
b . style . visibility = 'hidden' ;
2007-11-14 14:34:36 -05:00
2010-03-23 09:33:00 -04:00
var strip = this . tabStrip ;
2010-03-25 23:17:16 -04:00
var placeHolder = this . tabStripPlaceHolder || strip ;
2009-12-24 10:13:04 -05:00
var splitter = this . _ensureNewSplitter ( ) ;
2011-05-25 17:23:02 -04:00
var toggler = d . getAnonymousElementByAttribute ( b , 'class' , this . kTABBAR _TOGGLER ) ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
// Tab Mix Plus
2009-12-15 03:33:03 -05:00
var scrollFrame , newTabBox , tabBarMode ;
2012-10-23 12:43:56 -04:00
if ( utils . getTreePref ( 'compatibility.TMP' ) ) {
2011-05-25 17:23:02 -04:00
scrollFrame = d . getAnonymousElementByAttribute ( b . mTabContainer , 'class' , 'tabs-frame' ) ||
d . getAnonymousElementByAttribute ( b . mTabContainer , 'anonid' , 'scroll-tabs-frame' ) ;
newTabBox = d . getAnonymousElementByAttribute ( b . mTabContainer , 'id' , 'tabs-newbutton-box' ) ;
2011-05-25 22:14:15 -04:00
let newTabButton = d . getElementById ( 'new-tab-button' ) ;
2011-05-25 22:02:34 -04:00
if ( newTabButton && newTabButton . parentNode == b . tabContainer . _container )
newTabBox = newTabButton ;
2009-12-15 03:33:03 -05:00
tabBarMode = this . getPref ( 'extensions.tabmix.tabBarMode' ) ;
}
2007-11-14 14:34:36 -05:00
2008-03-03 01:00:59 -05:00
// All-in-One Sidebar
2011-05-25 17:23:02 -04:00
var toolboxContainer = d . getAnonymousElementByAttribute ( strip , 'anonid' , 'aiostbx-toolbox-tableft' ) ;
2008-03-03 01:00:59 -05:00
if ( toolboxContainer ) toolboxContainer = toolboxContainer . parentNode ;
2009-03-16 07:58:43 -04:00
var scrollInnerBox = b . mTabContainer . mTabstrip . _scrollbox ?
2011-05-25 17:23:02 -04:00
d . getAnonymousNodes ( b . mTabContainer . mTabstrip . _scrollbox ) [ 0 ] :
2009-03-16 07:58:43 -04:00
scrollFrame ; // Tab Mix Plus
2010-03-28 14:22:15 -04:00
this . removeTabbrowserAttribute ( this . kRESIZING , b ) ;
2007-11-14 14:34:36 -05:00
2010-03-25 23:17:16 -04:00
this . removeTabStripAttribute ( 'width' ) ;
2009-07-07 04:30:30 -04:00
b . mPanelContainer . removeAttribute ( 'width' ) ;
2009-07-07 21:41:37 -04:00
var delayedPostProcess ;
2007-11-17 00:20:26 -05:00
if ( pos & this . kTABBAR _VERTICAL ) {
2011-05-26 13:31:44 -04:00
this . collapseTarget = 'top' ;
this . screenPositionProp = 'screenY' ;
2012-08-29 16:28:03 -04:00
this . offsetProp = 'offsetY' ;
this . translateFunction = 'translateY' ;
2011-05-26 13:31:44 -04:00
this . sizeProp = 'height' ;
this . invertedScreenPositionProp = 'screenX' ;
this . invertedSizeProp = 'width' ;
this . startProp = 'top' ;
this . endProp = 'bottom' ;
2007-11-14 14:34:36 -05:00
2008-10-17 11:47:45 -04:00
b . mTabBox . orient = splitter . orient = 'horizontal' ;
2010-03-23 09:33:00 -04:00
strip . orient =
2010-03-25 23:17:16 -04:00
placeHolder . orient =
2009-03-30 12:36:54 -04:00
toggler . orient =
2007-11-17 00:20:26 -05:00
b . mTabContainer . orient =
b . mTabContainer . mTabstrip . orient =
b . mTabContainer . mTabstrip . parentNode . orient = 'vertical' ;
b . mTabContainer . setAttribute ( 'align' , 'stretch' ) ; // for Mac OS X
2009-12-15 03:58:29 -05:00
if ( scrollInnerBox )
scrollInnerBox . removeAttribute ( 'flex' ) ;
2007-11-14 14:34:36 -05:00
2012-10-23 12:43:56 -04:00
if ( utils . getTreePref ( 'compatibility.TMP' ) && scrollFrame ) { // Tab Mix Plus
2011-05-25 17:23:02 -04:00
d . getAnonymousNodes ( scrollFrame ) [ 0 ] . removeAttribute ( 'flex' ) ;
2007-11-17 00:20:26 -05:00
scrollFrame . parentNode . orient =
scrollFrame . orient = 'vertical' ;
2011-05-25 22:02:34 -04:00
if ( newTabBox )
newTabBox . orient = 'horizontal' ;
2007-11-17 00:20:26 -05:00
if ( tabBarMode == 2 )
this . setPref ( 'extensions.tabmix.tabBarMode' , 1 ) ;
2007-11-14 14:34:36 -05:00
}
2008-03-03 01:00:59 -05:00
if ( toolboxContainer )
toolboxContainer . orient = 'vertical' ;
2010-03-28 14:22:15 -04:00
this . setTabbrowserAttribute ( this . kMODE , 'vertical' ) ;
2009-07-07 11:56:38 -04:00
2012-10-23 12:43:56 -04:00
let width = this . maxTabbarWidth ( utils . getTreePref ( 'tabbar.width' ) , b ) ;
2010-04-22 04:12:31 -04:00
this . setTabStripAttribute ( 'width' , width ) ;
2010-03-25 23:17:16 -04:00
this . removeTabStripAttribute ( 'height' ) ;
2009-07-07 11:56:38 -04:00
b . mPanelContainer . removeAttribute ( 'height' ) ;
2007-11-14 14:34:36 -05:00
2011-03-14 12:23:30 -04:00
if ( strip . localName == 'toolbar' ) {
2012-02-04 16:31:03 -05:00
let nodes = strip . childNodes ;
for ( let i = 0 , maxi = nodes . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
let node = nodes [ i ] ;
2012-02-04 13:15:38 -05:00
if ( node . localName == 'tabs' )
continue ;
if ( node . hasAttribute ( 'flex' ) )
node . setAttribute ( 'treestyletab-backup-flex' , node . getAttribute ( 'flex' ) ) ;
node . removeAttribute ( 'flex' ) ;
}
2011-03-14 12:23:30 -04:00
}
2007-11-17 00:20:26 -05:00
if ( pos == this . kTABBAR _RIGHT ) {
2010-03-28 14:22:15 -04:00
this . setTabbrowserAttribute ( this . kTABBAR _POSITION , 'right' ) ;
2012-10-23 12:43:56 -04:00
if ( utils . getTreePref ( 'tabbar.invertTab' ) ) {
2010-03-28 14:22:15 -04:00
this . setTabbrowserAttribute ( this . kTAB _INVERTED , 'true' ) ;
2009-12-18 07:57:21 -05:00
this . indentTarget = 'right' ;
2007-11-17 00:20:26 -05:00
}
else {
2010-03-28 14:22:15 -04:00
this . removeTabbrowserAttribute ( this . kTAB _INVERTED ) ;
2009-12-18 07:57:21 -05:00
this . indentTarget = 'left' ;
2007-11-17 00:20:26 -05:00
}
2009-07-07 21:41:37 -04:00
delayedPostProcess = function ( aSelf , aTabBrowser , aSplitter , aToggler ) {
2007-11-17 00:20:26 -05:00
/ * i n F i r e f o x 3 , t h e w i d t h o f t h e r i g h t s i d e t a b b a r
unexpectedly becomes 0 on the startup . so , we have
to set the width again . * /
2010-04-22 04:12:31 -04:00
aSelf . setTabStripAttribute ( 'width' , width ) ;
2010-03-25 23:17:16 -04:00
aSelf . setTabStripAttribute ( 'ordinal' , 30 ) ;
2009-05-13 02:09:17 -04:00
aSplitter . setAttribute ( 'ordinal' , 20 ) ;
aToggler . setAttribute ( 'ordinal' , 40 ) ;
aTabBrowser . mPanelContainer . setAttribute ( 'ordinal' , 10 ) ;
aSplitter . setAttribute ( 'collapse' , 'after' ) ;
2009-07-07 21:41:37 -04:00
} ;
2007-11-14 14:34:36 -05:00
}
2007-11-17 00:20:26 -05:00
else {
2010-03-28 14:22:15 -04:00
this . setTabbrowserAttribute ( this . kTABBAR _POSITION , 'left' ) ;
this . removeTabbrowserAttribute ( this . kTAB _INVERTED ) ;
2009-12-18 07:57:21 -05:00
this . indentTarget = 'left' ;
2009-07-07 21:41:37 -04:00
delayedPostProcess = function ( aSelf , aTabBrowser , aSplitter , aToggler ) {
2010-03-25 23:17:16 -04:00
aSelf . setTabStripAttribute ( 'ordinal' , 10 ) ;
2009-05-13 02:09:17 -04:00
aSplitter . setAttribute ( 'ordinal' , 20 ) ;
aToggler . setAttribute ( 'ordinal' , 5 ) ;
aTabBrowser . mPanelContainer . setAttribute ( 'ordinal' , 30 ) ;
aSplitter . setAttribute ( 'collapse' , 'before' ) ;
2009-07-07 21:41:37 -04:00
} ;
2007-11-14 14:34:36 -05:00
}
}
2007-11-17 00:20:26 -05:00
else {
2011-05-26 13:31:44 -04:00
this . collapseTarget = 'left' ;
this . screenPositionProp = 'screenX' ;
2012-08-29 16:28:03 -04:00
this . offsetProp = 'offsetX' ;
this . translateFunction = 'translateX' ;
2011-05-26 13:31:44 -04:00
this . sizeProp = 'width' ;
this . invertedScreenPositionProp = 'screenY' ;
this . invertedSizeProp = 'height' ;
this . startProp = 'left' ;
this . endProp = 'right' ;
2007-11-14 14:34:36 -05:00
2008-10-17 11:47:45 -04:00
b . mTabBox . orient = splitter . orient = 'vertical' ;
2010-03-23 09:33:00 -04:00
strip . orient =
2010-03-25 23:17:16 -04:00
placeHolder . orient =
2009-03-30 12:36:54 -04:00
toggler . orient =
2007-11-17 00:20:26 -05:00
b . mTabContainer . orient =
b . mTabContainer . mTabstrip . orient =
b . mTabContainer . mTabstrip . parentNode . orient = 'horizontal' ;
b . mTabContainer . removeAttribute ( 'align' ) ; // for Mac OS X
2009-12-15 03:58:29 -05:00
if ( scrollInnerBox )
scrollInnerBox . setAttribute ( 'flex' , 1 ) ;
2007-11-14 14:34:36 -05:00
2012-10-23 12:43:56 -04:00
if ( utils . getTreePref ( 'compatibility.TMP' ) && scrollFrame ) { // Tab Mix Plus
2011-05-25 17:23:02 -04:00
d . getAnonymousNodes ( scrollFrame ) [ 0 ] . setAttribute ( 'flex' , 1 ) ;
2007-11-17 00:20:26 -05:00
scrollFrame . parentNode . orient =
scrollFrame . orient = 'horizontal' ;
2011-05-25 22:02:34 -04:00
if ( newTabBox )
newTabBox . orient = 'vertical' ;
2007-11-17 00:20:26 -05:00
}
2007-11-14 14:34:36 -05:00
2008-03-03 01:00:59 -05:00
if ( toolboxContainer )
toolboxContainer . orient = 'horizontal' ;
2012-10-23 12:43:56 -04:00
this . setTabbrowserAttribute ( this . kMODE , utils . getTreePref ( 'tabbar.multirow' ) ? 'multirow' : 'horizontal' ) ;
2010-03-28 14:22:15 -04:00
this . removeTabbrowserAttribute ( this . kTAB _INVERTED ) ;
2009-07-07 11:56:38 -04:00
2011-03-14 12:23:30 -04:00
if ( strip . localName == 'toolbar' ) {
2012-02-04 16:31:03 -05:00
let nodes = strip . childNodes ;
for ( let i = 0 , maxi = nodes . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
let node = nodes [ i ] ;
2012-02-04 13:15:38 -05:00
if ( node . localName == 'tabs' )
continue ;
let flex = node . hasAttribute ( 'treestyletab-backup-flex' ) ;
2011-03-14 12:23:30 -04:00
if ( ! flex )
2012-02-04 13:15:38 -05:00
continue ;
node . setAttribute ( 'flex' , flex ) ;
node . removeAttribute ( 'treestyletab-backup-flex' ) ;
}
2011-03-14 12:23:30 -04:00
}
2007-11-17 00:20:26 -05:00
if ( pos == this . kTABBAR _BOTTOM ) {
2010-03-28 14:22:15 -04:00
this . setTabbrowserAttribute ( this . kTABBAR _POSITION , 'bottom' ) ;
2009-12-18 07:57:21 -05:00
this . indentTarget = 'bottom' ;
2009-07-07 21:41:37 -04:00
delayedPostProcess = function ( aSelf , aTabBrowser , aSplitter , aToggler ) {
2010-03-25 23:17:16 -04:00
aSelf . setTabStripAttribute ( 'ordinal' , 30 ) ;
2009-08-25 04:36:50 -04:00
aSplitter . setAttribute ( 'ordinal' , 20 ) ;
aToggler . setAttribute ( 'ordinal' , 40 ) ;
2009-05-13 02:09:17 -04:00
aTabBrowser . mPanelContainer . setAttribute ( 'ordinal' , 10 ) ;
2009-07-07 21:41:37 -04:00
} ;
2007-11-17 00:20:26 -05:00
}
else {
2010-03-28 14:22:15 -04:00
this . setTabbrowserAttribute ( this . kTABBAR _POSITION , 'top' ) ;
2009-12-18 07:57:21 -05:00
this . indentTarget = 'top' ;
2009-07-07 21:41:37 -04:00
delayedPostProcess = function ( aSelf , aTabBrowser , aSplitter , aToggler ) {
2010-03-25 23:17:16 -04:00
aSelf . setTabStripAttribute ( 'ordinal' , 10 ) ;
2009-05-13 02:09:17 -04:00
aSplitter . setAttribute ( 'ordinal' , 20 ) ;
aToggler . setAttribute ( 'ordinal' , 5 ) ;
aTabBrowser . mPanelContainer . setAttribute ( 'ordinal' , 30 ) ;
2009-07-07 21:41:37 -04:00
} ;
2007-11-14 14:34:36 -05:00
}
}
2009-04-07 13:19:30 -04:00
2012-09-23 02:43:49 -04:00
var tabs = this . getAllTabs ( b ) ;
2012-02-04 16:31:03 -05:00
for ( let i = 0 , maxi = tabs . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
let tab = tabs [ i ] ;
2012-02-04 13:15:38 -05:00
tab . style . removeProperty ( this . indentCSSProp ) ;
tab . style . removeProperty ( this . collapseCSSProp ) ;
}
2010-08-13 13:14:46 -04:00
2012-10-23 12:43:56 -04:00
this . indentProp = utils . getTreePref ( 'indent.property' ) ;
2010-08-13 13:14:46 -04:00
this . indentCSSProp = this . indentProp + '-' + this . indentTarget ;
this . collapseCSSProp = 'margin-' + this . collapseTarget ;
2009-12-18 07:57:21 -05:00
2012-02-04 16:31:03 -05:00
for ( let i = 0 , maxi = tabs . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
let tab = tabs [ i ] ;
2012-02-04 13:15:38 -05:00
this . updateTabCollapsed ( tab , tab . getAttribute ( this . kCOLLAPSED ) == 'true' , true ) ;
}
2009-05-13 02:09:17 -04:00
2012-01-14 13:42:51 -05:00
// for updateTabbarOverflow(), we should reset the "overflow" now.
b . mTabContainer . removeAttribute ( 'overflow' ) ;
let ( container = this . document . getAnonymousElementByAttribute ( b . mTabContainer , 'class' , 'tabs-container' ) ) {
if ( container )
container . removeAttribute ( 'overflow' ) ;
}
2011-01-21 23:06:59 -05:00
this . updateTabbarState ( false ) ;
2011-05-25 16:54:46 -04:00
2012-08-04 13:53:57 -04:00
if ( this . deferredTasks [ 'initTabbar' ] )
this . deferredTasks [ 'initTabbar' ] . cancel ( ) ;
2011-05-25 16:54:46 -04:00
var self = this ;
2012-08-04 13:53:57 -04:00
( this . deferredTasks [ 'initTabbar' ] = this . Deferred . next ( function ( ) {
2011-05-25 16:54:46 -04:00
delayedPostProcess ( self , b , splitter , toggler ) ;
self . updateTabbarOverflow ( ) ;
self . updateAllTabsButton ( b ) ;
2012-01-13 11:45:51 -05:00
self . updateAllTabsCount ( ) ;
2009-07-07 21:41:37 -04:00
delayedPostProcess = null ;
2011-05-25 16:54:46 -04:00
self . mTabBrowser . style . visibility = '' ;
2011-01-21 12:15:04 -05:00
2011-05-25 17:23:02 -04:00
var event = d . createEvent ( 'Events' ) ;
2011-05-25 16:54:46 -04:00
event . initEvent ( self . kEVENT _TYPE _TABBAR _INITIALIZED , true , false ) ;
self . mTabBrowser . dispatchEvent ( event ) ;
2011-01-21 12:15:04 -05:00
2011-05-25 16:54:46 -04:00
self . startRendering ( ) ;
2012-08-04 13:53:57 -04:00
} ) ) . error ( this . defaultDeferredErrorHandler ) . next ( function ( ) {
delete self . deferredTasks [ 'initTabbar' ] ;
} ) ;
2009-07-07 21:37:00 -04:00
2009-05-13 02:09:17 -04:00
pos = null ;
scrollFrame = null ;
newTabBox = null
tabBarMode = null ;
toolboxContainer = null ;
scrollInnerBox = null ;
scrollInnerBox = null ;
2007-11-14 14:34:36 -05:00
} ,
2009-12-24 10:13:46 -05:00
2011-01-21 23:06:59 -05:00
_startListenTabbarEvents : function TSTBrowser _startListenTabbarEvents ( )
{
var b = this . mTabBrowser ;
var tabContainer = b . mTabContainer ;
tabContainer . addEventListener ( 'TabOpen' , this , true ) ;
tabContainer . addEventListener ( 'TabClose' , this , true ) ;
tabContainer . addEventListener ( 'TabMove' , this , true ) ;
tabContainer . addEventListener ( 'TabShow' , this , true ) ;
tabContainer . addEventListener ( 'TabHide' , this , true ) ;
tabContainer . addEventListener ( 'SSTabRestoring' , this , true ) ;
tabContainer . addEventListener ( 'SSTabRestored' , this , true ) ;
tabContainer . addEventListener ( 'TabPinned' , this , true ) ;
tabContainer . addEventListener ( 'TabUnpinned' , this , true ) ;
tabContainer . addEventListener ( 'mouseover' , this , true ) ;
2012-02-27 22:56:28 -05:00
tabContainer . addEventListener ( 'mouseout' , this , true ) ;
2011-01-21 23:06:59 -05:00
tabContainer . addEventListener ( 'dblclick' , this , true ) ;
tabContainer . addEventListener ( 'select' , this , true ) ;
tabContainer . addEventListener ( 'scroll' , this , true ) ;
var strip = this . tabStrip ;
strip . addEventListener ( 'MozMouseHittest' , this , true ) ; // to block default behaviors of the tab bar
strip . addEventListener ( 'mousedown' , this , true ) ;
strip . addEventListener ( 'click' , this , true ) ;
2012-01-06 05:38:38 -05:00
strip . addEventListener ( 'DOMMouseScroll' , this , true ) ;
2011-01-21 23:06:59 -05:00
this . scrollBox . addEventListener ( 'overflow' , this , true ) ;
this . scrollBox . addEventListener ( 'underflow' , this , true ) ;
} ,
2009-12-25 15:48:14 -05:00
_ensureNewSplitter : function TSTBrowser _ _ensureNewSplitter ( )
2009-12-24 10:13:04 -05:00
{
2011-05-25 17:23:02 -04:00
var d = this . document ;
2010-03-23 15:10:53 -04:00
var splitter = this . splitter ;
2009-12-24 10:13:04 -05:00
// We always have to re-create splitter, because its "collapse"
// behavior becomes broken by repositioning of the tab bar.
if ( splitter ) {
2010-03-23 15:10:53 -04:00
try {
2011-05-25 16:54:46 -04:00
splitter . removeEventListener ( 'mousedown' , this . windowService , false ) ;
splitter . removeEventListener ( 'mouseup' , this . windowService , false ) ;
splitter . removeEventListener ( 'dblclick' , this . windowService , false ) ;
2010-03-23 15:10:53 -04:00
}
catch ( e ) {
}
2010-03-02 09:40:12 -05:00
let oldSplitter = splitter ;
splitter = oldSplitter . cloneNode ( true ) ;
oldSplitter . parentNode . removeChild ( oldSplitter ) ;
}
else {
2011-05-25 17:23:02 -04:00
splitter = d . createElement ( 'splitter' ) ;
2010-03-02 09:40:12 -05:00
splitter . setAttribute ( 'state' , 'open' ) ;
2010-12-10 13:59:28 -05:00
splitter . setAttribute ( 'layer' , true ) ; // https://bugzilla.mozilla.org/show_bug.cgi?id=590468
2011-05-25 17:23:02 -04:00
splitter . appendChild ( d . createElement ( 'grippy' ) ) ;
2009-12-24 10:13:04 -05:00
}
2010-03-02 09:40:12 -05:00
var splitterClass = splitter . getAttribute ( 'class' ) || '' ;
if ( splitterClass . indexOf ( this . kSPLITTER ) < 0 )
splitterClass += ( splitterClass ? ' ' : '' ) + this . kSPLITTER ;
splitter . setAttribute ( 'class' , splitterClass ) ;
2009-12-24 10:13:04 -05:00
2011-05-25 16:54:46 -04:00
splitter . addEventListener ( 'mousedown' , this . windowService , false ) ;
splitter . addEventListener ( 'mouseup' , this . windowService , false ) ;
splitter . addEventListener ( 'dblclick' , this . windowService , false ) ;
2010-03-23 15:10:53 -04:00
2009-12-24 10:13:04 -05:00
var ref = this . mTabBrowser . mPanelContainer ;
ref . parentNode . insertBefore ( splitter , ref ) ;
return splitter ;
} ,
2009-12-24 10:13:46 -05:00
2011-01-21 23:06:59 -05:00
fireTabbarPositionEvent : function TSTBrowser _fireTabbarPositionEvent ( aChanging , aOldPosition , aNewPosition )
2009-07-07 11:56:38 -04:00
{
2011-01-21 23:06:59 -05:00
if ( aOldPosition == aNewPosition ) return false ;
var type = aChanging ? this . kEVENT _TYPE _TABBAR _POSITION _CHANGING : this . kEVENT _TYPE _TABBAR _POSITION _CHANGED ;
var data = {
oldPosition : aOldPosition ,
newPosition : aNewPosition
} ;
/* PUBLIC API */
this . fireDataContainerEvent ( type , this . mTabBrowser , true , false , data ) ;
// for backward compatibility
this . fireDataContainerEvent ( type . replace ( /^nsDOM/ , '' ) , this . mTabBrowser , true , false , data ) ;
return true ;
} ,
updateTabbarState : function TSTBrowser _updateTabbarState ( aCancelable )
{
if ( ! this . _fireTabbarStateChangingEvent ( ) && aCancelable )
return ;
2009-12-21 00:45:07 -05:00
this . stopRendering ( ) ;
2012-04-09 04:59:06 -04:00
var self = this ;
2011-05-25 17:23:02 -04:00
var w = this . window ;
var d = this . document ;
2009-07-07 11:56:38 -04:00
var b = this . mTabBrowser ;
2009-07-07 20:09:13 -04:00
var orient ;
2011-05-25 17:23:02 -04:00
var toggleTabsOnTop = d . getElementById ( 'cmd_ToggleTabsOnTop' ) ;
var TabsOnTop = 'TabsOnTop' in w ? w . TabsOnTop : null ;
2009-07-07 11:56:38 -04:00
if ( this . isVertical ) {
2009-07-07 20:09:13 -04:00
orient = 'vertical' ;
2011-01-22 09:43:55 -05:00
this . fixed = this . fixed ; // ensure set to the current orient
2010-04-06 21:37:58 -04:00
if ( toggleTabsOnTop )
toggleTabsOnTop . setAttribute ( 'disabled' , true ) ;
2009-07-07 11:56:38 -04:00
}
else {
2009-07-07 20:09:13 -04:00
orient = 'horizontal' ;
2011-01-22 09:43:55 -05:00
if ( this . fixed ) {
this . fixed = true ; // ensure set to the current orient
2009-07-07 12:00:17 -04:00
if ( ! this . isMultiRow ( ) ) {
2010-03-25 23:17:16 -04:00
this . removeTabStripAttribute ( 'height' ) ;
2009-07-07 11:56:38 -04:00
b . mPanelContainer . removeAttribute ( 'height' ) ;
}
2010-04-06 19:56:10 -04:00
// remove ordinal for "tabs on top" https://bugzilla.mozilla.org/show_bug.cgi?id=544815
2012-01-13 11:30:06 -05:00
if ( this . position == 'top' ) {
2010-04-06 19:56:10 -04:00
this . removeTabStripAttribute ( 'ordinal' ) ;
2012-04-09 04:59:06 -04:00
if ( TabsOnTop && ! this . windowService . isPopupWindow &&
this . windowService . initialized ) {
2012-04-09 07:18:52 -04:00
let currentState = TabsOnTop . enabled ;
2012-10-23 12:43:56 -04:00
let originalState = utils . getTreePref ( 'tabsOnTop.originalState' ) ;
2012-04-09 07:18:52 -04:00
if ( originalState !== null &&
currentState != originalState &&
this . windowService . tabsOnTopChangingByUI &&
! this . windowService . changingTabsOnTop )
2012-10-23 12:43:56 -04:00
utils . setTreePref ( 'tabsOnTop.originalState' , currentState ) ;
2012-04-09 07:18:52 -04:00
// Workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=555987
// This should be done when the value of the "ordinal" attribute
// is modified dynamically. So, we don' have to do it before
// the browser window is completely initialized.
TabsOnTop . enabled = ! currentState ;
2012-08-04 13:53:57 -04:00
if ( this . deferredTasks [ 'updateTabbarState_TabsOnTop' ] )
this . deferredTasks [ 'updateTabbarState_TabsOnTop' ] . cancel ( ) ;
( this . deferredTasks [ 'updateTabbarState_TabsOnTop' ] = this . Deferred . next ( function ( ) {
2012-04-09 07:18:52 -04:00
TabsOnTop . enabled = currentState ;
2012-08-04 13:53:57 -04:00
} ) ) . error ( this . defaultDeferredErrorHandler ) . next ( function ( ) {
delete self . deferredTasks [ 'updateTabbarState_TabsOnTop' ] ;
} ) ;
2010-04-06 19:56:10 -04:00
}
}
2009-07-07 11:56:38 -04:00
}
else {
2011-01-22 09:43:55 -05:00
this . fixed = false ; // ensure set to the current orient
2012-10-23 12:43:56 -04:00
this . setTabStripAttribute ( 'height' , this . maxTabbarHeight ( utils . getTreePref ( 'tabbar.height' ) , b ) ) ;
2010-06-27 00:01:15 -04:00
}
if ( toggleTabsOnTop ) {
2011-01-22 10:46:29 -05:00
if ( this . position == 'top' )
2010-06-27 00:01:15 -04:00
toggleTabsOnTop . removeAttribute ( 'disabled' ) ;
else
2010-04-06 21:37:58 -04:00
toggleTabsOnTop . setAttribute ( 'disabled' , true ) ;
2009-07-07 11:56:38 -04:00
}
}
2009-07-07 20:09:13 -04:00
2012-01-30 13:38:41 -05:00
if ( TabsOnTop && ! this . windowService . isPopupWindow ) {
2012-04-09 04:59:06 -04:00
let updateTabsOnTop = function ( ) {
2012-04-09 07:18:52 -04:00
self . windowService . updateTabsOnTop ( ) ;
2012-04-09 04:59:06 -04:00
} ;
// TabsOnTop.enabled is always "false" before the browser window is
// completely initialized. So, we have to check it with delay only
// on the Startup.
if ( this . initialized )
updateTabsOnTop ( ) ;
else
this . Deferred . next ( updateTabsOnTop ) ;
2011-05-04 17:25:40 -04:00
}
2010-06-27 00:01:15 -04:00
2012-08-04 13:53:57 -04:00
if ( this . deferredTasks [ 'updateTabbarState' ] )
this . deferredTasks [ 'updateTabbarState' ] . cancel ( ) ;
( this . deferredTasks [ 'updateTabbarState' ] = this . Deferred . next ( function ( ) {
2011-05-25 16:54:46 -04:00
self . updateFloatingTabbar ( self . kTABBAR _UPDATE _BY _APPEARANCE _CHANGE ) ;
self . _fireTabbarStateChangedEvent ( ) ;
self . startRendering ( ) ;
2012-08-04 13:53:57 -04:00
} ) ) . error ( this . defaultDeferredErrorHandler ) . next ( function ( ) {
delete self . deferredTasks [ 'updateTabbarState' ] ;
} ) ;
2010-03-23 15:10:53 -04:00
2012-10-23 12:43:56 -04:00
var allowToCollapse = utils . getTreePref ( 'allowSubtreeCollapseExpand.' + orient ) ;
2012-02-28 10:40:31 -05:00
if ( this . allowSubtreeCollapseExpand != allowToCollapse )
2012-02-28 07:51:19 -05:00
this . collapseExpandAllSubtree ( false , false ) ;
2012-02-28 07:42:37 -05:00
this . allowSubtreeCollapseExpand = allowToCollapse ;
2012-02-28 07:51:19 -05:00
2012-10-23 12:43:56 -04:00
this . maxTreeLevel = utils . getTreePref ( 'maxTreeLevel.' + orient ) ;
2010-11-29 03:42:06 -05:00
2010-11-24 11:14:36 -05:00
this . setTabbrowserAttribute ( this . kALLOW _STACK , this . canStackTabs ? 'true' : null ) ;
2010-11-24 18:37:26 -05:00
this . updateTabsZIndex ( this . canStackTabs ) ;
2010-11-24 11:14:36 -05:00
2010-11-29 03:42:06 -05:00
if ( this . maxTreeLevelPhisical )
this . promoteTooDeepLevelTabs ( ) ;
2009-07-07 20:09:13 -04:00
this . updateAllTabsIndent ( ) ;
2009-07-07 11:56:38 -04:00
} ,
2011-01-21 23:06:59 -05:00
_fireTabbarStateChangingEvent : function TSTBrowser _fireTabbarStateChangingEvent ( )
2010-06-27 00:01:15 -04:00
{
2011-01-21 23:06:59 -05:00
var b = this . mTabBrowser ;
var orient = this . isVertical ? 'vertical' : 'horizontal' ;
var oldState = {
2011-01-22 09:43:55 -05:00
fixed : this . fixed ,
2011-01-21 23:06:59 -05:00
maxTreeLevel : this . maxTreeLevel ,
indented : this . maxTreeLevel != 0 ,
canCollapse : b . getAttribute ( this . kALLOW _COLLAPSE ) == 'true'
} ;
var newState = {
2012-10-23 12:43:56 -04:00
fixed : utils . getTreePref ( 'tabbar.fixed.' + orient ) ,
maxTreeLevel : utils . getTreePref ( 'maxTreeLevel.' + orient ) ,
indented : utils . getTreePref ( 'maxTreeLevel.' + orient ) != 0 ,
canCollapse : utils . getTreePref ( 'allowSubtreeCollapseExpand.' + orient )
2011-01-21 23:06:59 -05:00
} ;
if ( oldState . fixed == newState . fixed &&
oldState . maxTreeLevel == newState . maxTreeLevel &&
oldState . indented == newState . indented &&
2012-01-13 03:38:12 -05:00
oldState . canCollapse == newState . canCollapse )
2011-01-21 23:06:59 -05:00
return false ;
var data = {
oldState : oldState ,
newState : newState
} ;
/* PUBLIC API */
this . fireDataContainerEvent ( this . kEVENT _TYPE _TABBAR _STATE _CHANGING , this . mTabBrowser , true , false , data ) ;
// for backward compatibility
this . fireDataContainerEvent ( this . kEVENT _TYPE _TABBAR _STATE _CHANGING . replace ( /^nsDOM/ , '' ) , this . mTabBrowser , true , false , data ) ;
return true ;
2010-06-27 00:01:15 -04:00
} ,
2011-01-21 23:06:59 -05:00
_fireTabbarStateChangedEvent : function TSTBrowser _fireTabbarStateChangedEvent ( )
{
var b = this . mTabBrowser ;
var state = {
2011-01-22 09:43:55 -05:00
fixed : this . fixed ,
2011-01-21 23:06:59 -05:00
maxTreeLevel : this . maxTreeLevel ,
indented : this . maxTreeLevel != 0 ,
canCollapse : b . getAttribute ( this . kALLOW _COLLAPSE ) == 'true'
} ;
var data = {
state : state
} ;
/* PUBLIC API */
this . fireDataContainerEvent ( this . kEVENT _TYPE _TABBAR _STATE _CHANGED , this . mTabBrowser , true , false , data ) ;
// for backward compatibility
this . fireDataContainerEvent ( this . kEVENT _TYPE _TABBAR _STATE _CHANGED . replace ( /^nsDOM/ , '' ) , this . mTabBrowser , true , false , data ) ;
return true ;
} ,
2010-12-03 09:50:42 -05:00
updateFloatingTabbar : function TSTBrowser _updateFloatingTabbar ( aReason )
2010-03-23 14:31:55 -04:00
{
2011-05-25 17:23:02 -04:00
var w = this . window ;
2011-01-21 23:06:59 -05:00
if ( this . _updateFloatingTabbarTimer ) {
2011-05-25 17:23:02 -04:00
w . clearTimeout ( this . _updateFloatingTabbarTimer ) ;
2011-01-21 23:06:59 -05:00
this . _updateFloatingTabbarTimer = null ;
2010-09-09 22:39:39 -04:00
}
2011-01-21 23:06:59 -05:00
this . _updateFloatingTabbarReason |= aReason ;
2010-12-03 09:50:42 -05:00
2011-01-21 23:06:59 -05:00
if ( this . _updateFloatingTabbarReason & this . kTABBAR _UPDATE _NOW ) {
2011-05-06 01:29:39 -04:00
this . _updateFloatingTabbarInternal ( this . _updateFloatingTabbarReason ) ;
2011-01-21 23:06:59 -05:00
this . _updateFloatingTabbarReason = 0 ;
2010-03-31 14:24:23 -04:00
}
else {
2011-05-25 17:23:02 -04:00
this . _updateFloatingTabbarTimer = w . setTimeout ( function ( aSelf ) {
2011-01-21 23:06:59 -05:00
aSelf . _updateFloatingTabbarTimer = null ;
aSelf . _updateFloatingTabbarInternal ( aSelf . _updateFloatingTabbarReason )
aSelf . _updateFloatingTabbarReason = 0 ;
2010-03-31 14:24:23 -04:00
} , 0 , this ) ;
}
2010-03-30 22:48:09 -04:00
} ,
2011-01-21 23:06:59 -05:00
_updateFloatingTabbarInternal : function TSTBrowser _updateFloatingTabbarInternal ( aReason )
2010-03-30 22:48:09 -04:00
{
2010-12-03 09:50:42 -05:00
aReason = aReason || this . kTABBAR _UPDATE _BY _UNKNOWN _REASON ;
2011-05-25 17:23:02 -04:00
var d = this . document ;
2011-05-25 14:05:48 -04:00
var splitter = this . splitter ;
if ( splitter . collapsed || splitter . getAttribute ( 'state' ) != 'collapsed' ) {
2010-09-16 00:05:12 -04:00
this . _tabStripPlaceHolder . collapsed =
2011-05-25 14:05:48 -04:00
splitter . collapsed =
2012-09-23 02:43:49 -04:00
( this . getPref ( 'browser.tabs.autoHide' ) && this . getTabs ( this . mTabBrowser ) . length == 1 ) ;
2010-09-16 00:05:12 -04:00
}
2010-03-23 14:31:55 -04:00
var strip = this . tabStrip ;
2011-05-25 14:05:48 -04:00
var collapsed = splitter . collapsed ?
strip . collapsed :
splitter . getAttribute ( 'state' ) == 'collapsed' ;
2011-04-07 02:13:10 -04:00
var stripStyle = strip . style ;
2010-04-29 23:20:18 -04:00
var tabContainerBox = this . getTabContainerBox ( this . mTabBrowser ) ;
2011-05-25 17:23:02 -04:00
var statusPanel = d . getElementById ( 'statusbar-display' ) ;
2011-04-07 02:13:10 -04:00
var statusPanelStyle = statusPanel ? statusPanel . style : null ;
2011-01-22 10:46:29 -05:00
var pos = this . position ;
2010-09-09 23:27:19 -04:00
if ( pos != 'top' ||
2010-03-25 04:51:49 -04:00
this . mTabBrowser . getAttribute ( this . kFIXED ) != 'true' ) {
2010-12-10 13:59:28 -05:00
strip . setAttribute ( 'layer' , true ) ; // https://bugzilla.mozilla.org/show_bug.cgi?id=590468
2010-03-25 06:04:47 -04:00
2011-01-12 03:25:41 -05:00
if (
this . autoHide . enabled &&
this . autoHide . expanded &&
2011-01-10 02:13:31 -05:00
( aReason & this . kTABBAR _UPDATE _SYNC _TO _PLACEHOLDER ) &&
2011-01-12 03:25:41 -05:00
this . autoHide . mode == this . autoHide . kMODE _SHRINK
)
2011-01-09 22:27:02 -05:00
this . autoHide . hide ( ) ;
2010-03-25 23:17:16 -04:00
let box = this . _tabStripPlaceHolder . boxObject ;
2011-05-25 17:23:02 -04:00
let root = d . documentElement . boxObject ;
2010-03-23 15:10:53 -04:00
2010-09-09 22:45:40 -04:00
let realWidth = parseInt ( this . _tabStripPlaceHolder . getAttribute ( 'width' ) || box . width ) ;
let realHeight = parseInt ( this . _tabStripPlaceHolder . getAttribute ( 'height' ) || box . height ) ;
2010-12-03 09:50:42 -05:00
let width = ( this . autoHide . expanded && this . isVertical && ( aReason & this . kTABBAR _UPDATE _SYNC _TO _TABBAR ) ?
2012-10-23 12:43:56 -04:00
this . maxTabbarWidth ( utils . getTreePref ( 'tabbar.width' ) ) :
2010-09-12 23:54:04 -04:00
0
) || realWidth ;
2010-12-03 09:50:42 -05:00
let height = ( this . autoHide . expanded && ! this . isVertical && ( aReason & this . kTABBAR _UPDATE _SYNC _TO _TABBAR ) ?
2012-10-23 12:43:56 -04:00
this . maxTabbarHeight ( utils . getTreePref ( 'tabbar.height' ) ) :
2010-09-12 23:54:04 -04:00
0
) || realHeight ;
2010-09-09 23:27:19 -04:00
let yOffset = pos == 'bottom' ? height - realHeight : 0 ;
2010-09-09 22:45:40 -04:00
2011-04-07 02:13:10 -04:00
stripStyle . top = ( box . screenY - root . screenY + root . y - yOffset ) + 'px' ;
2011-04-20 05:17:20 -04:00
stripStyle . left = pos == 'right' ? '' :
( box . screenX - root . screenX + root . x ) + 'px' ;
stripStyle . right = pos != 'right' ? '' :
2011-04-26 12:39:38 -04:00
( ( root . screenX + root . width ) - ( box . screenX + box . width ) ) + 'px' ;
2010-06-26 10:12:45 -04:00
2011-04-07 02:13:10 -04:00
stripStyle . width = ( tabContainerBox . width = width ) + 'px' ;
stripStyle . height = ( tabContainerBox . height = height ) + 'px' ;
2010-03-23 15:10:53 -04:00
2011-01-21 23:06:59 -05:00
this . _updateFloatingTabbarResizer ( {
2010-09-10 06:21:26 -04:00
width : width ,
realWidth : realWidth ,
height : height ,
realHeight : realHeight
} ) ;
2010-09-09 23:27:19 -04:00
2011-05-16 20:48:00 -04:00
strip . collapsed = tabContainerBox . collapsed = collapsed ;
2010-07-21 10:42:40 -04:00
2012-10-23 12:43:56 -04:00
if ( statusPanel && utils . getTreePref ( 'repositionStatusPanel' ) ) {
2012-10-29 14:11:39 -04:00
let offsetParentBox = this . base . findOffsetParent ( statusPanel ) . boxObject ;
2011-04-26 12:51:14 -04:00
let contentBox = this . mTabBrowser . mPanelContainer . boxObject ;
2011-05-25 17:23:02 -04:00
let chromeMargins = ( d . documentElement . getAttribute ( 'chromemargin' ) || '0,0,0,0' ) . split ( ',' ) ;
2011-05-04 09:03:59 -04:00
chromeMargins = chromeMargins . map ( function ( aMargin ) { return parseInt ( aMargin ) ; } ) ;
2011-04-07 02:13:10 -04:00
statusPanelStyle . marginTop = ( pos == 'bottom' ) ?
2011-05-04 09:03:59 -04:00
'-moz-calc(0px - ' + ( offsetParentBox . height - contentBox . height + chromeMargins [ 2 ] ) + 'px - 3em)' :
2011-01-30 11:22:14 -05:00
'' ;
2011-05-04 09:03:59 -04:00
statusPanelStyle . marginLeft = ( contentBox . screenX - offsetParentBox . screenX + chromeMargins [ 3 ] ) + 'px' ;
statusPanelStyle . marginRight = ( ( offsetParentBox . screenX + offsetParentBox . width ) - ( contentBox . screenX + contentBox . width ) + chromeMargins [ 1 ] ) + 'px' ;
2011-04-07 02:13:10 -04:00
statusPanelStyle . maxWidth = this . isVertical ?
2012-04-17 02:05:10 -04:00
( contentBox . width - 5 ) + 'px' : // emulate the margin defined on https://bugzilla.mozilla.org/show_bug.cgi?id=632634
2011-04-07 02:13:10 -04:00
'' ;
statusPanel . _ _treestyletab _ _repositioned = true ;
2011-01-30 11:22:14 -05:00
}
2010-07-21 10:42:40 -04:00
this . mTabBrowser . tabContainer . setAttribute ( 'context' , this . mTabBrowser . tabContextMenu . id ) ;
2010-03-23 14:31:55 -04:00
}
2010-04-06 19:56:10 -04:00
else {
2011-05-16 20:48:00 -04:00
strip . collapsed = tabContainerBox . collapsed = collapsed ;
2011-04-20 05:17:20 -04:00
stripStyle . top = stripStyle . left = stripStyle . right = stripStyle . width = stripStyle . height = '' ;
2010-07-21 10:42:40 -04:00
2011-04-07 02:13:10 -04:00
if (
statusPanel &&
(
2012-10-23 12:43:56 -04:00
utils . getTreePref ( 'repositionStatusPanel' ) ||
2011-04-07 02:13:10 -04:00
statusPanel . _ _treestyletab _ _repositioned
)
) {
statusPanelStyle . marginTop = statusPanelStyle . marginLeft =
statusPanelStyle . marginRight = statusPanelStyle . maxWidth = '' ;
statusPanel . _ _treestyletab _ _repositioned = false ;
2011-01-30 11:22:14 -05:00
}
2010-12-10 13:59:28 -05:00
strip . removeAttribute ( 'layer' ) ; // https://bugzilla.mozilla.org/show_bug.cgi?id=590468
2010-07-21 10:42:40 -04:00
this . mTabBrowser . tabContainer . removeAttribute ( 'context' ) ;
2010-04-06 19:56:10 -04:00
}
2010-03-25 06:04:47 -04:00
2011-05-06 05:47:36 -04:00
if ( tabContainerBox . boxObject . width )
this . positionPinnedTabs ( null , null , aReason & this . kTABBAR _UPDATE _BY _AUTOHIDE ) ;
else
this . positionPinnedTabsWithDelay ( null , null , aReason & this . kTABBAR _UPDATE _BY _AUTOHIDE ) ;
2010-03-23 14:31:55 -04:00
} ,
2011-01-21 23:06:59 -05:00
_updateFloatingTabbarResizer : function TSTBrowser _updateFloatingTabbarResizer ( aSize )
2010-09-09 23:27:19 -04:00
{
2011-05-25 17:23:02 -04:00
var d = this . document ;
2010-09-10 06:21:26 -04:00
var width = aSize . width ;
2010-09-10 09:46:06 -04:00
var realWidth = this . autoHide . mode == this . autoHide . kMODE _HIDE ? 0 : aSize . realWidth ;
2010-09-10 06:21:26 -04:00
var height = aSize . height ;
2010-09-10 09:46:06 -04:00
var realHeight = this . autoHide . mode == this . autoHide . kMODE _HIDE ? 0 : aSize . realHeight ;
2011-01-22 10:46:29 -05:00
var pos = this . position ;
2010-09-10 06:21:26 -04:00
var vertical = this . isVertical ;
2011-05-25 17:23:02 -04:00
var splitter = d . getElementById ( 'treestyletab-tabbar-resizer-splitter' ) ;
2010-12-06 09:16:06 -05:00
if ( ! splitter ) {
2011-05-25 17:23:02 -04:00
let box = d . createElement ( 'box' ) ;
2010-12-06 09:16:06 -05:00
box . setAttribute ( 'id' , 'treestyletab-tabbar-resizer-box' ) ;
2011-05-25 17:23:02 -04:00
splitter = d . createElement ( 'splitter' ) ;
2010-12-06 09:16:06 -05:00
splitter . setAttribute ( 'id' , 'treestyletab-tabbar-resizer-splitter' ) ;
splitter . setAttribute ( 'class' , this . kSPLITTER ) ;
splitter . setAttribute ( 'onmousedown' , 'TreeStyleTabService.handleEvent(event);' ) ;
splitter . setAttribute ( 'onmouseup' , 'TreeStyleTabService.handleEvent(event);' ) ;
splitter . setAttribute ( 'ondblclick' , 'TreeStyleTabService.handleEvent(event);' ) ;
box . appendChild ( splitter ) ;
this . tabStrip . appendChild ( box ) ;
}
2010-09-10 06:21:26 -04:00
var box = splitter . parentNode ;
box . orient = splitter . orient = vertical ? 'horizontal' : 'vertical' ;
box . width = ( width - realWidth ) || width ;
box . height = ( height - realHeight ) || height ;
var boxStyle = box . style ;
boxStyle . top = pos == 'top' ? realHeight + 'px' : '' ;
boxStyle . right = pos == 'right' ? realWidth + 'px' : '' ;
boxStyle . left = pos == 'left' ? realWidth + 'px' : '' ;
boxStyle . bottom = pos == 'bottom' ? realHeight + 'px' : '' ;
if ( vertical ) {
splitter . removeAttribute ( 'width' ) ;
splitter . setAttribute ( 'height' , height ) ;
}
else {
splitter . setAttribute ( 'width' , width ) ;
splitter . removeAttribute ( 'height' ) ;
}
var splitterWidth = splitter . boxObject . width ;
var splitterHeight = splitter . boxObject . height ;
var splitterStyle = splitter . style ;
splitterStyle . marginTop = pos == 'bottom' ? ( - splitterHeight ) + 'px' :
vertical ? '0' :
2011-01-21 23:06:59 -05:00
box . height + 'px' ;
splitterStyle . marginRight = pos == 'left' ? ( - splitterWidth ) + 'px' :
! vertical ? '0' :
box . width + 'px' ;
splitterStyle . marginLeft = pos == 'right' ? ( - splitterWidth ) + 'px' :
! vertical ? '0' :
box . width + 'px' ;
splitterStyle . marginBottom = pos == 'top' ? ( - splitterHeight ) + 'px' :
vertical ? '0' :
box . height + 'px' ;
2010-03-25 06:19:29 -04:00
} ,
2011-01-21 23:06:59 -05:00
2009-12-25 03:34:52 -05:00
updateTabbarOverflow : function TSTBrowser _updateTabbarOverflow ( )
2009-07-21 23:35:54 -04:00
{
2011-05-25 17:23:02 -04:00
var d = this . document ;
2009-07-21 23:35:54 -04:00
var b = this . mTabBrowser ;
2012-01-13 11:30:06 -05:00
b . mTabContainer . removeAttribute ( 'overflow' ) ;
2012-01-14 13:42:51 -05:00
var container = d . getAnonymousElementByAttribute ( b . mTabContainer , 'class' , 'tabs-container' ) || b . mTabContainer ;
2009-07-21 23:35:54 -04:00
2012-01-14 13:42:51 -05:00
if ( container != b . mTabContainer )
container . removeAttribute ( 'overflow' ) ;
2009-07-21 23:35:54 -04:00
var scrollBox = this . scrollBox ;
2012-01-14 13:42:51 -05:00
scrollBox = d . getAnonymousElementByAttribute ( scrollBox , 'anonid' , 'scrollbox' ) ;
if ( scrollBox ) scrollBox = d . getAnonymousNodes ( scrollBox ) [ 0 ] ;
if (
scrollBox &&
(
scrollBox . boxObject . width > container . boxObject . width ||
scrollBox . boxObject . height > container . boxObject . height
)
) {
b . mTabContainer . setAttribute ( 'overflow' , true ) ;
if ( container != b . mTabContainer )
2009-07-21 23:35:54 -04:00
container . setAttribute ( 'overflow' , true ) ;
2012-01-14 13:42:51 -05:00
}
else {
b . mTabContainer . removeAttribute ( 'overflow' ) ;
if ( container != b . mTabContainer )
2009-07-21 23:35:54 -04:00
container . removeAttribute ( 'overflow' ) ;
2012-01-14 13:42:51 -05:00
}
2009-07-21 23:35:54 -04:00
} ,
2009-12-25 04:49:47 -05:00
2011-01-22 11:08:26 -05:00
reinitAllTabs : function TSTBrowser _reinitAllTabs ( aSouldUpdateCount )
2011-01-21 22:31:57 -05:00
{
2012-09-23 02:43:49 -04:00
var tabs = this . getAllTabs ( this . mTabBrowser ) ;
2012-02-04 16:31:03 -05:00
for ( let i = 0 , maxi = tabs . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
let tab = tabs [ i ] ;
2012-02-04 13:15:38 -05:00
this . initTabAttributes ( tab ) ;
this . initTabContents ( tab ) ;
2011-01-22 11:08:26 -05:00
if ( aSouldUpdateCount )
2012-02-04 13:15:38 -05:00
this . updateTabsCount ( tab ) ;
}
2011-01-22 10:46:29 -05:00
} ,
2011-01-21 22:31:57 -05:00
2009-12-25 03:34:52 -05:00
destroy : function TSTBrowser _destroy ( )
2007-11-14 14:34:36 -05:00
{
2010-06-22 14:00:16 -04:00
this . animationManager . removeTask ( this . smoothScrollTask ) ;
2012-08-04 13:53:57 -04:00
Object . keys ( this . deferredTasks ) . forEach ( function ( key ) {
if ( this . deferredTasks [ key ] . cancel ) {
this . deferredTasks [ key ] . cancel ( ) ;
delete this . deferredTasks [ key ] ;
}
} , this ) ;
2009-09-03 02:24:06 -04:00
this . autoHide . destroy ( ) ;
2009-09-03 03:31:49 -04:00
delete this . _autoHide ;
2007-11-14 14:34:36 -05:00
2011-05-25 11:47:29 -04:00
this . _initDNDObservers ( ) ; // ensure initialized
2010-12-01 18:12:57 -05:00
this . tabbarDNDObserver . destroy ( ) ;
delete this . _tabbarDNDObserver ;
this . panelDNDObserver . destroy ( ) ;
delete this . _panelDNDObserver ;
2011-11-30 12:59:46 -05:00
if ( this . tooltipManager ) {
this . tooltipManager . destroy ( ) ;
delete this . tooltipManager ;
}
2011-05-25 17:23:02 -04:00
var w = this . window ;
var d = this . document ;
2007-11-14 14:34:36 -05:00
var b = this . mTabBrowser ;
2010-03-23 13:58:23 -04:00
delete b . tabContainer . treeStyleTab ;
2007-11-14 14:34:36 -05:00
2012-09-23 02:43:49 -04:00
var tabs = this . getAllTabs ( b ) ;
2012-02-04 16:31:03 -05:00
for ( let i = 0 , maxi = tabs . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
let tab = tabs [ i ] ;
2012-02-04 13:15:38 -05:00
this . stopTabIndentAnimation ( tab ) ;
this . stopTabCollapseAnimation ( tab ) ;
this . destroyTab ( tab ) ;
}
2007-11-14 14:34:36 -05:00
2011-01-21 23:06:59 -05:00
this . _endListenTabbarEvents ( ) ;
2009-08-25 03:20:56 -04:00
2011-05-25 17:23:02 -04:00
w . removeEventListener ( 'resize' , this , true ) ;
w . removeEventListener ( 'beforecustomization' , this , true ) ;
w . removeEventListener ( 'aftercustomization' , this , false ) ;
w . removeEventListener ( 'customizationchange' , this , false ) ;
w . removeEventListener ( this . kEVENT _TYPE _PRINT _PREVIEW _ENTERED , this , false ) ;
w . removeEventListener ( this . kEVENT _TYPE _PRINT _PREVIEW _EXITED , this , false ) ;
2012-01-01 15:18:14 -05:00
w . removeEventListener ( 'tabviewframeinitialized' , this , false ) ;
2011-11-29 06:36:49 -05:00
w . removeEventListener ( this . kEVENT _TYPE _TAB _FOCUS _SWITCHING _END , this , false ) ;
2011-12-13 02:10:49 -05:00
w . removeEventListener ( 'SSWindowStateBusy' , this , false ) ;
2010-03-28 14:22:15 -04:00
2010-12-20 07:04:21 -05:00
b . removeEventListener ( 'nsDOMMultipleTabHandlerTabsClosing' , this , false ) ;
2009-12-25 22:26:40 -05:00
2011-05-25 17:23:02 -04:00
w [ 'piro.sakura.ne.jp' ] . tabsDragUtils . destroyTabBrowser ( b ) ;
2010-11-29 22:23:08 -05:00
2010-03-25 20:20:51 -04:00
var tabContextMenu = b . tabContextMenu ||
2011-05-25 17:23:02 -04:00
d . getAnonymousElementByAttribute ( b , 'anonid' , 'tabContextMenu' ) ;
2009-05-12 12:56:39 -04:00
tabContextMenu . removeEventListener ( 'popupshowing' , this , false ) ;
2007-11-14 14:34:36 -05:00
2008-03-09 23:51:21 -04:00
if ( this . tabbarCanvas ) {
this . tabbarCanvas . parentNode . removeChild ( this . tabbarCanvas ) ;
this . tabbarCanvas = null ;
}
2012-09-17 11:31:48 -04:00
Services . obs . removeObserver ( this , this . kTOPIC _INDENT _MODIFIED ) ;
Services . obs . removeObserver ( this , this . kTOPIC _COLLAPSE _EXPAND _ALL ) ;
Services . obs . removeObserver ( this , this . kTOPIC _CHANGE _TREEVIEW _AVAILABILITY ) ;
Services . obs . removeObserver ( this , 'private-browsing-change-granted' ) ;
Services . obs . removeObserver ( this , 'lightweight-theme-styling-update' ) ;
2007-11-17 00:20:26 -05:00
this . removePrefListener ( this ) ;
2007-11-14 14:34:36 -05:00
2011-05-25 16:54:46 -04:00
delete this . windowService ;
delete this . window ;
delete this . document ;
delete this . mTabBrowser . treeStyleTab ;
2007-11-17 00:20:26 -05:00
delete this . mTabBrowser ;
2007-11-14 14:34:36 -05:00
} ,
2008-12-01 03:30:36 -05:00
2009-12-25 03:34:52 -05:00
destroyTab : function TSTBrowser _destroyTab ( aTab )
2007-11-17 00:20:26 -05:00
{
2010-03-03 21:43:12 -05:00
var id = aTab . getAttribute ( this . kID ) ;
2012-09-23 04:59:19 -04:00
if ( id in this . tabsHash &&
aTab == this . tabsHash [ id ] )
2010-03-24 11:38:08 -04:00
delete this . tabsHash [ id ] ;
2010-03-03 08:30:49 -05:00
2012-08-24 11:22:29 -04:00
if ( aTab . _ _treestyletab _ _checkTabsIndentOverflowOnMouseLeave ) {
aTab . removeEventListener ( 'mouseleave' , aTab . _ _treestyletab _ _checkTabsIndentOverflowOnMouseLeave , false ) ;
delete aTab . _ _treestyletab _ _checkTabsIndentOverflowOnMouseLeave ;
}
2007-11-17 00:20:26 -05:00
delete aTab . _ _treestyletab _ _linkedTabBrowser ;
} ,
2010-05-08 04:30:39 -04:00
2011-01-21 23:06:59 -05:00
_endListenTabbarEvents : function TSTBrowser _endListenTabbarEvents ( )
{
var b = this . mTabBrowser ;
var tabContainer = b . mTabContainer ;
tabContainer . removeEventListener ( 'TabOpen' , this , true ) ;
tabContainer . removeEventListener ( 'TabClose' , this , true ) ;
tabContainer . removeEventListener ( 'TabMove' , this , true ) ;
tabContainer . removeEventListener ( 'TabShow' , this , true ) ;
tabContainer . removeEventListener ( 'TabHide' , this , true ) ;
tabContainer . removeEventListener ( 'SSTabRestoring' , this , true ) ;
tabContainer . removeEventListener ( 'SSTabRestored' , this , true ) ;
tabContainer . removeEventListener ( 'TabPinned' , this , true ) ;
tabContainer . removeEventListener ( 'TabUnpinned' , this , true ) ;
tabContainer . removeEventListener ( 'mouseover' , this , true ) ;
2012-02-27 22:56:28 -05:00
tabContainer . removeEventListener ( 'mouseout' , this , true ) ;
2011-01-21 23:06:59 -05:00
tabContainer . removeEventListener ( 'dblclick' , this , true ) ;
tabContainer . removeEventListener ( 'select' , this , true ) ;
tabContainer . removeEventListener ( 'scroll' , this , true ) ;
var strip = this . tabStrip ;
strip . removeEventListener ( 'MozMouseHittest' , this , true ) ;
strip . removeEventListener ( 'mousedown' , this , true ) ;
strip . removeEventListener ( 'click' , this , true ) ;
2012-01-06 05:38:38 -05:00
strip . removeEventListener ( 'DOMMouseScroll' , this , true ) ;
2011-01-21 23:06:59 -05:00
this . scrollBox . removeEventListener ( 'overflow' , this , true ) ;
this . scrollBox . removeEventListener ( 'underflow' , this , true ) ;
} ,
2011-01-23 01:20:06 -05:00
saveCurrentState : function TSTBrowser _saveCurrentState ( )
{
this . autoHide . saveCurrentState ( ) ;
var b = this . mTabBrowser ;
var floatingBox = this . getTabStrip ( b ) . boxObject ;
var fixedBox = ( this . tabStripPlaceHolder || this . getTabStrip ( b ) ) . boxObject ;
var prefs = {
'tabbar.fixed.horizontal' : b . getAttribute ( this . kFIXED + '-horizontal' ) == 'true' ,
'tabbar.fixed.vertical' : b . getAttribute ( this . kFIXED + '-vertical' ) == 'true' ,
'tabbar.width' : this . isVertical && this . autoHide . expanded && floatingBox . width ? floatingBox . width : void ( 0 ) ,
'tabbar.shrunkenWidth' : this . isVertical && ! this . autoHide . expanded && fixedBox . width ? fixedBox . width : void ( 0 ) ,
'tabbar.height' : ! this . isVertical && this . autoHide . expanded && floatingBox . height ? floatingBox . height : void ( 0 )
} ;
for ( var i in prefs )
{
2012-10-23 12:43:56 -04:00
if ( prefs [ i ] !== void ( 0 ) && utils . getTreePref ( i ) != prefs [ i ] )
utils . setTreePref ( i , prefs [ i ] ) ;
2011-01-23 01:20:06 -05:00
}
this . position = this . position ;
} ,
2012-01-13 11:30:06 -05:00
/* toolbar customization */
2011-01-23 01:20:06 -05:00
2011-01-21 23:06:59 -05:00
syncDestroyTabbar : function TSTBrowser _syncDestroyTabbar ( )
{
2011-01-22 12:18:03 -05:00
this . stopRendering ( ) ;
2012-07-28 11:13:56 -04:00
this . _lastTreeViewEnabledBeforeDestroyed = this . treeViewEnabled ;
this . treeViewEnabled = false ;
this . maxTreeLevel = 0 ;
2011-01-22 11:08:26 -05:00
this . _lastTabbarPositionBeforeDestroyed = this . position ;
2011-01-22 10:46:29 -05:00
if ( this . position != 'top' ) {
2011-01-21 23:06:59 -05:00
let self = this ;
this . doAndWaitDOMEvent (
this . kEVENT _TYPE _TABBAR _POSITION _CHANGED ,
2011-05-25 16:54:46 -04:00
this . window ,
2011-01-21 23:06:59 -05:00
100 ,
2011-01-22 10:46:29 -05:00
function ( ) {
self . position = 'top' ;
}
2011-01-21 23:06:59 -05:00
) ;
}
2011-01-22 13:25:21 -05:00
this . fixed = true ;
2011-01-21 23:06:59 -05:00
2011-01-22 12:18:03 -05:00
var tabbar = this . mTabBrowser . tabContainer ;
tabbar . removeAttribute ( 'width' ) ;
tabbar . removeAttribute ( 'height' ) ;
tabbar . removeAttribute ( 'ordinal' ) ;
2011-01-21 23:06:59 -05:00
this . removeTabStripAttribute ( 'width' ) ;
this . removeTabStripAttribute ( 'height' ) ;
this . removeTabStripAttribute ( 'ordinal' ) ;
2011-01-22 12:24:02 -05:00
this . removeTabStripAttribute ( 'orient' ) ;
2011-01-22 10:46:29 -05:00
2011-03-16 07:12:37 -04:00
var toolbar = this . ownerToolbar ;
this . destroyTabStrip ( toolbar ) ;
toolbar . classList . add ( this . kTABBAR _TOOLBAR _READY ) ;
2011-01-23 01:57:01 -05:00
2011-01-21 23:38:08 -05:00
this . _endListenTabbarEvents ( ) ;
2011-01-21 23:06:59 -05:00
2011-01-22 09:43:55 -05:00
this . tabbarDNDObserver . endListenEvents ( ) ;
2011-05-25 16:54:46 -04:00
this . window . setTimeout ( function ( aSelf ) {
2011-01-23 02:01:26 -05:00
aSelf . updateCustomizedTabsToolbar ( ) ;
2011-01-25 20:21:41 -05:00
} , 100 , this ) ;
2011-01-22 12:18:03 -05:00
this . startRendering ( ) ;
2011-01-21 23:06:59 -05:00
} ,
2011-01-23 01:57:01 -05:00
destroyTabStrip : function TSTBrowser _destroyTabStrip ( aTabStrip )
{
aTabStrip . classList . remove ( this . kTABBAR _TOOLBAR ) ;
aTabStrip . style . top = aTabStrip . style . left = aTabStrip . style . width = aTabStrip . style . height = '' ;
aTabStrip . removeAttribute ( 'height' ) ;
aTabStrip . removeAttribute ( 'width' ) ;
aTabStrip . removeAttribute ( 'ordinal' ) ;
aTabStrip . removeAttribute ( 'orient' ) ;
} ,
2011-01-21 23:06:59 -05:00
2011-01-23 01:20:06 -05:00
syncReinitTabbar : function TSTBrowser _syncReinitTabbar ( )
2010-05-08 04:30:39 -04:00
{
2011-01-23 01:20:06 -05:00
this . stopRendering ( ) ;
2010-05-08 04:30:39 -04:00
2011-01-23 01:20:06 -05:00
this . ownerToolbar . classList . add ( this . kTABBAR _TOOLBAR ) ;
2011-03-16 07:12:37 -04:00
this . ownerToolbar . classList . remove ( this . kTABBAR _TOOLBAR _READY ) ;
2011-05-25 16:54:46 -04:00
Array . slice ( this . document . querySelectorAll ( '.' + this . kTABBAR _TOOLBAR _READY _POPUP ) )
2012-02-04 13:15:38 -05:00
. forEach ( this . safeRemovePopup , this ) ;
2011-01-23 01:20:06 -05:00
var position = this . _lastTabbarPositionBeforeDestroyed || this . position ;
delete this . _lastTabbarPositionBeforeDestroyed ;
var self = this ;
this . doAndWaitDOMEvent (
this . kEVENT _TYPE _TABBAR _INITIALIZED ,
2011-05-25 16:54:46 -04:00
this . window ,
2011-01-23 01:20:06 -05:00
100 ,
function ( ) {
self . initTabbar ( position , 'top' ) ;
}
) ;
this . reinitAllTabs ( true ) ;
this . tabbarDNDObserver . startListenEvents ( ) ;
this . treeViewEnabled = this . _lastTreeViewEnabledBeforeDestroyed ;
delete this . _lastTreeViewEnabledBeforeDestroyed ;
this . startRendering ( ) ;
2010-05-08 04:30:39 -04:00
} ,
2011-01-23 01:20:06 -05:00
updateCustomizedTabsToolbar : function TSTBrowser _updateCustomizedTabsToolbar ( )
{
2011-05-25 17:23:02 -04:00
var d = this . document ;
2011-01-23 02:12:53 -05:00
var newToolbar = this . ownerToolbar ;
2011-03-16 07:12:37 -04:00
newToolbar . classList . add ( this . kTABBAR _TOOLBAR _READY ) ;
2011-05-25 17:23:02 -04:00
var oldToolbar = d . querySelector ( '.' + this . kTABBAR _TOOLBAR _READY ) ;
2011-01-23 02:12:53 -05:00
if ( oldToolbar == newToolbar )
return ;
if ( oldToolbar && oldToolbar != newToolbar ) {
2011-05-25 17:23:02 -04:00
this . safeRemovePopup ( d . getElementById ( oldToolbar . id + '-' + this . kTABBAR _TOOLBAR _READY _POPUP ) ) ;
2011-01-23 01:20:06 -05:00
oldToolbar . classList . remove ( this . kTABBAR _TOOLBAR _READY ) ;
2011-01-23 02:01:26 -05:00
}
2011-01-23 01:21:29 -05:00
2011-01-23 02:12:53 -05:00
var id = newToolbar . id + '-' + this . kTABBAR _TOOLBAR _READY _POPUP ;
2011-05-25 17:23:02 -04:00
var panel = d . getElementById ( id ) ;
2011-01-23 02:01:26 -05:00
if ( ! panel ) {
2011-05-25 17:23:02 -04:00
panel = d . createElement ( 'panel' ) ;
2011-01-23 02:01:26 -05:00
panel . setAttribute ( 'id' , id ) ;
panel . setAttribute ( 'class' , this . kTABBAR _TOOLBAR _READY _POPUP ) ;
panel . setAttribute ( 'noautohide' , true ) ;
2011-01-23 02:12:53 -05:00
panel . setAttribute ( 'onmouseover' , 'this.hidePopup()' ) ;
panel . setAttribute ( 'ondragover' , 'this.hidePopup()' ) ;
2011-05-25 17:23:02 -04:00
panel . appendChild ( d . createElement ( 'label' ) ) ;
2011-01-23 02:01:26 -05:00
let position = this . _lastTabbarPositionBeforeDestroyed || this . position ;
let label = this . treeBundle . getString ( 'toolbarCustomizing_tabbar_' + ( position == 'left' || position == 'right' ? 'vertical' : 'horizontal' ) ) ;
2011-05-25 17:23:02 -04:00
panel . firstChild . appendChild ( d . createTextNode ( label ) ) ;
d . getElementById ( 'mainPopupSet' ) . appendChild ( panel ) ;
2011-01-23 02:01:26 -05:00
}
2011-01-23 02:12:53 -05:00
panel . openPopup ( newToolbar , 'end_after' , 0 , 0 , false , false ) ;
2011-01-23 02:01:26 -05:00
} ,
safeRemovePopup : function TSTBrowser _safeRemovePopup ( aPopup )
{
if ( ! aPopup )
return ;
if ( aPopup . state == 'open' ) {
aPopup . addEventListener ( 'popuphidden' , function ( aEvent ) {
aPopup . removeEventListener ( aEvent . type , arguments . callee , false ) ;
aPopup . parentNode . removeChild ( aPopup ) ;
} , false ) ;
aPopup . hidePopup ( ) ;
}
else {
aPopup . parentNode . removeChild ( aPopup ) ;
}
2011-01-23 01:20:06 -05:00
} ,
2007-11-17 00:20:26 -05:00
/* nsIObserver */
2008-03-03 04:21:33 -05:00
2009-08-09 22:15:10 -04:00
domains : [
2010-07-28 20:36:00 -04:00
'extensions.treestyletab.' ,
2010-12-06 11:11:34 -05:00
'browser.tabs.closeButtons' ,
'browser.tabs.closeWindowWithLastTab' ,
2010-08-07 12:29:40 -04:00
'browser.tabs.autoHide' ,
'browser.tabs.animate'
2009-08-09 22:15:10 -04:00
] ,
2007-11-14 14:34:36 -05:00
2009-12-25 03:34:52 -05:00
observe : function TSTBrowser _observe ( aSubject , aTopic , aData )
2007-11-14 14:34:36 -05:00
{
switch ( aTopic )
{
2010-11-30 19:33:07 -05:00
case this . kTOPIC _INDENT _MODIFIED :
2009-05-13 02:09:17 -04:00
if ( this . indent > - 1 )
2007-11-14 14:34:36 -05:00
this . updateAllTabsIndent ( ) ;
2011-01-19 21:55:49 -05:00
return ;
2007-11-14 14:34:36 -05:00
2010-11-30 19:33:07 -05:00
case this . kTOPIC _COLLAPSE _EXPAND _ALL :
2011-05-25 16:54:46 -04:00
if ( ! aSubject || aSubject == this . window ) {
2009-07-03 05:58:34 -04:00
aData = String ( aData ) ;
this . collapseExpandAllSubtree (
aData . indexOf ( 'collapse' ) > - 1 ,
aData . indexOf ( 'now' ) > - 1
) ;
}
2011-01-19 21:55:49 -05:00
return ;
2010-07-05 09:29:32 -04:00
case 'private-browsing-change-granted' :
this . collapseExpandAllSubtree ( false , true ) ;
2010-12-19 23:22:13 -05:00
this . updateFloatingTabbar ( this . kTABBAR _UPDATE _BY _PRIVATE _BROWSING ) ;
2011-01-19 21:55:49 -05:00
return ;
2010-12-19 23:22:13 -05:00
case 'lightweight-theme-styling-update' :
2011-05-06 08:46:28 -04:00
return this . updateFloatingTabbar ( this . kTABBAR _UPDATE _BY _APPEARANCE _CHANGE ) ;
2010-07-05 09:29:32 -04:00
2010-11-30 19:33:07 -05:00
case this . kTOPIC _CHANGE _TREEVIEW _AVAILABILITY :
2011-01-19 21:55:49 -05:00
return this . treeViewEnabled = ( aData != 'false' ) ;
2009-12-18 04:05:41 -05:00
2007-11-14 14:34:36 -05:00
case 'nsPref:changed' :
2011-01-19 21:55:49 -05:00
return this . onPrefChange ( aData ) ;
2007-11-14 14:34:36 -05:00
2009-05-13 02:09:17 -04:00
default :
2011-01-19 21:55:49 -05:00
return ;
2009-05-13 02:09:17 -04:00
}
} ,
2009-12-25 03:34:52 -05:00
onPrefChange : function TSTBrowser _onPrefChange ( aPrefName )
2009-05-13 02:09:17 -04:00
{
2012-01-23 14:07:56 -05:00
// ignore after destruction
if ( ! this . window || ! this . window . TreeStyleTabService )
return ;
2009-05-13 02:09:17 -04:00
var b = this . mTabBrowser ;
var value = this . getPref ( aPrefName ) ;
var tabContainer = b . mTabContainer ;
2012-09-23 02:43:49 -04:00
var tabs = this . getAllTabs ( b ) ;
2009-05-13 02:09:17 -04:00
switch ( aPrefName )
{
case 'extensions.treestyletab.tabbar.position' :
2011-01-22 10:46:29 -05:00
if ( this . shouldApplyNewPref )
this . position = value ;
2010-12-06 11:11:34 -05:00
return ;
2007-11-14 14:34:36 -05:00
2009-05-13 02:09:17 -04:00
case 'extensions.treestyletab.tabbar.invertTab' :
case 'extensions.treestyletab.tabbar.multirow' :
this . initTabbar ( ) ;
this . updateAllTabsIndent ( ) ;
2012-02-04 16:31:03 -05:00
for ( let i = 0 , maxi = tabs . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
this . initTabContents ( tabs [ i ] ) ;
2012-02-04 13:15:38 -05:00
}
2010-12-06 11:11:34 -05:00
return ;
2009-05-13 02:09:17 -04:00
case 'extensions.treestyletab.tabbar.invertTabContents' :
2010-03-28 14:22:15 -04:00
this . setTabbrowserAttribute ( this . kTAB _CONTENTS _INVERTED , value ) ;
2012-02-04 16:31:03 -05:00
for ( let i = 0 , maxi = tabs . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
this . initTabContents ( tabs [ i ] ) ;
2012-02-04 13:15:38 -05:00
}
2010-12-06 11:11:34 -05:00
return ;
2009-04-28 00:11:22 -04:00
2009-05-13 02:09:17 -04:00
case 'extensions.treestyletab.tabbar.invertClosebox' :
2010-03-28 14:22:15 -04:00
this . setTabbrowserAttribute ( this . kCLOSEBOX _INVERTED , value ) ;
2012-02-04 16:31:03 -05:00
for ( let i = 0 , maxi = tabs . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
this . initTabContents ( tabs [ i ] ) ;
2012-02-04 13:15:38 -05:00
}
2010-12-06 11:11:34 -05:00
return ;
2007-11-14 14:34:36 -05:00
2009-05-13 02:09:17 -04:00
case 'extensions.treestyletab.tabbar.style' :
2010-09-01 11:50:10 -04:00
case 'extensions.treestyletab.tabbar.style.aero' :
2012-10-23 12:43:56 -04:00
this . setTabbarStyle ( utils . getTreePref ( 'tabbar.style' ) ) ;
value = utils . getTreePref ( 'twisty.style' ) ;
2010-04-01 07:19:31 -04:00
if ( value != 'auto' )
2010-12-06 11:11:34 -05:00
return ;
2009-05-13 02:09:17 -04:00
case 'extensions.treestyletab.twisty.style' :
2010-12-06 11:11:34 -05:00
return this . setTwistyStyle ( value ) ;
2007-11-14 14:34:36 -05:00
2009-05-13 02:09:17 -04:00
case 'extensions.treestyletab.showBorderForFirstTab' :
2010-12-06 11:11:34 -05:00
return this . setTabbrowserAttribute ( this . kFIRSTTAB _BORDER , value ) ;
2007-11-14 14:34:36 -05:00
2010-05-08 02:22:49 -04:00
case 'extensions.treestyletab.tabbar.fixed.horizontal' :
2010-05-08 04:30:39 -04:00
if ( ! this . shouldApplyNewPref ) return ;
2010-05-08 02:22:49 -04:00
this . setTabbrowserAttribute ( this . kFIXED + '-horizontal' , value ? 'true' : null , b ) ;
2010-11-29 03:42:06 -05:00
case 'extensions.treestyletab.maxTreeLevel.horizontal' :
2009-07-07 20:09:13 -04:00
case 'extensions.treestyletab.allowSubtreeCollapseExpand.horizontal' :
2011-01-21 23:06:59 -05:00
if ( ! this . isVertical )
this . updateTabbarState ( true ) ;
2010-12-06 11:11:34 -05:00
return ;
2009-07-07 21:23:57 -04:00
2010-05-08 02:22:49 -04:00
case 'extensions.treestyletab.tabbar.fixed.vertical' :
2010-05-08 04:30:39 -04:00
if ( ! this . shouldApplyNewPref ) return ;
2010-05-08 02:22:49 -04:00
this . setTabbrowserAttribute ( this . kFIXED + '-vertical' , value ? 'true' : null , b ) ;
2010-11-29 03:42:06 -05:00
case 'extensions.treestyletab.maxTreeLevel.vertical' :
2009-07-07 20:09:13 -04:00
case 'extensions.treestyletab.allowSubtreeCollapseExpand.vertical' :
2011-01-21 23:06:59 -05:00
if ( this . isVertical )
this . updateTabbarState ( true ) ;
2010-12-06 11:11:34 -05:00
return ;
2008-03-10 00:11:44 -04:00
2009-05-13 02:09:17 -04:00
case 'extensions.treestyletab.tabbar.width' :
case 'extensions.treestyletab.tabbar.shrunkenWidth' :
2010-05-08 04:30:39 -04:00
if ( ! this . shouldApplyNewPref ) return ;
2009-09-03 04:18:41 -04:00
if ( ! this . autoHide . isResizing && this . isVertical ) {
2010-03-25 23:17:16 -04:00
this . removeTabStripAttribute ( 'width' ) ;
2012-01-13 11:30:06 -05:00
this . setTabStripAttribute ( 'width' , this . autoHide . placeHolderWidthFromMode ) ;
this . updateFloatingTabbar ( this . kTABBAR _UPDATE _BY _PREF _CHANGE ) ;
2009-05-13 02:09:17 -04:00
}
this . checkTabsIndentOverflow ( ) ;
2010-12-06 11:11:34 -05:00
return ;
2009-04-02 07:17:52 -04:00
2009-07-07 04:30:30 -04:00
case 'extensions.treestyletab.tabbar.height' :
2010-05-08 04:30:39 -04:00
if ( ! this . shouldApplyNewPref ) return ;
2009-07-07 04:30:30 -04:00
this . _horizontalTabMaxIndentBase = 0 ;
this . checkTabsIndentOverflow ( ) ;
2010-12-06 11:11:34 -05:00
return ;
2009-07-07 04:30:30 -04:00
2011-01-10 00:01:53 -05:00
case 'extensions.treestyletab.tabbar.autoShow.mousemove' :
2011-05-25 16:54:46 -04:00
let ( toggler = this . document . getAnonymousElementByAttribute ( b , 'class' , this . kTABBAR _TOGGLER ) ) {
2011-01-10 00:01:53 -05:00
if ( toggler ) {
if ( value )
toggler . removeAttribute ( 'hidden' ) ;
else
toggler . setAttribute ( 'hidden' , true ) ;
}
}
return ;
2011-03-24 23:12:33 -04:00
case 'extensions.treestyletab.tabbar.invertScrollbar' :
2011-04-07 12:42:00 -04:00
this . setTabbrowserAttribute ( this . kINVERT _SCROLLBAR , value ) ;
this . positionPinnedTabs ( ) ;
return ;
2011-03-24 22:42:50 -04:00
case 'extensions.treestyletab.tabbar.narrowScrollbar' :
return this . setTabbrowserAttribute ( this . kNARROW _SCROLLBAR , value ) ;
2010-11-29 03:24:45 -05:00
case 'extensions.treestyletab.maxTreeLevel.phisical' :
2010-11-29 03:42:06 -05:00
if ( this . maxTreeLevelPhisical = value )
2010-11-29 03:24:45 -05:00
this . promoteTooDeepLevelTabs ( ) ;
2010-12-06 11:11:34 -05:00
return ;
2010-11-29 03:24:45 -05:00
2010-08-07 12:29:40 -04:00
case 'browser.tabs.animate' :
2010-05-02 00:30:51 -04:00
case 'extensions.treestyletab.animation.enabled' :
2010-08-07 12:29:40 -04:00
this . setTabbrowserAttribute ( this . kANIMATION _ENABLED ,
(
this . getPref ( 'extensions.treestyletab.animation.enabled' ) &&
( this . getPref ( 'browser.tabs.animate' ) !== false )
) ? 'true' : null
) ;
2010-12-06 11:11:34 -05:00
return ;
case 'browser.tabs.closeButtons' :
case 'browser.tabs.closeWindowWithLastTab' :
return this . updateInvertedTabContentsOrder ( true ) ;
2010-05-02 00:30:51 -04:00
2010-07-28 20:36:00 -04:00
case 'browser.tabs.autoHide' :
2012-09-23 02:43:49 -04:00
if ( this . getTabs ( this . mTabBrowser ) . length == 1 )
2010-12-03 09:50:42 -05:00
this . updateFloatingTabbar ( this . kTABBAR _UPDATE _BY _SHOWHIDE _TABBAR ) ;
2010-12-06 11:11:34 -05:00
return ;
2010-07-28 20:36:00 -04:00
2011-05-25 11:47:29 -04:00
case 'extensions.treestyletab.tabbar.autoHide.mode' :
case 'extensions.treestyletab.tabbar.autoHide.mode.fullscreen' :
return this . autoHide ; // ensure initialized
2011-11-29 15:33:47 -05:00
case 'extensions.treestyletab.pinnedTab.faviconized' :
2011-07-29 01:44:31 -04:00
return this . positionPinnedTabsWithDelay ( ) ;
2012-01-13 11:45:51 -05:00
case 'extensions.treestyletab.counter.role.horizontal' :
if ( ! this . isVertical ) {
let self = this ;
2012-08-04 13:53:57 -04:00
if ( this . deferredTasks [ aPrefName ] )
this . deferredTasks [ aPrefName ] . cancel ( ) ;
( this . deferredTasks [ aPrefName ] = this . Deferred
. next ( function ( ) { self . updateAllTabsCount ( ) ; } ) )
. error ( this . defaultDeferredErrorHandler ) . next ( function ( ) {
delete self . deferredTasks [ aPrefName ] ;
} ) ;
2012-01-13 11:45:51 -05:00
}
return ;
case 'extensions.treestyletab.counter.role.vertical' :
if ( this . isVertical ) {
let self = this ;
2012-08-04 13:53:57 -04:00
if ( this . deferredTasks [ aPrefName ] )
this . deferredTasks [ aPrefName ] . cancel ( ) ;
( this . deferredTasks [ aPrefName ] = this . Deferred
. next ( function ( ) { self . updateAllTabsCount ( ) ; } ) )
. error ( this . defaultDeferredErrorHandler ) . next ( function ( ) {
delete self . deferredTasks [ aPrefName ] ;
} ) ;
2012-01-13 11:45:51 -05:00
}
return ;
2007-11-14 14:34:36 -05:00
default :
2010-12-06 11:11:34 -05:00
return ;
2007-11-14 14:34:36 -05:00
}
} ,
2010-04-01 07:19:31 -04:00
setTabbarStyle : function TSTBrowser _setTabbarStyle ( aStyle )
{
2010-09-01 11:43:19 -04:00
if ( /^(default|plain|flat|mixed|vertigo|metal|sidebar)(-aero)?$/ . test ( aStyle ) )
2010-04-01 07:19:31 -04:00
aStyle = aStyle . toLowerCase ( ) ;
2010-09-01 11:43:19 -04:00
if ( aStyle . indexOf ( 'default' ) == 0 ) { // old name (for compatibility)
2012-10-23 12:43:56 -04:00
utils . setTreePref ( 'tabbar.style' , aStyle = aStyle . replace ( 'default' , 'plain' ) ) ;
2010-04-01 07:19:31 -04:00
}
if ( aStyle ) {
let additionalValues = [ ] ;
if ( /^(plain|flat|mixed|vertigo)$/ . test ( aStyle ) )
additionalValues . push ( 'square' ) ;
if ( /^(plain|flat|mixed)$/ . test ( aStyle ) )
additionalValues . push ( 'border' ) ;
if ( /^(flat|mixed)$/ . test ( aStyle ) )
additionalValues . push ( 'color' ) ;
if ( /^(plain|mixed)$/ . test ( aStyle ) )
additionalValues . push ( 'shadow' ) ;
2012-10-23 12:43:56 -04:00
if ( utils . getTreePref ( 'tabbar.style.aero' ) )
2010-09-01 11:50:10 -04:00
additionalValues . push ( 'aero' ) ;
2010-04-01 07:19:31 -04:00
if ( additionalValues . length )
aStyle = additionalValues . join ( ' ' ) + ' ' + aStyle ;
this . setTabbrowserAttribute ( this . kSTYLE , aStyle ) ;
}
else {
this . removeTabbrowserAttribute ( this . kSTYLE ) ;
}
} ,
setTwistyStyle : function TSTBrowser _setTwistyStyle ( aStyle )
{
2010-07-02 04:39:24 -04:00
if ( aStyle != 'auto' ) {
this . setTabbrowserAttribute ( this . kTWISTY _STYLE , aStyle ) ;
return ;
2010-04-01 07:19:31 -04:00
}
2010-07-02 04:39:24 -04:00
aStyle = 'modern-black' ;
2012-10-23 12:43:56 -04:00
if ( utils . getTreePref ( 'tabbar.style' ) == 'sidebar' ) {
2010-07-02 04:39:24 -04:00
aStyle = 'osx' ;
}
else if (
this . getPref ( 'extensions.informationaltab.thumbnail.enabled' ) &&
this . getPref ( 'extensions.informationaltab.thumbnail.position' ) < 100
) {
let self = this ;
2010-07-02 04:56:28 -04:00
this . extensions . isAvailable ( 'informationaltab@piro.sakura.ne.jp' , {
2010-07-02 04:39:24 -04:00
ok : function ( ) {
aStyle = 'retro' ;
self . setTabbrowserAttribute ( self . kTWISTY _STYLE , aStyle ) ;
} ,
ng : function ( ) {
self . setTabbrowserAttribute ( self . kTWISTY _STYLE , aStyle ) ;
}
} ) ;
return ;
}
2010-04-01 07:19:31 -04:00
this . setTabbrowserAttribute ( this . kTWISTY _STYLE , aStyle ) ;
} ,
2008-02-24 02:58:12 -05:00
2007-11-17 00:20:26 -05:00
/* DOM Event Handling */
2008-03-09 23:51:21 -04:00
2009-12-25 03:34:52 -05:00
handleEvent : function TSTBrowser _handleEvent ( aEvent )
2007-11-14 14:34:36 -05:00
{
switch ( aEvent . type )
{
case 'TabOpen' :
2011-12-08 21:11:53 -05:00
return this . onTabOpen ( aEvent ) ;
2007-11-14 14:34:36 -05:00
case 'TabClose' :
2011-12-08 21:11:53 -05:00
return this . onTabClose ( aEvent ) ;
2007-11-14 14:34:36 -05:00
case 'TabMove' :
2010-03-02 09:40:12 -05:00
return this . onTabMove ( aEvent ) ;
2007-11-14 14:34:36 -05:00
2010-09-16 06:46:15 -04:00
case 'TabShow' :
case 'TabHide' :
return this . onTabVisibilityChanged ( aEvent ) ;
2007-11-14 14:34:36 -05:00
case 'SSTabRestoring' :
2010-03-02 09:40:12 -05:00
return this . onTabRestoring ( aEvent ) ;
2009-10-25 13:31:47 -04:00
case 'SSTabRestored' :
2010-03-02 09:40:12 -05:00
return this . onTabRestored ( aEvent ) ;
2007-11-14 14:34:36 -05:00
2010-09-16 05:01:52 -04:00
case 'TabPinned' :
2011-12-08 21:11:53 -05:00
return this . onTabPinned ( aEvent . originalTarget ) ;
2010-09-16 05:01:52 -04:00
case 'TabUnpinned' :
2011-12-08 21:11:53 -05:00
return this . onTabUnpinned ( aEvent . originalTarget ) ;
2010-09-16 05:01:52 -04:00
2007-11-14 14:34:36 -05:00
case 'select' :
2010-03-02 09:40:12 -05:00
return this . onTabSelect ( aEvent ) ;
2007-11-14 14:34:36 -05:00
case 'click' :
2010-03-02 09:40:12 -05:00
return this . onClick ( aEvent ) ;
2007-11-14 14:34:36 -05:00
case 'dblclick' :
2010-03-02 09:40:12 -05:00
return this . onDblClick ( aEvent ) ;
2007-11-14 14:34:36 -05:00
2010-07-01 23:39:31 -04:00
case 'MozMouseHittest' : // to block default behaviors of the tab bar
return this . onMozMouseHittest ( aEvent ) ;
2007-11-14 14:34:36 -05:00
case 'mousedown' :
2010-03-02 09:40:12 -05:00
return this . onMouseDown ( aEvent ) ;
2012-01-06 05:38:38 -05:00
case 'DOMMouseScroll' :
return this . onDOMMouseScroll ( aEvent ) ;
2007-11-14 14:34:36 -05:00
case 'scroll' :
2010-03-02 09:40:12 -05:00
return this . onScroll ( aEvent ) ;
2007-11-14 14:34:36 -05:00
case 'popupshowing' :
2011-11-29 13:40:11 -05:00
return this . onPopupShowing ( aEvent ) ;
case 'popuphiding' :
return this . onPopupHiding ( aEvent ) ;
2007-11-14 14:34:36 -05:00
2007-11-30 14:22:34 -05:00
case 'mouseover' :
2011-12-16 10:50:30 -05:00
if ( ! this . tooltipManager )
this . _initTooltipManager ( ) ;
if ( ! this . _DNDObserversInitialized )
this . _initDNDObservers ( ) ;
2011-01-13 10:05:28 -05:00
let ( tab = aEvent . target ) {
if ( tab . _ _treestyletab _ _twistyHoverTimer )
2011-05-25 16:54:46 -04:00
this . window . clearTimeout ( tab . _ _treestyletab _ _twistyHoverTimer ) ;
2012-02-27 22:56:28 -05:00
if ( this . isEventFiredOnTwisty ( aEvent ) ) {
tab . setAttribute ( this . kTWISTY _HOVER , true ) ;
2011-05-25 16:54:46 -04:00
tab . _ _treestyletab _ _twistyHoverTimer = this . window . setTimeout ( function ( aSelf ) {
2011-01-13 10:05:28 -05:00
tab . setAttribute ( aSelf . kTWISTY _HOVER , true ) ;
2012-02-27 22:56:28 -05:00
delete tab . _ _treestyletab _ _twistyHoverTimer ;
2011-01-13 10:05:28 -05:00
} , 0 , this ) ;
2012-02-27 22:56:28 -05:00
}
}
return ;
case 'mouseout' :
let ( tab = aEvent . target ) {
if ( tab . _ _treestyletab _ _twistyHoverTimer ) {
this . window . clearTimeout ( tab . _ _treestyletab _ _twistyHoverTimer ) ;
delete tab . _ _treestyletab _ _twistyHoverTimer ;
}
tab . removeAttribute ( this . kTWISTY _HOVER ) ;
2011-01-13 10:05:28 -05:00
}
2007-11-30 14:22:34 -05:00
return ;
2009-03-08 12:12:19 -04:00
2011-05-25 11:47:29 -04:00
case 'dragover' :
2011-12-16 10:50:30 -05:00
if ( ! this . tooltipManager )
this . _initTooltipManager ( ) ;
if ( ! this . _DNDObserversInitialized )
this . _initDNDObservers ( ) ;
2011-11-30 12:59:46 -05:00
return ;
2011-05-25 11:47:29 -04:00
2009-03-08 12:12:19 -04:00
case 'overflow' :
case 'underflow' :
2010-03-02 09:40:12 -05:00
return this . onTabbarOverflow ( aEvent ) ;
2009-12-25 22:26:40 -05:00
2010-03-23 15:10:53 -04:00
case 'resize' :
return this . onResize ( aEvent ) ;
2009-12-25 22:26:40 -05:00
2012-01-13 11:30:06 -05:00
// toolbar customizing
2011-01-21 12:15:04 -05:00
case 'beforecustomization' :
2011-03-18 11:45:27 -04:00
this . toolbarCustomizing = true ;
2011-01-21 22:33:29 -05:00
return this . syncDestroyTabbar ( ) ;
2011-01-21 12:15:04 -05:00
case 'aftercustomization' :
2011-03-18 11:45:27 -04:00
// Ignore it, because 'aftercustomization' fired not
// following to 'beforecustomization' is invalid.
// Personal Titlebar addon (or others) fires a fake
// event on its startup process.
if ( ! this . toolbarCustomizing ) return ;
this . toolbarCustomizing = false ;
2011-01-21 22:33:29 -05:00
return this . syncReinitTabbar ( ) ;
2011-01-23 01:20:06 -05:00
case 'customizationchange' :
return this . updateCustomizedTabsToolbar ( ) ;
2011-01-21 12:15:04 -05:00
2012-01-01 15:18:14 -05:00
case 'tabviewframeinitialized' :
return this . lastTabViewGroup = this . getTabViewGroupId ( ) ;
2011-10-29 16:03:44 -04:00
2011-01-21 12:15:04 -05:00
2010-11-30 05:05:00 -05:00
case this . kEVENT _TYPE _PRINT _PREVIEW _ENTERED :
2010-03-28 14:22:15 -04:00
return this . onTreeStyleTabPrintPreviewEntered ( aEvent ) ;
2010-11-30 05:05:00 -05:00
case this . kEVENT _TYPE _PRINT _PREVIEW _EXITED :
2010-03-28 14:22:15 -04:00
return this . onTreeStyleTabPrintPreviewExited ( aEvent ) ;
2011-11-29 06:36:49 -05:00
case this . kEVENT _TYPE _TAB _FOCUS _SWITCHING _END :
return this . cancelDelayedExpandOnTabSelect ( ) ;
2011-12-13 02:10:49 -05:00
case 'SSWindowStateBusy' :
2011-12-13 02:32:42 -05:00
return this . needRestoreTree = true ;
2011-12-13 02:10:49 -05:00
2010-12-20 07:04:21 -05:00
case 'nsDOMMultipleTabHandlerTabsClosing' :
2011-12-08 21:11:53 -05:00
if ( ! this . onTabsClosing ( aEvent ) )
2009-12-25 23:57:57 -05:00
aEvent . preventDefault ( ) ;
2009-12-25 22:26:40 -05:00
return ;
2007-11-14 14:34:36 -05:00
}
} ,
2008-06-18 20:15:57 -04:00
lastScrollX : - 1 ,
lastScrollY : - 1 ,
2009-05-13 02:09:17 -04:00
2011-12-13 09:21:31 -05:00
restoreLastScrollPosition : function TSTBrowser _restoreLastScrollPosition ( )
2011-08-24 01:27:19 -04:00
{
if ( this . lastScrollX < 0 || this . lastScrollY < 0 ) return ;
var lastX = this . lastScrollX ;
var lastY = this . lastScrollY ;
this . clearLastScrollPosition ( ) ;
if ( ! this . smoothScrollTask &&
! this . scrollBox . _smoothScrollTimer ) { // don't restore scroll position if another scroll is already running.
let x = { } , y = { } ;
let scrollBoxObject = this . scrollBoxObject ;
scrollBoxObject . getPosition ( x , y ) ;
if ( x . value != lastX || y . value != lastY )
scrollBoxObject . scrollTo ( lastX , lastY ) ;
}
} ,
2011-12-13 09:21:31 -05:00
clearLastScrollPosition : function TSTBrowser _clearLastScrollPosition ( )
2011-08-24 01:27:19 -04:00
{
2012-01-12 22:16:35 -05:00
this . lastScrollX = this . lastScrollY = - 1 ;
2011-08-24 01:27:19 -04:00
} ,
2011-12-13 09:21:31 -05:00
2009-12-25 03:34:52 -05:00
updateLastScrollPosition : function TSTBrowser _updateLastScrollPosition ( )
2009-05-13 02:09:17 -04:00
{
if ( ! this . isVertical ) return ;
var x = { } , y = { } ;
var scrollBoxObject = this . scrollBoxObject ;
if ( ! scrollBoxObject ) return ;
scrollBoxObject . getPosition ( x , y ) ;
this . lastScrollX = x . value ;
this . lastScrollY = y . value ;
} ,
2012-01-12 22:16:35 -05:00
2012-08-05 15:28:04 -04:00
cancelPerformingAutoScroll : function TSTBrowser _cancelPerformingAutoScroll ( aOnlyCancel )
2012-01-12 22:16:35 -05:00
{
if ( this . smoothScrollTask ) {
this . animationManager . removeTask ( this . smoothScrollTask ) ;
this . smoothScrollTask = null ;
}
this . clearLastScrollPosition ( ) ;
2012-08-05 15:28:04 -04:00
if ( this . deferredTasks [ 'cancelPerformingAutoScroll' ] ) {
2012-08-04 13:53:57 -04:00
this . deferredTasks [ 'cancelPerformingAutoScroll' ] . cancel ( ) ;
2012-08-05 15:28:04 -04:00
delete this . deferredTasks [ 'cancelPerformingAutoScroll' ] ;
}
if ( aOnlyCancel )
return ;
2012-01-12 22:16:35 -05:00
var self = this ;
2012-08-05 15:28:04 -04:00
( this . deferredTasks [ 'cancelPerformingAutoScroll' ] = this . Deferred . wait ( 0.3 ) )
. next ( function ( ) {
2012-08-04 13:53:57 -04:00
delete self . deferredTasks [ 'cancelPerformingAutoScroll' ] ;
2012-08-05 15:28:04 -04:00
} ) . error ( this . defaultDeferredErrorHandler ) ;
2012-01-12 22:16:35 -05:00
} ,
shouldCancelEnsureElementIsVisible : function TSTBRowser _shouldCancelEnsureElementIsVisible ( )
{
return (
2012-08-04 13:53:57 -04:00
this . deferredTasks [ 'cancelPerformingAutoScroll' ] &&
2012-01-12 22:16:35 -05:00
( new Error ( ) ) . stack . indexOf ( 'onxblDOMMouseScroll' ) < 0
) ;
} ,
2009-05-13 02:09:17 -04:00
2011-12-08 21:11:53 -05:00
onTabOpen : function TSTBrowser _onTabOpen ( aEvent , aTab )
2007-11-14 14:34:36 -05:00
{
2009-12-25 04:15:25 -05:00
var tab = aTab || aEvent . originalTarget ;
2007-11-14 14:34:36 -05:00
var b = this . mTabBrowser ;
2009-12-25 05:09:16 -05:00
if ( this . isTabInitialized ( tab ) )
return false ;
2007-11-14 14:34:36 -05:00
this . initTab ( tab ) ;
2009-07-30 04:57:42 -04:00
var hasStructure = this . treeStructure && this . treeStructure . length ;
2009-12-20 13:46:51 -05:00
var pareintIndexInTree = hasStructure ? this . treeStructure . shift ( ) : 0 ;
2011-07-28 21:34:44 -04:00
var lastRelatedTab = b . _lastRelatedTab ;
2009-07-30 03:56:11 -04:00
2009-09-08 22:57:30 -04:00
if ( this . readiedToAttachNewTab ) {
2009-12-20 13:46:51 -05:00
if ( pareintIndexInTree < 0 ) { // there is no parent, so this is a new parent!
this . parentTab = tab . getAttribute ( this . kID ) ;
}
2009-07-30 03:56:11 -04:00
let parent = this . getTabById ( this . parentTab ) ;
if ( parent ) {
let tabs = [ parent ] . concat ( this . getDescendantTabs ( parent ) ) ;
2009-12-20 13:46:51 -05:00
parent = pareintIndexInTree < tabs . length ? tabs [ pareintIndexInTree ] : parent ;
2009-07-30 03:56:11 -04:00
}
if ( parent ) {
2010-07-29 22:39:51 -04:00
this . attachTabTo ( tab , parent , {
dontExpand : this . shouldExpandAllTree
} ) ;
2009-07-30 03:56:11 -04:00
}
2007-11-14 14:34:36 -05:00
2009-07-30 03:56:11 -04:00
let refTab ;
let newIndex = - 1 ;
2009-07-30 04:57:42 -04:00
if ( hasStructure ) {
}
else if ( this . insertBefore &&
2007-11-14 14:34:36 -05:00
( refTab = this . getTabById ( this . insertBefore ) ) ) {
newIndex = refTab . _tPos ;
}
2010-12-07 11:28:23 -05:00
else if (
parent &&
2012-10-23 12:43:56 -04:00
utils . getTreePref ( 'insertNewChildAt' ) == this . kINSERT _FISRT &&
2011-10-29 16:26:01 -04:00
( this . multipleCount <= 0 || this . _addedCountInThisLoop <= 0 )
2010-12-07 11:28:23 -05:00
) {
2012-08-28 08:38:39 -04:00
/ * 複 数 の 子 タ ブ を 一 気 に 開 く 場 合 、 最 初 に 開 い た タ ブ だ け を
子タブの最初の位置に挿入し 、 続くタブは 「 最初の開いたタブ 」 と
「 元々最初の子だったタブ 」 との間に挿入していく * /
2007-11-14 14:34:36 -05:00
newIndex = parent . _tPos + 1 ;
if ( refTab = this . getFirstChildTab ( parent ) )
this . insertBefore = refTab . getAttribute ( this . kID ) ;
}
if ( newIndex > - 1 ) {
if ( newIndex > tab . _tPos ) newIndex -- ;
2009-09-30 01:42:48 -04:00
this . internallyTabMovingCount ++ ;
2007-11-14 14:34:36 -05:00
b . moveTabTo ( tab , newIndex ) ;
2009-09-30 01:42:48 -04:00
this . internallyTabMovingCount -- ;
2007-11-14 14:34:36 -05:00
}
2010-07-29 22:39:51 -04:00
if ( this . shouldExpandAllTree )
this . collapseExpandSubtree ( parent , false ) ;
2007-11-14 14:34:36 -05:00
}
2010-12-07 11:28:23 -05:00
this . _addedCountInThisLoop ++ ;
if ( ! this . _addedCountClearTimer ) {
2011-05-25 16:54:46 -04:00
this . _addedCountClearTimer = this . window . setTimeout ( function ( aSelf ) {
2010-12-07 11:28:23 -05:00
aSelf . _addedCountInThisLoop = 0 ;
aSelf . _addedCountClearTimer = null ;
} , 0 , this ) ;
}
2009-09-08 22:57:30 -04:00
if ( ! this . readiedToAttachMultiple ) {
2007-11-14 14:34:36 -05:00
this . stopToOpenChildTab ( b ) ;
}
else {
this . multipleCount ++ ;
}
2008-03-09 01:36:52 -05:00
2010-07-21 10:48:07 -04:00
if ( this . animationEnabled ) {
2009-04-07 14:07:27 -04:00
this . updateTabCollapsed ( tab , true , true ) ;
2012-01-27 14:33:02 -05:00
let self = this ;
this . updateTabCollapsed ( tab , false , this . windowService . restoringTree , function ( ) {
2012-01-27 14:48:21 -05:00
/ * *
* When the system is too slow , the animation can start after
2012-01-27 14:49:12 -05:00
* smooth scrolling is finished . The smooth scrolling should be
* started together with the start of the animation effect .
2012-01-27 14:48:21 -05:00
* /
2012-01-27 14:33:02 -05:00
self . scrollToNewTab ( tab ) ;
} ) ;
}
else {
this . scrollToNewTab ( tab ) ;
2009-04-07 14:07:27 -04:00
}
2011-12-07 01:14:02 -05:00
this . updateInsertionPositionInfo ( tab ) ;
2009-12-17 21:21:28 -05:00
2010-07-28 20:36:00 -04:00
if ( this . getPref ( 'browser.tabs.autoHide' ) )
2010-12-03 09:50:42 -05:00
this . updateFloatingTabbar ( this . kTABBAR _UPDATE _BY _SHOWHIDE _TABBAR ) ;
2010-07-28 20:36:00 -04:00
2010-11-24 11:14:36 -05:00
if ( this . canStackTabs )
2010-11-24 18:37:26 -05:00
this . updateTabsZIndex ( true ) ;
2010-11-24 11:14:36 -05:00
2010-12-06 11:11:34 -05:00
// if there is only one tab and new another tab is opened,
// closebox appearance is possibly changed.
2012-09-23 02:43:49 -04:00
var tabs = this . getTabs ( b ) ;
2010-12-06 11:11:34 -05:00
if ( tabs . length == 2 )
this . updateInvertedTabContentsOrder ( tabs ) ;
2011-07-28 21:34:44 -04:00
/ * *
2011-12-12 04:39:46 -05:00
* gBrowser . addTab ( ) resets gBrowser . _lastRelatedTab . owner
2011-07-28 21:34:44 -04:00
* when a new background tab is opened from the current tab ,
* but it will fail with TST because gBrowser . moveTab ( ) ( called
* by TST ) clears gBrowser . _lastRelatedTab .
* So , we have to restore gBrowser . _lastRelatedTab manually .
* /
b . _lastRelatedTab = lastRelatedTab ;
2009-12-25 05:09:16 -05:00
return true ;
2007-11-14 14:34:36 -05:00
} ,
2010-12-07 11:28:23 -05:00
_addedCountInThisLoop : 0 ,
_addedCountClearTimer : null ,
2009-12-17 21:21:28 -05:00
_checkRestoringWindowTimerOnTabAdded : null ,
2011-12-13 09:21:31 -05:00
2012-01-27 14:33:02 -05:00
scrollToNewTab : function TSTBrowser _scrollToNewTab ( aTab )
{
2012-08-04 13:53:57 -04:00
if ( ! aTab . parentNode ) return ; // do nothing for closed tab!
2012-01-27 14:33:02 -05:00
if ( this . scrollToNewTabMode > 0 )
this . scrollToTab ( aTab , this . scrollToNewTabMode < 2 ) ;
} ,
2011-12-13 09:21:31 -05:00
updateInsertionPositionInfo : function TSTBrowser _updateInsertionPositionInfo ( aTab )
2011-12-07 01:14:02 -05:00
{
2012-08-04 13:53:57 -04:00
if ( ! aTab . parentNode ) return ; // do nothing for closed tab!
2011-12-07 01:14:02 -05:00
var prev = this . getPreviousSiblingTab ( aTab ) ;
if ( prev ) {
this . setTabValue ( aTab , this . kINSERT _AFTER , prev . getAttribute ( this . kID ) ) ;
this . setTabValue ( prev , this . kINSERT _BEFORE , aTab . getAttribute ( this . kID ) ) ;
}
var next = this . getNextSiblingTab ( aTab ) ;
if ( next ) {
this . setTabValue ( aTab , this . kINSERT _BEFORE , next . getAttribute ( this . kID ) ) ;
this . setTabValue ( next , this . kINSERT _AFTER , aTab . getAttribute ( this . kID ) ) ;
}
} ,
2011-12-13 09:21:31 -05:00
2011-12-08 21:11:53 -05:00
onTabClose : function TSTBrowser _onTabClose ( aEvent )
2007-11-14 14:34:36 -05:00
{
var tab = aEvent . originalTarget ;
2011-05-25 17:23:02 -04:00
var d = this . document ;
2007-11-14 14:34:36 -05:00
var b = this . mTabBrowser ;
2010-08-07 11:46:16 -04:00
tab . setAttribute ( this . kREMOVED , true ) ;
2009-04-07 12:09:17 -04:00
this . stopTabIndentAnimation ( tab ) ;
2009-04-07 13:14:09 -04:00
this . stopTabCollapseAnimation ( tab ) ;
2007-11-14 14:34:36 -05:00
2011-04-07 23:15:42 -04:00
var closeParentBehavior = this . getCloseParentBehaviorForTab ( tab ) ;
2009-04-05 14:55:06 -04:00
2009-12-21 00:45:07 -05:00
var collapsed = this . isCollapsed ( tab ) ;
if ( collapsed )
2010-03-02 09:40:12 -05:00
this . stopRendering ( ) ;
2009-12-21 00:45:07 -05:00
2010-11-10 11:49:18 -05:00
var backupAttributes = { } ;
2011-12-08 21:12:27 -05:00
if ( this . hasChildTabs ( tab ) ) {
2010-11-10 11:52:02 -05:00
backupAttributes [ this . kCHILDREN ] = this . getTabValue ( tab , this . kCHILDREN ) ;
2011-12-08 21:12:27 -05:00
backupAttributes [ this . kSUBTREE _COLLAPSED ] = this . getTabValue ( tab , this . kSUBTREE _COLLAPSED ) ;
}
2010-11-10 11:49:18 -05:00
2009-12-21 00:45:07 -05:00
var subtreeCollapsed = this . isSubtreeCollapsed ( tab ) ;
2009-04-05 14:55:06 -04:00
if (
2011-03-18 13:56:00 -04:00
closeParentBehavior == this . kCLOSE _PARENT _BEHAVIOR _CLOSE _ALL _CHILDREN ||
2009-12-21 00:45:07 -05:00
subtreeCollapsed
2009-04-05 14:55:06 -04:00
) {
2009-12-25 16:09:52 -05:00
let tabs = this . getDescendantTabs ( tab ) ;
2009-12-25 23:49:58 -05:00
if ( this . fireTabSubtreeClosingEvent ( tab , tabs ) ) {
if ( subtreeCollapsed )
this . stopRendering ( ) ;
2009-12-25 16:09:52 -05:00
2009-12-25 23:49:58 -05:00
this . markAsClosedSet ( [ tab ] . concat ( tabs ) ) ;
2009-12-25 15:06:49 -05:00
2012-02-04 16:31:03 -05:00
tabs . reverse ( ) ;
for ( let i = 0 , maxi = tabs . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
b . removeTab ( tabs [ i ] , { animate : true } ) ;
2012-02-04 13:15:38 -05:00
}
2007-11-14 14:34:36 -05:00
2009-12-25 23:49:58 -05:00
this . fireTabSubtreeClosedEvent ( b , tab , tabs ) ;
2009-12-21 00:33:32 -05:00
2009-12-25 23:49:58 -05:00
if ( subtreeCollapsed )
this . startRendering ( ) ;
}
2007-11-14 14:34:36 -05:00
}
2011-07-29 14:07:37 -04:00
var toBeClosedSibling = ! this . hasChildTabs ( tab ) ?
this . _reserveCloseNeedlessGroupTabSibling ( tab ) : null ;
2007-11-14 14:34:36 -05:00
var firstChild = this . getFirstChildTab ( tab ) ;
var parentTab = this . getParentTab ( tab ) ;
var nextFocusedTab = null ;
2009-07-08 07:00:45 -04:00
var prev = this . getPreviousSiblingTab ( tab ) ;
2009-09-01 22:52:16 -04:00
var next = this . getNextSiblingTab ( tab ) ;
2009-07-08 07:00:45 -04:00
if ( prev ) {
2009-09-01 22:52:16 -04:00
this . setTabValue ( tab , this . kINSERT _AFTER , prev . getAttribute ( this . kID ) ) ;
2009-07-08 07:00:45 -04:00
if ( next )
this . setTabValue ( prev , this . kINSERT _BEFORE , next . getAttribute ( this . kID ) ) ;
else
this . deleteTabValue ( prev , this . kINSERT _BEFORE ) ;
}
2009-09-01 22:52:16 -04:00
if ( next ) {
this . setTabValue ( tab , this . kINSERT _BEFORE , next . getAttribute ( this . kID ) ) ;
if ( prev )
this . setTabValue ( next , this . kINSERT _AFTER , prev . getAttribute ( this . kID ) ) ;
else
this . deleteTabValue ( next , this . kINSERT _AFTER ) ;
}
2009-07-08 07:00:45 -04:00
2009-04-20 09:00:05 -04:00
var indentModifiedTabs = [ ] ;
2007-11-14 14:34:36 -05:00
if ( firstChild ) {
2010-08-13 14:32:43 -04:00
let children = this . getChildTabs ( tab ) ;
indentModifiedTabs = indentModifiedTabs . concat (
2011-04-07 23:15:42 -04:00
closeParentBehavior == this . kCLOSE _PARENT _BEHAVIOR _PROMOTE _FIRST _CHILD ?
2010-08-13 14:32:43 -04:00
[ children [ 0 ] ] :
children
) ;
2011-12-06 20:18:05 -05:00
this . detachAllChildren ( tab , {
2011-04-07 23:15:42 -04:00
behavior : closeParentBehavior ,
2010-08-13 14:32:43 -04:00
dontUpdateIndent : true
} ) ;
2011-04-07 23:15:42 -04:00
if ( closeParentBehavior == this . kCLOSE _PARENT _BEHAVIOR _PROMOTE _ALL _CHILDREN ||
closeParentBehavior == this . kCLOSE _PARENT _BEHAVIOR _PROMOTE _FIRST _CHILD )
2007-11-14 14:34:36 -05:00
nextFocusedTab = firstChild ;
}
if ( parentTab ) {
2009-04-20 08:45:27 -04:00
let firstSibling = this . getFirstChildTab ( parentTab ) ;
let lastSibling = this . getLastChildTab ( parentTab ) ;
2009-02-05 03:38:01 -05:00
if ( tab == lastSibling && ! nextFocusedTab ) {
2007-11-14 14:34:36 -05:00
if ( tab == firstSibling ) { // there is only one child
nextFocusedTab = parentTab ;
}
else { // previous sibling tab
nextFocusedTab = this . getPreviousSiblingTab ( tab ) ;
}
}
2007-11-26 14:55:58 -05:00
2012-08-04 16:31:38 -04:00
let ancestors = this . getAncestorTabs ( tab ) ;
ancestors = ancestors . map ( function ( aAncestor ) {
if ( ! next && ( next = this . getNextSiblingTab ( aAncestor ) ) )
2009-04-20 08:48:34 -04:00
backupAttributes [ this . kINSERT _BEFORE ] = next . getAttribute ( this . kID ) ;
2012-08-04 16:31:38 -04:00
return aAncestor . getAttribute ( this . kID ) ;
} , this ) ;
2009-04-20 08:48:34 -04:00
backupAttributes [ this . kANCESTOR ] = ancestors . join ( '|' ) ;
2007-11-26 14:55:58 -05:00
2009-07-06 21:15:13 -04:00
let shouldCloseParentTab = (
2009-07-06 21:09:50 -04:00
this . isGroupTab ( parentTab ) &&
this . getDescendantTabs ( parentTab ) . length == 1
) ;
if ( shouldCloseParentTab && nextFocusedTab == parentTab )
nextFocusedTab = this . getNextFocusedTab ( parentTab ) ;
2011-12-06 20:18:05 -05:00
this . detachTab ( tab , { dontUpdateIndent : true } ) ;
2009-06-19 14:02:48 -04:00
2009-07-06 21:09:50 -04:00
if ( shouldCloseParentTab ) {
2012-08-04 13:53:57 -04:00
let key = 'onTabClose_' + parseInt ( Math . random ( ) * 65000 ) ;
let self = this ;
( this . deferredTasks [ key ] = this . Deferred . next ( function ( ) {
2009-07-06 21:19:31 -04:00
if ( parentTab . parentNode )
2010-08-08 05:42:47 -04:00
b . removeTab ( parentTab , { animate : true } ) ;
2009-07-06 21:34:40 -04:00
parentTab = null ;
b = null ;
2012-08-04 13:53:57 -04:00
} ) ) . error ( this . defaultDeferredErrorHandler ) . next ( function ( ) {
delete self . deferredTasks [ key ] ;
} ) ;
2009-06-19 14:02:48 -04:00
}
2007-11-14 14:34:36 -05:00
}
else if ( ! nextFocusedTab ) {
2009-07-06 21:09:50 -04:00
nextFocusedTab = this . getNextFocusedTab ( tab ) ;
2007-11-14 14:34:36 -05:00
}
2009-12-18 01:35:08 -05:00
if ( indentModifiedTabs . length )
this . updateTabsIndentWithDelay ( indentModifiedTabs ) ;
this . checkTabsIndentOverflow ( ) ;
for ( var i in backupAttributes )
{
this . setTabValue ( tab , i , backupAttributes [ i ] ) ;
}
2009-07-06 21:53:19 -04:00
if ( b . selectedTab == tab ) {
2011-07-29 14:07:37 -04:00
if ( nextFocusedTab && nextFocusedTab == toBeClosedSibling )
nextFocusedTab = this . getFirstChildTab ( nextFocusedTab ) ;
2009-07-06 21:53:19 -04:00
if (
nextFocusedTab &&
2010-12-03 08:40:52 -05:00
! nextFocusedTab . hidden
) {
2011-05-25 17:23:02 -04:00
let event = d . createEvent ( 'Events' ) ;
2010-12-03 08:40:52 -05:00
event . initEvent ( this . kEVENT _TYPE _FOCUS _NEXT _TAB , true , true ) ;
2010-12-20 06:54:42 -05:00
let canFocus = tab . dispatchEvent ( event ) ;
// for backward compatibility
2011-05-25 17:23:02 -04:00
event = d . createEvent ( 'Events' ) ;
2010-12-20 06:54:42 -05:00
event . initEvent ( this . kEVENT _TYPE _FOCUS _NEXT _TAB . replace ( /^nsDOM/ , '' ) , true , true ) ;
canFocus = canFocus && tab . dispatchEvent ( event ) ;
2011-02-06 21:02:18 -05:00
if ( canFocus ) {
this . _focusChangedByCurrentTabRemove = true ;
2010-12-03 08:40:52 -05:00
b . selectedTab = nextFocusedTab ;
2011-02-06 21:02:18 -05:00
}
2010-12-03 08:40:52 -05:00
}
2009-07-06 21:53:19 -04:00
}
2009-12-21 00:45:07 -05:00
2010-03-02 09:40:12 -05:00
this . updateLastScrollPosition ( ) ;
2010-03-03 09:46:24 -05:00
this . destroyTab ( tab ) ;
2010-12-06 23:46:38 -05:00
if ( tab . getAttribute ( 'pinned' ) == 'true' )
this . positionPinnedTabsWithDelay ( ) ;
2010-07-28 20:36:00 -04:00
if ( this . getPref ( 'browser.tabs.autoHide' ) )
2010-12-03 09:50:42 -05:00
this . updateFloatingTabbar ( this . kTABBAR _UPDATE _BY _SHOWHIDE _TABBAR ) ;
2010-07-28 20:36:00 -04:00
2010-11-24 11:14:36 -05:00
if ( this . canStackTabs )
2010-11-24 18:37:26 -05:00
this . updateTabsZIndex ( true ) ;
2010-11-24 11:14:36 -05:00
2009-12-21 00:45:07 -05:00
if ( collapsed )
this . startRendering ( ) ;
2007-11-14 14:34:36 -05:00
} ,
2011-12-13 09:21:31 -05:00
_reserveCloseNeedlessGroupTabSibling : function TSTBrowser _reserveCloseNeedlessGroupTabSibling ( aTab )
2011-07-29 04:22:13 -04:00
{
2012-08-04 13:53:57 -04:00
if ( ! aTab || ! aTab . parentNode )
2011-07-29 14:07:37 -04:00
return null ;
2011-07-29 04:22:13 -04:00
var parent = this . getParentTab ( aTab ) ;
2011-07-29 14:07:37 -04:00
var siblings = this . getSiblingTabs ( aTab ) ;
2012-02-04 13:15:38 -05:00
var groupTabs = siblings . filter ( this . isGroupTab , this ) ;
2011-07-29 13:52:28 -04:00
var groupTab = (
2011-07-29 11:40:39 -04:00
groupTabs . length == 1 &&
siblings . length == 1 &&
2011-07-29 13:52:28 -04:00
this . hasChildTabs ( groupTabs [ 0 ] )
) ? groupTabs [ 0 ] : null ;
2011-07-29 14:07:37 -04:00
if ( groupTab ) {
2011-07-29 13:52:28 -04:00
this . window . setTimeout ( function ( aSelf , aGroupTab ) {
aSelf . getTabBrowserFromChild ( aGroupTab ) . removeTab ( aGroupTab , { animate : true } ) ;
} , 0 , this , groupTab ) ;
2011-07-29 14:07:37 -04:00
return groupTab ;
}
return null ;
2011-07-29 04:22:13 -04:00
} ,
2011-12-13 09:21:31 -05:00
2011-12-08 21:11:53 -05:00
onTabsClosing : function TSTBrowser _onTabsClosing ( aEvent )
2009-12-25 22:26:40 -05:00
{
2011-01-10 23:27:43 -05:00
var tabs = aEvent . tabs || aEvent . getData ( 'tabs' ) ;
var b = this . getTabBrowserFromChild ( tabs [ 0 ] ) ;
2009-12-25 23:57:57 -05:00
2011-01-10 23:27:43 -05:00
var trees = this . splitTabsToSubtrees ( tabs ) ;
2009-12-25 23:57:57 -05:00
if ( trees . some ( function ( aTabs ) {
return aTabs . length > 1 &&
! this . fireTabSubtreeClosingEvent ( aTabs [ 0 ] , aTabs ) ;
} , this ) )
return false ;
2012-02-04 13:15:38 -05:00
trees . forEach ( this . markAsClosedSet , this ) ;
2009-12-25 23:57:57 -05:00
2011-05-25 16:54:46 -04:00
var self = this ;
2012-08-04 13:53:57 -04:00
let key = 'onTabClosing_' + parseInt ( Math . random ( ) * 65000 ) ;
( this . deferredTasks [ key ] = this . Deferred . next ( function ( ) {
2012-02-04 16:31:03 -05:00
for ( let i = 0 , maxi = trees . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
let tabs = trees [ i ] ;
2012-02-04 13:15:38 -05:00
self . fireTabSubtreeClosedEvent ( b , tabs [ 0 ] , tabs ) ;
}
2012-08-04 13:53:57 -04:00
} ) ) . error ( this . defaultDeferredErrorHandler ) . next ( function ( ) {
delete self . deferredTasks [ key ] ;
} ) ;
2009-12-26 00:54:55 -05:00
return true ;
2009-12-25 22:26:40 -05:00
} ,
2009-12-25 03:34:52 -05:00
onTabMove : function TSTBrowser _onTabMove ( aEvent )
2007-11-14 14:34:36 -05:00
{
var tab = aEvent . originalTarget ;
var b = this . mTabBrowser ;
2011-10-29 16:50:27 -04:00
tab . _ _treestyletab _ _previousPosition = aEvent . detail ;
2009-12-25 04:15:25 -05:00
// When the tab was moved before TabOpen event is fired, we have to update manually.
2011-12-08 21:11:53 -05:00
var newlyOpened = ! this . isTabInitialized ( tab ) && this . onTabOpen ( null , tab ) ;
2009-12-25 04:15:25 -05:00
// twisty vanished after the tab is moved!!
this . initTabContents ( tab ) ;
2007-11-14 14:34:36 -05:00
2009-09-30 01:42:48 -04:00
if ( this . hasChildTabs ( tab ) && ! this . subTreeMovingCount ) {
2009-12-25 06:19:50 -05:00
this . moveTabSubtreeTo ( tab , tab . _tPos ) ;
2007-11-14 14:34:36 -05:00
}
var parentTab = this . getParentTab ( tab ) ;
2009-09-30 01:42:48 -04:00
if ( parentTab && ! this . subTreeChildrenMovingCount ) {
2007-11-14 14:34:36 -05:00
this . updateChildrenArray ( parentTab ) ;
}
2007-11-15 08:01:07 -05:00
this . updateTabsCount ( tab , true ) ;
2009-09-01 22:52:16 -04:00
var prev = this . getPreviousSiblingTab ( tab ) ;
2009-09-29 10:31:02 -04:00
var next = this . getNextSiblingTab ( tab ) ;
if ( prev ) {
this . setTabValue ( prev , this . kINSERT _BEFORE , tab . getAttribute ( this . kID ) ) ;
2009-09-01 22:52:16 -04:00
this . setTabValue ( tab , this . kINSERT _AFTER , prev . getAttribute ( this . kID ) ) ;
2009-09-29 10:31:02 -04:00
}
2009-09-01 22:52:16 -04:00
else
this . deleteTabValue ( tab , this . kINSERT _AFTER ) ;
2009-09-29 10:31:02 -04:00
if ( next ) {
this . setTabValue ( next , this . kINSERT _AFTER , tab . getAttribute ( this . kID ) ) ;
2009-07-08 07:00:45 -04:00
this . setTabValue ( tab , this . kINSERT _BEFORE , next . getAttribute ( this . kID ) ) ;
2009-09-29 10:31:02 -04:00
}
2009-07-08 07:00:45 -04:00
else
this . deleteTabValue ( tab , this . kINSERT _BEFORE ) ;
var old = aEvent . detail ;
if ( old > tab . _tPos ) old -- ;
2012-09-23 02:43:49 -04:00
var tabs = this . getAllTabs ( b ) ;
2010-11-24 11:14:36 -05:00
old = tabs [ old ] ;
2009-09-01 22:52:16 -04:00
prev = this . getPreviousSiblingTab ( old ) ;
2009-09-29 10:31:02 -04:00
next = this . getNextSiblingTab ( old ) ;
if ( prev ) {
this . setTabValue ( prev , this . kINSERT _BEFORE , old . getAttribute ( this . kID ) ) ;
2009-09-01 22:52:16 -04:00
this . setTabValue ( old , this . kINSERT _AFTER , prev . getAttribute ( this . kID ) ) ;
2009-09-29 10:31:02 -04:00
}
2009-09-01 22:52:16 -04:00
else
this . deleteTabValue ( old , this . kINSERT _AFTER ) ;
2009-09-29 10:31:02 -04:00
if ( next ) {
this . setTabValue ( next , this . kINSERT _AFTER , old . getAttribute ( this . kID ) ) ;
2009-07-08 07:00:45 -04:00
this . setTabValue ( old , this . kINSERT _BEFORE , next . getAttribute ( this . kID ) ) ;
2009-09-29 10:31:02 -04:00
}
2009-07-08 07:00:45 -04:00
else
this . deleteTabValue ( old , this . kINSERT _BEFORE ) ;
2010-12-06 23:46:38 -05:00
this . positionPinnedTabsWithDelay ( ) ;
2010-11-24 11:14:36 -05:00
if ( this . canStackTabs )
2010-11-24 18:37:26 -05:00
this . updateTabsZIndex ( true ) ;
2010-11-24 11:14:36 -05:00
2007-11-14 14:34:36 -05:00
if (
2009-09-30 01:42:48 -04:00
this . subTreeMovingCount ||
2009-12-25 05:09:16 -05:00
this . internallyTabMovingCount ||
// We don't have to fixup tree structure for a NEW TAB
// which has already been structured.
( newlyOpened && this . getParentTab ( tab ) )
2007-11-14 14:34:36 -05:00
)
return ;
2009-09-01 10:39:01 -04:00
this . attachTabFromPosition ( tab , aEvent . detail ) ;
2011-01-11 14:16:35 -05:00
this . rearrangeTabViewItems ( tab ) ;
2007-11-26 14:55:58 -05:00
} ,
2009-12-25 03:34:52 -05:00
attachTabFromPosition : function TSTBrowser _attachTabFromPosition ( aTab , aOldPosition )
2007-11-26 14:55:58 -05:00
{
2007-11-26 17:43:50 -05:00
var parent = this . getParentTab ( aTab ) ;
2009-09-01 10:39:01 -04:00
if ( aOldPosition === void ( 0 ) ) aOldPosition = aTab . _tPos ;
var pos = this . getChildIndex ( aTab , parent ) ;
2012-09-23 02:43:49 -04:00
var oldPos = this . getChildIndex ( this . getAllTabs ( this . mTabBrowser ) [ aOldPosition ] , parent ) ;
2009-09-01 10:39:01 -04:00
var delta ;
if ( pos == oldPos ) { // no move?
return ;
}
else if ( pos < 0 || oldPos < 0 ) {
delta = 2 ;
}
else {
delta = Math . abs ( pos - oldPos ) ;
}
2009-01-24 00:39:22 -05:00
var prevTab = this . getPreviousTab ( aTab ) ;
var nextTab = this . getNextTab ( aTab ) ;
2007-11-26 21:42:02 -05:00
var tabs = this . getDescendantTabs ( aTab ) ;
if ( tabs . length ) {
2009-01-24 00:39:22 -05:00
nextTab = this . getNextTab ( tabs [ tabs . length - 1 ] ) ;
2007-11-26 21:42:02 -05:00
}
var prevParent = this . getParentTab ( prevTab ) ;
var nextParent = this . getParentTab ( nextTab ) ;
2011-12-06 22:06:05 -05:00
var prevLevel = prevTab ? Number ( prevTab . getAttribute ( this . kNEST ) ) : - 1 ;
var nextLevel = nextTab ? Number ( nextTab . getAttribute ( this . kNEST ) ) : - 1 ;
2007-11-26 21:42:02 -05:00
var newParent ;
2007-11-26 17:43:50 -05:00
2009-09-01 10:39:01 -04:00
if ( ! prevTab ) { // moved to topmost position
2007-11-26 21:42:02 -05:00
newParent = null ;
2007-11-26 17:43:50 -05:00
}
2009-09-01 10:39:01 -04:00
else if ( ! nextTab ) { // moved to last position
newParent = ( delta > 1 ) ? prevParent : parent ;
2007-11-26 17:43:50 -05:00
}
2009-09-01 10:39:01 -04:00
else if ( prevParent == nextParent ) { // moved into existing tree
2007-11-26 17:43:50 -05:00
newParent = prevParent ;
}
2009-09-01 10:39:01 -04:00
else if ( prevLevel > nextLevel ) { // moved to end of existing tree
2009-09-01 22:03:58 -04:00
if ( this . mTabBrowser . selectedTab != aTab ) { // maybe newly opened tab
newParent = prevParent ;
}
else { // maybe drag and drop
var realDelta = Math . abs ( aTab . _tPos - aOldPosition ) ;
newParent = realDelta < 2 ? prevParent : ( parent || nextParent ) ;
}
2007-11-26 14:55:58 -05:00
}
2009-09-01 10:39:01 -04:00
else if ( prevLevel < nextLevel ) { // moved to first child position of existing tree
2009-09-01 06:30:21 -04:00
newParent = parent || nextParent ;
2007-11-26 17:43:50 -05:00
}
if ( newParent != parent ) {
2010-09-16 06:46:15 -04:00
if ( newParent ) {
if ( newParent . hidden == aTab . hidden )
this . attachTabTo ( aTab , newParent , { insertBefore : nextTab } ) ;
}
else {
2011-12-06 20:18:05 -05:00
this . detachTab ( aTab ) ;
2010-09-16 06:46:15 -04:00
}
2007-11-14 14:34:36 -05:00
}
} ,
2007-11-26 14:55:58 -05:00
2009-12-25 03:34:52 -05:00
updateChildrenArray : function TSTBrowser _updateChildrenArray ( aTab )
2007-11-14 14:34:36 -05:00
{
2012-08-04 13:53:57 -04:00
if ( ! aTab . parentNode ) return ; // do nothing for closed tab!
2007-11-14 14:34:36 -05:00
var children = this . getChildTabs ( aTab ) ;
2009-12-22 03:05:16 -05:00
children . sort ( this . sortTabsByOrder ) ;
2008-10-17 08:35:55 -04:00
this . setTabValue (
aTab ,
this . kCHILDREN ,
children
. map ( function ( aItem ) {
return aItem . getAttribute ( this . kID ) ;
} , this )
. join ( '|' )
) ;
2007-11-14 14:34:36 -05:00
} ,
2011-01-11 14:16:35 -05:00
2011-01-11 19:05:04 -05:00
// for TabView (Panorama aka Tab Candy)
2011-01-11 14:16:35 -05:00
rearrangeTabViewItems : function TSTBrowser _rearrangeTabViewItems ( aTab )
{
if (
2012-08-04 13:53:57 -04:00
! aTab . parentNode || // do nothing for closed tab!
2011-01-11 14:16:35 -05:00
! aTab . tabItem ||
! aTab . tabItem . parent ||
! aTab . tabItem . parent . reorderTabItemsBasedOnTabOrder
)
return ;
aTab . tabItem . parent . reorderTabItemsBasedOnTabOrder ( ) ;
} ,
2007-11-14 14:34:36 -05:00
2011-01-11 19:05:04 -05:00
// for TabView (Panorama aka Tab Candy)
2010-09-16 06:46:15 -04:00
onTabVisibilityChanged : function TSTBrowser _onTabVisibilityChanged ( aEvent )
{
2011-12-12 00:48:51 -05:00
/ * *
* Note : On this timing , we cannot know that which is the reason of this
* event , by exitting from Panorama or the "Move to Group" command in the
2012-01-01 15:18:14 -05:00
* context menu on tabs . So , we have to do operations with a delay to compare
* last and current group which is updated in the next event loop .
2011-12-12 00:48:51 -05:00
* /
2011-10-29 16:03:44 -04:00
var tab = aEvent . originalTarget ;
2011-12-12 00:48:51 -05:00
this . updateInvertedTabContentsOrder ( tab ) ;
this . tabVisibilityChangedTabs . push ( {
tab : tab ,
type : aEvent . type
} ) ;
if ( this . tabVisibilityChangedTimer ) {
this . window . clearTimeout ( this . tabVisibilityChangedTimer ) ;
this . tabVisibilityChangedTimer = null ;
}
this . tabVisibilityChangedTimer = this . window . setTimeout ( function ( aSelf ) {
aSelf . tabVisibilityChangedTimer = null ;
2010-12-06 11:11:34 -05:00
2011-12-12 00:48:51 -05:00
var tabs = aSelf . tabVisibilityChangedTabs ;
if ( ! tabs . length )
return ;
2011-12-13 23:30:29 -05:00
// restore tree from bottom safely
2012-02-04 13:15:38 -05:00
var restoreTabs = tabs . filter ( function ( aChanged ) {
2011-12-13 23:30:29 -05:00
return aChanged . type == 'TabShow' &&
aChanged . tab . _ _treestyletab _ _restoreState == aSelf . RESTORE _STATE _READY _TO _RESTORE ;
} )
2011-12-14 04:05:32 -05:00
. map ( function ( aChanged ) {
return aChanged . tab ;
} )
. sort ( function ( aA , aB ) {
return aB . _tPos - aA . _tPos ;
} )
2012-02-04 13:15:38 -05:00
. filter ( aSelf . restoreOneTab , aSelf ) ;
2012-02-04 16:31:03 -05:00
for ( let i = 0 , maxi = restoreTabs . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
let tab = restoreTabs [ i ] ;
2012-02-04 13:15:38 -05:00
aSelf . updateInsertionPositionInfo ( tab ) ;
delete tab . _ _treestyletab _ _restoreState ;
}
2011-12-13 23:30:29 -05:00
2012-01-01 15:18:14 -05:00
var currentGroupId = aSelf . getTabViewGroupId ( ) ;
if ( aSelf . lastTabViewGroup && currentGroupId != aSelf . lastTabViewGroup ) {
2011-12-12 00:48:51 -05:00
// We should clear it first, because updateTreeByTabVisibility() never change visibility of tabs.
aSelf . tabVisibilityChangedTabs = [ ] ;
aSelf . updateTreeByTabVisibility ( tabs . map ( function ( aChanged ) { return aChanged . tab ; } ) ) ;
2011-10-29 16:03:44 -04:00
}
2011-12-12 00:48:51 -05:00
else {
// For tabs moved by "Move to Group" command in the context menu on tabs
var processedTabs = { } ;
/ * *
* subtreeFollowParentAcrossTabGroups ( ) can change visibility of child tabs , so ,
* we must not clear tabVisibilityChangedTabs here , and we have to use
* simple "for" loop instead of Array . prototype . forEach .
* /
for ( let i = 0 ; i < aSelf . tabVisibilityChangedTabs . length ; i ++ )
{
let changed = aSelf . tabVisibilityChangedTabs [ i ] ;
let tab = changed . tab ;
if ( aSelf . getAncestorTabs ( tab ) . some ( function ( aTab ) {
return processedTabs [ aTab . getAttribute ( aSelf . kID ) ] ;
} ) )
continue ;
aSelf . subtreeFollowParentAcrossTabGroups ( tab ) ;
processedTabs [ tab . getAttribute ( aSelf . kID ) ] = true ;
}
// now we can clear it!
2011-10-29 16:03:44 -04:00
aSelf . tabVisibilityChangedTabs = [ ] ;
2011-12-12 00:48:51 -05:00
}
2012-01-01 15:18:14 -05:00
aSelf . lastTabViewGroup = currentGroupId ;
2012-08-24 07:52:26 -04:00
aSelf . checkTabsIndentOverflow ( ) ;
2011-12-12 00:48:51 -05:00
} , 0 , this ) ;
2010-09-16 06:46:15 -04:00
} ,
tabVisibilityChangedTimer : null ,
2012-01-01 15:18:14 -05:00
lastTabViewGroup : null ,
2011-12-13 09:21:31 -05:00
updateTreeByTabVisibility : function TSTBrowser _updateTreeByTabVisibility ( aChangedTabs )
2010-09-16 06:46:15 -04:00
{
2010-09-16 09:37:41 -04:00
this . internallyTabMovingCount ++ ;
2011-03-23 14:05:35 -04:00
2012-09-23 02:43:49 -04:00
var allTabs = this . getAllTabs ( this . mTabBrowser ) ;
2011-05-16 13:24:24 -04:00
var normalTabs = allTabs . filter ( function ( aTab ) {
return ! aTab . hasAttribute ( 'pinned' ) ;
} ) ;
aChangedTabs = aChangedTabs || normalTabs ;
2011-03-23 14:05:35 -04:00
2011-05-16 13:24:24 -04:00
var shownTabs = aChangedTabs . filter ( function ( aTab ) {
return ! aTab . hidden ;
} ) ;
2011-03-23 14:05:35 -04:00
2011-05-16 13:24:24 -04:00
var movingTabToAnotherGroup = ! shownTabs . length ;
var switchingGroup = ! movingTabToAnotherGroup ;
2010-12-09 08:58:06 -05:00
2011-05-16 13:24:24 -04:00
var lastIndex = allTabs . length - 1 ;
var lastMovedTab ;
normalTabs = normalTabs . slice ( 0 ) . reverse ( ) ;
2012-02-04 16:31:03 -05:00
for ( let i = 0 , maxi = normalTabs . length ; i < maxi ; i ++ )
2011-05-16 13:24:24 -04:00
{
2012-02-04 16:31:03 -05:00
let tab = normalTabs [ i ] ;
2011-05-16 13:24:24 -04:00
let parent = this . getParentTab ( tab ) ;
let attached = false ;
if ( parent && ( tab . hidden != parent . hidden ) ) {
let lastNextTab = null ;
2012-08-04 16:31:38 -04:00
this . getAncestorTabs ( tab ) . some ( function ( aAncestor ) {
if ( aAncestor . hidden == tab . hidden ) {
this . attachTabTo ( tab , aAncestor , {
2010-09-16 09:37:41 -04:00
dontMove : true ,
insertBefore : lastNextTab
} ) ;
attached = true ;
2012-08-04 16:31:38 -04:00
return true ;
2010-09-16 09:37:41 -04:00
}
2012-08-04 16:31:38 -04:00
lastNextTab = this . getNextSiblingTab ( aAncestor ) ;
return false ;
} , this ) ;
2010-09-16 09:37:41 -04:00
if ( ! attached ) {
2011-05-16 13:24:24 -04:00
this . collapseExpandTab ( tab , false , true ) ;
2011-12-06 20:18:05 -05:00
this . detachTab ( tab ) ;
2010-09-16 09:37:41 -04:00
}
2010-09-16 06:46:15 -04:00
}
2010-10-13 11:06:41 -04:00
2011-05-16 13:24:24 -04:00
if ( aChangedTabs . indexOf ( tab ) < 0 )
continue ;
2010-09-16 09:37:41 -04:00
if (
2011-05-16 13:24:24 -04:00
switchingGroup &&
! tab . hidden &&
2010-09-16 09:37:41 -04:00
! attached &&
2011-05-16 13:24:24 -04:00
! parent
2011-03-23 14:01:14 -04:00
) {
2011-05-16 13:24:24 -04:00
let prev = this . getPreviousTab ( tab ) ;
let next = this . getNextTab ( tab ) ;
2011-03-23 14:01:14 -04:00
if (
( prev && aChangedTabs . indexOf ( prev ) < 0 && ! prev . hidden ) ||
( next && aChangedTabs . indexOf ( next ) < 0 && ! next . hidden )
)
2011-05-16 13:24:24 -04:00
this . attachTabFromPosition ( tab , lastIndex ) ;
2011-03-23 14:01:14 -04:00
}
2010-10-13 11:06:41 -04:00
2011-05-16 13:24:24 -04:00
if ( movingTabToAnotherGroup && tab . hidden ) {
let index = lastMovedTab ? lastMovedTab . _tPos - 1 : lastIndex ;
this . mTabBrowser . moveTabTo ( tab , index ) ;
lastMovedTab = tab ;
2010-10-13 11:06:41 -04:00
}
2011-05-16 13:24:24 -04:00
}
2010-09-16 09:37:41 -04:00
this . internallyTabMovingCount -- ;
2010-09-16 06:46:15 -04:00
} ,
2011-12-13 09:21:31 -05:00
subtreeFollowParentAcrossTabGroups : function TSTBrowser _subtreeFollowParentAcrossTabGroups ( aParent )
2011-10-29 16:03:44 -04:00
{
if ( this . tabViewTreeIsMoving ) return ;
2011-12-12 00:48:51 -05:00
2012-01-01 15:18:14 -05:00
var id = this . getTabViewGroupId ( aParent ) ;
if ( ! id ) return ;
2011-10-29 16:03:44 -04:00
this . tabViewTreeIsMoving = true ;
this . internallyTabMovingCount ++ ;
2011-12-12 00:48:51 -05:00
var w = this . window ;
var b = this . mTabBrowser ;
2012-09-23 02:43:49 -04:00
var lastCount = this . getAllTabs ( b ) . length - 1 ;
2011-12-12 00:48:51 -05:00
this . detachTab ( aParent ) ;
b . moveTabTo ( aParent , lastCount ) ;
var descendantTabs = this . getDescendantTabs ( aParent ) ;
2012-02-04 16:31:03 -05:00
for ( let i = 0 , maxi = descendantTabs . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
let tab = descendantTabs [ i ] ;
2012-02-04 13:15:38 -05:00
w . TabView . moveTabTo ( tab , id ) ;
b . moveTabTo ( tab , lastCount ) ;
}
2011-12-12 00:48:51 -05:00
this . internallyTabMovingCount -- ;
this . tabViewTreeIsMoving = false ;
2011-10-29 16:03:44 -04:00
} ,
2011-12-13 09:21:31 -05:00
tabViewTreeIsMoving : false ,
2012-01-01 15:18:14 -05:00
getTabViewGroupId : function TSTBrowser _getTabViewGroupId ( aTab )
{
var tab = aTab || this . mTabBrowser . selectedTab ;
var item = tab . _tabViewTabItem ;
if ( ! item ) return null ;
var group = item . parent ;
if ( ! group ) return null ;
return group . id ;
} ,
2011-12-13 09:21:31 -05:00
2009-12-25 03:34:52 -05:00
onTabRestoring : function TSTBrowser _onTabRestoring ( aEvent )
2007-11-14 14:34:36 -05:00
{
2011-12-13 02:32:42 -05:00
this . restoreTree ( ) ;
2011-12-14 04:05:32 -05:00
var tab = aEvent . originalTarget ;
tab . linkedBrowser . _ _treestyletab _ _toBeRestored = false ;
this . handleRestoredTab ( tab ) ;
2011-02-02 23:57:19 -05:00
2011-04-06 01:33:59 -04:00
/ * *
* Updating of the counter which is used to know how many tabs were
* restored in a time .
2011-04-06 00:13:40 -04:00
* /
2011-05-25 16:54:46 -04:00
this . windowService . restoringCount ++ ;
2011-04-06 01:33:59 -04:00
/ * *
* By nsSessionStore . js , the next "SSTabRestoring" event will be fined
* with "window.setTimeout()" following this "SSTabRestoring" event .
2011-05-25 16:54:46 -04:00
* So , we have to do "setTimeout()" twice , instead of "Deferred.next()" .
2011-04-06 00:13:40 -04:00
* /
2011-05-25 16:54:46 -04:00
var self = this ;
this . window . setTimeout ( function ( ) {
2011-04-06 01:33:59 -04:00
/ * *
* On this timing , the next "SSTabRestoring" is not fired yet .
* We only register the countdown task for the next event loop .
2011-04-06 00:13:40 -04:00
* /
2012-08-04 13:53:57 -04:00
let key = 'onTabRestoring_' + parseInt ( Math . random ( ) * 65000 ) ;
( self . deferredTasks [ key ] = self . windowService . Deferred . next ( function ( ) {
2011-04-06 01:33:59 -04:00
/ * *
* On this timing , the next "SSTabRestoring" was fired .
* Now we can decrement the counter .
2011-04-06 00:13:40 -04:00
* /
2011-05-25 16:54:46 -04:00
self . windowService . restoringCount -- ;
2012-08-04 13:53:57 -04:00
} ) ) . error ( self . defaultDeferredErrorHandler ) . next ( function ( ) {
delete self . deferredTasks [ key ] ;
} ) ;
2011-04-06 00:13:40 -04:00
} , 0 ) ;
2011-12-14 04:05:32 -05:00
if ( ! tab . selected &&
2011-02-03 00:36:01 -05:00
this . mTabBrowser . currentURI . spec == 'about:sessionrestore' ) {
2011-02-02 23:57:19 -05:00
let frame = this . mTabBrowser . contentWindow ;
frame = frame . wrappedJSObject || frame ;
let tree = frame . document . getElementById ( 'tabList' ) ;
let data = frame . gTreeData ;
if ( tree && data ) {
let item = data [ tree . currentIndex ] ;
2011-05-25 16:54:46 -04:00
this . window . setTimeout ( function ( aSelf , aTab , aTitle , aParent ) {
2011-02-02 23:57:19 -05:00
if ( aTab . label == aTitle )
aSelf . attachTabTo ( aTab , aParent ) ;
2011-12-14 04:05:32 -05:00
} , 0 , this , tab , item . label , this . mTabBrowser . selectedTab ) ;
2011-02-02 23:57:19 -05:00
}
}
2008-11-09 23:48:11 -05:00
} ,
2009-12-25 15:48:14 -05:00
2011-03-01 10:08:56 -05:00
RESTORED _TREE _COLLAPSED _STATE _LAST _STATE : - 1 ,
RESTORED _TREE _COLLAPSED _STATE _COLLAPSED : 0 ,
RESTORED _TREE _COLLAPSED _STATE _EXPANDED : 1 ,
2011-12-13 23:30:29 -05:00
RESTORE _STATE _INITIAL : 0 ,
RESTORE _STATE _READY _TO _RESTORE : 1 ,
RESTORE _STATE _STRUCTURE _RESTORED : 2 ,
2011-12-12 13:54:43 -05:00
handleRestoredTab : function TSTBrowser _handleRestoredTab ( aTab )
2008-11-09 23:48:11 -05:00
{
2011-12-14 04:05:32 -05:00
if ( aTab . _ _treestyletab _ _restoreState == this . RESTORE _STATE _READY _TO _RESTORE ) {
// this is a hidden tab in the background group, and
// have to be restored by restoreOneTab() on "TabShown" event.
this . deleteTabValue ( aTab , this . kCLOSED _SET _ID ) ;
return ;
}
2009-10-25 13:31:47 -04:00
2011-12-14 04:05:32 -05:00
var [ id , mayBeDuplicated ] = this . _restoreTabId ( aTab ) ;
2011-12-13 23:30:29 -05:00
var structureRestored = aTab . _ _treestyletab _ _restoreState == this . RESTORE _STATE _STRUCTURE _RESTORED ;
2011-05-04 14:56:54 -04:00
var children = this . getTabValue ( aTab , this . kCHILDREN ) ;
2011-12-04 21:54:07 -05:00
if (
2011-12-05 05:31:12 -05:00
! structureRestored &&
(
! mayBeDuplicated ||
aTab . getAttribute ( this . kCHILDREN ) != children
)
2011-12-04 21:54:07 -05:00
) {
2011-12-07 14:40:26 -05:00
// failsafe
2011-12-06 20:18:05 -05:00
this . detachAllChildren ( aTab , {
2011-05-04 14:56:54 -04:00
dontUpdateIndent : true ,
2011-05-25 17:04:16 -04:00
dontAnimate : this . windowService . restoringTree
2011-05-04 14:56:54 -04:00
} ) ;
}
2011-12-08 12:58:36 -05:00
var closeSetId = ! structureRestored && this . _getCloseSetId ( aTab , mayBeDuplicated ) ;
2011-05-04 14:56:54 -04:00
2012-08-04 18:08:04 -04:00
// remove temporary cache
2011-12-12 13:54:43 -05:00
var currentId = aTab . getAttribute ( this . kID ) ;
2012-09-23 04:59:19 -04:00
if ( id != currentId &&
currentId &&
currentId in this . tabsHash &&
this . tabsHash [ currentId ] == aTab )
2011-12-12 13:54:43 -05:00
delete this . tabsHash [ currentId ] ;
2012-01-03 10:13:35 -05:00
this . setTabValue ( aTab , this . kID , id ) ;
this . tabsHash [ id ] = aTab ;
2011-05-04 14:56:54 -04:00
2011-12-07 14:40:26 -05:00
if ( structureRestored ) {
2011-12-14 04:05:32 -05:00
this . _fixMissingAttributesFromSessionData ( aTab ) ;
2011-12-07 14:40:26 -05:00
}
else {
2011-12-05 05:31:12 -05:00
let isSubtreeCollapsed = this . _restoreSubtreeCollapsedState ( aTab ) ;
2011-05-04 14:56:54 -04:00
2011-12-13 02:10:49 -05:00
let restoringMultipleTabs = this . windowService . restoringTree ;
let options = {
dontExpand : restoringMultipleTabs ,
dontUpdateIndent : true ,
dontAnimate : restoringMultipleTabs
} ;
let childTabs = this . _restoreChildTabsRelation ( aTab , children , mayBeDuplicated , options ) ;
2011-05-04 14:56:54 -04:00
2011-12-05 05:31:12 -05:00
this . _restoreTabPositionAndIndent ( aTab , childTabs , mayBeDuplicated ) ;
2011-05-04 14:56:54 -04:00
2012-01-03 08:03:51 -05:00
if ( closeSetId )
this . restoreClosedSet ( closeSetId , aTab ) ;
2011-12-05 05:31:12 -05:00
if ( isSubtreeCollapsed )
this . collapseExpandSubtree ( aTab , isSubtreeCollapsed ) ;
}
2011-05-04 14:56:54 -04:00
if ( mayBeDuplicated )
this . clearRedirectionTable ( ) ;
2011-12-14 04:05:32 -05:00
delete aTab . _ _treestyletab _ _restoreState ;
2011-05-04 14:56:54 -04:00
} ,
2011-12-13 09:21:31 -05:00
_restoreTabId : function TSTBrowser _restoreTabId ( aTab )
2011-05-04 14:56:54 -04:00
{
2012-09-23 04:19:09 -04:00
// kID can be overridden by nsSessionStore. kID_NEW is for failsafe.
var currentId = aTab . getAttribute ( this . kID _NEW ) || aTab . getAttribute ( this . kID ) ;
aTab . removeAttribute ( this . kID _NEW ) ;
2011-12-13 23:30:29 -05:00
var restoredId = this . getTabValue ( aTab , this . kID ) ;
2009-09-29 11:05:08 -04:00
var mayBeDuplicated = false ;
2007-11-17 07:50:36 -05:00
2011-12-13 23:30:29 -05:00
aTab . setAttribute ( this . kID _RESTORING , restoredId ) ;
2011-05-04 14:56:54 -04:00
if ( this . isTabDuplicated ( aTab ) ) {
2009-09-29 11:05:08 -04:00
mayBeDuplicated = true ;
2011-05-04 10:13:37 -04:00
/ * *
* If the tab has its ID as the attribute , then we should use it
* instead of redirected ID , because the tab has been possibly
* attached to another tab .
* /
2011-12-13 23:30:29 -05:00
restoredId = currentId || this . redirectId ( restoredId ) ;
2009-10-26 12:13:24 -04:00
}
2011-05-04 14:56:54 -04:00
aTab . removeAttribute ( this . kID _RESTORING ) ;
2009-10-26 12:13:24 -04:00
2011-12-13 23:30:29 -05:00
return [ restoredId || currentId , mayBeDuplicated ] ;
2011-05-04 14:56:54 -04:00
} ,
2011-12-13 09:21:31 -05:00
_getCloseSetId : function TSTBrowser _getCloseSetId ( aTab , aMayBeDuplicated )
2011-05-04 14:56:54 -04:00
{
2009-12-25 15:48:14 -05:00
var closeSetId = null ;
2011-05-04 14:56:54 -04:00
if ( ! aMayBeDuplicated ) {
closeSetId = this . getTabValue ( aTab , this . kCLOSED _SET _ID ) ;
2011-05-04 10:13:37 -04:00
/ * *
* If the tab is not a duplicated but it has a parent , then ,
* it is wrongly attacched by tab moving on restoring .
* Restoring the old ID ( the next statement ) breaks the children
* list of the temporary parent and causes many problems .
2011-12-06 20:20:14 -05:00
* So , to prevent these problems , I detach the tab from the temporary
2011-05-04 10:13:37 -04:00
* parent manually .
* If the ID stored in the session equals to the value of the
* attribute stored in the element itself , then don ' t reset the
* tab , because the restoring session is got from the tab itself .
* ( like SS . setTabState ( tab , SS . getTabState ( tab ) ) )
2010-09-09 04:26:32 -04:00
* /
2011-05-04 14:56:54 -04:00
if ( this . getTabValue ( aTab , this . kID ) != aTab . getAttribute ( this . kID ) )
this . resetTab ( aTab , false ) ;
2007-11-23 16:34:43 -05:00
}
2011-05-04 14:56:54 -04:00
this . deleteTabValue ( aTab , this . kCLOSED _SET _ID ) ;
return closeSetId ;
} ,
2011-12-13 09:21:31 -05:00
2012-01-29 05:54:02 -05:00
_fixMissingAttributesFromSessionData : function TSTBrowser _fixMissingAttributesFromSessionData ( aTab )
2011-12-14 04:05:32 -05:00
{
/ * *
* By some reasons ( ex . persistTabAttribute ( ) ) , actual state of
* the tab ( attributes ) can be lost on SSTabRestoring .
* For failsafe , we must override actual attributes by stored
* values .
* /
2012-02-04 16:31:03 -05:00
var keys = [
2012-02-04 13:15:38 -05:00
this . kINSERT _BEFORE ,
this . kINSERT _AFTER
2012-02-04 16:31:03 -05:00
] ;
for ( let i = 0 , maxi = keys . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
let key = keys [ i ] ;
2012-02-04 13:15:38 -05:00
let tab = this . getTabValue ( aTab , key ) ;
2011-12-14 04:05:32 -05:00
if ( this . getTabById ( tab ) )
2012-02-04 16:31:03 -05:00
this . setTabValue ( aTab , key , tab ) ;
2012-02-04 13:15:38 -05:00
}
2011-12-14 04:05:32 -05:00
let parentId = this . getTabValue ( aTab , this . kPARENT ) ;
let parentTab = this . getTabById ( parentId ) ;
if ( parentTab && parentTab . _tPos < aTab . _tPos )
this . setTabValue ( aTab , this . kPARENT , parentId ) ;
else
this . deleteTabValue ( aTab , this . kPARENT ) ;
let ancestors = [ aTab ] . concat ( this . getAncestorTabs ( aTab ) ) ;
let children = this . getTabValue ( aTab , this . kCHILDREN ) ;
children = children . split ( '|' ) . filter ( function ( aChild ) {
let tab = this . getTabById ( aChild ) ;
return tab && ancestors . indexOf ( tab ) < 0 ;
} , this ) ;
this . setTabValue ( aTab , this . kCHILDREN , children . join ( '|' ) ) ;
let subtreeCollapsed = this . getTabValue ( aTab , this . kSUBTREE _COLLAPSED ) ;
if ( subtreeCollapsed != aTab . getAttribute ( this . kSUBTREE _COLLAPSED ) )
this . collapseExpandSubtree ( aTab , subtreeCollapsed == 'true' , true ) ;
} ,
2011-12-13 09:21:31 -05:00
_restoreSubtreeCollapsedState : function TSTBrowser _restoreSubtreeCollapsedState ( aTab , aCollapsed )
2011-05-04 14:56:54 -04:00
{
2012-10-23 12:43:56 -04:00
var shouldCollapse = utils . getTreePref ( 'collapseExpandSubtree.sessionRestore' ) ;
2011-12-07 15:12:33 -05:00
if ( aCollapsed === void ( 0 ) )
aCollapsed = this . getTabValue ( aTab , this . kSUBTREE _COLLAPSED ) == 'true' ;
2011-03-01 10:08:56 -05:00
var isSubtreeCollapsed = (
2011-05-25 16:54:46 -04:00
this . windowService . restoringTree &&
2011-03-01 10:08:56 -05:00
(
shouldCollapse == this . RESTORED _TREE _COLLAPSED _STATE _LAST _STATE ?
2011-12-07 15:12:33 -05:00
aCollapsed :
2011-03-01 10:08:56 -05:00
shouldCollapse == this . RESTORED _TREE _COLLAPSED _STATE _COLLAPSED
)
) ;
2011-05-04 14:56:54 -04:00
this . setTabValue ( aTab , this . kSUBTREE _COLLAPSED , isSubtreeCollapsed ) ;
return isSubtreeCollapsed ;
} ,
2011-12-13 09:21:31 -05:00
_restoreChildTabsRelation : function TSTBrowser _restoreChildTabsRelation ( aTab , aChildrenList , aMayBeDuplicated , aOptions )
2011-05-04 14:56:54 -04:00
{
var childTabs = [ ] ;
if ( ! aChildrenList )
return childTabs ;
2007-11-14 14:34:36 -05:00
2011-05-04 14:56:54 -04:00
aTab . removeAttribute ( this . kCHILDREN ) ;
2007-11-17 07:50:36 -05:00
2011-05-04 14:56:54 -04:00
aChildrenList = aChildrenList . split ( '|' ) ;
if ( aMayBeDuplicated )
aChildrenList = aChildrenList . map ( function ( aChild ) {
return this . redirectId ( aChild ) ;
} , this ) ;
2009-09-01 22:52:16 -04:00
2012-02-04 16:31:03 -05:00
for ( let i = 0 , maxi = aChildrenList . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
let childTab = aChildrenList [ i ] ;
2012-02-04 13:15:38 -05:00
if ( childTab && ( childTab = this . getTabById ( childTab ) ) ) {
2011-12-13 02:10:49 -05:00
let options = aOptions ;
if ( options && typeof options == 'function' )
2012-02-04 13:15:38 -05:00
options = options ( childTab ) ;
this . attachTabTo ( childTab , aTab , options ) ;
childTabs . push ( childTab ) ;
2007-11-26 14:55:58 -05:00
}
2012-02-04 13:15:38 -05:00
}
2011-05-04 14:56:54 -04:00
aChildrenList = aChildrenList . join ( '|' ) ;
if ( aTab . getAttribute ( this . kCHILDREN ) == aChildrenList )
aTab . removeAttribute ( this . kCHILDREN _RESTORING ) ;
else
aTab . setAttribute ( this . kCHILDREN _RESTORING , aChildrenList ) ;
2007-11-26 14:55:58 -05:00
2011-05-04 14:56:54 -04:00
return childTabs ;
} ,
2011-12-13 09:21:31 -05:00
_restoreTabPositionAndIndent : function TSTBrowser _restoreTabPositionAndIndent ( aTab , aChildTabs , aMayBeDuplicated )
2011-05-04 14:56:54 -04:00
{
2011-05-25 16:54:46 -04:00
var restoringMultipleTabs = this . windowService . restoringTree ;
2011-05-04 14:56:54 -04:00
var position = this . _prepareInsertionPosition ( aTab , aMayBeDuplicated ) ;
var parent = position . parent ;
2007-11-14 14:34:36 -05:00
if ( parent ) {
2011-05-04 14:56:54 -04:00
aTab . removeAttribute ( this . kPARENT ) ;
2007-11-14 14:34:36 -05:00
parent = this . getTabById ( parent ) ;
if ( parent ) {
2011-05-04 14:56:54 -04:00
this . attachTabTo ( aTab , parent , {
2009-10-25 13:31:47 -04:00
dontExpand : restoringMultipleTabs ,
2011-05-04 14:56:54 -04:00
insertBefore : position . next ,
2009-08-26 05:33:54 -04:00
dontUpdateIndent : true ,
2009-10-25 13:31:47 -04:00
dontAnimate : restoringMultipleTabs
2007-11-14 14:34:36 -05:00
} ) ;
2011-05-04 14:56:54 -04:00
this . updateTabsIndent ( [ aTab ] , undefined , restoringMultipleTabs ) ;
2007-11-14 14:34:36 -05:00
this . checkTabsIndentOverflow ( ) ;
2009-09-29 19:54:57 -04:00
2009-09-30 01:36:08 -04:00
if ( parent . getAttribute ( this . kCHILDREN _RESTORING ) )
this . correctChildTabsOrderWithDelay ( parent ) ;
2007-11-14 14:34:36 -05:00
}
else {
2011-05-04 14:56:54 -04:00
this . deleteTabValue ( aTab , this . kPARENT ) ;
2007-11-14 14:34:36 -05:00
}
}
2011-05-04 14:56:54 -04:00
else {
if ( aChildTabs . length ) {
this . updateTabsIndent ( aChildTabs , undefined , restoringMultipleTabs ) ;
this . checkTabsIndentOverflow ( ) ;
}
this . _restoreTabPosition ( aTab , position . next ) ;
}
} ,
2011-12-13 09:21:31 -05:00
_prepareInsertionPosition : function TSTBrowser _prepareInsertionPosition ( aTab , aMayBeDuplicated )
2011-05-04 14:56:54 -04:00
{
var next = this . getTabValue ( aTab , this . kINSERT _BEFORE ) ;
if ( next && aMayBeDuplicated ) next = this . redirectId ( next ) ;
next = this . getTabById ( next ) ;
if ( ! next ) {
let prev = this . getTabValue ( aTab , this . kINSERT _AFTER ) ;
if ( prev && aMayBeDuplicated ) prev = this . redirectId ( prev ) ;
prev = this . getTabById ( prev ) ;
next = this . getNextSiblingTab ( prev ) ;
2007-11-14 14:34:36 -05:00
}
2011-05-04 14:56:54 -04:00
var ancestors = ( this . getTabValue ( aTab , this . kANCESTOR ) || this . getTabValue ( aTab , this . kPARENT ) ) . split ( '|' ) ;
var parent = null ;
for ( let i in ancestors )
{
if ( aMayBeDuplicated ) ancestors [ i ] = this . redirectId ( ancestors [ i ] ) ;
parent = this . getTabById ( ancestors [ i ] ) ;
if ( parent ) {
parent = ancestors [ i ] ;
break ;
2008-04-29 14:17:44 -04:00
}
2007-11-14 14:34:36 -05:00
}
2011-05-04 14:56:54 -04:00
this . deleteTabValue ( aTab , this . kANCESTOR ) ;
2007-11-14 14:34:36 -05:00
2011-05-04 14:56:54 -04:00
/ * *
* If the tab is a duplicated and the tab has already been
* attached , then reuse current status based on attributes .
* ( Note , if the tab is not a duplicated tab , all attributes
* have been cleared . )
* /
if ( ! parent ) {
parent = aTab . getAttribute ( this . kPARENT ) ;
if ( parent && ! next )
next = this . getNextSiblingTab ( aTab ) ;
}
2008-02-22 16:52:44 -05:00
2011-05-04 14:56:54 -04:00
return {
parent : parent ,
next : next
} ;
} ,
2011-12-13 09:21:31 -05:00
_restoreTabPosition : function TSTBrowser _restoreTabPosition ( aTab , aNextTab )
2011-05-04 14:56:54 -04:00
{
if ( ! aNextTab ) aNextTab = this . getNextTab ( aTab ) ;
var parentOfNext = this . getParentTab ( aNextTab ) ;
var newPos = - 1 ;
if ( parentOfNext ) {
let descendants = this . getDescendantTabs ( parentOfNext ) ;
newPos = descendants [ descendants . length - 1 ] . _tPos ;
}
else if ( aNextTab ) {
newPos = aNextTab . _tPos ;
if ( newPos > aTab . _tPos ) newPos -- ;
}
if ( newPos > - 1 )
this . mTabBrowser . moveTabTo ( aTab , newPos ) ;
2008-02-23 20:06:19 -05:00
} ,
2011-12-13 09:21:31 -05:00
2009-12-25 15:48:14 -05:00
correctChildTabsOrderWithDelay : function TSTBrowser _correctChildTabsOrderWithDelay ( aTab )
2009-09-30 01:36:08 -04:00
{
if ( aTab . correctChildTabsOrderWithDelayTimer )
2011-05-25 16:54:46 -04:00
this . window . clearTimeout ( aTab . correctChildTabsOrderWithDelayTimer ) ;
2009-09-30 01:36:08 -04:00
2011-05-25 16:54:46 -04:00
aTab . correctChildTabsOrderWithDelayTimer = this . window . setTimeout ( function ( aSelf ) {
2009-09-30 01:36:08 -04:00
aSelf . correctChildTabsOrder ( aTab ) ;
2009-09-30 04:14:54 -04:00
} , 10 , this ) ;
2009-09-30 01:36:08 -04:00
} ,
2009-12-25 15:48:14 -05:00
correctChildTabsOrder : function TSTBrowser _correctChildTabsOrder ( aTab )
2009-09-30 01:36:08 -04:00
{
2012-08-04 13:53:57 -04:00
if ( ! aTab . parentNode ) return ; // do nothing for closed tab!
2009-09-30 01:36:08 -04:00
var restoringChildren = aTab . getAttribute ( this . kCHILDREN _RESTORING ) ;
if ( ! restoringChildren ) return ;
var children = aTab . getAttribute ( this . kCHILDREN ) ;
if ( restoringChildren != children ) {
2012-02-04 16:31:03 -05:00
var restoringChildrenIDs = restoringChildren . split ( '|' ) . reverse ( ) ;
for ( let i = 0 , maxi = restoringChildrenIDs . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
let child = this . getTabById ( restoringChildrenIDs [ i ] ) ;
2012-02-04 13:15:38 -05:00
if ( ! child ) continue ;
2009-09-30 01:36:08 -04:00
2012-02-04 13:15:38 -05:00
let nextTab = i > 0 ?
this . getTabById ( restoringChildrenIDs [ i - 1 ] ) :
2009-09-30 01:36:08 -04:00
this . getNextSiblingTab ( aTab ) ;
2012-02-04 13:15:38 -05:00
if ( nextTab == this . getNextSiblingTab ( child ) ) continue ;
2009-09-30 01:36:08 -04:00
2009-09-30 20:18:03 -04:00
let newPos = - 1 ;
2009-09-30 01:36:08 -04:00
if ( nextTab ) {
newPos = nextTab . _tPos ;
2012-02-04 13:15:38 -05:00
if ( newPos > child . _tPos ) newPos -- ;
2009-09-30 01:36:08 -04:00
}
2009-09-30 20:18:03 -04:00
if ( newPos > - 1 )
2012-02-04 13:15:38 -05:00
this . moveTabSubtreeTo ( child , newPos ) ;
}
2009-09-30 01:36:08 -04:00
children = aTab . getAttribute ( this . kCHILDREN ) ;
}
if ( restoringChildren == children )
aTab . removeAttribute ( this . kCHILDREN _RESTORING ) ;
aTab . correctChildTabsOrderWithDelayTimer = null ;
} ,
2009-12-25 15:48:14 -05:00
2009-12-25 03:34:52 -05:00
redirectId : function TSTBrowser _redirectId ( aId )
2008-02-23 20:06:19 -05:00
{
2008-11-10 00:21:34 -05:00
if ( ! ( aId in this . _redirectionTable ) )
this . _redirectionTable [ aId ] = this . makeNewId ( ) ;
return this . _redirectionTable [ aId ] ;
2008-02-23 20:06:19 -05:00
} ,
2008-11-10 00:21:34 -05:00
_redirectionTable : { } ,
2008-02-24 02:58:12 -05:00
2009-12-25 03:34:52 -05:00
clearRedirectionTable : function TSTBrowser _clearRedirectionTable ( )
2008-02-23 20:06:19 -05:00
{
2008-11-10 00:21:34 -05:00
if ( this . _clearRedirectionTableTimer ) {
2011-05-25 16:54:46 -04:00
this . window . clearTimeout ( this . _clearRedirectionTableTimer ) ;
2008-11-10 00:21:34 -05:00
this . _clearRedirectionTableTimer = null ;
2008-02-23 20:06:19 -05:00
}
2011-05-25 16:54:46 -04:00
this . _clearRedirectionTableTimer = this . window . setTimeout ( function ( aSelf ) {
2008-11-10 00:21:34 -05:00
aSelf . _redirectionTable = { } ;
2008-02-23 20:06:19 -05:00
} , 1000 , this ) ;
} ,
2008-11-10 00:21:34 -05:00
_clearRedirectionTableTimer : null ,
2009-12-25 15:48:14 -05:00
2010-03-03 08:30:49 -05:00
restoreClosedSet : function TSTBrowser _restoreClosedSet ( aId , aRestoredTab )
2009-12-25 15:48:14 -05:00
{
2010-11-10 11:14:04 -05:00
var behavior = this . undoCloseTabSetBehavior ;
2009-12-25 15:48:14 -05:00
if (
2010-01-14 03:50:10 -05:00
aRestoredTab . _ _treestyletab _ _restoredByUndoCloseTab ||
! this . browser . _ _treestyletab _ _readyToUndoCloseTab ||
2011-12-15 00:12:41 -05:00
this . useTMPSessionAPI ||
2009-12-25 15:48:14 -05:00
this . _restoringClosedSet ||
2009-12-26 23:56:16 -05:00
! ( behavior & this . kUNDO _CLOSE _SET || behavior & this . kUNDO _ASK )
2009-12-25 15:48:14 -05:00
)
return ;
var indexes = [ ] ;
2012-02-04 16:31:03 -05:00
var items = this . evalInSandbox ( '(' + this . SessionStore . getClosedTabData ( this . window ) + ')' ) ;
for ( let i = 0 , maxi = items . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
let item = items [ i ] ;
2012-02-04 13:15:38 -05:00
if ( item . state . extData &&
item . state . extData [ this . kCLOSED _SET _ID ] &&
item . state . extData [ this . kCLOSED _SET _ID ] == aId )
indexes . push ( i ) ;
}
2009-12-25 15:48:14 -05:00
2009-12-25 16:10:25 -05:00
var count = parseInt ( aId . split ( '::' ) [ 1 ] ) ;
2009-12-25 16:09:52 -05:00
if (
! indexes . length ||
(
indexes . length + 1 < count &&
2009-12-26 23:56:16 -05:00
behavior & this . kUNDO _CLOSE _FULL _SET
2010-11-10 11:14:04 -05:00
)
2009-12-25 16:09:52 -05:00
)
2010-11-10 09:02:53 -05:00
return ;
2010-11-10 12:13:18 -05:00
if ( behavior & this . kUNDO _ASK ) {
let self = this ;
2011-12-08 12:58:36 -05:00
aRestoredTab . addEventListener ( 'SSTabRestoring' , function ( aEvent ) {
2010-11-10 12:13:18 -05:00
aRestoredTab . removeEventListener ( aEvent . type , arguments . callee , false ) ;
self . askUndoCloseTabSetBehavior ( aRestoredTab , indexes . length )
. next ( function ( aBehavior ) {
if ( aBehavior & self . kUNDO _CLOSE _SET )
self . doRestoreClosedSet ( aRestoredTab , indexes ) ;
} ) ;
} , false ) ;
}
else if ( behavior & this . kUNDO _CLOSE _SET ) {
this . doRestoreClosedSet ( aRestoredTab , indexes ) ;
}
2010-11-10 09:02:53 -05:00
} ,
2011-12-13 09:21:31 -05:00
doRestoreClosedSet : function TSTBrowser _doRestoreClosedSet ( aRestoredTab , aIndexes )
2010-11-10 11:14:04 -05:00
{
2011-05-25 16:54:46 -04:00
if ( ! this . window . PlacesUIUtils . _confirmOpenInTabs ( aIndexes . length ) )
2009-12-25 16:09:52 -05:00
return ;
2009-12-25 15:48:14 -05:00
this . _restoringClosedSet = true ;
this . stopRendering ( ) ;
2011-05-25 16:54:46 -04:00
this . windowService . restoringTree = true ;
2009-12-25 15:48:14 -05:00
var offset = 0 ;
2012-02-04 16:31:03 -05:00
for ( let i = 0 , maxi = aIndexes . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
this . window . undoCloseTab ( aIndexes [ i ] - ( offset ++ ) ) ;
2012-02-04 13:15:38 -05:00
}
2009-12-25 15:48:14 -05:00
2011-05-25 16:54:46 -04:00
this . window . setTimeout ( function ( aSelf , aNextFocused ) {
2011-12-08 11:40:43 -05:00
aSelf . windowService . restoringTree = false ;
2009-12-25 22:34:13 -05:00
aSelf . mTabBrowser . selectedTab = aNextFocused ;
} , 0 , this , aRestoredTab || aSelf . mTabBrowser . selectedTab ) ;
2009-12-25 15:48:14 -05:00
this . startRendering ( ) ;
this . _restoringClosedSet = false ;
} ,
_restoringClosedSet : false ,
2011-12-13 09:21:31 -05:00
2009-12-25 03:34:52 -05:00
onTabRestored : function TSTBrowser _onTabRestored ( aEvent )
2009-10-25 13:31:47 -04:00
{
2010-01-14 03:50:10 -05:00
delete aEvent . originalTarget . _ _treestyletab _ _restoredByUndoCloseTab ;
2009-10-25 13:31:47 -04:00
} ,
2011-12-08 21:11:53 -05:00
onTabPinned : function TSTBrowser _onTabPinned ( aTab )
2011-01-21 23:21:39 -05:00
{
var parentTab = this . getParentTab ( aTab ) ;
2012-08-02 14:29:23 -04:00
this . collapseExpandSubtree ( aTab , false ) ;
2011-10-29 16:50:27 -04:00
/ * *
* Children of the newly pinned tab are possibly
* moved to the top of the tab bar , by TabMove event
* from the newly pinned tab . So , we have to
* reposition unexpectedly moved children .
* /
2011-09-05 22:33:38 -04:00
if ( ! parentTab ) {
2011-10-29 16:50:27 -04:00
/ * *
* Universal but dangerous logic . "__treestyletab__previousPosition"
* can be broken by multiple movings .
* /
let b = this . browser ;
this . internallyTabMovingCount ++ ;
2012-02-04 16:31:03 -05:00
let children = this . getDescendantTabs ( aTab ) . reverse ( ) ;
for ( let i = 0 , maxi = children . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
let childTab = children [ i ] ;
2012-02-04 13:15:38 -05:00
if ( childTab . _ _treestyletab _ _previousPosition > childTab . _tPos )
b . moveTabTo ( childTab , childTab . _ _treestyletab _ _previousPosition ) ;
}
2011-10-29 16:50:27 -04:00
this . internallyTabMovingCount -- ;
2011-09-05 22:33:38 -04:00
}
else {
2011-09-05 22:37:24 -04:00
/ * *
2011-10-29 16:50:27 -04:00
* Safer logic . This cannot be available for "root" tabs because
* their children ( already moved ) have no way to know the anchor
* position ( the next sibling of the pinned tab itself ) .
2011-09-05 22:37:24 -04:00
* /
2011-09-05 22:33:38 -04:00
let b = this . browser ;
this . internallyTabMovingCount ++ ;
2012-02-04 16:31:03 -05:00
let children = this . getChildTabs ( aTab ) . reverse ( ) ;
for ( let i = 0 , maxi = children . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
let childTab = children [ i ] ;
2012-02-04 13:15:38 -05:00
if ( childTab . _tPos < parentTab . _tPos )
b . moveTabTo ( childTab , parentTab . _tPos ) ;
}
2011-09-05 22:33:38 -04:00
this . internallyTabMovingCount -- ;
}
2011-01-21 23:21:39 -05:00
2011-12-06 20:18:05 -05:00
this . detachAllChildren ( aTab , {
2011-09-05 22:33:38 -04:00
behavior : this . getCloseParentBehaviorForTab (
aTab ,
this . kCLOSE _PARENT _BEHAVIOR _PROMOTE _FIRST _CHILD
)
} ) ;
2011-12-06 20:18:05 -05:00
this . detachTab ( aTab ) ;
2011-01-21 23:21:39 -05:00
this . collapseExpandTab ( aTab , false ) ;
2011-03-18 17:06:04 -04:00
if ( this . isVertical ) this . positionPinnedTabsWithDelay ( ) ;
2011-01-21 23:21:39 -05:00
} ,
2011-12-08 21:11:53 -05:00
onTabUnpinned : function TSTBrowser _onTabUnpinned ( aTab )
2011-01-21 23:21:39 -05:00
{
2011-04-07 14:26:22 -04:00
var style = aTab . style ;
style . marginLeft = style . marginRight = style . marginTop = '' ;
2011-01-21 23:21:39 -05:00
this . updateInvertedTabContentsOrder ( aTab ) ;
2011-03-18 17:06:04 -04:00
if ( this . isVertical ) this . positionPinnedTabsWithDelay ( ) ;
2011-01-21 23:21:39 -05:00
} ,
2009-12-25 03:34:52 -05:00
onTabSelect : function TSTBrowser _onTabSelect ( aEvent )
2007-11-14 14:34:36 -05:00
{
var b = this . mTabBrowser ;
var tab = b . selectedTab
2011-11-29 06:36:49 -05:00
this . cancelDelayedExpandOnTabSelect ( ) ;
2011-05-06 10:40:07 -04:00
if (
/ * *
* < tabbrowser > . previewTab ( ) focuses to the tab internally ,
* so we should ignore this event if it is fired from previewTab ( ) .
* /
b . _previewMode ||
/ * *
* Ignore selected tabs which is being closed . For example ,
* when a collapsed tree is closed , Firefox unexpectedly gives
* focus to a collapsed child in the tree .
* /
( b . _removingTabs && b . _removingTabs . indexOf ( tab ) > - 1 )
)
2010-04-06 10:28:51 -04:00
return ;
2012-10-23 12:43:56 -04:00
var shouldCollapseExpandNow = utils . getTreePref ( 'autoCollapseExpandSubtreeOnSelect' ) ;
2012-02-09 13:59:13 -05:00
var newActiveTabOptions = {
canCollapseTree : shouldCollapseExpandNow ,
canExpandTree : shouldCollapseExpandNow
} ;
2009-10-25 22:36:42 -04:00
if ( this . isCollapsed ( tab ) ) {
2012-10-23 12:43:56 -04:00
if ( utils . getTreePref ( 'autoExpandSubtreeOnCollapsedChildFocused' ) ) {
2012-08-04 16:31:38 -04:00
this . getAncestorTabs ( tab ) . forEach ( function ( aAncestor ) {
this . collapseExpandSubtree ( aAncestor , false ) ;
} , this ) ;
2012-02-09 13:59:13 -05:00
this . handleNewActiveTab ( tab , newActiveTabOptions ) ;
2009-07-09 01:03:07 -04:00
}
else {
b . selectedTab = this . getRootTab ( tab ) ;
2007-11-14 14:34:36 -05:00
}
}
2009-08-14 02:12:08 -04:00
else if (
(
2012-02-09 13:59:13 -05:00
/ * *
* Focus movings by arrow keys should not be handled on TabSelect ,
* because they are already handled by handleAdvanceSelectedTab ( ) .
* /
this . windowService . arrowKeyEventOnTab &&
this . windowService . arrowKeyEventOnTab . advanceFocus
) ||
(
/ * *
* Focus movings by closing of the old current tab should be handled
* only when it is activated by user preference expressly .
* /
this . _focusChangedByCurrentTabRemove &&
2012-10-23 12:43:56 -04:00
! utils . getTreePref ( 'autoCollapseExpandSubtreeOnSelect.onCurrentTabRemove' )
2009-08-14 02:12:08 -04:00
)
2012-02-09 13:59:13 -05:00
) {
// do nothing!
}
else if ( this . hasChildTabs ( tab ) && this . isSubtreeCollapsed ( tab ) ) {
if (
this . _focusChangedByShortcut &&
this . windowService . accelKeyPressed
2009-08-14 02:12:08 -04:00
) {
2012-10-23 12:43:56 -04:00
if ( utils . getTreePref ( 'autoExpandSubtreeOnSelect.whileFocusMovingByShortcut' ) ) {
2012-02-09 13:59:13 -05:00
newActiveTabOptions . canExpandTree = true ;
newActiveTabOptions . canCollapseTree = (
newActiveTabOptions . canCollapseTree &&
2012-10-23 12:43:56 -04:00
utils . getTreePref ( 'autoExpandSubtreeOnSelect.whileFocusMovingByShortcut.collapseOthers' )
2012-02-09 13:59:13 -05:00
) ;
2012-10-23 12:43:56 -04:00
let delay = utils . getTreePref ( 'autoExpandSubtreeOnSelect.whileFocusMovingByShortcut.delay' ) ;
2012-02-09 13:59:13 -05:00
if ( delay > 0 ) {
this . _autoExpandOnTabSelectTimer = this . window . setTimeout ( function ( aSelf ) {
if ( tab && tab . parentNode )
aSelf . handleNewActiveTab ( tab , newActiveTabOptions ) ;
} , delay , this ) ;
2011-11-29 12:21:33 -05:00
}
else {
2012-02-09 13:59:13 -05:00
this . handleNewActiveTab ( tab , newActiveTabOptions ) ;
2011-11-29 12:21:33 -05:00
}
2011-11-29 06:36:49 -05:00
}
2012-02-09 13:59:13 -05:00
else if ( newActiveTabOptions . canExpandTree ) {
this . windowService . expandTreeAfterKeyReleased ( tab ) ;
2011-12-02 15:01:38 -05:00
}
2011-11-29 12:21:33 -05:00
}
2012-02-09 13:59:13 -05:00
else {
this . handleNewActiveTab ( tab , newActiveTabOptions ) ;
}
2007-11-14 14:34:36 -05:00
}
2009-07-06 21:53:19 -04:00
this . _focusChangedByCurrentTabRemove = false ;
2009-08-14 02:12:08 -04:00
this . _focusChangedByShortcut = false ;
2009-07-06 21:53:19 -04:00
2008-03-03 04:21:33 -05:00
this . updateInvertedTabContentsOrder ( ) ;
2010-12-06 11:21:17 -05:00
if ( ! this . isTabInViewport ( tab ) ) {
this . scrollToTab ( tab ) ;
aEvent . stopPropagation ( ) ;
}
2007-11-14 14:34:36 -05:00
} ,
2011-11-29 06:36:49 -05:00
cancelDelayedExpandOnTabSelect : function TSTBrowser _cancelDelayedExpandOnTabSelect ( ) {
if ( this . _autoExpandOnTabSelectTimer ) {
this . window . clearTimeout ( this . _autoExpandOnTabSelectTimer ) ;
this . _autoExpandOnTabSelectTimer = null ;
}
} ,
2012-02-09 13:59:13 -05:00
handleNewActiveTab : function TSTBrowser _handleNewActiveTab ( aTab , aOptions )
{
2012-08-04 13:53:57 -04:00
if ( this . doingCollapseExpand || ! aTab || ! aTab . parentNode ) return ;
2012-02-09 13:59:13 -05:00
aOptions = aOptions || { } ;
if ( this . _handleNewActiveTabTimer )
this . window . clearTimeout ( this . _handleNewActiveTabTimer ) ;
/ * *
* First , we wait until all event listeners for the TabSelect
* event were processed .
* /
this . _handleNewActiveTabTimer = this . window . setTimeout ( function ( aSelf ) {
aSelf . window . clearTimeout ( aSelf . _handleNewActiveTabTimer ) ;
aSelf . _handleNewActiveTabTimer = null ;
if ( aOptions . canExpandTree ) {
2012-05-30 08:43:36 -04:00
if ( aOptions . canCollapseTree &&
2012-10-31 10:03:50 -04:00
utils . getTreePref ( 'autoExpand.intelligently' ) )
2012-02-09 13:59:13 -05:00
aSelf . collapseExpandTreesIntelligentlyFor ( aTab ) ;
else
aSelf . collapseExpandSubtree ( aTab , false ) ;
}
} , 0 , this ) ;
} ,
_handleNewActiveTabTimer : null ,
2011-12-13 09:21:31 -05:00
2011-12-02 15:01:38 -05:00
handleAdvanceSelectedTab : function TSTBrowser _handleAdvanceSelectedTab ( aDir , aWrap )
2011-01-21 23:38:08 -05:00
{
2011-05-25 16:54:46 -04:00
this . _focusChangedByShortcut = this . windowService . accelKeyPressed ;
2011-01-21 23:38:08 -05:00
2011-12-02 15:01:38 -05:00
if ( ! this . canCollapseSubtree ( this . mTabBrowser . selectedTab ) ||
2012-10-23 12:43:56 -04:00
utils . getTreePref ( 'focusMode' ) != this . kFOCUS _VISIBLE )
2011-01-21 23:38:08 -05:00
return false ;
2011-12-02 15:01:38 -05:00
if ( this . processArrowKeyOnFocusAdvanced ( ) )
return true ;
return this . advanceSelectedTab ( aDir , aWrap ) ;
} ,
2011-12-13 09:21:31 -05:00
processArrowKeyOnFocusAdvanced : function TSTBrowser _processArrowKeyOnFocusAdvanced ( )
2011-12-02 15:01:38 -05:00
{
var event = this . windowService . arrowKeyEventOnTab ;
if ( ! event )
return false ;
if (
event . altKey ||
event . ctrlKey ||
event . metaKey ||
event . shiftKey ||
( this . isVertical ? ( event . up || event . down ) : ( event . left || event . right ) )
) {
event . advanceFocus = true ;
return false ;
}
var collapse , expand ;
switch ( this . position )
{
case 'top' :
collapse = event . up ;
expand = event . down ;
break ;
case 'bottom' :
collapse = event . down ;
expand = event . up ;
break ;
case 'left' :
collapse = event . left ;
expand = event . right ;
break ;
case 'right' :
2012-10-23 12:43:56 -04:00
if ( utils . getTreePref ( 'tabbar.invertTab' ) ) {
2011-12-02 15:01:38 -05:00
collapse = event . right ;
expand = event . left ;
}
else {
collapse = event . left ;
expand = event . right ;
}
break ;
}
var tab = this . mTabBrowser . selectedTab ;
var collapsed = this . isSubtreeCollapsed ( tab ) ;
if ( this . hasChildTabs ( tab ) && ( collapsed ? expand : collapse ) ) {
event . collapse = collapse ;
event . expand = expand ;
this . collapseExpandSubtree ( tab , ! collapsed ) ;
return true ;
}
var nextSelected ;
if ( expand )
nextSelected = this . getFirstChildTab ( tab ) ;
else if ( collapse )
nextSelected = this . getParentTab ( tab ) ;
if ( nextSelected ) {
event . advanceFocus = true ;
this . mTabBrowser . selectedTab = nextSelected ;
return true ;
}
return true ;
} ,
2011-12-13 09:21:31 -05:00
advanceSelectedTab : function TSTBrowser _advanceSelectedTab ( aDir , aWrap )
2011-12-02 15:01:38 -05:00
{
var tab = this . mTabBrowser . selectedTab ;
var tabbar = this . mTabBrowser . mTabContainer ;
var nextTab = ( aDir < 0 ) ? this . getPreviousVisibleTab ( tab ) : this . getNextVisibleTab ( tab ) ;
2011-01-21 23:38:08 -05:00
if ( ! nextTab && aWrap ) {
2012-09-23 03:11:03 -04:00
let tabs = tabbar . querySelectorAll ( 'tab:not([' + this . kCOLLAPSED + '="true"])' ) ;
nextTab = tabs [ aDir < 0 ? tabs . length - 1 : 0 ] ;
2011-01-21 23:38:08 -05:00
}
2011-12-02 15:01:38 -05:00
if ( nextTab && nextTab != tab )
tabbar . _selectNewTab ( nextTab , aDir , aWrap ) ;
2011-01-21 23:38:08 -05:00
return true ;
} ,
2011-12-13 09:21:31 -05:00
2010-03-02 09:40:12 -05:00
onTabClick : function TSTBrowser _onTabClick ( aEvent , aTab )
2007-11-14 14:34:36 -05:00
{
2010-03-02 09:40:12 -05:00
aTab = aTab || this . getTabFromEvent ( aEvent ) ;
2009-12-18 00:56:41 -05:00
if ( aEvent . button == 1 ) {
2010-03-02 09:40:12 -05:00
if ( ! this . warnAboutClosingTabSubtreeOf ( aTab ) ) {
2009-12-18 00:56:41 -05:00
aEvent . preventDefault ( ) ;
aEvent . stopPropagation ( ) ;
}
return ;
}
if ( aEvent . button != 0 )
return ;
2007-11-14 14:34:36 -05:00
2008-12-03 07:48:42 -05:00
if ( this . isEventFiredOnTwisty ( aEvent ) ) {
2010-11-29 03:24:45 -05:00
if ( this . hasChildTabs ( aTab ) && this . canCollapseSubtree ( aTab ) ) {
2011-12-26 23:21:23 -05:00
this . manualCollapseExpandSubtree ( aTab , aTab . getAttribute ( this . kSUBTREE _COLLAPSED ) != 'true' ) ;
2009-04-26 22:18:17 -04:00
aEvent . preventDefault ( ) ;
aEvent . stopPropagation ( ) ;
}
2009-12-18 00:46:20 -05:00
return ;
}
if ( this . isEventFiredOnClosebox ( aEvent ) ) {
2010-03-02 09:40:12 -05:00
if ( ! this . warnAboutClosingTabSubtreeOf ( aTab ) ) {
2009-12-18 00:52:47 -05:00
aEvent . preventDefault ( ) ;
aEvent . stopPropagation ( ) ;
2009-12-18 00:46:20 -05:00
}
return ;
2008-12-03 07:48:42 -05:00
}
2007-11-14 14:34:36 -05:00
} ,
2010-03-02 09:40:12 -05:00
onClick : function TSTBrowser _onClick ( aEvent )
{
2010-04-08 19:24:02 -04:00
if (
2011-05-25 16:54:46 -04:00
aEvent . target . ownerDocument != this . document ||
2010-04-08 19:24:02 -04:00
aEvent . button != 0 ||
this . isAccelKeyPressed ( aEvent )
)
2010-03-02 09:40:12 -05:00
return ;
var tab = this . getTabFromEvent ( aEvent ) ;
if ( tab ) {
this . onTabClick ( aEvent , tab ) ;
}
else {
// click on indented space on the tab bar
tab = this . getTabFromTabbarEvent ( aEvent ) ;
if ( tab ) this . mTabBrowser . selectedTab = tab ;
}
} ,
2009-12-25 03:34:52 -05:00
onDblClick : function TSTBrowser _onDblClick ( aEvent )
2009-05-13 02:09:17 -04:00
{
2010-09-12 23:54:04 -04:00
let tab = this . getTabFromEvent ( aEvent ) ;
if ( tab &&
this . hasChildTabs ( tab ) &&
2012-10-23 12:43:56 -04:00
utils . getTreePref ( 'collapseExpandSubtree.dblclick' ) ) {
2011-12-26 23:21:23 -05:00
this . manualCollapseExpandSubtree ( tab , tab . getAttribute ( this . kSUBTREE _COLLAPSED ) != 'true' ) ;
2010-09-12 23:54:04 -04:00
aEvent . preventDefault ( ) ;
aEvent . stopPropagation ( ) ;
2009-05-13 02:09:17 -04:00
}
} ,
2010-07-01 23:39:31 -04:00
onMozMouseHittest : function TSTBrowser _onMozMouseHittest ( aEvent )
2007-11-14 14:34:36 -05:00
{
2010-07-01 23:39:31 -04:00
// block default behaviors of the tab bar (dragging => window move, etc.)
2010-06-25 13:43:30 -04:00
if (
2010-09-14 22:58:36 -04:00
! this . getTabFromEvent ( aEvent ) &&
! this . isEventFiredOnClickable ( aEvent ) &&
(
2011-01-22 10:46:29 -05:00
this . position != 'top' ||
2010-09-14 22:58:36 -04:00
aEvent . shiftKey ||
this . tabbarDNDObserver . canDragTabbar ( aEvent )
)
2010-09-14 20:34:28 -04:00
)
2010-06-25 13:43:30 -04:00
aEvent . stopPropagation ( ) ;
2007-11-14 14:34:36 -05:00
} ,
2009-05-13 02:09:17 -04:00
2010-07-01 23:39:31 -04:00
onMouseDown : function TSTBrowser _onMouseDown ( aEvent )
{
2012-01-12 22:16:35 -05:00
if ( this . isEventFiredOnScrollbar ( aEvent ) )
this . cancelPerformingAutoScroll ( ) ;
2012-01-06 05:38:38 -05:00
2010-07-01 23:39:31 -04:00
if (
aEvent . button == 0 &&
this . isEventFiredOnTwisty ( aEvent )
) {
2010-12-06 10:25:14 -05:00
// prevent to select the tab for clicking on twisty
aEvent . stopPropagation ( ) ;
2010-12-06 11:56:21 -05:00
// prevent to focus to the tab element itself
aEvent . preventDefault ( ) ;
2010-07-01 23:39:31 -04:00
}
else {
this . onMozMouseHittest ( aEvent ) ;
}
} ,
2012-01-06 05:38:38 -05:00
onDOMMouseScroll : function TSTBrowser _onDOMMouseScroll ( aEvent )
{
2012-01-12 22:16:35 -05:00
this . cancelPerformingAutoScroll ( ) ;
2012-01-06 05:38:38 -05:00
} ,
2009-12-25 03:34:52 -05:00
onScroll : function TSTBrowser _onScroll ( aEvent )
2009-05-13 02:09:17 -04:00
{
2011-04-06 03:40:44 -04:00
// restore scroll position when a tab is closed.
2011-08-24 01:17:01 -04:00
this . restoreLastScrollPosition ( ) ;
} ,
2007-11-14 14:34:36 -05:00
2009-12-25 03:34:52 -05:00
onTabbarOverflow : function TSTBrowser _onTabbarOverflow ( aEvent )
2009-03-24 13:44:30 -04:00
{
var tabs = this . mTabBrowser . mTabContainer ;
var horizontal = tabs . orient == 'horizontal' ;
if ( horizontal ) return ;
aEvent . stopPropagation ( ) ;
2010-12-06 23:46:38 -05:00
this . positionPinnedTabsWithDelay ( ) ;
2012-01-14 13:42:51 -05:00
if ( aEvent . detail == 1 ) {
/ * *
* By horizontal overflow / underflow , Firefox can wrongly
* removes "overflow" attribute for vertical tab bar .
* We have to override the result .
* /
this . updateTabbarOverflow ( ) ;
2009-03-24 13:44:30 -04:00
}
else {
2012-01-14 13:42:51 -05:00
if ( aEvent . type == 'overflow' ) {
tabs . setAttribute ( 'overflow' , 'true' ) ;
this . scrollBoxObject . ensureElementIsVisible ( tabs . selectedItem ) ;
}
else {
tabs . removeAttribute ( 'overflow' ) ;
}
2009-03-24 13:44:30 -04:00
}
} ,
2010-03-23 15:10:53 -04:00
onResize : function TSTBrowser _onResize ( aEvent )
{
if (
! aEvent . originalTarget ||
2012-01-30 13:15:00 -05:00
! ( aEvent . originalTarget instanceof Ci . nsIDOMWindow )
2010-03-23 15:10:53 -04:00
)
return ;
2012-01-30 13:15:00 -05:00
var resizedTopFrame = aEvent . originalTarget . top ;
if ( resizedTopFrame == this . mTabBrowser . contentWindow ||
resizedTopFrame == this . window ) {
this . updateFloatingTabbar ( this . kTABBAR _UPDATE _BY _WINDOW _RESIZE ) ;
2012-11-08 06:07:03 -05:00
this . updateInvertedTabContentsOrder ( true ) ;
this . mTabBrowser . mTabContainer . adjustTabstrip ( ) ;
2012-01-30 13:15:00 -05:00
}
2010-03-23 15:10:53 -04:00
} ,
2009-12-25 03:34:52 -05:00
onPopupShowing : function TSTBrowser _onPopupShowing ( aEvent )
2009-03-24 13:44:30 -04:00
{
2011-11-29 13:40:11 -05:00
if ( aEvent . target == aEvent . currentTarget )
2010-04-30 00:49:00 -04:00
this . initTabContextMenu ( aEvent ) ;
2009-03-24 13:44:30 -04:00
} ,
2009-12-25 03:34:52 -05:00
initTabContextMenu : function TSTBrowser _initTabContextMenu ( aEvent )
2007-11-14 14:34:36 -05:00
{
var b = this . mTabBrowser ;
2009-07-06 05:21:06 -04:00
var sep , items = { } ;
2012-02-04 16:31:03 -05:00
var ids = [
2012-02-04 13:15:38 -05:00
this . kMENUITEM _RELOADSUBTREE ,
this . kMENUITEM _RELOADCHILDREN ,
this . kMENUITEM _REMOVESUBTREE ,
this . kMENUITEM _REMOVECHILDREN ,
this . kMENUITEM _REMOVEALLTABSBUT ,
this . kMENUITEM _COLLAPSE ,
this . kMENUITEM _EXPAND ,
this . kMENUITEM _AUTOHIDE ,
this . kMENUITEM _FIXED ,
this . kMENUITEM _BOOKMARKSUBTREE
2012-02-04 16:31:03 -05:00
] ;
for ( let i = 0 , maxi = ids . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
let id = ids [ i ] ;
2012-09-23 03:11:03 -04:00
let item = aEvent . currentTarget . querySelector ( '*[id^="' + id + '"]' ) ;
2012-02-04 13:15:38 -05:00
if ( ! item ) continue ;
items [ id ] = item ;
2012-10-23 12:43:56 -04:00
if ( utils . getTreePref ( 'show.' + id ) )
2009-07-06 05:21:06 -04:00
item . removeAttribute ( 'hidden' ) ;
else
item . setAttribute ( 'hidden' , true ) ;
2012-02-04 13:15:38 -05:00
switch ( id )
2009-07-07 04:31:00 -04:00
{
case this . kMENUITEM _RELOADSUBTREE :
case this . kMENUITEM _RELOADCHILDREN :
case this . kMENUITEM _REMOVESUBTREE :
case this . kMENUITEM _REMOVECHILDREN :
2010-12-08 06:34:42 -05:00
case this . kMENUITEM _REMOVEALLTABSBUT :
2009-07-07 04:31:00 -04:00
case this . kMENUITEM _COLLAPSE :
case this . kMENUITEM _EXPAND :
case this . kMENUITEM _BOOKMARKSUBTREE :
2009-12-25 06:19:50 -05:00
this . showHideSubtreeMenuItem ( item , [ b . mContextTab ] ) ;
2012-02-04 13:15:38 -05:00
continue ;
2009-07-07 04:31:00 -04:00
default :
2012-02-04 13:15:38 -05:00
continue ;
2009-07-07 04:31:00 -04:00
}
2012-02-04 13:15:38 -05:00
}
2007-11-26 10:07:10 -05:00
2007-11-17 01:05:23 -05:00
// collapse/expand all
2012-09-23 03:11:03 -04:00
sep = aEvent . currentTarget . querySelector ( 'menuseparator[id^="' + this . kMENUITEM _COLLAPSEEXPAND _SEPARATOR + '"]' ) ;
2009-07-07 11:34:14 -04:00
let collapseItem = items [ this . kMENUITEM _COLLAPSE ] ;
2011-06-17 11:02:43 -04:00
let expandItem = items [ this . kMENUITEM _EXPAND ] ;
2009-10-25 22:47:38 -04:00
if ( this . canCollapseSubtree ( b ) &&
2012-09-23 03:11:03 -04:00
b . mTabContainer . querySelector ( 'tab[' + this . kCHILDREN + ']' ) ) {
2011-06-17 11:02:43 -04:00
if ( collapseItem ) {
2012-09-23 03:11:03 -04:00
if ( b . mTabContainer . querySelector ( 'tab[' + this . kCHILDREN + ']:not([' + this . kSUBTREE _COLLAPSED + '="true"])' ) )
2011-06-17 11:02:43 -04:00
collapseItem . removeAttribute ( 'disabled' ) ;
else
collapseItem . setAttribute ( 'disabled' , true ) ;
}
2007-11-17 01:05:23 -05:00
2011-06-17 11:02:43 -04:00
if ( expandItem ) {
2012-09-23 03:11:03 -04:00
if ( b . mTabContainer . querySelector ( 'tab[' + this . kCHILDREN + '][' + this . kSUBTREE _COLLAPSED + '="true"]' ) )
2011-06-17 11:02:43 -04:00
expandItem . removeAttribute ( 'disabled' ) ;
else
expandItem . setAttribute ( 'disabled' , true ) ;
}
2007-11-17 01:05:23 -05:00
}
else {
2011-06-17 11:02:43 -04:00
if ( collapseItem ) collapseItem . setAttribute ( 'hidden' , true ) ;
if ( expandItem ) expandItem . setAttribute ( 'hidden' , true ) ;
2007-11-17 01:05:23 -05:00
}
2011-06-17 11:02:43 -04:00
if ( sep ) {
if (
( ! collapseItem || collapseItem . getAttribute ( 'hidden' ) == 'true' ) &&
( ! expandItem || expandItem . getAttribute ( 'hidden' ) == 'true' )
) {
sep . setAttribute ( 'hidden' , true ) ;
}
else {
sep . removeAttribute ( 'hidden' ) ;
}
2007-11-17 01:05:23 -05:00
}
2010-12-08 06:34:42 -05:00
// close all tabs but this tree
let removeAllTabsBut = items [ this . kMENUITEM _REMOVEALLTABSBUT ] ;
2011-06-19 09:57:35 -04:00
if ( removeAllTabsBut ) {
2011-06-17 11:02:43 -04:00
let rootTabs = this . visibleRootTabs ;
if ( rootTabs . length == 1 && rootTabs [ 0 ] == b . mContextTab )
removeAllTabsBut . setAttribute ( 'disabled' , true ) ;
else
removeAllTabsBut . removeAttribute ( 'disabled' ) ;
}
2010-12-08 06:34:42 -05:00
2007-11-17 01:05:23 -05:00
// auto hide
2009-07-07 11:34:14 -04:00
let autohide = items [ this . kMENUITEM _AUTOHIDE ] ;
2011-06-17 11:02:43 -04:00
if ( autohide )
this . autoHide . updateMenuItem ( autohide ) ;
2008-02-22 12:55:35 -05:00
// fix
2009-07-07 11:34:14 -04:00
let fixedPref ;
let fixedLabel ;
if ( this . isVertical ) {
2010-05-08 02:22:49 -04:00
fixedPref = b . getAttribute ( this . kFIXED + '-vertical' ) == 'true' ;
2009-07-07 11:34:14 -04:00
fixedLabel = 'label-vertical' ;
}
else {
2010-05-08 02:22:49 -04:00
fixedPref = b . getAttribute ( this . kFIXED + '-horizontal' ) == 'true' ;
2009-07-07 11:34:14 -04:00
fixedLabel = 'label-horizontal' ;
}
let fixed = items [ this . kMENUITEM _FIXED ] ;
2011-06-17 11:02:43 -04:00
if ( fixed ) {
fixed . setAttribute ( 'label' , fixed . getAttribute ( fixedLabel ) ) ;
if ( fixedPref )
fixed . setAttribute ( 'checked' , true ) ;
else
fixed . removeAttribute ( 'checked' ) ;
}
2008-02-22 12:55:35 -05:00
2012-09-23 03:11:03 -04:00
sep = aEvent . currentTarget . querySelector ( 'menuseparator[id^="' + this . kMENUITEM _AUTOHIDE _SEPARATOR + '"]' ) ;
2011-06-17 11:02:43 -04:00
if ( sep ) {
if (
( autohide && autohide . getAttribute ( 'hidden' ) != 'true' ) ||
( fixed && fixed . getAttribute ( 'hidden' ) != 'true' )
) {
sep . removeAttribute ( 'hidden' ) ;
}
else {
sep . setAttribute ( 'hidden' , true ) ;
}
2007-11-14 14:34:36 -05:00
}
} ,
2010-03-28 14:22:15 -04:00
2011-01-21 23:06:59 -05:00
onTabsOnTopSyncCommand : function TSTBrowser _onTabsOnTopSyncCommand ( aEnabled )
{
if (
2012-04-09 07:18:52 -04:00
this . windowService . tabsOnTopChangingByUI ||
2011-01-21 23:06:59 -05:00
! aEnabled ||
2011-01-22 10:46:29 -05:00
this . position != 'top' ||
2012-01-30 13:38:41 -05:00
this . fixed ||
2012-04-09 07:18:52 -04:00
this . windowService . isPopupWindow
2011-01-21 23:06:59 -05:00
)
return ;
2012-04-09 07:18:52 -04:00
this . windowService . tabsOnTopChangingByUI = true ;
2011-05-25 16:54:46 -04:00
var self = this ;
2012-08-04 13:53:57 -04:00
if ( this . deferredTasks [ 'onTabsOnTopSyncCommand' ] )
this . deferredTasks [ 'onTabsOnTopSyncCommand' ] . cancel ( ) ;
( this . deferredTasks [ 'onTabsOnTopSyncCommand' ] = this . Deferred
2011-05-25 16:54:46 -04:00
. next ( function ( ) {
self . windowService . toggleFixed ( self . mTabBrowser ) ;
2012-08-04 13:53:57 -04:00
} ) )
2011-05-25 16:54:46 -04:00
. next ( function ( ) {
2012-04-09 07:18:52 -04:00
if ( self . window . TabsOnTop . enabled != aEnabled )
2011-05-25 16:54:46 -04:00
self . window . TabsOnTop . enabled = aEnabled ;
2012-02-06 12:13:46 -05:00
} )
2012-04-09 07:18:52 -04:00
. error ( this . defaultDeferredErrorHandler )
. next ( function ( ) {
self . windowService . tabsOnTopChangingByUI = false ;
2012-08-04 13:53:57 -04:00
delete self . deferredTasks [ 'onTabsOnTopSyncCommand' ] ;
2012-04-09 07:18:52 -04:00
} ) ;
2011-01-21 23:06:59 -05:00
} ,
2012-09-14 23:09:15 -04:00
onBeforeFullScreenToggle : function TSTBrowser _onBeforeFullScreenToggle ( )
{
if ( this . position != 'top' ) {
if ( this . window . fullScreen )
this . autoHide . endForFullScreen ( ) ;
else
this . autoHide . startForFullScreen ( ) ;
}
} ,
2010-03-28 14:22:15 -04:00
onTreeStyleTabPrintPreviewEntered : function TSTBrowser _onTreeStyleTabPrintPreviewEntered ( aEvent )
{
this . setTabbrowserAttribute ( this . kPRINT _PREVIEW , true ) ;
} ,
onTreeStyleTabPrintPreviewExited : function TSTBrowser _onTreeStyleTabPrintPreviewExited ( aEvent )
{
this . removeTabbrowserAttribute ( this . kPRINT _PREVIEW ) ;
} ,
2007-11-17 00:20:26 -05:00
/* commands */
2007-11-14 14:34:36 -05:00
2009-12-16 12:52:25 -05:00
/* reset */
2011-12-07 11:40:33 -05:00
resetTab : function TSTBrowser _resetTab ( aTab , aDetachAllChildren )
2009-12-16 12:52:25 -05:00
{
2012-08-04 13:53:57 -04:00
if ( ! aTab . parentNode ) return ; // do nothing for closed tab!
2011-12-07 11:40:33 -05:00
if ( aDetachAllChildren )
2011-12-06 20:18:05 -05:00
this . detachAllChildren ( aTab , {
2009-12-16 12:52:25 -05:00
dontUpdateIndent : true ,
dontAnimate : true
} ) ;
2011-12-06 20:18:05 -05:00
this . detachTab ( aTab , {
2009-12-16 12:52:25 -05:00
dontUpdateIndent : true ,
dontAnimate : true
} ) ;
2011-12-13 02:10:49 -05:00
this . resetTabState ( aTab ) ;
this . updateTabsIndent ( [ aTab ] , undefined , true ) ;
} ,
2011-12-13 09:21:31 -05:00
resetTabState : function TSTBrowser _resetTabState ( aTab )
2011-12-13 02:10:49 -05:00
{
2012-08-04 13:53:57 -04:00
if ( ! aTab . parentNode ) return ; // do nothing for closed tab!
2009-12-16 12:52:25 -05:00
aTab . removeAttribute ( this . kID ) ;
2011-12-13 04:03:16 -05:00
aTab . removeAttribute ( this . kID _RESTORING ) ;
2009-12-16 12:52:25 -05:00
aTab . removeAttribute ( this . kPARENT ) ;
aTab . removeAttribute ( this . kCHILDREN ) ;
2011-12-13 04:03:16 -05:00
aTab . removeAttribute ( this . kCHILDREN _RESTORING ) ;
2009-12-16 12:52:25 -05:00
aTab . removeAttribute ( this . kSUBTREE _COLLAPSED ) ;
2011-12-26 23:21:23 -05:00
aTab . removeAttribute ( this . kSUBTREE _EXPANDED _MANUALLY ) ;
2009-12-16 12:52:25 -05:00
aTab . removeAttribute ( this . kCOLLAPSED ) ;
aTab . removeAttribute ( this . kNEST ) ;
2011-12-13 02:10:49 -05:00
this . updateTabCollapsed ( aTab , false , true ) ;
2009-12-16 12:52:25 -05:00
} ,
2011-12-13 09:21:31 -05:00
2011-12-07 11:40:33 -05:00
resetAllTabs : function TSTBrowser _resetAllTabs ( aDetachAllChildren )
2009-12-16 12:52:25 -05:00
{
2012-09-23 02:43:49 -04:00
var tabs = this . getAllTabs ( this . mTabBrowser ) ;
2012-02-04 16:31:03 -05:00
for ( let i = 0 , maxi = tabs . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
this . resetTab ( tabs [ i ] , aDetachAllChildren ) ;
2012-02-04 13:15:38 -05:00
}
2009-12-16 12:52:25 -05:00
} ,
2009-12-18 04:05:41 -05:00
2011-01-21 23:06:59 -05:00
resetTabbarSize : function TSTBrowser _resetTabbarSize ( )
{
if ( this . isVertical ) {
2012-10-23 12:43:56 -04:00
utils . setTreePref ( 'tabbar.shrunkenWidth' , utils . getTreePref ( 'tabbar.shrunkenWidth.default' ) ) ;
utils . setTreePref ( 'tabbar.width' , utils . getTreePref ( 'tabbar.width.default' ) ) ;
2011-01-21 23:06:59 -05:00
}
else {
2012-10-23 12:43:56 -04:00
utils . setTreePref ( 'tabbar.height' , utils . getTreePref ( 'tabbar.height.default' ) ) ;
2012-01-13 11:30:06 -05:00
let tabContainerBox = this . getTabContainerBox ( this . mTabBrowser ) ;
tabContainerBox . removeAttribute ( 'height' ) ;
this . _tabStripPlaceHolder . height = tabContainerBox . boxObject . height ;
2011-01-21 23:06:59 -05:00
}
this . updateFloatingTabbar ( this . kTABBAR _UPDATE _BY _RESET ) ;
} ,
2009-12-18 04:05:41 -05:00
get treeViewEnabled ( ) /* PUBLIC API */
{
return this . _treeViewEnabled ;
} ,
set treeViewEnabled ( aValue )
{
2011-10-29 14:10:53 -04:00
var newValue = ! ! aValue ;
if ( newValue == this . _treeViewEnabled )
return aValue ;
this . _treeViewEnabled = newValue ;
2009-12-18 04:05:41 -05:00
if ( this . _treeViewEnabled ) {
2011-01-22 13:25:21 -05:00
if ( this . _lastAllowSubtreeCollapseExpand )
this . allowSubtreeCollapseExpand = true ;
delete this . _lastAllowSubtreeCollapseExpand ;
2012-09-23 02:43:49 -04:00
let tabs = this . getAllTabs ( this . browser ) ;
2012-02-04 16:31:03 -05:00
for ( let i = 0 , maxi = tabs . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
let tab = tabs [ i ] ;
2012-02-04 13:15:38 -05:00
if ( tab . _TSTLastSubtreeCollapsed )
this . collapseExpandSubtree ( tab , true , true ) ;
if ( tab . _TSTLastSubtreeExpandedManually )
this . setTabValue ( tab , this . kSUBTREE _EXPANDED _MANUALLY , true ) ;
delete tab . _TSTLastSubtreeCollapsed ;
delete tab . _TSTLastSubtreeExpandedManually ;
this . updateTabIndent ( tab , 0 , true ) ;
}
2010-08-13 13:14:46 -04:00
this . updateTabsIndent ( this . rootTabs , undefined , true ) ;
2009-12-18 04:05:41 -05:00
}
else {
2012-09-23 02:43:49 -04:00
let tabs = this . getAllTabs ( this . browser ) ;
2012-02-04 16:31:03 -05:00
for ( let i = 0 , maxi = tabs . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
let tab = tabs [ i ] ;
2012-02-04 13:15:38 -05:00
this . updateTabIndent ( tab , 0 , true ) ;
tab . _TSTLastSubtreeCollapsed = this . isSubtreeCollapsed ( tab ) ;
tab . _TSTLastSubtreeExpandedManually = this . getTabValue ( tab , this . kSUBTREE _EXPANDED _MANUALLY ) == 'true' ;
this . collapseExpandSubtree ( tab , false , true ) ;
}
2011-01-22 13:25:21 -05:00
this . _lastAllowSubtreeCollapseExpand = this . allowSubtreeCollapseExpand ;
this . allowSubtreeCollapseExpand = false ;
2009-12-18 04:05:41 -05:00
}
return aValue ;
} ,
// _treeViewEnabled : true,
2009-12-16 12:52:25 -05:00
2011-12-06 20:20:14 -05:00
/* attach/detach */
2007-11-17 00:20:26 -05:00
2009-12-25 03:34:52 -05:00
attachTabTo : function TSTBrowser _attachTabTo ( aChild , aParent , aInfo ) /* PUBLIC API */
2007-11-14 14:34:36 -05:00
{
2012-08-04 13:53:57 -04:00
if ( ! aChild . parentNode || ( aParent && ! aParent . parentNode ) ) return ; // do nothing for closed tab!
2010-11-29 03:24:45 -05:00
aInfo = aInfo || { } ;
2012-08-04 16:31:38 -04:00
var newAncestors = [ ] ;
if ( aParent ) {
newAncestors = [ aParent ] . concat ( this . getAncestorTabs ( aParent ) ) ;
if ( this . maxTreeLevelPhisical && this . maxTreeLevel > - 1 ) {
let level = parseInt ( aParent . getAttribute ( this . kNEST ) || 0 ) + 1 ;
newAncestors . some ( function ( aAncestor ) {
if ( level <= this . maxTreeLevel )
return true ;
level -- ;
return false ;
} , this ) ;
2010-11-29 03:24:45 -05:00
}
}
2009-04-07 12:09:17 -04:00
var currentParent ;
2007-11-17 00:20:26 -05:00
if (
! aChild ||
! aParent ||
aChild == aParent ||
2010-06-25 12:28:01 -04:00
( currentParent = this . getParentTab ( aChild ) ) == aParent ||
2010-09-09 05:38:48 -04:00
aChild . getAttribute ( 'pinned' ) == 'true' ||
aParent . getAttribute ( 'pinned' ) == 'true'
2008-02-28 02:45:39 -05:00
) {
2009-12-25 23:49:58 -05:00
this . fireAttachedEvent ( aChild , aParent ) ;
2007-11-17 00:20:26 -05:00
return ;
2008-02-28 02:45:39 -05:00
}
2007-11-14 14:34:36 -05:00
2011-12-12 13:54:43 -05:00
// avoid recursive tree
var ancestors = [ aParent ] . concat ( this . getAncestorTabs ( aChild ) ) ;
if ( ancestors . indexOf ( aChild ) > - 1 )
2010-06-26 13:36:08 -04:00
return ;
2011-12-12 13:54:43 -05:00
currentParent = ancestors [ ancestors . length - 1 ] ;
var shouldInheritIndent = (
! currentParent ||
( currentParent . getAttribute ( this . kNEST ) == aParent . getAttribute ( this . kNEST ) )
) ;
2009-04-07 12:09:17 -04:00
2009-03-31 14:25:49 -04:00
this . ensureTabInitialized ( aChild ) ;
this . ensureTabInitialized ( aParent ) ;
2007-11-17 00:20:26 -05:00
if ( ! aInfo ) aInfo = { } ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
var id = aChild . getAttribute ( this . kID ) ;
2007-11-14 14:34:36 -05:00
2011-12-06 20:18:05 -05:00
this . detachTab ( aChild , {
2009-07-30 05:56:28 -04:00
dontUpdateIndent : true
} ) ;
2007-11-17 00:20:26 -05:00
2009-04-20 08:03:38 -04:00
var children = aParent . getAttribute ( this . kCHILDREN )
. split ( '|' ) . filter ( function ( aId ) {
return this . getTabById ( aId ) ;
} , this ) ;
2007-11-17 00:20:26 -05:00
var newIndex ;
2009-04-20 08:03:38 -04:00
var oldIndex = children . indexOf ( id ) ;
2009-04-20 09:22:34 -04:00
if ( oldIndex > - 1 ) children . splice ( oldIndex , 1 ) ;
2007-11-17 00:20:26 -05:00
2009-08-03 17:53:08 -04:00
var insertBefore = aInfo . insertBefore ||
( aInfo . dontMove ? this . getNextTab ( aChild ) : null ) ;
2007-11-17 00:20:26 -05:00
var beforeTab = insertBefore ? insertBefore . getAttribute ( this . kID ) : null ;
2009-04-20 08:03:38 -04:00
var beforeIndex ;
if ( beforeTab && ( beforeIndex = children . indexOf ( beforeTab ) ) > - 1 ) {
children . splice ( beforeIndex , 0 , id ) ;
2007-11-17 00:20:26 -05:00
newIndex = insertBefore . _tPos ;
}
else {
2009-04-20 08:03:38 -04:00
children . push ( id ) ;
2009-12-22 03:05:16 -05:00
if ( aInfo . dontMove && children . length > 1 ) {
children = children
. map ( this . getTabById , this )
. sort ( this . sortTabsByOrder )
. map ( function ( aTab ) {
return aTab . getAttribute ( this . kID ) ;
} , this ) ;
}
2009-07-30 05:56:28 -04:00
let refTab = aParent ;
let descendant = this . getDescendantTabs ( aParent ) ;
2011-04-07 15:08:46 -04:00
if ( descendant . length ) {
let lastDescendant = descendant [ descendant . length - 1 ] ;
2011-04-07 15:20:12 -04:00
/ * *
* The last descendant tab can be temporarilly moved
* upper than the root parent tab , in some cases .
* ( the parent tab is pinned , etc . )
* /
2011-04-07 15:08:46 -04:00
if ( ! refTab || lastDescendant . _tPos > refTab . _tPos )
refTab = lastDescendant ;
}
2007-11-17 00:20:26 -05:00
newIndex = refTab . _tPos + 1 ;
}
2009-04-20 08:03:38 -04:00
this . setTabValue ( aParent , this . kCHILDREN , children . join ( '|' ) ) ;
2007-11-17 00:20:26 -05:00
this . setTabValue ( aChild , this . kPARENT , aParent . getAttribute ( this . kID ) ) ;
2010-03-03 08:30:49 -05:00
2007-11-17 00:20:26 -05:00
this . updateTabsCount ( aParent ) ;
2009-06-26 20:37:39 -04:00
if ( shouldInheritIndent && ! aInfo . dontUpdateIndent )
this . inheritTabIndent ( aChild , aParent ) ;
2007-11-17 00:20:26 -05:00
2009-07-30 05:56:28 -04:00
if ( ! aInfo . dontMove ) {
if ( newIndex > aChild . _tPos ) newIndex -- ;
2009-12-25 06:19:50 -05:00
this . moveTabSubtreeTo ( aChild , newIndex ) ;
2009-07-30 05:56:28 -04:00
}
2007-11-17 00:20:26 -05:00
2011-12-06 22:06:05 -05:00
if ( aInfo . forceExpand ) {
this . collapseExpandSubtree ( aParent , false , aInfo . dontAnimate ) ;
}
else if ( ! aInfo . dontExpand ) {
2012-10-23 12:43:56 -04:00
if ( utils . getTreePref ( 'autoCollapseExpandSubtreeOnSelect' ) ) {
2009-09-29 09:34:36 -04:00
if ( this . shouldTabAutoExpanded ( aParent ) )
2009-09-29 09:18:36 -04:00
this . collapseExpandTreesIntelligentlyFor ( aParent ) ;
2012-08-04 16:31:38 -04:00
newAncestors . forEach ( function ( aAncestor ) {
if ( this . shouldTabAutoExpanded ( aAncestor ) )
this . collapseExpandSubtree ( aAncestor , false , aInfo . dontAnimate ) ;
} , this ) ;
2007-11-17 00:20:26 -05:00
}
2009-09-29 09:34:36 -04:00
else if ( this . shouldTabAutoExpanded ( aParent ) ) {
2012-10-23 12:43:56 -04:00
if ( utils . getTreePref ( 'autoExpandSubtreeOnAppendChild' ) ) {
2012-08-04 16:31:38 -04:00
newAncestors . forEach ( function ( aAncestor ) {
if ( this . shouldTabAutoExpanded ( aAncestor ) )
this . collapseExpandSubtree ( aAncestor , false , aInfo . dontAnimate ) ;
} , this ) ;
2007-11-17 00:20:26 -05:00
}
else
2009-08-26 05:33:54 -04:00
this . collapseExpandTab ( aChild , true , aInfo . dontAnimate ) ;
2007-11-17 00:20:26 -05:00
}
2009-10-25 22:36:42 -04:00
if ( this . isCollapsed ( aParent ) )
2009-08-26 05:33:54 -04:00
this . collapseExpandTab ( aChild , true , aInfo . dontAnimate ) ;
2007-11-17 00:20:26 -05:00
}
2009-09-29 09:34:36 -04:00
else if ( this . shouldTabAutoExpanded ( aParent ) ||
2009-10-25 22:36:42 -04:00
this . isCollapsed ( aParent ) ) {
2009-08-26 05:33:54 -04:00
this . collapseExpandTab ( aChild , true , aInfo . dontAnimate ) ;
2007-11-17 00:20:26 -05:00
}
if ( ! aInfo . dontUpdateIndent ) {
2010-08-13 13:14:46 -04:00
this . updateTabsIndent ( [ aChild ] , undefined , aInfo . dontAnimate ) ;
2007-11-17 00:20:26 -05:00
this . checkTabsIndentOverflow ( ) ;
}
2008-02-28 02:45:39 -05:00
2010-11-29 03:24:45 -05:00
this . promoteTooDeepLevelTabs ( aChild ) ;
2009-12-25 23:49:58 -05:00
this . fireAttachedEvent ( aChild , aParent ) ;
} ,
fireAttachedEvent : function TSTBrowser _fireAttachedEvent ( aChild , aParent )
{
2011-01-11 05:29:14 -05:00
var data = {
parentTab : aParent
} ;
2010-12-20 06:54:42 -05:00
2011-01-11 05:29:14 -05:00
/* PUBLIC API */
this . fireDataContainerEvent ( this . kEVENT _TYPE _ATTACHED , aChild , true , false , data ) ;
2010-12-20 06:54:42 -05:00
// for backward compatibility
2011-01-11 05:29:14 -05:00
this . fireDataContainerEvent ( this . kEVENT _TYPE _ATTACHED . replace ( /^nsDOM/ , '' ) , aChild , true , false , data ) ;
2008-02-28 02:45:39 -05:00
} ,
2011-05-25 16:54:46 -04:00
2009-12-25 03:34:52 -05:00
shouldTabAutoExpanded : function TSTBrowser _shouldTabAutoExpanded ( aTab )
2009-09-29 09:34:36 -04:00
{
return this . hasChildTabs ( aTab ) &&
2009-10-25 22:36:42 -04:00
this . isSubtreeCollapsed ( aTab ) ;
2009-09-29 09:34:36 -04:00
} ,
2011-05-25 16:54:46 -04:00
2011-12-06 20:18:05 -05:00
detachTab : function TSTBrowser _detachTab ( aChild , aInfo ) /* PUBLIC API */
2007-11-14 14:34:36 -05:00
{
2012-08-04 13:53:57 -04:00
if ( ! aChild || ! aChild . parentNode ) return ;
2009-07-30 05:56:28 -04:00
if ( ! aInfo ) aInfo = { } ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
var parentTab = this . getParentTab ( aChild ) ;
if ( ! parentTab ) return ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
var id = aChild . getAttribute ( this . kID ) ;
2010-03-03 08:30:49 -05:00
2010-03-03 21:50:28 -05:00
this . setTabValue (
parentTab ,
this . kCHILDREN ,
parentTab . getAttribute ( this . kCHILDREN )
. split ( '|' )
. filter ( function ( aId ) {
return this . getTabById ( aId ) && aId != id ;
} , this ) . join ( '|' )
) ;
2010-03-25 11:52:11 -04:00
this . deleteTabValue ( aChild , this . kPARENT ) ;
2010-03-03 08:30:49 -05:00
2009-09-29 09:34:36 -04:00
if ( ! this . hasChildTabs ( parentTab ) )
this . setTabValue ( parentTab , this . kSUBTREE _COLLAPSED , true ) ;
2010-03-03 08:30:49 -05:00
2007-11-17 00:20:26 -05:00
this . updateTabsCount ( parentTab ) ;
2007-11-14 14:34:36 -05:00
2009-07-30 05:56:28 -04:00
if ( ! aInfo . dontUpdateIndent ) {
2010-08-13 13:14:46 -04:00
this . updateTabsIndent ( [ aChild ] , undefined , aInfo . dontAnimate ) ;
2007-11-17 00:20:26 -05:00
this . checkTabsIndentOverflow ( ) ;
}
2008-02-28 02:45:39 -05:00
2011-01-11 05:29:14 -05:00
var data = {
parentTab : parentTab
} ;
2009-07-23 12:26:33 -04:00
2011-01-11 05:29:14 -05:00
/* PUBLIC API */
this . fireDataContainerEvent ( this . kEVENT _TYPE _DETACHED , aChild , true , false , data ) ;
2010-12-20 06:54:42 -05:00
// for backward compatibility
2011-01-11 05:29:14 -05:00
this . fireDataContainerEvent ( this . kEVENT _TYPE _DETACHED . replace ( /^nsDOM/ , '' ) , aChild , true , false , data ) ;
2010-12-20 06:54:42 -05:00
2009-07-23 12:28:31 -04:00
if ( this . isGroupTab ( parentTab ) && ! this . hasChildTabs ( parentTab ) ) {
2011-05-25 16:54:46 -04:00
this . window . setTimeout ( function ( aTabBrowser ) {
2009-07-23 12:59:35 -04:00
if ( parentTab . parentNode )
2010-08-08 05:42:47 -04:00
aTabBrowser . removeTab ( parentTab , { animate : true } ) ;
2009-07-23 12:59:35 -04:00
parentTab = null ;
} , 0 , this . getTabBrowserFromChild ( parentTab ) ) ;
2009-07-23 12:26:33 -04:00
}
} ,
2011-12-06 20:18:05 -05:00
partTab : function TSTBrowser _partTab ( aChild , aInfo ) /* PUBLIC API, for backward compatibility */
2009-07-23 12:26:33 -04:00
{
2011-12-06 20:18:05 -05:00
return this . detachTab ( aChild , aInfo ) ;
2007-11-14 14:34:36 -05:00
} ,
2009-12-16 12:52:25 -05:00
2011-12-06 20:18:05 -05:00
detachAllChildren : function TSTBrowser _detachAllChildren ( aTab , aInfo )
2009-12-16 12:52:25 -05:00
{
2012-08-04 13:53:57 -04:00
if ( ! aTab . parentNode ) return ; // do nothing for closed tab!
2010-08-13 14:32:43 -04:00
aInfo = aInfo || { } ;
if ( ! ( 'behavior' in aInfo ) )
2011-03-18 13:56:00 -04:00
aInfo . behavior = this . kCLOSE _PARENT _BEHAVIOR _SIMPLY _DETACH _ALL _CHILDREN ;
if ( aInfo . behavior == this . kCLOSE _PARENT _BEHAVIOR _CLOSE _ALL _CHILDREN )
aInfo . behavior = this . kCLOSE _PARENT _BEHAVIOR _PROMOTE _FIRST _CHILD ;
2010-08-13 14:32:43 -04:00
var b = this . mTabBrowser ;
var parentTab = this . getParentTab ( aTab ) ;
var children = this . getChildTabs ( aTab ) ;
2011-07-29 13:10:28 -04:00
if (
this . isGroupTab ( aTab ) &&
2012-09-23 02:43:49 -04:00
this . getTabs ( b ) . filter ( function ( aTab ) {
2011-07-29 13:10:28 -04:00
return ! b . _removingTabs || b . _removingTabs . indexOf ( aTab ) < 0 ;
} ) . length == children . length
) {
aInfo . behavior = this . kCLOSE _PARENT _BEHAVIOR _PROMOTE _ALL _CHILDREN ;
2011-07-29 13:11:08 -04:00
aInfo . dontUpdateIndent = false ;
2011-07-29 13:10:28 -04:00
}
2010-09-18 12:13:07 -04:00
var insertBefore = null ;
2011-03-18 13:56:00 -04:00
if ( aInfo . behavior == this . kCLOSE _PARENT _BEHAVIOR _DETACH _ALL _CHILDREN &&
2012-10-23 12:43:56 -04:00
! utils . getTreePref ( 'closeParentBehavior.moveDetachedTabsToBottom' ) ) {
2010-09-18 12:13:07 -04:00
insertBefore = this . getNextSiblingTab ( this . getRootTab ( aTab ) ) ;
}
2012-02-04 16:31:03 -05:00
for ( let i = 0 , maxi = children . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
let tab = children [ i ] ;
2012-02-04 13:15:38 -05:00
if ( aInfo . behavior == this . kCLOSE _PARENT _BEHAVIOR _DETACH _ALL _CHILDREN ) {
this . detachTab ( tab , aInfo ) ;
this . moveTabSubtreeTo ( tab , insertBefore ? insertBefore . _tPos - 1 : this . getLastTab ( b ) . _tPos ) ;
}
else if ( aInfo . behavior == this . kCLOSE _PARENT _BEHAVIOR _PROMOTE _FIRST _CHILD ) {
this . detachTab ( tab , aInfo ) ;
if ( i == 0 ) {
if ( parentTab ) {
this . attachTabTo ( tab , parentTab , {
2010-08-13 14:32:43 -04:00
_ _proto _ _ : aInfo ,
dontExpand : true ,
dontMove : true
} ) ;
}
2012-02-04 13:15:38 -05:00
this . collapseExpandSubtree ( tab , false ) ;
this . deleteTabValue ( tab , this . kSUBTREE _COLLAPSED ) ;
}
else {
this . attachTabTo ( tab , children [ 0 ] , {
2010-08-13 14:32:43 -04:00
_ _proto _ _ : aInfo ,
dontExpand : true ,
dontMove : true
} ) ;
}
2012-02-04 13:15:38 -05:00
}
else if ( aInfo . behavior == this . kCLOSE _PARENT _BEHAVIOR _PROMOTE _ALL _CHILDREN && parentTab ) {
this . attachTabTo ( tab , parentTab , {
_ _proto _ _ : aInfo ,
dontExpand : true ,
dontMove : true
} ) ;
}
else { // aInfo.behavior == this.kCLOSE_PARENT_BEHAVIOR_SIMPLY_DETACH_ALL_CHILDREN
this . detachTab ( tab , aInfo ) ;
}
}
2009-12-16 12:52:25 -05:00
} ,
2011-12-06 20:18:05 -05:00
partAllChildren : function TSTBrowser _partAllChildren ( aTab , aInfo ) /* for backward compatibility */
{
return this . detachAllChildren ( aTab , aInfo ) ;
} ,
2011-04-07 23:15:42 -04:00
2011-12-06 20:18:05 -05:00
detachTabs : function TSTBrowser _detachTabs ( aTabs )
2011-06-15 04:38:14 -04:00
{
2012-02-04 16:31:03 -05:00
for ( let i = 0 , maxi = aTabs . length ; i < maxi ; i ++ )
2011-06-15 04:38:14 -04:00
{
2012-02-04 16:31:03 -05:00
let tab = aTabs [ i ] ;
2011-06-15 04:38:14 -04:00
if ( aTabs . indexOf ( this . getParentTab ( tab ) ) > - 1 )
continue ;
2011-12-06 20:18:05 -05:00
this . detachAllChildren ( tab , {
2011-06-15 04:38:14 -04:00
behavior : this . getCloseParentBehaviorForTab (
tab ,
this . kCLOSE _PARENT _BEHAVIOR _PROMOTE _FIRST _CHILD
)
} ) ;
}
} ,
2011-12-06 20:18:05 -05:00
partTabs : function TSTBrowser _partTabs ( aTabs ) /* for backward compatibility */
{
return this . detachTabs ( aTabs ) ;
} ,
2011-06-15 04:38:14 -04:00
2011-05-25 11:47:29 -04:00
getCloseParentBehaviorForTab : function TSTBrowser _getCloseParentBehaviorForTab ( aTab , aDefaultBehavior )
2011-04-07 23:15:42 -04:00
{
2012-10-23 12:43:56 -04:00
var closeParentBehavior = utils . getTreePref ( 'closeParentBehavior' ) ;
var closeRootBehavior = utils . getTreePref ( 'closeRootBehavior' ) ;
2011-04-07 23:15:42 -04:00
var parentTab = this . getParentTab ( aTab ) ;
var behavior = aDefaultBehavior ?
aDefaultBehavior :
2011-04-26 12:24:33 -04:00
( ! parentTab && closeParentBehavior == this . kCLOSE _PARENT _BEHAVIOR _PROMOTE _ALL _CHILDREN ) ?
closeRootBehavior :
closeParentBehavior ;
2011-04-07 23:15:42 -04:00
if ( behavior == this . kCLOSE _PARENT _BEHAVIOR _PROMOTE _FIRST _CHILD &&
parentTab &&
this . getChildTabs ( parentTab ) . length == 1 )
behavior = this . kCLOSE _PARENT _BEHAVIOR _PROMOTE _ALL _CHILDREN ;
return behavior ;
} ,
2009-12-16 12:52:25 -05:00
2010-08-13 13:14:46 -04:00
updateTabsIndent : function TSTBrowser _updateTabsIndent ( aTabs , aLevel , aJustNow )
2007-11-14 14:34:36 -05:00
{
2009-12-18 04:05:41 -05:00
if ( ! aTabs || ! aTabs . length || ! this . _treeViewEnabled ) return ;
2007-11-17 00:20:26 -05:00
2010-12-01 03:40:18 -05:00
if ( aLevel === void ( 0 ) )
aLevel = this . getAncestorTabs ( aTabs [ 0 ] ) . length ;
2007-11-17 00:20:26 -05:00
var b = this . mTabBrowser ;
2009-04-07 13:14:09 -04:00
var margin = this . indent < 0 ? this . baseIndent : this . indent ;
2010-11-29 03:24:45 -05:00
var indent = ( this . maxTreeLevel < 0 ? aLevel : Math . min ( aLevel , this . maxTreeLevel ) ) * margin ;
2007-11-17 00:20:26 -05:00
2009-12-18 07:57:21 -05:00
var multirow = this . isMultiRow ( ) ;
if ( multirow ) {
let maxIndent = parseInt ( aTabs [ 0 ] . boxObject . height / 2 ) ;
indent = Math . min ( aLevel * 3 , maxIndent ) ;
}
2012-02-04 16:31:03 -05:00
for ( let i = 0 , maxi = aTabs . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
let tab = aTabs [ i ] ;
2012-02-04 13:15:38 -05:00
if ( ! tab . parentNode ) continue ; // ignore removed tabs
this . updateTabIndent ( tab , indent , aJustNow ) ;
tab . setAttribute ( this . kNEST , aLevel ) ;
this . updateCanCollapseSubtree ( tab , aLevel ) ;
this . updateTabsIndent ( this . getChildTabs ( tab ) , aLevel + 1 , aJustNow ) ;
}
2007-11-14 14:34:36 -05:00
} ,
2009-12-25 03:34:52 -05:00
updateTabsIndentWithDelay : function TSTBrowser _updateTabsIndentWithDelay ( aTabs )
2009-04-20 09:00:05 -04:00
{
if ( this . updateTabsIndentWithDelayTimer )
2011-05-25 16:54:46 -04:00
this . window . clearTimeout ( this . updateTabsIndentWithDelayTimer ) ;
2009-04-20 09:00:05 -04:00
2009-04-20 10:10:58 -04:00
this . updateTabsIndentWithDelayTabs = this . updateTabsIndentWithDelayTabs . concat ( aTabs ) ;
2011-05-25 16:54:46 -04:00
this . updateTabsIndentWithDelayTimer = this . window . setTimeout ( function ( aSelf ) {
2009-04-20 10:10:58 -04:00
var tabs = [ ] ;
2012-02-04 16:31:03 -05:00
for ( let i = 0 , maxi = aSelf . updateTabsIndentWithDelayTabs . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
let tab = aSelf . updateTabsIndentWithDelayTabs [ i ] ;
2012-02-04 13:15:38 -05:00
if ( tabs . indexOf ( tab ) < 0 && tab . parentNode ) tabs . push ( tab ) ;
}
2009-04-22 07:32:39 -04:00
aSelf . updateTabsIndentWithDelayTabs = [ ] ;
2009-04-20 10:10:58 -04:00
aSelf . updateTabsIndent ( tabs ) ;
2011-05-25 16:54:46 -04:00
aSelf . window . clearTimeout ( aSelf . updateTabsIndentWithDelayTimer ) ;
2009-04-20 09:00:05 -04:00
aSelf . updateTabsIndentWithDelayTimer = null ;
2009-05-13 02:09:17 -04:00
tabs = null ;
2009-04-20 09:00:05 -04:00
} , 0 , this ) ;
} ,
updateTabsIndentWithDelayTimer : null ,
2009-04-07 12:09:17 -04:00
2010-08-13 13:14:46 -04:00
updateTabIndent : function TSTBrowser _updateTabIndent ( aTab , aIndent , aJustNow )
2009-04-07 12:09:17 -04:00
{
2012-08-04 13:53:57 -04:00
if ( ! aTab . parentNode ) return ; // do nothing for closed tab!
2009-04-07 12:09:17 -04:00
this . stopTabIndentAnimation ( aTab ) ;
2011-01-12 10:13:12 -05:00
if ( aTab . hasAttribute ( 'pinned' ) )
return ;
2010-11-18 23:00:42 -05:00
if ( ! this . enableSubtreeIndent )
aIndent = 0 ;
2009-12-18 04:05:41 -05:00
if ( this . isMultiRow ( ) ) {
2010-08-13 13:14:46 -04:00
let colors = '-moz-border-' + this . indentTarget + '-colors:' + ( function ( ) {
2009-12-18 04:05:41 -05:00
var retVal = [ ] ;
2009-12-18 07:57:21 -05:00
for ( var i = 1 ; i < aIndent ; i ++ )
2009-12-18 04:05:41 -05:00
{
retVal . push ( 'transparent' ) ;
}
retVal . push ( 'ThreeDShadow' ) ;
return retVal . length == 1 ? 'none' : retVal . join ( ' ' ) ;
2009-12-18 07:57:21 -05:00
} ) ( ) + ' !important;' ;
2012-02-04 16:31:03 -05:00
let boxes = this . document . getAnonymousNodes ( aTab ) ;
for ( let i = 0 , box = boxes . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
let box = boxes [ i ] ;
2012-02-04 13:15:38 -05:00
if ( box . nodeType != Node . ELEMENT _NODE ) continue ;
box . setAttribute (
2009-12-18 04:05:41 -05:00
'style' ,
2012-02-04 13:15:38 -05:00
box . getAttribute ( 'style' )
. replace ( /(-moz-)?border-(top|bottom)(-[^:]*)?.*:[^;]+;?/g , '' ) +
2010-08-13 13:14:46 -04:00
'; border-' + this . indentTarget + ': solid transparent ' + aIndent + 'px !important;' + colors
2009-12-18 04:05:41 -05:00
) ;
2012-02-04 13:15:38 -05:00
}
2009-12-18 07:57:21 -05:00
return ;
}
2009-12-18 04:05:41 -05:00
2009-04-07 12:09:17 -04:00
if (
! this . animationEnabled ||
2009-04-07 13:58:58 -04:00
aJustNow ||
2009-04-09 21:32:03 -04:00
this . indentDuration < 1 ||
2009-10-25 22:36:42 -04:00
this . isCollapsed ( aTab )
2009-04-07 12:09:17 -04:00
) {
2010-08-13 13:14:46 -04:00
aTab . style . setProperty ( this . indentCSSProp , aIndent + 'px' , 'important' ) ;
2009-04-07 12:09:17 -04:00
return ;
}
2010-08-13 13:14:46 -04:00
var self = this ;
2010-08-08 08:46:33 -04:00
var CSSTransitionEnabled = ( 'Transition' in aTab . style || 'MozTransition' in aTab . style ) ;
if ( CSSTransitionEnabled ) {
aTab . _ _treestyletab _ _updateTabIndentTask = function ( aTime , aBeginning , aChange , aDuration ) {
2012-08-04 17:11:23 -04:00
delete aTab . _ _treestyletab _ _updateTabIndentTask ;
if ( ! self . isDestroying )
aTab . style . setProperty ( self . indentCSSProp , aIndent + 'px' , 'important' ) ;
2010-08-08 08:46:33 -04:00
return true ;
} ;
this . animationManager . addTask (
aTab . _ _treestyletab _ _updateTabIndentTask ,
2011-05-25 16:54:46 -04:00
0 , 0 , 1 , this . window
2010-08-08 08:46:33 -04:00
) ;
return ;
}
2010-08-13 13:14:46 -04:00
var startIndent = this . getPropertyPixelValue ( aTab , this . indentCSSProp ) ;
2009-04-07 12:09:17 -04:00
var delta = aIndent - startIndent ;
2009-04-08 09:43:44 -04:00
var radian = 90 * Math . PI / 180 ;
2009-04-09 21:32:03 -04:00
aTab . _ _treestyletab _ _updateTabIndentTask = function ( aTime , aBeginning , aChange , aDuration ) {
2012-02-04 18:24:26 -05:00
if ( self . isDestroying ) return true ;
2009-04-08 09:43:44 -04:00
var indent , finished ;
2009-04-09 21:32:03 -04:00
if ( aTime >= aDuration ) {
2009-04-08 05:16:39 -04:00
delete aTab . _ _treestyletab _ _updateTabIndentTask ;
2009-04-08 09:43:44 -04:00
indent = aIndent ;
finished = true ;
2009-04-08 05:16:39 -04:00
}
else {
2009-04-09 21:32:03 -04:00
indent = startIndent + ( delta * Math . sin ( aTime / aDuration * radian ) ) ;
2009-04-08 09:43:44 -04:00
finished = false ;
2009-04-08 05:16:39 -04:00
}
2010-08-13 13:14:46 -04:00
aTab . style . setProperty ( self . indentCSSProp , indent + 'px' , 'important' ) ;
2009-05-13 02:09:17 -04:00
if ( finished ) {
startIndent = null ;
delta = null ;
radian = null ;
self = null ;
aTab = null ;
}
2009-04-08 09:43:44 -04:00
return finished ;
2009-04-08 05:16:39 -04:00
} ;
2010-06-22 14:00:16 -04:00
this . animationManager . addTask (
2009-04-08 05:44:44 -04:00
aTab . _ _treestyletab _ _updateTabIndentTask ,
2011-05-25 16:54:46 -04:00
0 , 0 , this . indentDuration , this . window
2009-04-08 05:44:44 -04:00
) ;
2009-04-07 12:09:17 -04:00
} ,
2009-12-25 03:34:52 -05:00
stopTabIndentAnimation : function TSTBrowser _stopTabIndentAnimation ( aTab )
2009-04-07 10:44:39 -04:00
{
2012-08-04 13:53:57 -04:00
if ( ! aTab . parentNode ) return ; // do nothing for closed tab!
2010-06-22 14:00:16 -04:00
this . animationManager . removeTask (
2009-04-08 05:44:44 -04:00
aTab . _ _treestyletab _ _updateTabIndentTask
) ;
2012-08-04 17:11:23 -04:00
delete aTab . _ _treestyletab _ _updateTabIndentTask ;
2009-04-07 12:09:17 -04:00
} ,
2009-12-25 03:34:52 -05:00
inheritTabIndent : function TSTBrowser _inheritTabIndent ( aNewTab , aExistingTab )
2009-04-07 12:09:17 -04:00
{
2010-08-13 13:14:46 -04:00
var indent = this . getPropertyPixelValue ( aExistingTab , this . indentCSSProp ) ;
if ( indent )
aNewTab . style . setProperty ( this . indentCSSProp , indent + 'px' , 'important' ) ;
else
aNewTab . style . removeProperty ( this . indentCSSProp ) ;
2009-04-07 10:44:39 -04:00
} ,
2007-11-14 14:34:36 -05:00
2011-01-22 13:25:21 -05:00
updateAllTabsIndent : function TSTBrowser _updateAllTabsIndent ( aJustNow )
2007-11-14 14:34:36 -05:00
{
2011-01-22 13:25:21 -05:00
this . updateTabsIndent ( this . rootTabs , 0 , aJustNow ) ;
2007-11-17 00:20:26 -05:00
// this.checkTabsIndentOverflow();
2007-11-14 14:34:36 -05:00
} ,
2007-11-17 00:20:26 -05:00
2012-08-24 08:30:24 -04:00
checkTabsIndentOverflow : function TSTBrowser _checkTabsIndentOverflow ( aDelay )
{
this . cancelCheckTabsIndentOverflow ( ) ;
this . checkTabsIndentOverflowTimer = this . window . setTimeout ( function ( aSelf ) {
aSelf . checkTabsIndentOverflowTimer = null ;
aSelf . checkTabsIndentOverflowCallback ( ) ;
} , aDelay || 100 , this ) ;
} ,
cancelCheckTabsIndentOverflow : function TSTBrowser _cancelCheckTabsIndentOverflow ( )
2007-11-14 14:34:36 -05:00
{
2007-11-17 00:20:26 -05:00
if ( this . checkTabsIndentOverflowTimer ) {
2011-05-25 16:54:46 -04:00
this . window . clearTimeout ( this . checkTabsIndentOverflowTimer ) ;
2007-11-17 00:20:26 -05:00
this . checkTabsIndentOverflowTimer = null ;
2007-11-14 14:34:36 -05:00
}
} ,
2007-11-17 00:20:26 -05:00
checkTabsIndentOverflowTimer : null ,
2009-12-25 03:34:52 -05:00
checkTabsIndentOverflowCallback : function TSTBrowser _checkTabsIndentOverflowCallback ( )
2007-11-14 14:34:36 -05:00
{
2012-10-23 12:43:56 -04:00
if ( ! utils . getTreePref ( 'indent.autoShrink' ) ) {
2011-03-30 00:04:29 -04:00
this . indent = - 1 ;
return ;
}
2007-11-17 00:20:26 -05:00
var b = this . mTabBrowser ;
2012-09-23 03:11:03 -04:00
var tabs = Array . slice ( b . mTabContainer . querySelectorAll (
'tab[' + this . kNEST + ']:not([' + this . kNEST + '="0"]):not([' + this . kNEST + '=""])' +
':not([' + this . kCOLLAPSED + '="true"])' +
':not([hidden="true"])' +
2012-09-23 03:13:01 -04:00
':not([collapsed="true"])'
2007-11-17 00:20:26 -05:00
) ) ;
if ( ! tabs . length ) return ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
var self = this ;
2011-12-07 07:33:57 -05:00
tabs . sort ( function ( aA , aB ) { return Number ( aA . getAttribute ( self . kNEST ) ) - Number ( aB . getAttribute ( self . kNEST ) ) ; } ) ;
2011-12-06 22:06:05 -05:00
var nest = tabs [ tabs . length - 1 ] . getAttribute ( this . kNEST ) ;
2010-11-29 03:24:45 -05:00
if ( this . maxTreeLevel > - 1 )
nest = Math . min ( nest , this . maxTreeLevel ) ;
if ( ! nest )
return ;
2007-11-14 14:34:36 -05:00
2009-04-07 13:14:09 -04:00
var oldIndent = this . indent ;
var indent = ( oldIndent < 0 ? this . baseIndent : oldIndent ) * nest ;
2009-07-07 04:30:30 -04:00
var maxIndentBase = Math . min (
2010-06-25 11:59:59 -04:00
this . getFirstNormalTab ( b ) . boxObject [ this . invertedSizeProp ] ,
2009-05-12 15:09:13 -04:00
b . mTabContainer . boxObject [ this . invertedSizeProp ]
) ;
2012-08-30 13:51:21 -04:00
var isVertical = this . isVertical ;
if ( ! isVertical ) {
2009-05-12 15:09:13 -04:00
if ( this . _horizontalTabMaxIndentBase )
maxIndentBase = this . _horizontalTabMaxIndentBase ;
else
this . _horizontalTabMaxIndentBase = maxIndentBase ;
}
2012-08-30 13:51:21 -04:00
var maxIndent = maxIndentBase * ( isVertical ? 0.33 : 0.5 ) ;
2007-11-14 14:34:36 -05:00
2012-10-23 12:43:56 -04:00
var indentMin = utils . getTreePref ( isVertical ? 'indent.min.vertical' : 'indent.min.horizontal' ) ;
2012-08-30 13:51:21 -04:00
var indentUnit = Math . max ( Math . floor ( maxIndent / nest ) , indentMin ) ;
2007-11-17 00:20:26 -05:00
if ( indent > maxIndent ) {
2009-04-07 13:14:09 -04:00
this . indent = indentUnit ;
2007-11-17 00:20:26 -05:00
}
else {
2009-04-07 13:14:09 -04:00
this . indent = - 1 ;
if ( ( this . baseIndent * nest ) > maxIndent )
this . indent = indentUnit ;
2007-11-17 00:20:26 -05:00
}
2007-11-14 14:34:36 -05:00
2009-04-07 13:14:09 -04:00
if ( oldIndent != this . indent ) {
2007-11-17 00:20:26 -05:00
this . updateAllTabsIndent ( ) ;
}
} ,
2009-05-12 15:09:13 -04:00
_horizontalTabMaxIndentBase : 0 ,
2007-11-17 00:20:26 -05:00
2010-12-01 03:40:18 -05:00
updateCanCollapseSubtree : function TSTBrowser _updateCanCollapseSubtree ( aTab , aLevel )
{
2012-08-04 13:53:57 -04:00
if ( ! aTab . parentNode ) return ; // do nothing for closed tab!
2010-12-01 03:40:18 -05:00
if (
! aLevel ||
this . maxTreeLevel < 0 ||
this . maxTreeLevel > aLevel
) {
aTab . setAttribute ( this . kALLOW _COLLAPSE , true ) ;
this . collapseExpandSubtree ( aTab , this . isSubtreeCollapsed ( aTab ) ) ;
}
else {
this . collapseExpandSubtree ( aTab , false ) ;
aTab . removeAttribute ( this . kALLOW _COLLAPSE ) ;
}
} ,
2009-12-25 03:34:52 -05:00
updateTabsCount : function TSTBrowser _updateTabsCount ( aTab , aDontUpdateAncestor )
2007-11-17 00:20:26 -05:00
{
2012-08-04 13:53:57 -04:00
if ( ! aTab . parentNode ) return ; // do nothing for closed tab!
2011-05-25 16:54:46 -04:00
var count = this . document . getAnonymousElementByAttribute ( aTab , 'class' , this . kCOUNTER ) ;
2007-11-17 00:20:26 -05:00
if ( count ) {
2012-01-13 11:45:51 -05:00
let value = this . getDescendantTabs ( aTab ) . length ;
if ( this . counterRole == this . kCOUNTER _ROLE _ALL _TABS )
value += 1 ;
count . setAttribute ( 'value' , value ) ;
2007-11-17 00:20:26 -05:00
}
2011-01-22 11:08:26 -05:00
if ( ! aDontUpdateAncestor ) {
let parent = this . getParentTab ( aTab ) ;
if ( parent )
this . updateTabsCount ( parent ) ;
}
2007-11-17 00:20:26 -05:00
} ,
2010-11-29 03:24:45 -05:00
2011-12-04 22:19:50 -05:00
updateAllTabsCount : function TSTBrowser _updateAllTabsCount ( )
{
2012-02-04 16:31:03 -05:00
var tabs = this . rootTabs ;
for ( let i = 0 , maxi = tabs . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
let tab = tabs [ i ] ;
2012-02-04 13:15:38 -05:00
this . updateTabsCount ( tab , this ) ;
}
2011-12-04 22:19:50 -05:00
} ,
2010-12-01 19:00:39 -05:00
promoteTooDeepLevelTabs : function TSTBrowser _promoteTooDeepLevelTabs ( aParent )
2010-11-29 03:24:45 -05:00
{
if ( this . maxTreeLevel < 0 || ! this . maxTreeLevelPhisical )
return ;
2012-09-23 02:43:49 -04:00
var tabs = aParent ? this . getDescendantTabs ( aParent ) : this . getAllTabs ( this . mTabBrowser ) ;
2012-02-04 16:31:03 -05:00
for ( let i = 0 , maxi = tabs . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
let level = parseInt ( tab . getAttribute ( this . kNEST ) || 0 ) ;
2010-11-29 03:24:45 -05:00
if ( level <= this . maxTreeLevel )
2012-02-04 13:15:38 -05:00
continue ;
2010-11-29 03:24:45 -05:00
2012-02-04 13:15:38 -05:00
let parent = this . getParentTab ( tab ) ;
let newParent = this . getParentTab ( parent ) ;
2010-11-29 03:24:45 -05:00
if ( this . maxTreeLevel == 0 || ! newParent ) {
2011-12-06 20:18:05 -05:00
this . detachTab ( aTab ) ;
2010-11-29 03:24:45 -05:00
}
else {
2012-02-04 13:15:38 -05:00
let nextSibling = this . getNextTab ( tab ) ;
this . attachTabTo ( tab , newParent , {
2010-11-29 03:24:45 -05:00
dontMove : true ,
insertBefore : nextSibling
} ) ;
}
2012-02-04 13:15:38 -05:00
}
2010-11-29 03:24:45 -05:00
} ,
2007-11-17 00:20:26 -05:00
/* move */
2009-12-25 06:19:50 -05:00
moveTabSubtreeTo : function TSTBrowser _moveTabSubtreeTo ( aTab , aIndex )
2007-11-17 00:20:26 -05:00
{
2012-08-04 13:53:57 -04:00
if ( ! aTab || ! aTab . parentNode ) return ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
var b = this . mTabBrowser ;
2009-09-30 01:42:48 -04:00
this . subTreeMovingCount ++ ;
2007-11-14 14:34:36 -05:00
2009-09-30 01:42:48 -04:00
this . internallyTabMovingCount ++ ;
2007-11-17 00:20:26 -05:00
b . moveTabTo ( aTab , aIndex ) ;
2009-09-30 01:42:48 -04:00
this . internallyTabMovingCount -- ;
2007-11-14 14:34:36 -05:00
2009-09-30 01:42:48 -04:00
this . subTreeChildrenMovingCount ++ ;
this . internallyTabMovingCount ++ ;
2012-02-04 16:31:03 -05:00
var descendantTabs = this . getDescendantTabs ( aTab ) ;
for ( let i = 0 , maxi = descendantTabs . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
let descendantTab = descendantTabs [ i ] ;
2012-02-04 13:15:38 -05:00
b . moveTabTo ( descendantTab , aTab . _tPos + i + ( aTab . _tPos < descendantTab . _tPos ? 1 : 0 ) ) ;
}
2009-09-30 01:42:48 -04:00
this . internallyTabMovingCount -- ;
this . subTreeChildrenMovingCount -- ;
2007-11-14 14:34:36 -05:00
2009-09-30 01:42:48 -04:00
this . subTreeMovingCount -- ;
2007-11-17 00:20:26 -05:00
} ,
2009-12-25 06:36:22 -05:00
moveTabSubTreeTo : function ( ) { return this . moveTabSubtreeTo . apply ( this , arguments ) ; } , // obsolete, for backward compatibility
2007-11-17 00:20:26 -05:00
2009-12-25 03:34:52 -05:00
moveTabLevel : function TSTBrowser _moveTabLevel ( aEvent )
2007-11-17 00:20:26 -05:00
{
var b = this . mTabBrowser ;
var parentTab = this . getParentTab ( b . mCurrentTab ) ;
2011-05-25 16:54:46 -04:00
if ( aEvent . keyCode == Ci . nsIDOMKeyEvent . DOM _VK _RIGHT ) {
let prevTab = this . getPreviousSiblingTab ( b . mCurrentTab ) ;
2007-11-17 00:20:26 -05:00
if ( ( ! parentTab && prevTab ) ||
( parentTab && b . mCurrentTab != this . getFirstChildTab ( parentTab ) ) ) {
this . attachTabTo ( b . mCurrentTab , prevTab ) ;
b . mCurrentTab . focus ( ) ;
return true ;
}
}
2011-05-25 16:54:46 -04:00
else if ( aEvent . keyCode == Ci . nsIDOMKeyEvent . DOM _VK _LEFT && parentTab ) {
let grandParent = this . getParentTab ( parentTab ) ;
2007-11-17 00:20:26 -05:00
if ( grandParent ) {
this . attachTabTo ( b . mCurrentTab , grandParent , {
insertBefore : this . getNextSiblingTab ( parentTab )
} ) ;
b . mCurrentTab . focus ( ) ;
return true ;
}
else {
2011-05-25 16:54:46 -04:00
let nextTab = this . getNextSiblingTab ( parentTab ) ;
2011-12-06 20:18:05 -05:00
this . detachTab ( b . mCurrentTab ) ;
2009-09-30 01:42:48 -04:00
this . internallyTabMovingCount ++ ;
2007-11-17 00:20:26 -05:00
if ( nextTab ) {
b . moveTabTo ( b . mCurrentTab , nextTab . _tPos - 1 ) ;
}
else {
2009-01-26 01:37:29 -05:00
b . moveTabTo ( b . mCurrentTab , this . getLastTab ( b ) . _tPos ) ;
2007-11-17 00:20:26 -05:00
}
2009-09-30 01:42:48 -04:00
this . internallyTabMovingCount -- ;
2007-11-17 00:20:26 -05:00
b . mCurrentTab . focus ( ) ;
return true ;
}
}
return false ;
} ,
2011-06-15 04:38:14 -04:00
2011-06-15 05:13:23 -04:00
/ * *
* Imports tabs from another window with their tree structure .
* aOptions is an optional hash which can have two properties :
* * duplicate ( boolean )
* * insertBefore ( nsIDOMElement )
* /
2011-06-16 12:48:32 -04:00
importTabs : function TSTBrowser _importTabs ( aTabs , aInsertBefore ) /* PUBLIC API */
2011-06-15 05:13:23 -04:00
{
2011-06-16 12:48:32 -04:00
return this . moveTabsInternal ( aTabs , { insertBefore : aInsertBefore } ) ;
2011-06-15 05:13:23 -04:00
} ,
2011-11-29 13:40:11 -05:00
duplicateTabs : function TSTBrowser _duplicateTabs ( aTabs , aInsertBefore ) /* PUBLIC API */
2011-06-16 12:48:32 -04:00
{
return this . moveTabsInternal ( aTabs , { insertBefore : aInsertBefore , duplicate : true } ) ;
} ,
moveTabs : function TSTBrowser _importTabs ( aTabs , aInsertBefore ) /* PUBLIC API */
{
return this . moveTabsInternal ( aTabs , { insertBefore : aInsertBefore } ) ;
} ,
moveTabsInternal : function TSTBrowser _moveTabsInternal ( aTabs , aOptions )
2011-06-15 05:13:23 -04:00
{
aOptions = aOptions || { } ;
var targetBrowser = this . mTabBrowser ;
var sourceWindow = aTabs [ 0 ] . ownerDocument . defaultView ;
var sourceBrowser = sourceWindow . TreeStyleTabService . getTabBrowserFromChild ( aTabs [ 0 ] ) ;
var sourceService = sourceBrowser . treeStyleTab ;
// prevent Multiple Tab Handler feature
targetBrowser . duplicatingSelectedTabs = true ;
targetBrowser . movingSelectedTabs = true ;
var shouldClose = (
! aOptions . duplicate &&
2012-09-23 02:43:49 -04:00
sourceService . getAllTabs ( sourceBrowser ) . length == aTabs . length
2011-06-15 05:13:23 -04:00
) ;
var newTabs = [ ] ;
var treeStructure = sourceService . getTreeStructureFromTabs ( aTabs ) ;
// Firefox fails to "move" collapsed tabs. So, expand them first
// and collapse them after they are moved.
var collapsedStates = sourceService . forceExpandTabs ( aTabs ) ; ;
var shouldResetSelection = (
aTabs . every ( function ( aTab ) {
return aTab . getAttribute ( 'multiselected' ) == 'true' ;
} ) &&
( sourceService != this || aOptions . duplicate )
) ;
2012-09-23 02:43:49 -04:00
var tabs = this . getTabs ( targetBrowser ) ;
2011-06-15 05:13:23 -04:00
var lastTabIndex = tabs [ tabs . length - 1 ] . _tPos ;
for ( let i in aTabs )
{
let tab = aTabs [ i ] ;
if ( shouldResetSelection ) {
if ( 'MultipleTabService' in sourceWindow )
sourceWindow . MultipleTabService . setSelection ( tab , false ) ;
else
tab . removeAttribute ( 'multiselected' ) ;
}
if ( aOptions . duplicate ) {
tab = this . duplicateTabAsOrphan ( tab ) ;
newTabs . push ( tab ) ;
}
else if ( sourceService != this ) {
tab = this . importTab ( tab ) ;
newTabs . push ( tab ) ;
}
if ( shouldResetSelection ) {
if ( 'MultipleTabService' in sourceWindow )
sourceWindow . MultipleTabService . setSelection ( tab , true ) ;
else
tab . setAttribute ( 'multiselected' , true ) ;
}
lastTabIndex ++ ;
let newIndex = aOptions . insertBefore ? aOptions . insertBefore . _tPos : lastTabIndex ;
if ( aOptions . insertBefore && newIndex > tab . _tPos ) newIndex -- ;
this . internallyTabMovingCount ++ ;
targetBrowser . moveTabTo ( tab , newIndex ) ;
this . collapseExpandTab ( tab , false , true ) ;
this . internallyTabMovingCount -- ;
}
if ( shouldClose )
sourceService . closeOwner ( sourceBrowser ) ;
if ( newTabs . length )
this . applyTreeStructureToTabs (
newTabs ,
treeStructure ,
collapsedStates . map ( function ( aCollapsed ) {
return ! aCollapsed
} )
) ;
for ( let i = collapsedStates . length - 1 ; i > - 1 ; i -- )
{
sourceService . collapseExpandSubtree ( aTabs [ i ] , collapsedStates [ i ] , true ) ;
}
// Multiple Tab Handler
targetBrowser . movingSelectedTabs = false ;
targetBrowser . duplicatingSelectedTabs = false ;
return newTabs ;
} ,
2011-11-29 13:40:11 -05:00
importTab : function TSTBrowser _importTab ( aTab )
2011-06-15 04:38:14 -04:00
{
2012-08-04 13:53:57 -04:00
if ( ! aTab . parentNode ) return null ; // do nothing for closed tab!
2011-06-15 04:38:14 -04:00
var newTab = this . mTabBrowser . addTab ( ) ;
newTab . linkedBrowser . stop ( ) ;
newTab . linkedBrowser . docShell ;
this . mTabBrowser . swapBrowsersAndCloseOther ( newTab , aTab ) ;
this . mTabBrowser . setTabTitle ( newTab ) ;
return newTab ;
} ,
2011-11-29 13:40:11 -05:00
duplicateTabAsOrphan : function TSTBrowser _duplicateTabAsOrphan ( aTab )
2011-06-15 04:38:14 -04:00
{
2012-08-04 13:53:57 -04:00
if ( ! aTab . parentNode ) return null ; // do nothing for closed tab!
2011-06-15 04:38:14 -04:00
var newTab = this . mTabBrowser . duplicateTab ( aTab ) ;
this . deleteTabValue ( newTab , this . kCHILDREN ) ;
this . deleteTabValue ( newTab , this . kPARENT ) ;
return newTab ;
} ,
2011-06-15 05:13:23 -04:00
closeOwner : function TSTBrowser _closeOwner ( aTabOwner )
{
var w = aTabOwner . ownerDocument . defaultView ;
if ( ! w ) return ;
if ( 'SplitBrowser' in w ) {
if ( 'getSubBrowserFromChild' in w . SplitBrowser ) {
var subbrowser = w . SplitBrowser . getSubBrowserFromChild ( aTabOwner ) ;
if ( subbrowser ) {
subbrowser . close ( ) ;
return ;
}
}
if ( w . SplitBrowser . browsers . length ) return ;
}
w . close ( ) ;
} ,
2007-11-17 00:20:26 -05:00
/* collapse/expand */
2008-12-01 03:30:36 -05:00
2009-12-25 03:34:52 -05:00
collapseExpandSubtree : function TSTBrowser _collapseExpandSubtree ( aTab , aCollapse , aJustNow ) /* PUBLIC API */
2007-11-17 00:20:26 -05:00
{
2012-08-04 13:53:57 -04:00
if ( ! aTab || ! aTab . parentNode ) return ;
2007-11-14 14:34:36 -05:00
2009-10-25 22:36:42 -04:00
if ( this . isSubtreeCollapsed ( aTab ) == aCollapse ) return ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
var b = this . mTabBrowser ;
this . doingCollapseExpand = true ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
this . setTabValue ( aTab , this . kSUBTREE _COLLAPSED , aCollapse ) ;
2007-11-14 14:34:36 -05:00
2012-01-28 16:22:04 -05:00
var expandedTabs = this . getChildTabs ( aTab ) ;
var lastExpandedTabIndex = expandedTabs . length - 1 ;
2012-02-04 16:31:03 -05:00
for ( let i = 0 , maxi = expandedTabs . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
let childTab = expandedTabs [ i ] ;
2012-02-04 13:15:38 -05:00
if ( ! aCollapse && ! aJustNow && i == lastExpandedTabIndex ) {
2012-01-28 16:22:04 -05:00
let self = this ;
2012-02-04 13:15:38 -05:00
this . collapseExpandTab ( childTab , aCollapse , aJustNow , function ( ) {
2012-01-28 16:22:04 -05:00
self . scrollToTabSubtree ( aTab ) ;
} ) ;
}
else
2012-02-04 13:15:38 -05:00
this . collapseExpandTab ( childTab , aCollapse , aJustNow ) ;
}
2007-11-14 14:34:36 -05:00
2011-12-26 23:21:23 -05:00
if ( aCollapse )
this . deleteTabValue ( aTab , this . kSUBTREE _EXPANDED _MANUALLY ) ;
2007-11-17 00:20:26 -05:00
2012-10-23 12:43:56 -04:00
if ( utils . getTreePref ( 'indent.autoShrink' ) &&
utils . getTreePref ( 'indent.autoShrink.onlyForVisible' ) )
2012-08-24 07:51:37 -04:00
this . checkTabsIndentOverflow ( ) ;
2007-11-17 00:20:26 -05:00
this . doingCollapseExpand = false ;
2007-11-14 14:34:36 -05:00
} ,
2011-12-26 23:21:23 -05:00
manualCollapseExpandSubtree : function ( aTab , aCollapse , aJustNow )
{
this . collapseExpandSubtree ( aTab , aCollapse , aJustNow ) ;
if ( ! aCollapse )
this . setTabValue ( aTab , this . kSUBTREE _EXPANDED _MANUALLY , true ) ;
2012-08-24 08:30:24 -04:00
2012-10-23 12:43:56 -04:00
if ( utils . getTreePref ( 'indent.autoShrink' ) &&
utils . getTreePref ( 'indent.autoShrink.onlyForVisible' ) ) {
2012-08-24 08:30:24 -04:00
this . cancelCheckTabsIndentOverflow ( ) ;
2012-08-24 11:22:29 -04:00
if ( ! aTab . _ _treestyletab _ _checkTabsIndentOverflowOnMouseLeave ) {
var self = this ;
aTab . _ _treestyletab _ _checkTabsIndentOverflowOnMouseLeave = function ( aEvent ) {
var x = aEvent . clientX ;
var y = aEvent . clientY ;
var rect = aTab . getBoundingClientRect ( ) ;
if ( x > rect . left && x < rect . right && y > rect . top && y < rect . bottom )
return ;
aTab . removeEventListener ( aEvent . type , aTab . _ _treestyletab _ _checkTabsIndentOverflowOnMouseLeave , false ) ;
delete aTab . _ _treestyletab _ _checkTabsIndentOverflowOnMouseLeave ;
self . checkTabsIndentOverflow ( ) ;
} ;
aTab . addEventListener ( 'mouseleave' , aTab . _ _treestyletab _ _checkTabsIndentOverflowOnMouseLeave , false ) ;
}
2012-08-24 08:30:24 -04:00
}
2011-12-26 23:21:23 -05:00
} ,
2007-11-17 00:20:26 -05:00
2012-01-28 16:22:04 -05:00
collapseExpandTab : function TSTBrowser _collapseExpandTab ( aTab , aCollapse , aJustNow , aCallbackToRunOnStartAnimation )
2007-11-14 14:34:36 -05:00
{
2012-08-04 13:53:57 -04:00
if ( ! aTab || ! aTab . parentNode || ! this . getParentTab ( aTab ) ) return ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
this . setTabValue ( aTab , this . kCOLLAPSED , aCollapse ) ;
2012-01-28 16:22:04 -05:00
this . updateTabCollapsed ( aTab , aCollapse , aJustNow , aCallbackToRunOnStartAnimation ) ;
2007-11-14 14:34:36 -05:00
2011-01-11 05:29:14 -05:00
var data = {
collapsed : aCollapse
} ;
2010-12-20 06:54:42 -05:00
2011-01-11 05:29:14 -05:00
/* PUBLIC API */
this . fireDataContainerEvent ( this . kEVENT _TYPE _TAB _COLLAPSED _STATE _CHANGED , aTab , true , false , data ) ;
2010-12-20 06:54:42 -05:00
// for backward compatibility
2011-01-11 05:29:14 -05:00
this . fireDataContainerEvent ( this . kEVENT _TYPE _TAB _COLLAPSED _STATE _CHANGED . replace ( /^nsDOM/ , '' ) , aTab , true , false , data ) ;
2009-03-25 09:26:41 -04:00
2007-11-17 00:20:26 -05:00
var b = this . mTabBrowser ;
2008-07-30 14:03:44 -04:00
var parent ;
if ( aCollapse && aTab == b . selectedTab && ( parent = this . getParentTab ( aTab ) ) ) {
var newSelection = parent ;
2012-08-04 16:31:38 -04:00
this . getAncestorTabs ( aTab ) . some ( function ( aAncestor ) {
2012-08-08 08:25:22 -04:00
if ( ! this . isCollapsed ( aAncestor ) ) {
newSelection = aAncestor ;
2012-08-04 16:31:38 -04:00
return true ;
2012-08-08 08:25:22 -04:00
}
2012-08-04 16:31:38 -04:00
return false ;
} , this ) ;
2008-07-30 14:03:44 -04:00
b . selectedTab = newSelection ;
2007-11-14 14:34:36 -05:00
}
2007-11-17 00:20:26 -05:00
2009-10-25 22:36:42 -04:00
if ( ! this . isSubtreeCollapsed ( aTab ) ) {
2012-02-04 16:31:03 -05:00
let tabs = this . getChildTabs ( aTab ) ;
for ( let i = 0 , maxi = tabs . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
this . collapseExpandTab ( tabs [ i ] , aCollapse , aJustNow ) ;
2012-02-04 13:15:38 -05:00
}
2007-11-14 14:34:36 -05:00
}
} ,
2012-01-27 14:33:02 -05:00
updateTabCollapsed : function TSTBrowser _updateTabCollapsed ( aTab , aCollapsed , aJustNow , aCallbackToRunOnStartAnimation )
2009-04-07 13:14:09 -04:00
{
2012-08-04 13:53:57 -04:00
if ( ! aTab . parentNode ) return ; // do nothing for closed tab!
2009-04-07 13:14:09 -04:00
this . stopTabCollapseAnimation ( aTab ) ;
2009-04-08 11:00:21 -04:00
aTab . removeAttribute ( this . kX _OFFSET ) ;
aTab . removeAttribute ( this . kY _OFFSET ) ;
2012-02-28 10:36:50 -05:00
if ( ! this . canCollapseSubtree ( this . getParentTab ( aTab ) ) )
aCollapsed = false ;
2010-05-02 00:30:51 -04:00
aTab . setAttribute ( this . kCOLLAPSING _PHASE , aCollapsed ? this . kCOLLAPSING _PHASE _TO _BE _COLLAPSED : this . kCOLLAPSING _PHASE _TO _BE _EXPANDED ) ;
2010-05-06 13:39:10 -04:00
var CSSTransitionEnabled = ( 'Transition' in aTab . style || 'MozTransition' in aTab . style ) ;
2009-04-07 13:14:09 -04:00
2009-04-08 11:00:21 -04:00
var maxMargin ;
var offsetAttr ;
2010-05-06 13:39:10 -04:00
var collapseProp = 'margin-' + this . collapseTarget ;
2010-08-13 13:14:46 -04:00
let ( firstTab = this . getFirstNormalTab ( this . mTabBrowser ) ) {
2009-05-13 02:47:06 -04:00
if ( this . isVertical ) {
maxMargin = firstTab . boxObject . height ;
offsetAttr = this . kY _OFFSET ;
if ( firstTab . style . height )
aTab . style . height = firstTab . style . height ;
}
else {
maxMargin = firstTab . boxObject . width ;
offsetAttr = this . kX _OFFSET ;
if ( firstTab . style . width )
aTab . style . width = firstTab . style . width ;
}
2009-04-08 11:00:21 -04:00
}
2009-04-08 09:43:44 -04:00
var startMargin , endMargin , startOpacity , endOpacity ;
if ( aCollapsed ) {
startMargin = 0 ;
2009-04-08 11:00:21 -04:00
endMargin = maxMargin ;
2009-04-08 09:43:44 -04:00
startOpacity = 1 ;
endOpacity = 0 ;
2010-11-24 11:14:36 -05:00
if ( this . canStackTabs && this . getParentTab ( aTab ) ) {
endOpacity = 1 ;
endMargin = this . kSTACKED _TAB _MARGIN ;
}
2009-04-08 09:43:44 -04:00
}
else {
2009-04-08 11:00:21 -04:00
startMargin = maxMargin ;
2009-04-08 09:43:44 -04:00
endMargin = 0 ;
startOpacity = 0 ;
endOpacity = 1 ;
2010-11-24 11:14:36 -05:00
if ( this . canStackTabs && this . getParentTab ( aTab ) ) {
startOpacity = 1 ;
startMargin = this . kSTACKED _TAB _MARGIN ;
}
2009-04-08 09:43:44 -04:00
}
2010-05-06 13:39:10 -04:00
if (
! this . animationEnabled ||
aJustNow ||
2010-12-01 04:09:07 -05:00
this . collapseDuration < 1 // ||
2010-05-06 13:39:10 -04:00
// !this.isVertical ||
2010-12-01 04:09:07 -05:00
// !this.canCollapseSubtree(this.getParentTab(aTab))
2010-05-06 13:39:10 -04:00
) {
2010-05-06 13:41:25 -04:00
if ( aCollapsed )
2011-12-12 13:54:43 -05:00
aTab . setAttribute ( this . kCOLLAPSED _DONE , true ) ;
2010-05-06 13:41:25 -04:00
else
2011-12-12 13:54:43 -05:00
aTab . removeAttribute ( this . kCOLLAPSED _DONE ) ;
2011-04-06 00:59:31 -04:00
aTab . removeAttribute ( this . kCOLLAPSING _PHASE ) ;
2010-05-06 13:41:25 -04:00
2012-08-02 14:26:23 -04:00
// Pinned tabs are positioned by "margin-top", so
// we must not reset the property for pinned tabs.
// (However, we still must update "opacity".)
let pinned = aTab . getAttribute ( 'pinned' ) == 'true' ;
let canExpand = ! pinned || this . collapseCSSProp != 'margin-top' ;
2010-08-13 13:14:46 -04:00
if ( CSSTransitionEnabled ) {
2012-08-02 14:26:23 -04:00
if ( canExpand )
aTab . style . setProperty ( this . collapseCSSProp , endMargin ? '-' + endMargin + 'px' : '' , 'important' ) ;
2010-08-13 13:14:46 -04:00
if ( endOpacity == 0 )
2010-11-24 19:49:26 -05:00
aTab . style . setProperty ( 'opacity' , endOpacity == 1 ? '' : endOpacity , 'important' ) ;
2010-08-13 13:14:46 -04:00
else
aTab . style . removeProperty ( 'opacity' ) ;
}
else {
2012-08-02 14:26:23 -04:00
if ( canExpand )
aTab . style . removeProperty ( this . collapseCSSProp ) ;
2010-08-13 13:14:46 -04:00
aTab . style . removeProperty ( 'opacity' ) ;
}
2012-01-27 14:33:02 -05:00
if ( aCallbackToRunOnStartAnimation )
aCallbackToRunOnStartAnimation ( ) ;
2010-05-06 13:39:10 -04:00
return ;
}
2009-04-07 13:14:09 -04:00
var deltaMargin = endMargin - startMargin ;
var deltaOpacity = endOpacity - startOpacity ;
2010-11-24 19:49:26 -05:00
aTab . style . setProperty ( this . collapseCSSProp , startMargin ? '-' + startMargin + 'px' : '' , 'important' ) ;
aTab . style . setProperty ( 'opacity' , startOpacity == 1 ? '' : startOpacity , 'important' ) ;
2009-04-08 11:00:21 -04:00
2010-05-06 13:39:10 -04:00
if ( ! aCollapsed ) {
aTab . setAttribute ( offsetAttr , maxMargin ) ;
2011-12-12 13:54:43 -05:00
aTab . removeAttribute ( this . kCOLLAPSED _DONE ) ;
2010-05-06 13:39:10 -04:00
}
2009-04-07 13:14:09 -04:00
2009-04-08 09:43:44 -04:00
var radian = 90 * Math . PI / 180 ;
var self = this ;
2010-08-07 12:11:08 -04:00
var firstFrame = true ;
2009-04-09 21:32:03 -04:00
aTab . _ _treestyletab _ _updateTabCollapsedTask = function ( aTime , aBeginning , aChange , aDuration ) {
2012-02-04 18:24:26 -05:00
if ( self . isDestroying ) return true ;
2012-01-27 14:33:02 -05:00
if ( firstFrame ) {
2012-01-28 16:22:04 -05:00
// The callback must be started before offsetAttr is changed!
2012-01-27 14:33:02 -05:00
if ( aCallbackToRunOnStartAnimation )
aCallbackToRunOnStartAnimation ( ) ;
if ( CSSTransitionEnabled ) {
aTab . style . setProperty ( self . collapseCSSProp , endMargin ? '-' + endMargin + 'px' : '' , 'important' ) ;
aTab . style . setProperty ( 'opacity' , endOpacity == 1 ? '' : endOpacity , 'important' ) ;
}
2010-08-07 12:11:08 -04:00
}
firstFrame = false ;
2009-05-12 13:35:06 -04:00
// If this is the last tab, negative scroll happens.
// Then, we shouldn't do animation.
var stopAnimation = false ;
var scrollBox = self . scrollBox ;
if ( scrollBox ) {
if ( scrollBox . _scrollbox ) scrollBox = scrollBox . _scrollbox ;
if ( 'scrollTop' in scrollBox &&
( scrollBox . scrollTop < 0 || scrollBox . scrollLeft < 0 ) ) {
scrollBox . scrollTop = 0 ;
scrollBox . scrollLeft = 0 ;
stopAnimation = true ;
}
}
if ( aTime >= aDuration || stopAnimation ) {
2009-04-08 09:43:44 -04:00
delete aTab . _ _treestyletab _ _updateTabCollapsedTask ;
2011-12-12 13:54:43 -05:00
if ( aCollapsed ) aTab . setAttribute ( self . kCOLLAPSED _DONE , true ) ;
2010-12-01 03:59:07 -05:00
if ( ! CSSTransitionEnabled ) {
2010-08-13 13:14:46 -04:00
aTab . style . removeProperty ( self . collapseCSSProp ) ;
2010-12-01 03:59:07 -05:00
aTab . style . removeProperty ( 'opacity' ) ;
}
2009-04-08 11:00:21 -04:00
aTab . removeAttribute ( offsetAttr ) ;
2011-04-06 00:59:31 -04:00
aTab . removeAttribute ( self . kCOLLAPSING _PHASE ) ;
2009-05-13 02:09:17 -04:00
maxMargin = null ;
offsetAttr = null ;
startMargin = null ;
endMargin = null ;
startOpacity = null ;
endOpacity = null ;
deltaMargin = null ;
deltaOpacity = null ;
collapseProp = null ;
radian = null ;
self = null ;
aTab = null ;
2009-04-08 05:16:39 -04:00
return true ;
2009-04-07 13:14:09 -04:00
}
2009-04-08 05:16:39 -04:00
else {
2010-05-02 00:30:51 -04:00
if ( ! CSSTransitionEnabled ) {
let power = Math . sin ( aTime / aDuration * radian ) ;
let margin = startMargin + ( deltaMargin * power ) ;
let opacity = startOpacity + ( deltaOpacity * power ) ;
2010-11-24 19:49:26 -05:00
aTab . style . setProperty ( self . collapseCSSProp , margin ? '-' + margin + 'px' : '' , 'important' ) ;
aTab . style . setProperty ( 'opacity' , opacity == 1 ? '' : opacity , 'important' ) ;
2010-05-02 00:30:51 -04:00
}
2009-04-08 11:16:34 -04:00
aTab . setAttribute ( offsetAttr , maxMargin ) ;
2009-04-08 05:16:39 -04:00
return false ;
}
} ;
2010-06-22 14:00:16 -04:00
this . animationManager . addTask (
2009-04-08 05:44:44 -04:00
aTab . _ _treestyletab _ _updateTabCollapsedTask ,
2011-05-25 16:54:46 -04:00
0 , 0 , this . collapseDuration , this . window
2009-04-08 05:44:44 -04:00
) ;
2009-04-07 13:14:09 -04:00
} ,
kOPACITY _RULE _REGEXP : /opacity\s*:[^;]+;?/ ,
2010-11-24 11:14:36 -05:00
kSTACKED _TAB _MARGIN : 15 ,
2009-12-25 03:34:52 -05:00
stopTabCollapseAnimation : function TSTBrowser _stopTabCollapseAnimation ( aTab )
2009-04-07 13:14:09 -04:00
{
2012-08-04 13:53:57 -04:00
if ( ! aTab . parentNode ) return ; // do nothing for closed tab!
2010-06-22 14:00:16 -04:00
this . animationManager . removeTask (
2009-04-08 05:44:44 -04:00
aTab . _ _treestyletab _ _updateTabCollapsedTask
) ;
2009-04-07 13:14:09 -04:00
} ,
2007-11-14 14:34:36 -05:00
2009-12-25 03:34:52 -05:00
collapseExpandTreesIntelligentlyFor : function TSTBrowser _collapseExpandTreesIntelligentlyFor ( aTab , aJustNow )
2007-11-14 14:34:36 -05:00
{
2009-10-25 22:47:38 -04:00
if ( ! aTab ||
2012-08-04 13:53:57 -04:00
! aTab . parentNode ||
2009-10-25 22:47:38 -04:00
this . doingCollapseExpand ||
2010-11-29 03:24:45 -05:00
! this . canCollapseSubtree ( aTab ) )
2009-10-25 22:47:38 -04:00
return ;
2007-11-14 14:34:36 -05:00
2009-08-14 02:12:08 -04:00
var b = this . mTabBrowser ;
2007-11-17 00:20:26 -05:00
var sameParentTab = this . getParentTab ( aTab ) ;
2012-08-04 16:31:38 -04:00
var expandedAncestors = [ aTab ] . concat ( this . getAncestorTabs ( aTab ) )
. map ( function ( aAncestor ) {
return aAncestor . getAttribute ( this . kID ) ;
} , this )
. join ( '|' ) ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
var xpathResult = this . evaluateXPath (
2012-08-04 16:31:38 -04:00
'child::xul:tab[@' + this . kCHILDREN + ' and not(@' + this . kCOLLAPSED + '="true") and not(@' + this . kSUBTREE _COLLAPSED + '="true") and @' + this . kID + ' and not(contains("' + expandedAncestors + '", @' + this . kID + ')) and not(@hidden="true")]' ,
2007-11-17 00:20:26 -05:00
b . mTabContainer
) ;
for ( var i = 0 , maxi = xpathResult . snapshotLength ; i < maxi ; i ++ )
{
2011-12-26 23:21:23 -05:00
let dontCollapse = false ;
let collapseTab = xpathResult . snapshotItem ( i ) ;
2007-11-14 14:34:36 -05:00
2011-12-26 23:21:23 -05:00
let parentTab = this . getParentTab ( collapseTab ) ;
2007-11-17 00:20:26 -05:00
if ( parentTab ) {
dontCollapse = true ;
2009-10-25 22:36:42 -04:00
if ( ! this . isSubtreeCollapsed ( parentTab ) ) {
2012-08-04 16:31:38 -04:00
this . getAncestorTabs ( collapseTab ) . some ( function ( aAncestor ) {
if ( expandedAncestors . indexOf ( aAncestor . getAttribute ( this . kID ) ) < 0 )
return false ;
2007-11-17 00:20:26 -05:00
dontCollapse = false ;
2012-08-04 16:31:38 -04:00
return true ;
} , this ) ;
2007-11-17 00:20:26 -05:00
}
2007-11-14 14:34:36 -05:00
}
2007-11-17 00:20:26 -05:00
2011-12-26 23:21:23 -05:00
let manuallyExpanded = this . getTabValue ( collapseTab , this . kSUBTREE _EXPANDED _MANUALLY ) == 'true' ;
if ( ! dontCollapse && ! manuallyExpanded )
2009-04-07 13:58:58 -04:00
this . collapseExpandSubtree ( collapseTab , true , aJustNow ) ;
2007-11-14 14:34:36 -05:00
}
2007-11-17 00:20:26 -05:00
2009-04-07 13:58:58 -04:00
this . collapseExpandSubtree ( aTab , false , aJustNow ) ;
2007-11-14 14:34:36 -05:00
} ,
2009-12-25 03:34:52 -05:00
collapseExpandAllSubtree : function TSTBrowser _collapseExpandAllSubtree ( aCollapse , aJustNow )
2007-11-14 14:34:36 -05:00
{
2012-09-23 03:11:03 -04:00
var tabs = this . mTabBrowser . mTabContainer . querySelectorAll (
'tab[' + this . kID + '][' + this . kCHILDREN + ']' +
2007-11-17 00:20:26 -05:00
(
aCollapse ?
2012-09-23 03:11:03 -04:00
':not([' + this . kSUBTREE _COLLAPSED + '="true"])' :
'[' + this . kSUBTREE _COLLAPSED + '="true"]'
2012-09-23 03:13:35 -04:00
)
2007-11-17 00:20:26 -05:00
) ;
2012-09-23 03:11:03 -04:00
for ( var i = 0 , maxi = tabs . length ; i < maxi ; i ++ )
2007-11-14 14:34:36 -05:00
{
2012-09-23 03:11:03 -04:00
this . collapseExpandSubtree ( tabs [ i ] , aCollapse , aJustNow ) ;
2007-11-14 14:34:36 -05:00
}
2007-11-17 00:20:26 -05:00
} ,
/* scroll */
2008-12-01 03:30:36 -05:00
2009-12-25 03:34:52 -05:00
scrollTo : function TSTBrowser _scrollTo ( aEndX , aEndY )
2007-11-17 00:20:26 -05:00
{
2012-08-04 13:53:57 -04:00
if ( this . deferredTasks [ 'cancelPerformingAutoScroll' ] ) return ;
2011-04-06 06:53:46 -04:00
2009-04-08 12:00:51 -04:00
if ( this . animationEnabled || this . smoothScrollEnabled ) {
2007-11-17 00:20:26 -05:00
this . smoothScrollTo ( aEndX , aEndY ) ;
2007-11-14 14:34:36 -05:00
}
else {
2007-11-17 00:20:26 -05:00
try {
2012-01-12 22:16:35 -05:00
this . cancelPerformingAutoScroll ( ) ;
2008-06-20 01:57:38 -04:00
this . scrollBoxObject . scrollTo ( aEndX , aEndY ) ;
2007-11-17 00:20:26 -05:00
}
catch ( e ) {
2007-11-14 14:34:36 -05:00
}
}
} ,
2008-12-01 03:30:36 -05:00
2011-04-06 00:59:31 -04:00
smoothScrollTo : function TSTBrowser _smoothScrollTo ( aEndX , aEndY , aDuration )
2007-11-14 14:34:36 -05:00
{
2012-08-05 15:28:04 -04:00
this . cancelPerformingAutoScroll ( true ) ;
2007-11-14 14:34:36 -05:00
2012-01-12 22:16:35 -05:00
var b = this . mTabBrowser ;
2008-06-20 01:57:38 -04:00
var scrollBoxObject = this . scrollBoxObject ;
2007-11-17 00:20:26 -05:00
var x = { } , y = { } ;
scrollBoxObject . getPosition ( x , y ) ;
2009-04-08 06:03:17 -04:00
var startX = x . value ;
var startY = y . value ;
var deltaX = aEndX - startX ;
var deltaY = aEndY - startY ;
2007-11-14 14:34:36 -05:00
2010-08-26 05:40:58 -04:00
var arrowscrollbox = scrollBoxObject . element . parentNode ;
if (
arrowscrollbox &&
(
arrowscrollbox . localName != 'arrowscrollbox' ||
! ( '_isScrolling' in arrowscrollbox )
)
)
arrowscrollbox = null ;
2009-04-08 09:43:44 -04:00
var radian = 90 * Math . PI / 180 ;
2009-04-08 06:03:17 -04:00
var self = this ;
2009-04-09 21:32:03 -04:00
this . smoothScrollTask = function ( aTime , aBeginning , aChange , aDuration ) {
2012-02-04 18:24:26 -05:00
if ( self . isDestroying ) return true ;
2009-04-08 06:03:17 -04:00
var scrollBoxObject = self . scrollBoxObject ;
2012-08-04 16:58:35 -04:00
if ( aTime >= aDuration || self . deferredTasks [ 'cancelPerformingAutoScroll' ] ) {
if ( ! self . deferredTasks [ 'cancelPerformingAutoScroll' ] ) {
2012-01-12 22:16:35 -05:00
scrollBoxObject . scrollTo ( aEndX , aEndY ) ;
/ * *
* When there is any expanding tab , we have to retry to scroll .
* if the scroll box was expanded .
* /
let oldSize = self . _getMaxScrollSize ( scrollBoxObject ) ;
2012-08-04 13:53:57 -04:00
let key = 'smoothScrollTo_' + parseInt ( Math . random ( ) * 65000 ) ;
( self . deferredTasks [ key ] = self . Deferred . next ( function ( ) {
2012-01-12 22:16:35 -05:00
let newSize = self . _getMaxScrollSize ( scrollBoxObject ) ;
let lastTab = self . getLastVisibleTab ( self . mTabBrowser ) ;
if (
// scroll size can be expanded by expanding tabs.
oldSize [ 0 ] < newSize [ 0 ] || oldSize [ 1 ] < newSize [ 1 ] ||
// there are still animating tabs
self . getXOffsetOfTab ( lastTab ) || self . getYOffsetOfTab ( lastTab ) ||
2012-09-23 03:11:03 -04:00
self . mTabBrowser . mTabContainer . querySelector ( 'tab[' + self . kCOLLAPSING _PHASE + '="' + self . kCOLLAPSING _PHASE _TO _BE _EXPANDED + '"]' )
2012-01-12 22:16:35 -05:00
)
self . smoothScrollTo ( aEndX , aEndY , parseInt ( aDuration * 0.5 ) ) ;
self = null ;
scrollBoxObject = null ;
2012-08-04 16:58:35 -04:00
} ) ) . error ( self . defaultDeferredErrorHandler ) . next ( function ( ) {
2012-08-04 13:53:57 -04:00
delete self . deferredTasks [ key ] ;
} ) ;
2012-01-12 22:16:35 -05:00
}
2011-04-06 00:59:31 -04:00
2009-05-13 02:09:17 -04:00
b = null ;
x = null ;
y = null ;
startX = null ;
startY = null ;
radian = null ;
2011-04-06 06:53:46 -04:00
self . smoothScrollTask = null ;
2009-05-13 02:09:17 -04:00
2009-04-08 06:03:17 -04:00
return true ;
}
2007-11-14 14:34:36 -05:00
2009-04-09 21:32:03 -04:00
var power = Math . sin ( aTime / aDuration * radian ) ;
2009-04-08 09:43:44 -04:00
var newX = startX + parseInt ( deltaX * power ) ;
var newY = startY + parseInt ( deltaY * power ) ;
2009-04-08 06:03:17 -04:00
scrollBoxObject . scrollTo ( newX , newY ) ;
return false ;
} ;
2010-06-22 14:00:16 -04:00
this . animationManager . addTask (
2009-04-08 06:03:17 -04:00
this . smoothScrollTask ,
2011-05-25 16:54:46 -04:00
0 , 0 , this . smoothScrollDuration || aDuration , this . window
2009-04-08 06:03:17 -04:00
) ;
2007-11-17 00:20:26 -05:00
} ,
2011-04-06 00:59:31 -04:00
_getMaxScrollSize : function ( aScrollBoxObject ) {
var x = { } , y = { } ;
aScrollBoxObject . getPosition ( x , y ) ;
var w = { } , h = { } ;
aScrollBoxObject . getScrolledSize ( w , h ) ;
var maxX = Math . max ( 0 , w . value - aScrollBoxObject . width ) ;
var maxY = Math . max ( 0 , h . value - aScrollBoxObject . height ) ;
return [ maxX , maxY ] ;
} ,
2009-04-08 06:03:17 -04:00
smoothScrollTask : null ,
2007-11-17 00:20:26 -05:00
2010-07-25 12:06:03 -04:00
scrollToTab : function TSTBrowser _scrollToTab ( aTab , aOnlyWhenCurrentTabIsInViewport )
2007-11-17 00:20:26 -05:00
{
2010-03-25 11:52:11 -04:00
if ( ! aTab || ! aTab . parentNode || this . isTabInViewport ( aTab ) )
return ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
var b = this . mTabBrowser ;
2007-11-14 14:34:36 -05:00
2008-06-20 01:57:38 -04:00
var scrollBoxObject = this . scrollBoxObject ;
2007-11-17 00:20:26 -05:00
var w = { } , h = { } ;
try {
scrollBoxObject . getScrolledSize ( w , h ) ;
}
2009-12-15 03:33:03 -05:00
catch ( e ) { // Tab Mix Plus (or others)
2007-11-17 00:20:26 -05:00
return ;
2007-11-14 14:34:36 -05:00
}
2012-01-28 16:43:43 -05:00
var targetTabBox = this . getFutureBoxObject ( aTab ) ;
2010-06-25 11:59:59 -04:00
var baseTabBox = this . getFirstNormalTab ( b ) . boxObject ;
2007-11-14 14:34:36 -05:00
2012-01-28 16:43:43 -05:00
var targetX = ( targetTabBox . screenX < scrollBoxObject . screenX ) ?
( targetTabBox . screenX - baseTabBox . screenX ) - ( targetTabBox . width * 0.5 ) :
( targetTabBox . screenX - baseTabBox . screenX ) - scrollBoxObject . width + ( targetTabBox . width * 1.5 ) ;
2009-04-08 11:16:34 -04:00
2012-01-28 16:43:43 -05:00
var targetY = ( targetTabBox . screenY < scrollBoxObject . screenY ) ?
( targetTabBox . screenY - baseTabBox . screenY ) - ( targetTabBox . height * 0.5 ) :
( targetTabBox . screenY - baseTabBox . screenY ) - scrollBoxObject . height + ( targetTabBox . height * 1.5 ) ;
2007-11-17 00:20:26 -05:00
2010-07-25 12:06:03 -04:00
if ( aOnlyWhenCurrentTabIsInViewport && b . selectedTab != aTab ) {
let box = b . selectedTab . boxObject ;
2012-01-28 16:43:43 -05:00
if ( targetTabBox . screenX - box . screenX + baseTabBox . width > scrollBoxObject . width ||
targetTabBox . screenY - box . screenY + baseTabBox . height > scrollBoxObject . height )
2010-07-25 12:06:03 -04:00
return ;
}
2007-11-17 00:20:26 -05:00
this . scrollTo ( targetX , targetY ) ;
} ,
2009-12-25 06:19:50 -05:00
scrollToTabSubtree : function TSTBrowser _scrollToTabSubtree ( aTab )
2007-11-17 00:20:26 -05:00
{
2012-08-04 13:53:57 -04:00
if ( ! aTab . parentNode ) return ; // do nothing for closed tab!
2007-11-17 00:20:26 -05:00
var b = this . mTabBrowser ;
var descendant = this . getDescendantTabs ( aTab ) ;
2012-01-28 16:43:43 -05:00
var parentTabBox = aTab . boxObject ;
var containerPosition = this . tabStrip . boxObject [ this . screenPositionProp ] ;
var containerSize = this . tabStrip . boxObject [ this . sizeProp ] ;
var parentPosition = parentTabBox [ this . screenPositionProp ] ;
2007-11-17 00:20:26 -05:00
var lastVisible = aTab ;
2012-01-28 16:43:43 -05:00
for ( let i = descendant . length - 1 ; i > - 1 ; i -- )
2007-11-17 00:20:26 -05:00
{
2012-01-28 16:43:43 -05:00
let tab = descendant [ i ] ;
if ( this . isCollapsed ( tab ) )
continue ;
let box = this . getFutureBoxObject ( tab ) ;
if ( box [ this . screenPositionProp ] + box [ this . sizeProp ] - parentPosition > containerSize )
continue ;
lastVisible = tab ;
2007-11-17 00:20:26 -05:00
break ;
}
2007-11-14 14:34:36 -05:00
2012-01-28 16:43:43 -05:00
if ( this . isTabInViewport ( aTab ) && this . isTabInViewport ( lastVisible ) )
2008-06-18 22:11:00 -04:00
return ;
2012-01-28 16:43:43 -05:00
var lastPosition = lastVisible . boxObject [ this . screenPositionProp ] ;
var tabSize = lastVisible . boxObject [ this . sizeProp ] ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
if ( lastPosition - parentPosition + tabSize > containerSize - tabSize ) { // out of screen
2011-05-26 13:31:44 -04:00
var endPos = parentPosition - this . getFirstNormalTab ( b ) . boxObject [ this . screenPositionProp ] - tabSize * 0.5 ;
2007-11-17 00:20:26 -05:00
var endX = this . isVertical ? 0 : endPos ;
var endY = this . isVertical ? endPos : 0 ;
this . scrollTo ( endX , endY ) ;
}
else if ( ! this . isTabInViewport ( aTab ) && this . isTabInViewport ( lastVisible ) ) {
this . scrollToTab ( aTab ) ;
}
else if ( this . isTabInViewport ( aTab ) && ! this . isTabInViewport ( lastVisible ) ) {
this . scrollToTab ( lastVisible ) ;
}
else if ( parentPosition < containerPosition ) {
this . scrollToTab ( aTab ) ;
}
else {
this . scrollToTab ( lastVisible ) ;
2007-11-14 14:34:36 -05:00
}
} ,
2011-12-13 09:21:31 -05:00
2012-01-29 05:54:02 -05:00
notifyBackgroundTab : function TSTBrowser _notifyBackgroundTab ( )
{
var animateElement = this . mTabBrowser . mTabContainer . _animateElement ;
var attrName = this . kBG _NOTIFY _PHASE ;
if ( ! animateElement )
return ;
2012-08-04 13:53:57 -04:00
if ( this . deferredTasks [ 'notifyBackgroundTab' ] )
this . deferredTasks [ 'notifyBackgroundTab' ] . cancel ( ) ;
2012-01-29 05:54:02 -05:00
if ( ! animateElement . hasAttribute ( attrName ) )
animateElement . setAttribute ( attrName , 'ready' ) ;
var self = this ;
2012-08-04 13:53:57 -04:00
( this . deferredTasks [ 'notifyBackgroundTab' ] = this . Deferred
2012-01-29 05:54:02 -05:00
. next ( function ( ) {
animateElement . setAttribute ( attrName , 'notifying' ) ;
2012-08-04 13:53:57 -04:00
} ) )
2012-01-29 05:54:02 -05:00
. wait ( 0.15 )
. next ( function ( ) {
animateElement . setAttribute ( attrName , 'finish' ) ;
} )
. wait ( 1 )
. next ( function ( ) {
animateElement . removeAttribute ( attrName ) ;
2012-02-06 12:13:46 -05:00
} )
2012-08-04 13:53:57 -04:00
. error ( this . defaultDeferredErrorHandler ) . next ( function ( ) {
delete self . deferredTasks [ 'notifyBackgroundTab' ] ;
} ) ;
2012-01-29 05:54:02 -05:00
} ,
2011-12-13 23:30:29 -05:00
restoreTree : function TSTBrowser _restoreTree ( )
2011-12-13 09:21:31 -05:00
{
2011-12-14 09:51:56 -05:00
if ( ! this . needRestoreTree || this . useTMPSessionAPI )
2011-12-13 09:21:31 -05:00
return ;
this . needRestoreTree = false ;
2011-12-15 00:28:40 -05:00
if ( this . useTMPSessionAPI && this . getPref ( 'extensions.tabmix.sessions.manager' ) )
return ;
2012-10-23 12:43:56 -04:00
var level = utils . getTreePref ( 'restoreTree.level' ) ;
2012-08-05 09:38:06 -04:00
dump ( 'TSTBrowser::restoreTree\n' ) ;
dump ( ' level = ' + level + '\n' ) ;
dump ( ' tabsToRestore = ' + this . window . _ _SS _tabsToRestore + '\n' ) ;
2011-12-13 23:30:29 -05:00
if (
level <= this . kRESTORE _TREE _LEVEL _NONE ||
! this . window . _ _SS _tabsToRestore ||
this . window . _ _SS _tabsToRestore <= 1
)
2011-12-13 09:21:31 -05:00
return ;
2011-12-13 23:30:29 -05:00
var onlyVisible = level <= this . kRESTORE _TREE _ONLY _VISIBLE ;
2012-09-23 02:43:49 -04:00
var tabs = this . getAllTabs ( this . mTabBrowser ) ;
2011-12-13 09:21:31 -05:00
tabs = tabs . filter ( function ( aTab ) {
2012-01-02 05:52:51 -05:00
return (
aTab . linkedBrowser . _ _SS _restoreState &&
aTab . linkedBrowser . _ _treestyletab _ _toBeRestored &&
( ! onlyVisible || ! aTab . hidden )
) ;
} ) ;
2012-08-05 09:38:06 -04:00
dump ( ' restoring member tabs = ' + tabs . length + '\n' ) ;
2012-01-02 05:52:51 -05:00
if ( tabs . length <= 1 )
return ;
2011-12-13 09:21:31 -05:00
2012-02-04 16:31:03 -05:00
for ( let i = 0 , maxi = tabs . length ; i < maxi ; i ++ )
2012-02-04 13:15:38 -05:00
{
2012-02-04 16:31:03 -05:00
let tab = tabs [ i ] ;
2012-02-04 13:15:38 -05:00
let currentId = tab . getAttribute ( this . kID ) ;
if ( this . tabsHash [ currentId ] == tab )
2011-12-13 09:21:31 -05:00
delete this . tabsHash [ currentId ] ;
2012-02-04 13:15:38 -05:00
this . resetTabState ( tab ) ;
2011-12-13 09:21:31 -05:00
2012-02-04 13:15:38 -05:00
tab . setAttribute ( this . kID , currentId ) ; // to fallback to it
let [ id , duplicated ] = this . _restoreTabId ( tab ) ;
2011-12-13 09:21:31 -05:00
2012-02-04 13:15:38 -05:00
this . setTabValue ( tab , this . kID , id ) ;
this . tabsHash [ id ] = tab ;
2011-12-13 09:21:31 -05:00
2012-02-04 13:15:38 -05:00
tab . _ _treestyletab _ _restoreState = this . RESTORE _STATE _READY _TO _RESTORE ;
tab . _ _treestyletab _ _duplicated = duplicated ;
}
2011-12-13 09:21:31 -05:00
this . updateAllTabsIndent ( true ) ;
// restore tree from bottom safely
tabs . reverse ( )
. filter ( this . restoreOneTab , this )
. forEach ( this . updateInsertionPositionInfo , this ) ;
} ,
restoreOneTab : function TSTBrowser _restoreOneTab ( aTab )
{
2011-12-13 23:30:29 -05:00
if ( aTab . _ _treestyletab _ _restoreState != this . RESTORE _STATE _READY _TO _RESTORE )
return false ;
2011-12-13 09:21:31 -05:00
let duplicated = aTab . _ _treestyletab _ _duplicated ;
let children = this . getTabValue ( aTab , this . kCHILDREN ) ;
if ( children ) {
this . deleteTabValue ( aTab , this . kCHILDREN ) ;
2011-12-26 23:21:23 -05:00
let manuallyExpanded = this . getTabValue ( aTab , this . kSUBTREE _EXPANDED _MANUALLY ) == 'true' ;
2011-12-13 09:21:31 -05:00
let subTreeCollapsed = this . getTabValue ( aTab , this . kSUBTREE _COLLAPSED ) == 'true' ;
subTreeCollapsed = this . _restoreSubtreeCollapsedState ( aTab , subTreeCollapsed ) ;
let self = this ;
this . _restoreChildTabsRelation ( aTab , children , duplicated , function ( aChild ) {
/ * *
* When the child has the reference to the parent tab , attachTabTo ( )
* does nothing . To ensure they are correctly related , we have to
* clear the relation here .
* /
self . deleteTabValue ( aChild , self . kPARENT ) ;
let refId = self . getTabValue ( aChild , self . kINSERT _BEFORE ) ;
if ( refId && duplicated ) refId = self . redirectId ( refId ) ;
return {
forceExpand : true , // to prevent to collapse the selected tab
dontAnimate : true ,
insertBefore : self . getTabById ( refId )
} ;
} ) ;
this . collapseExpandSubtree ( aTab , subTreeCollapsed , true ) ;
2011-12-26 23:21:23 -05:00
if ( manuallyExpanded && ! subTreeCollapsed )
this . setTabValue ( aTab , this . kSUBTREE _EXPANDED _MANUALLY , true ) ;
else
this . deleteTabValue ( aTab , this . kSUBTREE _EXPANDED _MANUALLY ) ;
2011-12-13 09:21:31 -05:00
}
delete aTab . _ _treestyletab _ _duplicated ;
2011-12-13 23:30:29 -05:00
aTab . _ _treestyletab _ _restoreState = this . RESTORE _STATE _STRUCTURE _RESTORED ;
2011-12-13 09:21:31 -05:00
return true
} ,
2011-01-21 23:21:39 -05:00
/* sub modules */
get tabbarDNDObserver ( )
{
if ( ! this . _tabbarDNDObserver ) {
2012-11-11 08:48:42 -05:00
this . _tabbarDNDObserver = new TabbarDNDObserver ( this . mTabBrowser ) ;
2011-01-21 23:21:39 -05:00
}
return this . _tabbarDNDObserver ;
} ,
get panelDNDObserver ( )
{
if ( ! this . _panelDNDObserver ) {
2012-11-11 08:48:42 -05:00
this . _panelDNDObserver = new TabpanelDNDObserver ( this . mTabBrowser ) ;
2011-01-21 23:21:39 -05:00
}
return this . _panelDNDObserver ;
} ,
2011-05-27 18:49:02 -04:00
/* proxying for window service */
_callWindowServiceMethod : function TSTBrowser _callWindowServiceMethod ( aName , aArgs )
{
return this . windowService [ aName ] . apply ( this . windowService , aArgs ) ;
} ,
isPopupShown : function TSTBrowser _isPopupShown ( ) { return this . _callWindowServiceMethod ( 'isPopupShown' , arguments ) ; } ,
updateTabsOnTop : function TSTBrowser _updateTabsOnTop ( ) { return this . _callWindowServiceMethod ( 'updateTabsOnTop' , arguments ) ; } ,
registerTabFocusAllowance : function TSTBrowser _registerTabFocusAllowance ( ) { return this . _callWindowServiceMethod ( 'registerTabFocusAllowance' , arguments ) ; } ,
2011-06-12 12:23:52 -04:00
isPopupShown : function TSTBrowser _isPopupShown ( ) { return this . _callWindowServiceMethod ( 'isPopupShown' , arguments ) ; } ,
toggleAutoHide : function TSTBrowser _toggleAutoHide ( ) { return this . _callWindowServiceMethod ( 'toggleAutoHide' , arguments ) ; } ,
2011-05-27 18:49:02 -04:00
2009-09-03 03:31:49 -04:00
/* show/hide tab bar */
get autoHide ( )
{
2010-12-06 08:31:58 -05:00
if ( ! this . _autoHide ) {
2012-11-11 08:48:42 -05:00
this . _autoHide = new AutoHideBrowser ( this . mTabBrowser ) ;
2010-12-06 08:31:58 -05:00
}
return this . _autoHide ;
2009-09-03 03:31:49 -04:00
} ,
// for backward compatibility
2009-12-17 22:20:35 -05:00
get tabbarShown ( ) { return this . autoHide . expanded ; } ,
set tabbarShown ( aValue ) { if ( aValue ) this . autoHide . show ( ) ; else this . autoHide . hide ( ) ; return aValue ; } ,
2009-09-03 04:18:41 -04:00
get tabbarExpanded ( ) { return this . autoHide . expanded ; } ,
2009-12-17 22:20:35 -05:00
set tabbarExpanded ( aValue ) { return this . tabbarShown = aValue ; } ,
2009-09-03 04:18:41 -04:00
get tabbarResizing ( ) { return this . autoHide . isResizing ; } ,
set tabbarResizing ( aValue ) { return this . autoHide . isResizing = aValue ; } ,
2009-09-03 02:24:06 -04:00
get togglerSize ( ) { return this . autoHide . togglerSize ; } ,
set togglerSize ( aValue ) { return this . autoHide . togglerSize = aValue ; } ,
get sensitiveArea ( ) { return this . autoHide . sensitiveArea ; } ,
set sensitiveArea ( aValue ) { return this . autoHide . sensitiveArea = aValue ; } ,
get lastMouseDownTarget ( ) { return this . autoHide . lastMouseDownTarget ; } ,
set lastMouseDownTarget ( aValue ) { return this . autoHide . lastMouseDownTarget = aValue ; } ,
2009-09-03 04:18:41 -04:00
get tabbarWidth ( ) { return this . autoHide . width ; } ,
set tabbarWidth ( aValue ) { return this . autoHide . widthwidth = aValue ; } ,
get tabbarHeight ( ) { return this . autoHide . height ; } ,
set tabbarHeight ( aValue ) { return this . autoHide . height = aValue ; } ,
2009-09-03 02:24:06 -04:00
get splitterWidth ( ) { return this . autoHide . splitterWidth ; } ,
2010-08-24 13:39:20 -04:00
get autoHideShown ( ) { return this . autoHide . expanded ; } ,
2009-12-17 22:20:35 -05:00
set autoHideShown ( aValue ) { return this . tabbarShown = aValue ; } ,
2010-08-24 13:39:20 -04:00
get autoHideXOffset ( ) { return this . autoHide . XOffset ; } ,
get autoHideYOffset ( ) { return this . autoHide . YOffset ; } ,
2009-09-03 02:24:06 -04:00
get autoHideMode ( ) { return this . autoHide . mode ; } ,
set autoHideMode ( aValue ) { return this . autoHide . mode = aValue ; } ,
2009-12-25 03:34:52 -05:00
updateAutoHideMode : function TSTBrowser _updateAutoHideMode ( ) { this . autoHide . updateAutoHideMode ( ) ; } ,
showHideTabbarInternal : function TSTBrowser _showHideTabbarInternal ( aReason ) { this . autoHide . showHideInternal ( aReason ) ; } ,
showTabbar : function TSTBrowser _showTabbar ( aReason ) { this . autoHide . show ( aReason ) ; } ,
hideTabbar : function TSTBrowser _hideTabbar ( aReason ) { this . autoHide . hide ( aReason ) ; } ,
redrawContentArea : function TSTBrowser _redrawContentArea ( ) { this . autoHide . redrawContentArea ( ) ; } ,
drawTabbarCanvas : function TSTBrowser _drawTabbarCanvas ( ) { this . autoHide . drawBG ( ) ; } ,
2009-09-03 02:24:06 -04:00
get splitterBorderColor ( ) { this . autoHide . splitterBorderColor ; } ,
2009-12-25 03:34:52 -05:00
clearTabbarCanvas : function TSTBrowser _clearTabbarCanvas ( ) { this . autoHide . clearBG ( ) ; } ,
updateTabbarTransparency : function TSTBrowser _updateTabbarTransparency ( ) { this . autoHide . updateTransparency ( ) ; } ,
2009-09-03 02:24:06 -04:00
get autoHideEnabled ( ) { return this . autoHide . enabled ; } ,
set autoHideEnabled ( aValue ) { return this . autoHide . enabled = aValue ; } ,
2009-12-25 03:34:52 -05:00
startAutoHide : function TSTBrowser _startAutoHide ( ) { this . autoHide . start ( ) ; } ,
endAutoHide : function TSTBrowser _endAutoHide ( ) { this . autoHide . end ( ) ; } ,
startAutoHideForFullScreen : function TSTBrowser _startAutoHideForFullScreen ( ) { this . autoHide . startForFullScreen ( ) ; } ,
endAutoHideForFullScreen : function TSTBrowser _endAutoHideForFullScreen ( ) { this . autoHide . endForFullScreen ( ) ; } ,
2009-09-03 02:24:06 -04:00
2009-12-25 03:34:52 -05:00
startListenMouseMove : function TSTBrowser _startListenMouseMove ( ) { this . autoHide . startListenMouseMove ( ) ; } ,
endListenMouseMove : function TSTBrowser _endListenMouseMove ( ) { this . autoHide . endListenMouseMove ( ) ; } ,
2009-09-03 02:24:06 -04:00
get shouldListenMouseMove ( ) { return this . autoHide . shouldListenMouseMove ; } ,
2009-12-25 03:34:52 -05:00
showHideTabbarOnMousemove : function TSTBrowser _showHideTabbarOnMousemove ( ) { this . autoHide . showHideOnMousemove ( ) ; } ,
cancelShowHideTabbarOnMousemove : function TSTBrowser _cancelShowHideTabbarOnMousemove ( ) { this . autoHide . cancelShowHideOnMousemove ( ) ; } ,
showTabbarForFeedback : function TSTBrowser _showTabbarForFeedback ( ) { this . autoHide . showForFeedback ( ) ; } ,
delayedShowTabbarForFeedback : function TSTBrowser _delayedShowTabbarForFeedback ( ) { this . autoHide . delayedShowForFeedback ( ) ; } ,
cancelHideTabbarForFeedback : function TSTBrowser _cancelHideTabbarForFeedback ( ) { this . autoHide . cancelHideForFeedback ( ) ; }
2008-03-09 23:51:21 -04:00
2007-11-14 14:34:36 -05:00
} ;