2007-11-14 14:34:36 -05:00
function TreeStyleTabBrowser ( aTabBrowser )
{
this . mTabBrowser = aTabBrowser ;
}
TreeStyleTabBrowser . prototype = {
2007-11-17 01:05:23 -05:00
kMENUITEM _REMOVESUBTREE : 'context-item-removeTabSubTree' ,
2007-11-26 10:07:10 -05:00
kMENUITEM _REMOVECHILDREN : 'context-item-removeDescendantTabs' ,
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' ,
2008-02-26 12:02:59 -05:00
kMENUITEM _POSITION : 'context-menu-tabbarPosition' ,
2007-11-17 00:20:26 -05:00
2007-11-14 14:34:36 -05:00
mTabBrowser : null ,
tabbarResizing : false ,
levelMargin : - 1 ,
levelMarginProp : 'margin-left' ,
positionProp : 'screenY' ,
sizeProp : 'height' ,
invertedPositionProp : 'screenX' ,
invertedSizeProp : 'width' ,
2007-11-17 07:59:48 -05:00
get browser ( )
{
return this . mTabBrowser ;
} ,
2007-11-14 14:34:36 -05:00
get container ( )
{
if ( ! this . _container ) {
this . _container = document . getElementById ( 'appcontent' ) ;
}
return this . _container ;
} ,
_container : null ,
/* utils */
2008-03-09 23:51:21 -04:00
2008-02-22 02:44:06 -05:00
/* get tab contents */
2008-03-03 04:21:33 -05:00
2007-11-17 00:20:26 -05:00
getTabLabel : function ( aTab )
{
var label = document . getAnonymousElementByAttribute ( aTab , 'class' , 'tab-text-container' ) || // Tab Mix Plus
document . getAnonymousElementByAttribute ( aTab , 'class' , 'tab-text' ) ;
return label ;
} ,
getTabClosebox : function ( aTab )
{
var close = document . getAnonymousElementByAttribute ( aTab , 'class' , 'tab-close-button tabs-closebutton always-right' ) || // Tab Mix Plus
document . getAnonymousElementByAttribute ( aTab , 'class' , 'tab-close-button' ) ;
return close ;
} ,
/* status */
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
{
var b = this . mTabBrowser ;
if ( ! b ) return false ;
var box = b . mTabContainer . mTabstrip || b . mTabContainer ;
return ( box . getAttribute ( 'orient' ) || window . getComputedStyle ( box , '' ) . getPropertyValue ( '-moz-box-orient' ) ) == 'vertical' ;
} ,
isTabInViewport : function ( aTab )
{
if ( ! aTab ) return false ;
var tabBox = aTab . boxObject ;
var barBox = this . mTabBrowser . mTabContainer . mTabstrip . boxObject ;
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 ) ;
} ,
2008-02-22 02:44:06 -05:00
isMultiRow : function ( )
{
return false ;
} ,
2008-02-22 12:55:35 -05:00
2007-11-17 00:20:26 -05:00
/* initialize */
2008-03-09 23:51:21 -04:00
2007-11-17 00:20:26 -05:00
init : function ( )
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
2007-11-17 00:20:26 -05:00
this . initTabbar ( ) ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
b . addEventListener ( 'TabOpen' , this , true ) ;
b . addEventListener ( 'TabClose' , this , true ) ;
b . addEventListener ( 'TabMove' , this , true ) ;
b . addEventListener ( 'SSTabRestoring' , this , true ) ;
2007-11-17 12:21:33 -05:00
b . mStrip . addEventListener ( 'dragenter' , this , false ) ;
b . mStrip . addEventListener ( 'dragexit' , this , false ) ;
b . mStrip . addEventListener ( 'dragover' , this , false ) ;
2007-11-17 12:52:51 -05:00
b . mStrip . addEventListener ( 'dragdrop' , this , false ) ;
2007-11-30 14:22:34 -05:00
b . mTabContainer . addEventListener ( 'mouseover' , this , true ) ;
b . mTabContainer . addEventListener ( 'mouseout' , this , true ) ;
2007-11-17 00:20:26 -05:00
b . mTabContainer . addEventListener ( 'click' , this , true ) ;
b . mTabContainer . addEventListener ( 'dblclick' , this , true ) ;
b . mTabContainer . addEventListener ( 'mousedown' , this , true ) ;
b . mTabContainer . addEventListener ( 'select' , this , true ) ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
var selectNewTab = '_selectNewTab' in b . mTabContainer ? '_selectNewTab' : 'selectNewTab' ; // Fx3 / Fx2
2007-11-14 14:34:36 -05:00
2007-11-29 11:49:18 -05:00
/ * C l o s i n g c o l l a p s e d l a s t t r e e b r e a k s s e l e c t e d t a b .
To solve this problem , I override the setter to
force to set a tab and forbid it becomes null . * /
var getter = b . _ _lookupGetter _ _ ( 'selectedTab' ) ;
var setter = b . _ _lookupSetter _ _ ( 'selectedTab' ) ;
eval ( 'setter = ' + setter . toSource ( ) . replace (
'{' ,
'{ if (!val) val = this.mTabContainer.lastChild;'
) ) ;
/ * W e h a v e t o u s e b o t h _ _ d e f i n e S e t t e r _ _ a n d _ _ d e f i n e G e t t e r _ _
just in same time ! ! If we update only setter ,
getter will be vanished . * /
b . _ _defineGetter _ _ ( 'selectedTab' , getter ) ;
b . _ _defineSetter _ _ ( 'selectedTab' , setter ) ;
2007-11-17 00:20:26 -05:00
eval ( 'b.mTabContainer.' + selectNewTab + ' = ' +
b . mTabContainer [ selectNewTab ] . toSource ( ) . replace (
'{' ,
2008-03-03 04:07:02 -05:00
< > < ! [ CDATA [ $ &
if ( arguments [ 0 ] . _ _treestyletab _ _preventSelect ) {
arguments [ 0 ] . _ _treestyletab _ _preventSelect = false ;
return ;
}
2007-11-17 00:20:26 -05:00
] ] > < / >
)
) ;
2007-11-14 14:34:36 -05:00
2008-03-03 04:07:02 -05:00
eval ( 'b.mTabContainer.adjustTabstrip = ' +
b . mTabContainer . adjustTabstrip . toSource ( ) . replace (
/(\})(\)?)$/ ,
< > < ! [ CDATA [
2008-03-03 04:21:33 -05:00
var b = TreeStyleTabService . getTabBrowserFromChild ( this ) ;
b . treeStyleTab . updateInvertedTabContentsOrder ( true ) ;
2008-03-03 04:07:02 -05:00
$1$2 ] ] > < / >
)
) ;
2007-11-17 00:20:26 -05:00
eval ( 'b.mTabContainer.advanceSelectedTab = ' +
b . mTabContainer . advanceSelectedTab . toSource ( ) . replace (
'{' ,
2008-03-03 04:07:02 -05:00
< > < ! [ CDATA [ $ &
if ( TreeStyleTabService . getTreePref ( 'focusMode' ) == TreeStyleTabService . kFOCUS _VISIBLE ) {
( function ( aDir , aWrap , aSelf ) {
var treeStyleTab = TreeStyleTabService . getTabBrowserFromChild ( aSelf ) . treeStyleTab ;
var nextTab = ( aDir < 0 ) ? treeStyleTab . getPreviousVisibleTab ( aSelf . selectedItem ) : treeStyleTab . getNextVisibleTab ( aSelf . selectedItem ) ;
if ( ! nextTab && aWrap ) {
var xpathResult = TreeStyleTabService . evaluateXPath (
'child::xul:tab[not(@' + TreeStyleTabService . kCOLLAPSED + '="true")]' ,
aSelf
) ;
nextTab = xpathResult . snapshotItem ( aDir < 0 ? xpathResult . snapshotLength - 1 : 0 ) ;
}
if ( nextTab && nextTab != aSelf . selectedItem ) {
if ( '_selectNewTab' in aSelf )
aSelf . _selectNewTab ( nextTab , aDir , aWrap ) ; // Fx 3
else
aSelf . selectNewTab ( nextTab , aDir , aWrap ) ; // Fx 2
}
} ) ( arguments [ 0 ] , arguments [ 1 ] , this ) ;
return ;
}
2007-11-17 00:20:26 -05:00
] ] > < / >
)
) ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
eval ( 'b.mTabContainer._handleTabSelect = ' +
b . mTabContainer . _handleTabSelect . toSource ( ) . replace (
'{' ,
2008-03-03 04:07:02 -05:00
< > < ! [ CDATA [ $ &
var treeStyleTab = TreeStyleTabService . getTabBrowserFromChild ( this ) . treeStyleTab ;
if ( ! treeStyleTab . isTabInViewport ( this . selectedItem ) ) {
treeStyleTab . scrollToTab ( this . selectedItem ) ;
return ;
}
2007-11-17 00:20:26 -05:00
] ] > < / >
)
) ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
eval ( 'b.mTabContainer._notifyBackgroundTab = ' +
b . mTabContainer . _notifyBackgroundTab . toSource ( ) . replace (
'{' ,
2007-11-17 08:32:41 -05:00
'{ var treeStyleTab = TreeStyleTabService.getTabBrowserFromChild(this).treeStyleTab;'
2007-11-17 00:20:26 -05:00
) . replace (
/\.screenX/g , '[treeStyleTab.positionProp]'
) . replace (
/\.width/g , '[treeStyleTab.sizeProp]'
)
) ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
this . updateTabDNDObserver ( b ) ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
eval ( 'b.getNewIndex = ' +
b . getNewIndex . toSource ( ) . replace (
/\.screenX/g , '[this.treeStyleTab.positionProp]'
) . replace (
/\.width/g , '[this.treeStyleTab.sizeProp]'
)
) ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
eval ( 'b.moveTabForward = ' +
b . moveTabForward . toSource ( ) . replace (
'{' , '{ var nextTab;'
) . replace (
'tabPos < this.browsers.length - 1' ,
'nextTab = this.treeStyleTab.getNextSiblingTab(this.mCurrentTab)'
) . replace (
'tabPos + 1' , 'nextTab._tPos'
) . replace (
'this.moveTabTo(' ,
< > < ! [ CDATA [
var descendant = this . treeStyleTab . getDescendantTabs ( nextTab ) ;
if ( descendant . length ) {
nextTab = descendant [ descendant . length - 1 ] ;
}
2008-03-03 04:07:02 -05:00
$ & ] ] > < / >
2007-11-17 00:20:26 -05:00
) . replace (
'this.moveTabToStart();' ,
< > < ! [ CDATA [
this . treeStyleTab . internallyTabMoving = true ;
var parentTab = this . treeStyleTab . getParentTab ( this . mCurrentTab ) ;
if ( parentTab ) {
this . moveTabTo ( this . mCurrentTab , this . treeStyleTab . getFirstChildTab ( parentTab ) . _tPos ) ;
this . mCurrentTab . focus ( ) ;
}
else {
2008-03-03 04:07:02 -05:00
$ &
2007-11-17 00:20:26 -05:00
}
this . treeStyleTab . internallyTabMoving = false ;
] ] > < / >
)
) ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
eval ( 'b.moveTabBackward = ' +
b . moveTabBackward . toSource ( ) . replace (
'{' , '{ var prevTab;'
) . replace (
'tabPos > 0' ,
'prevTab = this.treeStyleTab.getPreviousSiblingTab(this.mCurrentTab)'
) . replace (
'tabPos - 1' , 'prevTab._tPos'
) . replace (
'this.moveTabToEnd();' ,
< > < ! [ CDATA [
this . treeStyleTab . internallyTabMoving = true ;
var parentTab = this . treeStyleTab . getParentTab ( this . mCurrentTab ) ;
if ( parentTab ) {
this . moveTabTo ( this . mCurrentTab , this . treeStyleTab . getLastChildTab ( parentTab ) . _tPos ) ;
this . mCurrentTab . focus ( ) ;
}
else {
2008-03-03 04:07:02 -05:00
$ &
2007-11-17 00:20:26 -05:00
}
this . treeStyleTab . internallyTabMoving = false ;
] ] > < / >
)
) ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
eval ( 'b._keyEventHandler.handleEvent = ' +
b . _keyEventHandler . handleEvent . toSource ( ) . replace (
'this.tabbrowser.moveTabOver(aEvent);' ,
< > < ! [ CDATA [
if ( ! this . tabbrowser . treeStyleTab . isVertical ||
! this . tabbrowser . treeStyleTab . moveTabLevel ( aEvent ) ) {
2008-03-03 04:07:02 -05:00
$ &
2007-11-17 00:20:26 -05:00
}
] ] > < / >
) . replace (
'this.tabbrowser.moveTabForward();' ,
< > < ! [ CDATA [
if ( this . tabbrowser . treeStyleTab . isVertical ||
! this . tabbrowser . treeStyleTab . moveTabLevel ( aEvent ) ) {
2008-03-03 04:07:02 -05:00
$ &
2007-11-17 00:20:26 -05:00
}
] ] > < / >
) . replace (
'this.tabbrowser.moveTabBackward();' ,
< > < ! [ CDATA [
if ( this . tabbrowser . treeStyleTab . isVertical ||
! this . tabbrowser . treeStyleTab . moveTabLevel ( aEvent ) ) {
2008-03-03 04:07:02 -05:00
$ &
2007-11-17 00:20:26 -05:00
}
] ] > < / >
)
) ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
eval ( 'b.loadTabs = ' +
b . loadTabs . toSource ( ) . replace (
'var tabNum = ' ,
< > < ! [ CDATA [
if ( this . treeStyleTab . readyToAttachNewTabGroup )
TreeStyleTabService . readyToOpenChildTab ( firstTabAdded || this . selectedTab , true ) ;
2008-03-03 04:07:02 -05:00
$ & ] ] > < / >
2007-11-17 00:20:26 -05:00
) . replace (
'if (!aLoadInBackground)' ,
< > < ! [ CDATA [
if ( TreeStyleTabService . checkToOpenChildTab ( this ) )
TreeStyleTabService . stopToOpenChildTab ( this ) ;
2008-03-03 04:07:02 -05:00
$ & ] ] > < / >
2007-11-17 00:20:26 -05:00
)
) ;
2007-11-14 14:34:36 -05:00
2007-11-30 14:22:34 -05:00
eval ( 'b.createTooltip = ' +
b . createTooltip . toSource ( ) . replace (
'if (tn.hasAttribute("label")) {' ,
< > < ! [ CDATA [
else if ( tn . getAttribute ( TreeStyleTabService . kTWISTY _HOVER ) == 'true' ) {
var key = tn . getAttribute ( TreeStyleTabService . kSUBTREE _COLLAPSED ) == 'true' ? 'tooltip.expandSubtree' : 'tooltip.collapseSubtree' ;
event . target . setAttribute (
'label' ,
tn . hasAttribute ( 'label' ) ?
TreeStyleTabService . stringbundle . getFormattedString (
key + '.labeled' ,
[ tn . getAttribute ( 'label' ) ]
) :
TreeStyleTabService . stringbundle . getString ( key )
) ;
return true ;
}
$ & ] ] > < / >
)
) ;
2008-02-22 13:06:22 -05:00
eval ( 'b.onTabBarDblClick = ' +
b . onTabBarDblClick . toSource ( ) . replace (
'aEvent.originalTarget.localName == "box"' ,
'/^(box|(arrow)?scrollbox|tabs)$/.test(aEvent.originalTarget.localName)'
)
) ;
2007-11-17 00:20:26 -05:00
var tabs = b . mTabContainer . childNodes ;
for ( var i = 0 , maxi = tabs . length ; i < maxi ; i ++ )
{
this . initTab ( tabs [ i ] ) ;
2007-11-14 14:34:36 -05:00
}
2007-11-17 00:20:26 -05:00
this . observe ( null , 'nsPref:changed' , 'extensions.treestyletab.tabbar.style' ) ;
2008-02-28 07:12:02 -05:00
this . observe ( null , 'nsPref:changed' , 'extensions.treestyletab.twisty.style' ) ;
2007-11-17 00:20:26 -05:00
this . observe ( null , 'nsPref:changed' , 'extensions.treestyletab.showBorderForFirstTab' ) ;
this . observe ( null , 'nsPref:changed' , 'extensions.treestyletab.tabbar.invertScrollbar' ) ;
this . observe ( null , 'nsPref:changed' , 'extensions.treestyletab.tabbar.hideAlltabsButton' ) ;
this . observe ( null , 'nsPref:changed' , 'extensions.treestyletab.allowSubtreeCollapseExpand' ) ;
2008-02-25 06:25:53 -05:00
this . observe ( null , 'nsPref:changed' , 'extensions.treestyletab.tabbar.fixed' ) ;
2008-03-09 23:51:21 -04:00
this . observe ( null , 'nsPref:changed' , 'extensions.treestyletab.tabbar.transparent' ) ;
2007-11-17 00:20:26 -05:00
window . setTimeout ( function ( ) {
b . treeStyleTab . observe ( null , 'nsPref:changed' , 'extensions.treestyletab.tabbar.autoHide.enabled' ) ;
} , 0 ) ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
delete i ;
delete maxi ;
delete tabs ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
var tabContext = document . getAnonymousElementByAttribute ( b , 'anonid' , 'tabContextMenu' ) ;
tabContext . addEventListener ( 'popupshowing' , this , false ) ;
tabContext . addEventListener ( 'popuphiding' , this , false ) ;
2007-11-17 01:05:23 -05:00
window . setTimeout ( function ( aSelf ) {
2007-11-17 00:20:26 -05:00
var suffix = '-' + parseInt ( Math . random ( ) * 65000 ) ;
2007-11-17 01:05:23 -05:00
[
aSelf . kMENUITEM _REMOVESUBTREE ,
2007-11-26 10:07:10 -05:00
aSelf . kMENUITEM _REMOVECHILDREN ,
2007-11-17 01:05:23 -05:00
aSelf . kMENUITEM _COLLAPSEEXPAND _SEPARATOR ,
aSelf . kMENUITEM _COLLAPSE ,
aSelf . kMENUITEM _EXPAND ,
aSelf . kMENUITEM _AUTOHIDE _SEPARATOR ,
2008-02-22 12:55:35 -05:00
aSelf . kMENUITEM _AUTOHIDE ,
2008-02-26 12:02:59 -05:00
aSelf . kMENUITEM _FIXED ,
aSelf . kMENUITEM _POSITION
2007-11-17 01:05:23 -05:00
] . forEach ( function ( aID ) {
var item = document . getElementById ( aID ) . cloneNode ( true ) ;
item . setAttribute ( 'id' , item . getAttribute ( 'id' ) + suffix ) ;
tabContext . appendChild ( item ) ;
} ) ;
2007-11-17 00:20:26 -05:00
} , 0 , this ) ;
var allTabPopup = document . getAnonymousElementByAttribute ( b . mTabContainer , 'anonid' , 'alltabs-popup' ) ;
allTabPopup . addEventListener ( 'popupshowing' , this , false ) ;
/ * T o m o v e u p c o n t e n t a r e a o n t h e t a b b a r , s w i t c h t a b .
If we don ' t do it , a gray space appears on the content area
by negative margin of it . * /
if ( b . getAttribute ( this . kTABBAR _POSITION ) == 'left' &&
b . getAttribute ( this . kSCROLLBAR _INVERTED ) == 'true' ) {
b . removeTab (
b . selectedTab = b . addTab ( 'about:blank' )
) ;
2007-11-14 14:34:36 -05:00
}
2007-11-17 00:20:26 -05:00
2008-03-09 23:51:21 -04:00
var stack = document . getAnonymousElementByAttribute ( b . mTabContainer , 'class' , 'tabs-stack' ) ;
if ( stack ) {
var canvas = document . createElementNS ( 'http://www.w3.org/1999/xhtml' , 'canvas' ) ;
canvas . setAttribute ( 'style' , 'width:0;height:0;' ) ;
stack . firstChild . appendChild ( canvas ) ;
this . tabbarCanvas = canvas ;
this . clearTabbarCanvas ( ) ;
}
2007-11-17 00:20:26 -05:00
this . ObserverService . addObserver ( this , 'TreeStyleTab:levelMarginModified' , false ) ;
this . ObserverService . addObserver ( this , 'TreeStyleTab:collapseExpandAllSubtree' , false ) ;
this . addPrefListener ( this ) ;
2007-11-14 14:34:36 -05:00
} ,
2007-11-17 07:50:36 -05:00
2007-11-17 00:20:26 -05:00
initTab : function ( aTab )
2007-11-14 14:34:36 -05:00
{
2007-11-17 00:20:26 -05:00
if ( ! aTab . hasAttribute ( this . kID ) ) {
2007-11-17 07:50:36 -05:00
this . setTabValue ( aTab , this . kID , this . makeNewId ( ) ) ;
2007-11-17 00:20:26 -05:00
}
aTab . _ _treestyletab _ _linkedTabBrowser = this . mTabBrowser ;
this . initTabAttributes ( aTab ) ;
this . initTabContents ( aTab ) ;
aTab . setAttribute ( this . kNEST , 0 ) ;
2007-11-14 14:34:36 -05:00
} ,
2008-03-09 23:51:21 -04:00
2007-11-17 00:20:26 -05:00
initTabAttributes : function ( aTab )
2007-11-14 14:34:36 -05:00
{
2007-11-17 00:20:26 -05:00
var pos = this . mTabBrowser . getAttribute ( this . kTABBAR _POSITION ) ;
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 ;
aTab . setAttribute ( 'dir' , 'ltr' ) ; // Tab Mix Plus
}
else {
aTab . removeAttribute ( 'align' ) ;
aTab . setAttribute ( 'maxwidth' , 250 ) ;
aTab . setAttribute ( 'minwidth' , this . mTabBrowser . mTabContainer . mTabMinWidth ) ;
aTab . setAttribute ( 'width' , '0' ) ;
aTab . setAttribute ( 'flex' , 100 ) ;
aTab . maxWidth = 250 ;
aTab . minWidth = this . mTabBrowser . mTabContainer . mTabMinWidth ;
aTab . removeAttribute ( 'dir' ) ; // Tab Mix Plus
2007-11-14 14:34:36 -05:00
}
} ,
2007-11-17 00:20:26 -05:00
initTabContents : function ( aTab )
2007-11-14 14:34:36 -05:00
{
2007-11-17 00:20:26 -05:00
var icon = document . getAnonymousElementByAttribute ( aTab , 'class' , 'tab-icon' ) ;
var label = this . getTabLabel ( aTab ) ;
var close = this . getTabClosebox ( aTab ) ;
var counter = document . getAnonymousElementByAttribute ( aTab , 'class' , this . kCOUNTER _CONTAINER ) ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
if ( ! document . getAnonymousElementByAttribute ( aTab , 'class' , this . kTWISTY ) ) {
var twisty = document . createElement ( 'image' ) ;
twisty . setAttribute ( 'class' , this . kTWISTY ) ;
var container = document . createElement ( 'hbox' ) ;
container . setAttribute ( 'class' , this . kTWISTY _CONTAINER ) ;
container . appendChild ( twisty ) ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
icon . appendChild ( container ) ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
var marker = document . createElement ( 'image' ) ;
marker . setAttribute ( 'class' , this . kDROP _MARKER ) ;
container = document . createElement ( 'hbox' ) ;
container . setAttribute ( 'class' , this . kDROP _MARKER _CONTAINER ) ;
container . appendChild ( marker ) ;
icon . appendChild ( container ) ;
2007-11-14 14:34:36 -05:00
}
2007-11-17 00:20:26 -05:00
if ( ! counter ) {
var counter = document . createElement ( 'hbox' ) ;
counter . setAttribute ( 'class' , this . kCOUNTER _CONTAINER ) ;
counter . appendChild ( document . createElement ( 'label' ) ) ;
counter . lastChild . setAttribute ( 'class' , this . kCOUNTER ) ;
counter . lastChild . setAttribute ( 'value' , '(0)' ) ;
if ( label ) {
if ( label . nextSibling )
label . parentNode . insertBefore ( counter , label . nextSibling ) ;
else
label . parentNode . appendChild ( counter ) ;
}
2007-11-14 14:34:36 -05:00
}
2007-11-17 00:20:26 -05:00
this . initTabContentsOrder ( aTab ) ;
2007-11-14 14:34:36 -05:00
} ,
2007-11-17 00:20:26 -05:00
initTabContentsOrder : function ( aTab )
2007-11-14 14:34:36 -05:00
{
2007-11-17 00:20:26 -05:00
var label = this . getTabLabel ( aTab ) ;
var close = this . getTabClosebox ( aTab ) ;
var counter = document . getAnonymousElementByAttribute ( aTab , 'class' , this . kCOUNTER _CONTAINER ) ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
var nodes = document . getAnonymousNodes ( aTab ) ;
for ( var i = nodes . length - 1 ; i > - 1 ; i -- )
{
nodes [ i ] . setAttribute ( 'ordinal' , ( i + 1 ) * 10 ) ;
}
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
nodes = label . parentNode . childNodes ;
if ( this . mTabBrowser . getAttribute ( this . kTABBAR _POSITION ) == 'right' &&
this . mTabBrowser . getAttribute ( this . kUI _INVERTED ) == 'true' ) {
for ( var i = nodes . length - 1 ; i > - 1 ; i -- )
{
if ( nodes [ i ] . getAttribute ( 'class' ) == 'informationaltab-thumbnail-container' )
continue ;
nodes [ i ] . setAttribute ( 'ordinal' , ( nodes . length - i + 1 ) * 10 ) ;
2007-11-14 14:34:36 -05:00
}
2007-11-17 00:20:26 -05:00
counter . setAttribute ( 'ordinal' , parseInt ( label . getAttribute ( 'ordinal' ) ) + 1 ) ;
close . setAttribute ( 'ordinal' , parseInt ( label . parentNode . getAttribute ( 'ordinal' ) ) - 5 ) ;
2007-11-14 14:34:36 -05:00
}
2007-11-17 00:20:26 -05:00
else {
for ( var i = nodes . length - 1 ; i > - 1 ; i -- )
{
if ( nodes [ i ] . getAttribute ( 'class' ) == 'informationaltab-thumbnail-container' )
continue ;
nodes [ i ] . setAttribute ( 'ordinal' , ( i + 1 ) * 10 ) ;
2007-11-14 14:34:36 -05:00
}
}
} ,
2008-03-03 04:21:33 -05:00
updateInvertedTabContentsOrder : function ( aAll )
{
if ( this . getTreePref ( 'tabbar.position' ) != 'right' ||
! this . getTreePref ( 'tabbar.invertUI' ) ) return ;
window . setTimeout ( function ( aSelf ) {
var b = aSelf . mTabBrowser ;
if ( aAll ) {
Array . prototype . slice . call ( b . mTabContainer . childNodes ) . forEach ( function ( aTab ) {
aSelf . initTabContentsOrder ( aTab ) ;
} ) ;
}
else {
aSelf . initTabContentsOrder ( b . selectedTab ) ;
}
} , 0 , this ) ;
} ,
2008-03-08 03:57:17 -05:00
2007-11-17 00:20:26 -05:00
initTabbar : function ( aPosition )
2007-11-14 14:34:36 -05:00
{
var b = this . mTabBrowser ;
2007-11-17 00:20:26 -05:00
if ( ! aPosition ) aPosition = this . getTreePref ( 'tabbar.position' ) ;
aPosition = String ( aPosition ) . toLowerCase ( ) ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
if ( b . getAttribute ( 'id' ) != 'content' ) {
aPosition = 'top' ;
2007-11-14 14:34:36 -05:00
}
2007-11-17 00:20:26 -05:00
var pos = ( aPosition == 'left' ) ? this . kTABBAR _LEFT :
( aPosition == 'right' ) ? this . kTABBAR _RIGHT :
( aPosition == 'bottom' ) ? this . kTABBAR _BOTTOM :
this . kTABBAR _TOP ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
var splitter = document . getAnonymousElementByAttribute ( b , 'class' , this . kSPLITTER ) ;
if ( ! splitter ) {
splitter = document . createElement ( 'splitter' ) ;
splitter . setAttribute ( 'class' , this . kSPLITTER ) ;
splitter . setAttribute ( 'onmouseup' , 'TreeStyleTabService.onTabbarResized(event);' ) ;
splitter . setAttribute ( 'state' , 'open' ) ;
splitter . appendChild ( document . createElement ( 'grippy' ) ) ;
var ref = b . mPanelContainer ;
ref . parentNode . insertBefore ( splitter , ref ) ;
}
2007-11-14 14:34:36 -05:00
2008-03-02 12:34:39 -05:00
var scrollInnerBox = b . mTabContainer . mTabstrip . _scrollbox ? document . getAnonymousNodes ( b . mTabContainer . mTabstrip . _scrollbox ) [ 0 ] :
document . getAnonymousElementByAttribute ( b . mTabContainer , 'class' , 'tabs-frame' ) ; // Tab Mix Plus
var allTabsButton = document . getAnonymousElementByAttribute ( b . mTabContainer , 'class' , 'tabs-alltabs-button' ) ||
document . getAnonymousElementByAttribute ( b . mTabContainer , 'anonid' , 'alltabs-button' ) ; // Tab Mix Plus
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
// Tab Mix Plus
2008-03-02 11:01:33 -05:00
var scrollFrame = document . getAnonymousElementByAttribute ( b . mTabContainer , 'id' , 'scroll-tabs-frame' ) ||
document . getAnonymousElementByAttribute ( b . mTabContainer , 'class' , 'tabs-frame' ) ; // 0.3.6.1 or later
2007-11-17 00:20:26 -05:00
var newTabBox = document . getAnonymousElementByAttribute ( b . mTabContainer , 'id' , 'tabs-newbutton-box' ) ;
var 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
var toolboxContainer = document . getAnonymousElementByAttribute ( b . mStrip , 'anonid' , 'aiostbx-toolbox-tableft' ) ;
if ( toolboxContainer ) toolboxContainer = toolboxContainer . parentNode ;
2007-11-17 00:20:26 -05:00
this . tabbarResizing = false ;
2008-03-09 23:51:21 -04:00
b . removeAttribute ( this . kRESIZING ) ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
if ( pos & this . kTABBAR _VERTICAL ) {
this . positionProp = 'screenY' ;
this . sizeProp = 'height' ;
this . invertedPositionProp = 'screenX' ;
this . invertedSizeProp = 'width' ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
b . mTabBox . orient = 'horizontal' ;
b . mStrip . orient =
b . mTabContainer . orient =
b . mTabContainer . mTabstrip . orient =
b . mTabContainer . mTabstrip . parentNode . orient = 'vertical' ;
if ( allTabsButton . parentNode . localName == 'hbox' ) { // Firefox 2
allTabsButton . parentNode . orient = 'vertical' ;
allTabsButton . parentNode . setAttribute ( 'align' , 'stretch' ) ;
}
allTabsButton . firstChild . setAttribute ( 'position' , 'before_start' ) ;
b . mTabContainer . setAttribute ( 'align' , 'stretch' ) ; // for Mac OS X
scrollInnerBox . removeAttribute ( 'flex' ) ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
if ( scrollFrame ) { // Tab Mix Plus
scrollFrame . parentNode . orient =
scrollFrame . orient = 'vertical' ;
newTabBox . orient = 'horizontal' ;
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' ;
2007-11-17 00:20:26 -05:00
b . mStrip . removeAttribute ( 'width' ) ;
b . mStrip . setAttribute ( 'width' , this . getTreePref ( 'tabbar.width' ) ) ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
b . setAttribute ( this . kMODE , 'vertical' ) ;
if ( pos == this . kTABBAR _RIGHT ) {
b . setAttribute ( this . kTABBAR _POSITION , 'right' ) ;
if ( this . getTreePref ( 'tabbar.invertUI' ) ) {
b . setAttribute ( this . kUI _INVERTED , 'true' ) ;
this . levelMarginProp = 'margin-right' ;
}
else {
b . removeAttribute ( this . kUI _INVERTED ) ;
this . levelMarginProp = 'margin-left' ;
}
window . setTimeout ( function ( aWidth ) {
/ * 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 . * /
b . mStrip . setAttribute ( 'width' , aWidth ) ;
b . mTabDropIndicatorBar . setAttribute ( 'ordinal' , 1 ) ;
b . mStrip . setAttribute ( 'ordinal' , 30 ) ;
splitter . setAttribute ( 'ordinal' , 20 ) ;
b . mPanelContainer . setAttribute ( 'ordinal' , 10 ) ;
splitter . setAttribute ( 'collapse' , 'after' ) ;
} , 0 , this . getTreePref ( 'tabbar.width' ) ) ;
2007-11-14 14:34:36 -05:00
}
2007-11-17 00:20:26 -05:00
else {
b . setAttribute ( this . kTABBAR _POSITION , 'left' ) ;
b . removeAttribute ( this . kUI _INVERTED ) ;
this . levelMarginProp = 'margin-left' ;
window . setTimeout ( function ( ) {
b . mTabDropIndicatorBar . setAttribute ( 'ordinal' , 1 ) ;
b . mStrip . setAttribute ( 'ordinal' , 10 ) ;
splitter . setAttribute ( 'ordinal' , 20 ) ;
b . mPanelContainer . setAttribute ( 'ordinal' , 30 ) ;
splitter . setAttribute ( 'collapse' , 'before' ) ;
} , 0 ) ;
2007-11-14 14:34:36 -05:00
}
}
2007-11-17 00:20:26 -05:00
else {
this . positionProp = 'screenX' ;
this . sizeProp = 'width' ;
this . invertedPositionProp = 'screenY' ;
this . invertedSizeProp = 'height' ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
b . mTabBox . orient = 'vertical' ;
b . mStrip . orient =
b . mTabContainer . orient =
b . mTabContainer . mTabstrip . orient =
b . mTabContainer . mTabstrip . parentNode . orient = 'horizontal' ;
if ( allTabsButton . parentNode . localName == 'hbox' ) { // Firefox 2
allTabsButton . parentNode . orient = 'horizontal' ;
allTabsButton . parentNode . removeAttribute ( 'align' ) ;
}
allTabsButton . firstChild . setAttribute ( 'position' , 'after_end' ) ;
b . mTabContainer . removeAttribute ( 'align' ) ; // for Mac OS X
scrollInnerBox . setAttribute ( 'flex' , 1 ) ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
if ( scrollFrame ) { // Tab Mix Plus
scrollFrame . parentNode . orient =
scrollFrame . orient = 'horizontal' ;
newTabBox . orient = 'vertical' ;
}
2007-11-14 14:34:36 -05:00
2008-03-03 01:00:59 -05:00
if ( toolboxContainer )
toolboxContainer . orient = 'horizontal' ;
2007-11-17 00:20:26 -05:00
b . mStrip . removeAttribute ( 'width' ) ;
b . mPanelContainer . removeAttribute ( 'width' ) ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
b . setAttribute ( this . kMODE , this . getTreePref ( 'tabbar.multirow' ) ? 'multirow' : 'horizontal' ) ;
b . removeAttribute ( this . kUI _INVERTED ) ;
if ( pos == this . kTABBAR _BOTTOM ) {
b . setAttribute ( this . kTABBAR _POSITION , 'bottom' ) ;
this . levelMarginProp = 'margin-bottom' ;
window . setTimeout ( function ( ) {
b . mTabDropIndicatorBar . setAttribute ( 'ordinal' , 1 ) ;
b . mStrip . setAttribute ( 'ordinal' , 30 ) ;
splitter . setAttribute ( 'ordinal' , 20 ) ;
b . mPanelContainer . setAttribute ( 'ordinal' , 10 ) ;
} , 0 ) ;
}
else {
b . setAttribute ( this . kTABBAR _POSITION , 'top' ) ;
this . levelMarginProp = 'margin-top' ;
window . setTimeout ( function ( ) {
b . mTabDropIndicatorBar . setAttribute ( 'ordinal' , 1 ) ;
b . mStrip . setAttribute ( 'ordinal' , 10 ) ;
splitter . setAttribute ( 'ordinal' , 20 ) ;
b . mPanelContainer . setAttribute ( 'ordinal' , 30 ) ;
} , 0 ) ;
2007-11-14 14:34:36 -05:00
}
}
} ,
2007-11-17 00:20:26 -05:00
destroy : function ( )
2007-11-14 14:34:36 -05:00
{
2007-11-17 00:20:26 -05:00
this . endAutoHide ( ) ;
2007-11-14 14:34:36 -05:00
var b = this . mTabBrowser ;
2007-11-17 00:20:26 -05:00
var tabs = b . mTabContainer . childNodes ;
for ( var i = 0 , maxi = tabs . length ; i < maxi ; i ++ )
{
this . destroyTab ( tabs [ i ] ) ;
2007-11-14 14:34:36 -05:00
}
2007-11-17 00:20:26 -05:00
b . removeEventListener ( 'TabOpen' , this , true ) ;
b . removeEventListener ( 'TabClose' , this , true ) ;
b . removeEventListener ( 'TabMove' , this , true ) ;
b . removeEventListener ( 'SSTabRestoring' , this , true ) ;
2007-11-17 12:52:51 -05:00
b . mStrip . removeEventListener ( 'dragenter' , this , false ) ;
b . mStrip . removeEventListener ( 'dragexit' , this , false ) ;
b . mStrip . removeEventListener ( 'dragover' , this , false ) ;
b . mStrip . removeEventListener ( 'dragdrop' , this , false ) ;
2007-11-17 00:20:26 -05:00
b . mTabContainer . removeEventListener ( 'click' , this , true ) ;
b . mTabContainer . removeEventListener ( 'dblclick' , this , true ) ;
b . mTabContainer . removeEventListener ( 'mousedown' , this , true ) ;
b . mTabContainer . removeEventListener ( 'select' , this , true ) ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
var tabContext = document . getAnonymousElementByAttribute ( b , 'anonid' , 'tabContextMenu' ) ;
tabContext . removeEventListener ( 'popupshowing' , this , false ) ;
tabContext . removeEventListener ( 'popuphiding' , this , false ) ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
var allTabPopup = document . getAnonymousElementByAttribute ( b . mTabContainer , 'anonid' , 'alltabs-popup' ) ;
allTabPopup . 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 ;
}
2007-11-17 00:20:26 -05:00
this . ObserverService . removeObserver ( this , 'TreeStyleTab:levelMarginModified' ) ;
this . ObserverService . removeObserver ( this , 'TreeStyleTab:collapseExpandAllSubtree' ) ;
this . removePrefListener ( this ) ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
delete this . mTabBrowser ;
2007-11-14 14:34:36 -05:00
} ,
2008-03-09 23:51:21 -04:00
2007-11-17 00:20:26 -05:00
destroyTab : function ( aTab )
{
delete aTab . _ _treestyletab _ _linkedTabBrowser ;
} ,
2007-11-17 07:50:36 -05:00
2007-11-17 00:20:26 -05:00
/* nsIObserver */
2008-03-03 04:21:33 -05:00
2007-11-14 14:34:36 -05:00
domain : 'extensions.treestyletab' ,
observe : function ( aSubject , aTopic , aData )
{
var b = this . mTabBrowser ;
var self = this ;
switch ( aTopic )
{
case 'TreeStyleTab:levelMarginModified' :
if ( this . levelMargin > - 1 ) {
this . updateAllTabsIndent ( ) ;
}
break ;
2007-11-17 00:20:26 -05:00
case 'TreeStyleTab:collapseExpandAllSubtree' :
if ( aSubject == window )
this . collapseExpandAllSubtree ( aData == 'collapse' ) ;
break ;
2007-11-14 14:34:36 -05:00
case 'nsPref:changed' :
var value = this . getPref ( aData ) ;
var tabContainer = b . mTabContainer ;
var tabs = Array . prototype . slice . call ( tabContainer . childNodes ) ;
switch ( aData )
{
case 'extensions.treestyletab.tabbar.position' :
2008-03-08 05:15:58 -05:00
// if (value != 'left' && value != 'right') {
// this.endAutoHide();
// }
2008-03-08 05:22:36 -05:00
if ( this . autoHideEnabled && this . tabbarShown ) this . hideTabbar ( ) ;
2007-11-14 14:34:36 -05:00
this . initTabbar ( ) ;
tabs . forEach ( function ( aTab ) {
self . initTabAttributes ( aTab ) ;
} ) ;
this . updateAllTabsIndent ( ) ;
tabs . forEach ( function ( aTab ) {
self . initTabContents ( aTab ) ;
} ) ;
2008-03-08 05:22:36 -05:00
if ( this . autoHideEnabled ) this . showTabbar ( ) ;
2008-03-10 00:11:44 -04:00
this . updateTabbarTransparency ( ) ;
2007-11-14 14:34:36 -05:00
break ;
case 'extensions.treestyletab.tabbar.invertUI' :
case 'extensions.treestyletab.tabbar.multirow' :
this . initTabbar ( ) ;
this . updateAllTabsIndent ( ) ;
tabs . forEach ( function ( aTab ) {
self . initTabContents ( aTab ) ;
} ) ;
break ;
case 'extensions.treestyletab.enableSubtreeIndent' :
this . updateAllTabsIndent ( ) ;
break ;
case 'extensions.treestyletab.tabbar.style' :
b . setAttribute ( this . kSTYLE , value ) ;
break ;
2008-02-28 07:12:02 -05:00
case 'extensions.treestyletab.twisty.style' :
2008-03-02 11:01:33 -05:00
if ( value == 'auto' ) {
if ( document . documentElement . getAttribute ( 'informationaltab-thumbnail-enabled' ) == 'true' ) {
value = 'retro' ;
}
else {
value = 'modern-black' ;
}
}
2008-02-28 07:12:02 -05:00
b . setAttribute ( this . kTWISTY _STYLE , value ) ;
break ;
2007-11-14 14:34:36 -05:00
case 'extensions.treestyletab.showBorderForFirstTab' :
if ( value )
b . setAttribute ( this . kFIRSTTAB _BORDER , true ) ;
else
b . removeAttribute ( this . kFIRSTTAB _BORDER ) ;
break ;
case 'extensions.treestyletab.tabbar.invertScrollbar' :
if ( value &&
2008-03-10 00:11:44 -04:00
b . getAttribute ( this . kTABBAR _POSITION ) == 'left' &&
2007-11-14 14:34:36 -05:00
this . isGecko18 )
b . setAttribute ( this . kSCROLLBAR _INVERTED , true ) ;
else
b . removeAttribute ( this . kSCROLLBAR _INVERTED ) ;
break ;
case 'extensions.treestyletab.tabbar.hideAlltabsButton' :
2008-03-10 00:11:44 -04:00
var pos = b . getAttribute ( this . kTABBAR _POSITION ) ;
2007-11-14 14:34:36 -05:00
if ( value && ( pos == 'left' || pos == 'right' ) )
b . setAttribute ( this . kHIDE _ALLTABS , true ) ;
else
b . removeAttribute ( this . kHIDE _ALLTABS ) ;
break ;
case 'extensions.treestyletab.allowSubtreeCollapseExpand' :
if ( value )
b . setAttribute ( this . kALLOW _COLLAPSE , true ) ;
else
b . removeAttribute ( this . kALLOW _COLLAPSE ) ;
break ;
case 'extensions.treestyletab.tabbar.autoHide.enabled' :
2008-03-10 00:11:44 -04:00
var pos = b . getAttribute ( this . kTABBAR _POSITION ) ;
2008-03-08 05:15:58 -05:00
if ( value /* && (pos == 'left' || pos == 'right')*/ )
2007-11-14 14:34:36 -05:00
this . startAutoHide ( ) ;
else
this . endAutoHide ( ) ;
break ;
2008-03-09 08:46:19 -04:00
case 'extensions.treestyletab.tabbar.autoShow.mousemove' :
if ( this . autoHideEnabled && value )
this . startListenMouseMove ( ) ;
else
this . endListenMouseMove ( ) ;
break ;
2008-02-22 12:55:35 -05:00
case 'extensions.treestyletab.tabbar.fixed' :
if ( value )
b . setAttribute ( this . kFIXED , true ) ;
else
b . removeAttribute ( this . kFIXED ) ;
break ;
2008-03-10 00:11:44 -04:00
case 'extensions.treestyletab.tabbar.transparent' :
this . updateTabbarTransparency ( ) ;
break ;
2007-11-14 14:34:36 -05:00
default :
break ;
}
break ;
default :
break ;
}
} ,
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
2007-11-14 14:34:36 -05:00
handleEvent : function ( aEvent )
{
switch ( aEvent . type )
{
case 'TabOpen' :
this . onTabAdded ( aEvent ) ;
return ;
case 'TabClose' :
this . onTabRemoved ( aEvent ) ;
return ;
case 'TabMove' :
this . onTabMove ( aEvent ) ;
return ;
case 'SSTabRestoring' :
this . onTabRestored ( aEvent ) ;
return ;
case 'select' :
this . onTabSelect ( aEvent ) ;
return ;
case 'click' :
if ( aEvent . target . ownerDocument == document ) {
this . onTabClick ( aEvent ) ;
return ;
}
return ;
case 'dblclick' :
var tab = this . getTabFromEvent ( aEvent ) ;
if ( tab &&
tab . getAttribute ( this . kCHILDREN ) &&
this . getTreePref ( 'collapseExpandSubTree.dblclick' ) ) {
2007-11-17 00:20:26 -05:00
this . collapseExpandSubtree ( tab , tab . getAttribute ( this . kSUBTREE _COLLAPSED ) != 'true' ) ;
2007-11-14 14:34:36 -05:00
aEvent . preventDefault ( ) ;
aEvent . stopPropagation ( ) ;
}
return ;
case 'mousedown' :
if ( aEvent . currentTarget == this . mTabBrowser . mTabContainer ) {
this . onTabMouseDown ( aEvent ) ;
}
else {
2008-03-09 23:51:21 -04:00
if ( aEvent . originalTarget . getAttribute ( 'class' ) == this . kSPLITTER ) {
2007-11-14 14:34:36 -05:00
this . tabbarResizing = true ;
2008-03-09 23:51:21 -04:00
this . mTabBrowser . setAttribute ( this . kRESIZING , true ) ;
}
2008-03-09 01:36:52 -05:00
this . cancelShowHideTabbarOnMousemove ( ) ;
if (
this . autoHideEnabled &&
this . tabbarShown &&
(
aEvent . originalTarget . ownerDocument != document ||
! this . getTabBrowserFromChild ( aEvent . originalTarget )
)
)
this . hideTabbar ( ) ;
2007-11-14 14:34:36 -05:00
}
return ;
case 'mouseup' :
2008-03-09 23:51:21 -04:00
if ( aEvent . originalTarget . getAttribute ( 'class' ) == this . kSPLITTER ) {
2007-11-14 14:34:36 -05:00
this . tabbarResizing = false ;
2008-03-09 23:51:21 -04:00
this . mTabBrowser . removeAttribute ( this . kRESIZING ) ;
}
2008-03-09 01:36:52 -05:00
this . cancelShowHideTabbarOnMousemove ( ) ;
2007-11-14 14:34:36 -05:00
return ;
case 'mousemove' :
if ( ! this . tabbarResizing ) {
2008-03-09 01:36:52 -05:00
if (
! this . tabContextMenuShown &&
(
! this . tabbarShown ||
this . showHideTabbarReason == this . kSHOWN _BY _MOUSEMOVE
)
)
this . showHideTabbarOnMousemove ( aEvent ) ;
2007-11-14 14:34:36 -05:00
return ;
}
case 'resize' :
if ( this . tabbarShown ) {
switch ( this . mTabBrowser . getAttribute ( this . kTABBAR _POSITION ) )
{
case 'left' :
this . container . style . marginRight = '-' + this . tabbarWidth + 'px' ;
break ;
case 'right' :
this . container . style . marginLeft = '-' + this . tabbarWidth + 'px' ;
break ;
case 'bottom' :
this . container . style . marginTop = '-' + this . tabbarHeight + 'px' ;
break ;
default :
this . container . style . marginBottom = '-' + this . tabbarHeight + 'px' ;
break ;
}
this . redrawContentArea ( ) ;
}
return ;
case 'scroll' :
this . redrawContentArea ( ) ;
return ;
case 'load' :
this . redrawContentArea ( ) ;
return ;
case 'popupshowing' :
if ( aEvent . target != aEvent . currentTarget ) return ;
2007-11-17 00:20:26 -05:00
switch ( aEvent . target . getAttribute ( 'anonid' ) )
{
case 'tabContextMenu' :
this . tabContextMenuShown = true ;
this . initTabContextMenu ( aEvent ) ;
break ;
case 'alltabs-popup' :
this . initAllTabsPopup ( aEvent ) ;
break ;
}
2007-11-14 14:34:36 -05:00
return ;
case 'popuphiding' :
2007-11-17 00:20:26 -05:00
if ( aEvent . target != aEvent . currentTarget ) return ;
switch ( aEvent . target . getAttribute ( 'anonid' ) )
{
case 'tabContextMenu' :
this . tabContextMenuShown = false ;
break ;
}
2007-11-14 14:34:36 -05:00
return ;
2007-11-17 12:21:33 -05:00
case 'dragenter' :
nsDragAndDrop . dragEnter ( aEvent , this ) ;
return ;
case 'dragexit' :
nsDragAndDrop . dragExit ( aEvent , this ) ;
return ;
case 'dragover' :
nsDragAndDrop . dragOver ( aEvent , this ) ;
return ;
2007-11-17 12:52:51 -05:00
case 'dragdrop' :
nsDragAndDrop . drop ( aEvent , this ) ;
return ;
2007-11-30 14:22:34 -05:00
case 'mouseover' :
if ( this . isEventFiredOnTwisty ( aEvent ) ) {
aEvent . target . setAttribute ( this . kTWISTY _HOVER , true ) ;
}
return ;
case 'mouseout' :
if ( this . isEventFiredOnTwisty ( aEvent ) ) {
aEvent . target . removeAttribute ( this . kTWISTY _HOVER ) ;
}
return ;
2007-11-14 14:34:36 -05:00
}
} ,
onTabAdded : function ( aEvent )
{
var tab = aEvent . originalTarget ;
var b = this . mTabBrowser ;
this . initTab ( tab ) ;
if ( this . readyToAttachNewTab ) {
var parent = this . getTabById ( this . parentTab ) ;
if ( parent )
this . attachTabTo ( tab , parent ) ;
var refTab ;
var newIndex = - 1 ;
if ( this . insertBefore &&
( refTab = this . getTabById ( this . insertBefore ) ) ) {
newIndex = refTab . _tPos ;
}
else if ( parent &&
this . getTreePref ( 'insertNewChildAt' ) == this . kINSERT _FISRT &&
this . multipleCount == 0 ) {
/ * <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ̎ q <EFBFBD> ^ <EFBFBD> u <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> C <EFBFBD> Ɋ J <EFBFBD> <EFBFBD> <EFBFBD> ꍇ <EFBFBD> A <EFBFBD> ŏ <EFBFBD> <EFBFBD> Ɋ J <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ^ <EFBFBD> u <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
<EFBFBD> q <EFBFBD> ^ <EFBFBD> u <EFBFBD> ̍ ŏ <EFBFBD> <EFBFBD> ̈ ʒu <EFBFBD> ɑ } <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> A <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ^ <EFBFBD> u <EFBFBD> ́ u <EFBFBD> ŏ <EFBFBD> <EFBFBD> ̊ J <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ^ <EFBFBD> u <EFBFBD> v <EFBFBD> <EFBFBD>
<EFBFBD> u <EFBFBD> <EFBFBD> <EFBFBD> X <EFBFBD> ŏ <EFBFBD> <EFBFBD> ̎ q <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ^ <EFBFBD> u <EFBFBD> v <EFBFBD> Ƃ ̊ Ԃɑ } <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ă <EFBFBD> <EFBFBD> <EFBFBD> * /
newIndex = parent . _tPos + 1 ;
if ( refTab = this . getFirstChildTab ( parent ) )
this . insertBefore = refTab . getAttribute ( this . kID ) ;
}
if ( newIndex > - 1 ) {
if ( newIndex > tab . _tPos ) newIndex -- ;
this . internallyTabMoving = true ;
b . moveTabTo ( tab , newIndex ) ;
this . internallyTabMoving = false ;
}
}
if ( ! this . readyToAttachMultiple ) {
this . stopToOpenChildTab ( b ) ;
}
else {
this . multipleCount ++ ;
}
2008-03-09 01:36:52 -05:00
this . showTabbarForFeedback ( ) ;
2007-11-14 14:34:36 -05:00
} ,
onTabRemoved : function ( aEvent )
{
var tab = aEvent . originalTarget ;
var b = this . mTabBrowser ;
this . destroyTab ( tab ) ;
if ( tab . getAttribute ( this . kSUBTREE _COLLAPSED ) == 'true' ) {
var descendant = this . getDescendantTabs ( tab ) ;
for ( var i = descendant . length - 1 ; i > - 1 ; i -- )
{
b . removeTab ( descendant [ i ] ) ;
}
if ( b . mTabContainer . childNodes . length == 1 ) { // this is the last tab
b . addTab ( 'about:blank' ) ;
}
}
var firstChild = this . getFirstChildTab ( tab ) ;
var parentTab = this . getParentTab ( tab ) ;
var nextFocusedTab = null ;
var next = this . getNextSiblingTab ( tab ) ;
if ( next )
this . setTabValue ( tab , this . kINSERT _BEFORE , next . getAttribute ( this . kID ) ) ;
if ( firstChild ) {
var backupChildren = this . getTabValue ( tab , this . kCHILDREN ) ;
var children = this . getChildTabs ( tab ) ;
var self = this ;
var attach = this . getTreePref ( 'attachChildrenToGrandParentOnRemoveTab' ) ;
var processTab = ! attach ? function ( aTab ) {
self . partTab ( aTab , true ) ;
self . moveTabSubTreeTo ( aTab , b . mTabContainer . lastChild . _tPos ) ;
} :
parentTab ? function ( aTab ) {
self . attachTabTo ( aTab , parentTab , {
insertBefore : tab ,
dontUpdateIndent : true ,
dontExpand : true
} ) ;
} :
function ( aTab ) {
self . partTab ( aTab , true ) ;
} ;
for ( var i = 0 , maxi = children . length ; i < maxi ; i ++ )
{
processTab ( children [ i ] ) ;
}
this . updateTabsIndent ( children ) ;
this . checkTabsIndentOverflow ( ) ;
if ( attach ) {
nextFocusedTab = firstChild ;
}
this . setTabValue ( tab , this . kCHILDREN , backupChildren ) ;
}
if ( parentTab ) {
var firstSibling = this . getFirstChildTab ( parentTab ) ;
var lastSibling = this . getLastChildTab ( parentTab ) ;
if ( tab == lastSibling ) {
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
var ancestors = [ ] ;
do {
ancestors . push ( parentTab . getAttribute ( this . kID ) ) ;
if ( ! next && ( next = this . getNextSiblingTab ( parentTab ) ) )
this . setTabValue ( tab , this . kINSERT _BEFORE , next . getAttribute ( this . kID ) ) ;
}
while ( parentTab = this . getParentTab ( parentTab ) ) ;
2007-11-26 16:17:46 -05:00
this . setTabValue ( tab , this . kANCESTOR , ancestors . join ( '|' ) ) ;
2007-11-26 14:55:58 -05:00
2007-11-14 14:34:36 -05:00
this . partTab ( tab , true ) ;
}
else if ( ! nextFocusedTab ) {
nextFocusedTab = this . getNextSiblingTab ( tab ) ;
}
2008-03-02 13:16:57 -05:00
if (
nextFocusedTab &&
b . selectedTab == tab &&
this . _tabFocusAllowance . every ( function ( aFunc ) {
return aFunc ( b ) ;
} )
)
2007-11-14 14:34:36 -05:00
b . selectedTab = nextFocusedTab ;
this . checkTabsIndentOverflow ( ) ;
2008-03-09 01:36:52 -05:00
this . showTabbarForFeedback ( ) ;
2007-11-14 14:34:36 -05:00
} ,
onTabMove : function ( aEvent )
{
var tab = aEvent . originalTarget ;
var b = this . mTabBrowser ;
this . initTabContents ( tab ) ; // twisty vanished after the tab is moved!!
2007-11-26 19:41:51 -05:00
// var rebuildTreeDone = false;
2007-11-14 14:34:36 -05:00
if ( tab . getAttribute ( this . kCHILDREN ) && ! this . isSubTreeMoving ) {
this . moveTabSubTreeTo ( tab , tab . _tPos ) ;
2007-11-26 19:41:51 -05:00
// rebuildTreeDone = true;
2007-11-14 14:34:36 -05:00
}
var parentTab = this . getParentTab ( tab ) ;
if ( parentTab && ! this . isSubTreeChildrenMoving ) {
this . updateChildrenArray ( parentTab ) ;
}
2007-11-15 08:01:07 -05:00
this . updateTabsCount ( tab , true ) ;
2007-11-14 14:34:36 -05:00
if (
2007-11-26 19:41:51 -05:00
// rebuildTreeDone ||
2007-11-14 14:34:36 -05:00
this . isSubTreeMoving ||
this . internallyTabMoving
)
return ;
2007-11-26 14:55:58 -05:00
this . attachTabFromPosition ( tab , aEvent . detail ) ;
2008-03-09 01:36:52 -05:00
this . showTabbarForFeedback ( ) ;
2007-11-26 14:55:58 -05:00
} ,
attachTabFromPosition : function ( aTab , aOldPosition )
{
2007-11-26 17:43:50 -05:00
var parent = this . getParentTab ( aTab ) ;
2007-11-26 14:55:58 -05:00
if ( aOldPosition === void ( 0 ) ) aOldPosition = aTab . _tPos ;
2007-11-26 19:41:51 -05:00
var pos = this . getChildIndex ( aTab , parent ) ;
2007-11-26 17:43:50 -05:00
var oldPos = this . getChildIndex ( this . mTabBrowser . mTabContainer . childNodes [ aOldPosition ] , parent ) ;
2007-11-26 19:41:51 -05:00
var delta ;
2007-11-26 21:42:02 -05:00
if ( pos == oldPos ) { // no move?
return ;
}
else if ( pos < 0 || oldPos < 0 ) {
2007-11-26 19:41:51 -05:00
delta = 2 ;
}
else {
delta = Math . abs ( pos - oldPos ) ;
2007-11-26 14:55:58 -05:00
}
2007-11-26 17:43:50 -05:00
2007-11-26 21:42:02 -05:00
var prevTab = aTab . previousSibling ;
var nextTab = aTab . nextSibling ;
var tabs = this . getDescendantTabs ( aTab ) ;
if ( tabs . length ) {
nextTab = tabs [ tabs . length - 1 ] . nextSibling ;
}
var prevParent = this . getParentTab ( prevTab ) ;
var nextParent = this . getParentTab ( nextTab ) ;
var prevLevel = prevTab ? Number ( prevTab . getAttribute ( this . kNEST ) ) : - 1 ;
var nextLevel = nextTab ? Number ( nextTab . getAttribute ( this . kNEST ) ) : - 1 ;
var newParent ;
2007-11-26 17:43:50 -05:00
if ( ! prevTab ) {
2007-11-26 21:42:02 -05:00
newParent = null ;
2007-11-26 17:43:50 -05:00
}
else if ( ! nextTab ) {
newParent = ( delta > 1 ) ? prevParent : parent ;
}
else if ( prevParent == nextParent ) {
newParent = prevParent ;
}
else if ( prevLevel > nextLevel ) {
2007-11-26 21:42:02 -05:00
var realDelta = Math . abs ( aTab . _tPos - aOldPosition ) ;
newParent = realDelta < 2 ? prevParent : parent ;
2007-11-26 14:55:58 -05:00
}
2007-11-26 17:43:50 -05:00
else if ( prevLevel < nextLevel ) {
newParent = aTab . previousSibling ;
}
if ( newParent != parent ) {
if ( newParent )
2007-11-26 21:42:02 -05:00
this . attachTabTo ( aTab , newParent , { insertBefore : nextTab } ) ;
2007-11-14 14:34:36 -05:00
else
2007-11-26 14:55:58 -05:00
this . partTab ( aTab ) ;
2007-11-14 14:34:36 -05:00
}
} ,
2007-11-26 14:55:58 -05:00
2007-11-14 14:34:36 -05:00
updateChildrenArray : function ( aTab )
{
var children = this . getChildTabs ( aTab ) ;
children . sort ( function ( aA , aB ) { return aA . _tPos - aB . _tPos ; } ) ;
var self = this ;
this . setTabValue ( aTab , this . kCHILDREN ,
children . map ( function ( aItem ) { return aItem . getAttribute ( self . kID ) ; } ) . join ( '|' ) ) ;
} ,
onTabRestored : function ( aEvent )
{
var tab = aEvent . originalTarget ;
var b = this . mTabBrowser ;
2008-02-23 20:06:19 -05:00
var self = this ;
2007-11-15 08:11:26 -05:00
2007-11-17 07:50:36 -05:00
var isDuplicated = false ;
var id = this . getTabValue ( tab , this . kID ) ;
2008-02-23 21:01:50 -05:00
2007-11-17 07:50:36 -05:00
if ( this . getTabById ( id ) ) { // this is a duplicated tab!
isDuplicated = true ;
2008-02-23 20:06:19 -05:00
id = this . getDuplicatedId ( id ) ;
2007-11-17 07:50:36 -05:00
}
2007-11-23 16:34:43 -05:00
if ( ! isDuplicated ) {
/ * I f i t h a s a p a r e n t , i t i s w r o n g l y a t t a c c h e d b y t a b m o v i n g
on restoring . Restoring the old ID ( the next statement )
breaks the children list of the temporary parent and causes
many problems . So , to prevent these problems , I part the tab
from the temporary parent manually . * /
2007-11-17 07:50:36 -05:00
this . partTab ( tab ) ;
2007-11-23 16:34:43 -05:00
/* reset attributes before restoring */
tab . removeAttribute ( this . kID ) ;
tab . removeAttribute ( this . kPARENT ) ;
tab . removeAttribute ( this . kCHILDREN ) ;
tab . removeAttribute ( this . kSUBTREE _COLLAPSED ) ;
tab . removeAttribute ( this . kCOLLAPSED ) ;
tab . removeAttribute ( this . kNEST ) ;
this . updateTabsIndent ( [ tab ] ) ;
}
2007-11-15 08:11:26 -05:00
2007-11-14 14:34:36 -05:00
this . setTabValue ( tab , this . kID , id ) ;
var isSubTreeCollapsed = ( this . getTabValue ( tab , this . kSUBTREE _COLLAPSED ) == 'true' ) ;
var children = this . getTabValue ( tab , this . kCHILDREN ) ;
2007-11-15 08:01:07 -05:00
var tabs = [ ] ;
2007-11-14 14:34:36 -05:00
if ( children ) {
2008-02-23 21:01:50 -05:00
tab . removeAttribute ( this . kCHILDREN ) ;
2007-11-14 14:34:36 -05:00
children = children . split ( '|' ) ;
2007-11-17 07:50:36 -05:00
if ( isDuplicated )
2008-02-23 20:06:19 -05:00
children = children . map ( function ( aChild ) {
return self . getDuplicatedId ( aChild ) ;
} ) ;
2007-11-14 14:34:36 -05:00
for ( var i = 0 , maxi = children . length ; i < maxi ; i ++ )
{
if ( children [ i ] && ( children [ i ] = this . getTabById ( children [ i ] ) ) ) {
this . attachTabTo ( children [ i ] , tab , { dontExpand : true , dontUpdateIndent : true } ) ;
tabs . push ( children [ i ] ) ;
}
}
}
var before = this . getTabValue ( tab , this . kINSERT _BEFORE ) ;
2008-02-23 20:06:19 -05:00
if ( before && isDuplicated ) {
before = this . getDuplicatedId ( before ) ;
}
2007-11-17 07:50:36 -05:00
2007-11-26 16:17:46 -05:00
var ancestors = ( this . getTabValue ( tab , this . kANCESTOR ) || this . getTabValue ( tab , this . kPARENT ) || '' ) . split ( '|' ) ;
2007-11-26 14:55:58 -05:00
var parent = null ;
for ( var i in ancestors )
{
2008-02-23 21:01:50 -05:00
if ( isDuplicated ) ancestors [ i ] = this . getDuplicatedId ( ancestors [ i ] ) ;
2007-11-26 14:55:58 -05:00
parent = this . getTabById ( ancestors [ i ] ) ;
if ( parent ) {
parent = ancestors [ i ] ;
break ;
}
}
2007-11-26 16:17:46 -05:00
this . deleteTabValue ( tab , this . kANCESTOR ) ;
2007-11-26 14:55:58 -05:00
2007-11-14 14:34:36 -05:00
if ( parent ) {
2008-02-23 21:01:50 -05:00
tab . removeAttribute ( this . kPARENT ) ;
2007-11-14 14:34:36 -05:00
parent = this . getTabById ( parent ) ;
if ( parent ) {
this . attachTabTo ( tab , parent , {
dontExpand : true ,
insertBefore : ( before ? this . getTabById ( before ) : null ) ,
dontUpdateIndent : true
} ) ;
this . updateTabsIndent ( [ tab ] ) ;
this . checkTabsIndentOverflow ( ) ;
}
else {
this . deleteTabValue ( tab , this . kPARENT ) ;
}
}
else if ( children ) {
this . updateTabsIndent ( tabs ) ;
this . checkTabsIndentOverflow ( ) ;
}
if ( ! parent && ( before = this . getTabById ( before ) ) ) {
var index = before . _tPos ;
if ( index > tab . _tPos ) index -- ;
b . moveTabTo ( tab , index ) ;
}
this . deleteTabValue ( tab , this . kINSERT _BEFORE ) ;
if ( isSubTreeCollapsed ) {
2007-11-17 00:20:26 -05:00
this . collapseExpandSubtree ( tab , isSubTreeCollapsed ) ;
2007-11-14 14:34:36 -05:00
}
2008-02-22 16:52:44 -05:00
2008-02-24 02:58:12 -05:00
if ( isDuplicated ) this . clearCachedIds ( ) ;
2008-02-23 20:06:19 -05:00
} ,
2008-03-08 03:57:17 -05:00
2008-02-24 02:58:12 -05:00
getDuplicatedId : function ( aId )
2008-02-23 20:06:19 -05:00
{
if ( ! ( aId in this . duplicatedIdsHash ) )
this . duplicatedIdsHash [ aId ] = this . makeNewId ( ) ;
return this . duplicatedIdsHash [ aId ] ;
} ,
duplicatedIdsHash : { } ,
2008-02-24 02:58:12 -05:00
2008-02-23 20:06:19 -05:00
clearCachedIds : function ( )
{
if ( this . clearCachedIdsTimer ) {
window . clearTimeout ( this . clearCachedIdsTimer ) ;
this . clearCachedIdsTimer = null ;
}
this . clearCachedIdsTimer = window . setTimeout ( function ( aSelf ) {
aSelf . clearCachedIdsCallback ( ) ;
} , 1000 , this ) ;
} ,
clearCachedIdsTimer : null ,
clearCachedIdsCallback : function ( )
{
this . duplicatedIdsHash = { } ;
2007-11-14 14:34:36 -05:00
} ,
2008-03-03 04:21:33 -05:00
2007-11-14 14:34:36 -05:00
onTabSelect : function ( aEvent )
{
var b = this . mTabBrowser ;
var tab = b . selectedTab
if ( tab . getAttribute ( this . kCOLLAPSED ) == 'true' ) {
var parentTab = tab ;
while ( parentTab = this . getParentTab ( parentTab ) )
{
2007-11-17 00:20:26 -05:00
this . collapseExpandSubtree ( parentTab , false ) ;
2007-11-14 14:34:36 -05:00
}
}
else if ( tab . getAttribute ( this . kCHILDREN ) &&
( tab . getAttribute ( this . kSUBTREE _COLLAPSED ) == 'true' ) &&
this . getTreePref ( 'autoCollapseExpandSubTreeOnSelect' ) ) {
this . collapseExpandTreesIntelligentlyFor ( tab ) ;
}
if ( this . autoHideEnabled && this . tabbarShown )
this . redrawContentArea ( ) ;
2008-03-03 04:21:33 -05:00
this . updateInvertedTabContentsOrder ( ) ;
2008-03-09 01:36:52 -05:00
2008-03-09 08:18:58 -04:00
if ( ! this . accelKeyPressed )
this . showTabbarForFeedback ( ) ;
2007-11-14 14:34:36 -05:00
} ,
onTabClick : function ( aEvent )
{
if ( aEvent . button != 0 ||
! this . isEventFiredOnTwisty ( aEvent ) )
return ;
var tab = this . getTabFromEvent ( aEvent ) ;
2007-11-17 00:20:26 -05:00
this . collapseExpandSubtree ( tab , tab . getAttribute ( this . kSUBTREE _COLLAPSED ) != 'true' ) ;
2007-11-14 14:34:36 -05:00
aEvent . preventDefault ( ) ;
aEvent . stopPropagation ( ) ;
} ,
onTabMouseDown : function ( aEvent )
{
if ( aEvent . button != 0 ||
! this . isEventFiredOnTwisty ( aEvent ) )
return ;
this . getTabFromEvent ( aEvent ) . _ _treestyletab _ _preventSelect = true ;
} ,
initTabContextMenu : function ( aEvent )
{
var b = this . mTabBrowser ;
2007-11-17 01:05:23 -05:00
var item , sep ;
// remove subtree
item = this . evaluateXPath (
'descendant::xul:menuitem[starts-with(@id, "' + this . kMENUITEM _REMOVESUBTREE + '")]' ,
2007-11-14 14:34:36 -05:00
aEvent . currentTarget ,
XPathResult . FIRST _ORDERED _NODE _TYPE
) . singleNodeValue ;
2007-11-17 01:05:23 -05:00
if ( this . getTreePref ( 'show.' + this . kMENUITEM _REMOVESUBTREE ) )
2007-11-14 14:34:36 -05:00
item . removeAttribute ( 'hidden' ) ;
else
item . setAttribute ( 'hidden' , true ) ;
this . showHideRemoveSubTreeMenuItem ( item , [ b . mContextTab ] ) ;
2007-11-26 10:07:10 -05:00
item = this . evaluateXPath (
'descendant::xul:menuitem[starts-with(@id, "' + this . kMENUITEM _REMOVECHILDREN + '")]' ,
aEvent . currentTarget ,
XPathResult . FIRST _ORDERED _NODE _TYPE
) . singleNodeValue ;
if ( this . getTreePref ( 'show.' + this . kMENUITEM _REMOVECHILDREN ) )
item . removeAttribute ( 'hidden' ) ;
else
item . setAttribute ( 'hidden' , true ) ;
this . showHideRemoveSubTreeMenuItem ( item , [ b . mContextTab ] ) ;
2007-11-17 01:05:23 -05:00
// collapse/expand all
sep = this . evaluateXPath (
'descendant::xul:menuseparator[starts-with(@id, "' + this . kMENUITEM _COLLAPSEEXPAND _SEPARATOR + '")]' ,
aEvent . currentTarget ,
XPathResult . FIRST _ORDERED _NODE _TYPE
) . singleNodeValue ;
var collapseItem = this . evaluateXPath (
'descendant::xul:menuitem[starts-with(@id, "' + this . kMENUITEM _COLLAPSE + '")]' ,
aEvent . currentTarget ,
XPathResult . FIRST _ORDERED _NODE _TYPE
) . singleNodeValue ;
var expanndItem = this . evaluateXPath (
'descendant::xul:menuitem[starts-with(@id, "' + this . kMENUITEM _EXPAND + '")]' ,
aEvent . currentTarget ,
XPathResult . FIRST _ORDERED _NODE _TYPE
) . singleNodeValue ;
if ( this . evaluateXPath (
'child::xul:tab[@' + this . kCHILDREN + ']' ,
b . mTabContainer
) . snapshotLength ) {
if ( this . getTreePref ( 'show.' + this . kMENUITEM _COLLAPSE ) ) {
collapseItem . removeAttribute ( 'hidden' ) ;
if ( this . evaluateXPath (
'child::xul:tab[@' + this . kCHILDREN + ' and not(@' + this . kSUBTREE _COLLAPSED + '="true")]' ,
b . mTabContainer
) . snapshotLength ) {
collapseItem . removeAttribute ( 'disabled' ) ;
}
else {
collapseItem . setAttribute ( 'disabled' , true ) ;
}
}
else {
collapseItem . setAttribute ( 'hidden' , true ) ;
}
if ( this . getTreePref ( 'show.' + this . kMENUITEM _EXPAND ) ) {
expanndItem . removeAttribute ( 'hidden' ) ;
if ( this . evaluateXPath (
'child::xul:tab[@' + this . kCHILDREN + ' and @' + this . kSUBTREE _COLLAPSED + '="true"]' ,
b . mTabContainer
) . snapshotLength ) {
expanndItem . removeAttribute ( 'disabled' ) ;
}
else {
expanndItem . setAttribute ( 'disabled' , true ) ;
}
}
else {
expanndItem . setAttribute ( 'hidden' , true ) ;
}
}
else {
collapseItem . setAttribute ( 'hidden' , true ) ;
expanndItem . setAttribute ( 'hidden' , true ) ;
}
if ( collapseItem . getAttribute ( 'hidden' ) == 'true' &&
expanndItem . getAttribute ( 'hidden' ) == 'true' ) {
sep . setAttribute ( 'hidden' , true ) ;
}
else {
sep . removeAttribute ( 'hidden' ) ;
}
// auto hide
2008-02-22 12:55:35 -05:00
var autohide = this . evaluateXPath (
2007-11-17 01:05:23 -05:00
'descendant::xul:menuitem[starts-with(@id, "' + this . kMENUITEM _AUTOHIDE + '")]' ,
2007-11-14 14:34:36 -05:00
aEvent . currentTarget ,
XPathResult . FIRST _ORDERED _NODE _TYPE
) . singleNodeValue ;
2008-02-22 12:55:35 -05:00
var pos = b . getAttribute ( this . kTABBAR _POSITION ) ;
2008-03-08 05:15:58 -05:00
if ( this . getTreePref ( 'show.' + this . kMENUITEM _AUTOHIDE ) / * &&
( pos == 'left' || pos == 'right' ) * / ) {
2008-02-22 12:55:35 -05:00
autohide . removeAttribute ( 'hidden' ) ;
if ( this . getTreePref ( 'tabbar.autoHide.enabled' ) )
autohide . setAttribute ( 'checked' , true ) ;
else
autohide . removeAttribute ( 'checked' ) ;
}
else {
autohide . setAttribute ( 'hidden' , true ) ;
}
// fix
var fixed = this . evaluateXPath (
'descendant::xul:menuitem[starts-with(@id, "' + this . kMENUITEM _FIXED + '")]' ,
aEvent . currentTarget ,
XPathResult . FIRST _ORDERED _NODE _TYPE
) . singleNodeValue ;
if ( this . getTreePref ( 'show.' + this . kMENUITEM _FIXED ) &&
( pos == 'left' || pos == 'right' ) ) {
fixed . removeAttribute ( 'hidden' ) ;
if ( this . getTreePref ( 'tabbar.fixed' ) )
fixed . setAttribute ( 'checked' , true ) ;
else
fixed . removeAttribute ( 'checked' ) ;
}
else {
fixed . setAttribute ( 'hidden' , true ) ;
}
2008-02-26 12:02:59 -05:00
// position
var position = this . evaluateXPath (
'descendant::xul:menu[starts-with(@id, "' + this . kMENUITEM _POSITION + '")]' ,
aEvent . currentTarget ,
XPathResult . FIRST _ORDERED _NODE _TYPE
) . singleNodeValue ;
if ( this . getTreePref ( 'show.' + this . kMENUITEM _POSITION ) ) {
position . removeAttribute ( 'hidden' ) ;
position . getElementsByAttribute ( 'value' , pos ) [ 0 ] . setAttribute ( 'checked' , true ) ;
}
else {
position . setAttribute ( 'hidden' , true ) ;
}
2007-11-17 01:05:23 -05:00
sep = this . evaluateXPath (
'descendant::xul:menuseparator[starts-with(@id, "' + this . kMENUITEM _AUTOHIDE _SEPARATOR + '")]' ,
2007-11-14 14:34:36 -05:00
aEvent . currentTarget ,
XPathResult . FIRST _ORDERED _NODE _TYPE
) . singleNodeValue ;
2008-02-22 12:55:35 -05:00
if ( autohide . getAttribute ( 'hidden' ) != 'true' ||
2008-02-26 12:02:59 -05:00
fixed . getAttribute ( 'hidden' ) != 'true' ||
position . getAttribute ( 'hidden' ) != 'true' ) {
2007-11-14 14:34:36 -05:00
sep . removeAttribute ( 'hidden' ) ;
}
else {
sep . setAttribute ( 'hidden' , true ) ;
}
} ,
2007-11-17 07:50:36 -05:00
initAllTabsPopup : function ( aEvent )
2007-11-17 00:20:26 -05:00
{
2007-11-17 01:05:23 -05:00
if ( ! this . getTreePref ( 'enableSubtreeIndent.allTabsPopup' ) ) return ;
2007-11-17 00:20:26 -05:00
var items = aEvent . target . childNodes ;
var tabs = this . mTabBrowser . mTabContainer . childNodes ;
for ( var i = 0 , maxi = items . length ; i < maxi ; i ++ )
{
items [ i ] . style . paddingLeft = tabs [ i ] . getAttribute ( this . kNEST ) + 'em' ;
}
} ,
/* drag and drop */
2008-02-22 02:44:06 -05:00
isPlatformNotSupported : navigator . platform . indexOf ( 'Mac' ) != - 1 , // see bug 136524
2007-11-17 12:21:33 -05:00
isTimerSupported : navigator . platform . indexOf ( 'Win' ) == - 1 , // see bug 232795.
autoExpandTimer : null ,
autoExpandTarget : null ,
2007-11-17 12:52:51 -05:00
autoExpandedTabs : [ ] ,
2007-11-17 00:20:26 -05:00
2008-02-22 02:44:06 -05:00
onDragEnter : function ( aEvent , aDragSession )
2007-11-17 12:21:33 -05:00
{
var tab = aEvent . target ;
2007-11-17 12:55:46 -05:00
if ( tab . localName != 'tab' ||
! this . getTreePref ( 'autoExpand.enabled' ) )
return ;
2007-11-17 12:21:33 -05:00
var now = ( new Date ( ) ) . getTime ( ) ;
if ( this . isPlatformNotSupported ) return ;
if ( this . isTimerSupported || ! aDragSession . sourceNode ) {
window . clearTimeout ( this . autoExpandTimer ) ;
if ( aEvent . target == aDragSession . sourceNode ) return ;
2007-11-17 12:52:51 -05:00
this . autoExpandTimer = window . setTimeout (
function ( aSelf , aTarget ) {
var tab = aSelf . getTabById ( aTarget ) ;
if ( tab &&
tab . getAttribute ( aSelf . kSUBTREE _COLLAPSED ) == 'true' &&
tab . getAttribute ( aSelf . kDROP _POSITION ) == 'self' ) {
2007-11-17 12:55:46 -05:00
if ( aSelf . getTreePref ( 'autoExpand.intelligently' ) ) {
2007-11-17 12:52:51 -05:00
aSelf . collapseExpandTreesIntelligentlyFor ( tab ) ;
}
else {
aSelf . autoExpandedTabs . push ( aTarget ) ;
aSelf . collapseExpandSubtree ( tab , false ) ;
}
}
} ,
this . getTreePref ( 'autoExpand.delay' ) ,
this ,
tab . getAttribute ( this . kID )
) ;
2007-11-17 12:21:33 -05:00
}
else {
this . autoExpandTimer = now ;
this . autoExpandTarget = tab . getAttribute ( this . kID ) ;
}
} ,
onDragExit : function ( aEvent , aDragSession )
{
var now = ( new Date ( ) ) . getTime ( ) ;
if ( this . isPlatformNotSupported ) return ;
if ( this . isTimerSupported || ! aDragSession . sourceNode ) {
window . clearTimeout ( this . autoExpandTimer ) ;
this . autoExpandTimer = null ;
}
else {
this . autoExpandTimer = null ;
this . autoExpandTarget = null ;
}
} ,
onDragOver : function ( aEvent , aFlavour , aDragSession )
{
if ( this . isPlatformNotSupported ) return ;
if ( this . isTimerSupported || ! aDragSession . sourceNode ) return ;
var now = ( new Date ( ) ) . getTime ( ) ;
2007-11-17 12:52:51 -05:00
var delay = this . getTreePref ( 'autoExpand.delay' ) ;
2007-11-17 12:21:33 -05:00
if ( this . autoExpandTimer && ( now - delay > this . autoExpandTimer ) ) {
var tab = this . getTabById ( this . autoExpandTarget ) ;
2007-11-17 12:52:51 -05:00
if ( tab &&
tab . getAttribute ( this . kSUBTREE _COLLAPSED ) == 'true' &&
tab . getAttribute ( this . kDROP _POSITION ) == 'self' ) {
2007-11-17 12:55:46 -05:00
if ( this . getTreePref ( 'autoExpand.intelligently' ) ) {
2007-11-17 12:52:51 -05:00
this . collapseExpandTreesIntelligentlyFor ( tab ) ;
}
else {
this . autoExpandedTabs . push ( this . autoExpandTarget ) ;
this . collapseExpandSubtree ( tab , false ) ;
}
}
2007-11-17 12:21:33 -05:00
this . autoExpandTimer = null ;
this . autoExpandTarget = null ;
}
} ,
2007-11-17 12:52:51 -05:00
onDrop : function ( aEvent , aXferData , aDragSession )
{
if ( ! this . autoExpandedTabs . length ) return ;
if ( this . getTreePref ( 'autoExpand.collapseFinally' ) ) {
var self = this ;
this . autoExpandedTabs . forEach ( function ( aTarget ) {
self . collapseExpandSubtree ( self . getTabById ( aTarget ) , true ) ;
} ) ;
}
this . autoExpandedTabs = [ ] ;
} ,
2007-11-23 10:43:40 -05:00
canDrop : function ( aEvent , aDragSession )
{
return this . getDropAction ( aEvent , aDragSession ) . canDrop ;
} ,
2007-11-17 12:21:33 -05:00
getSupportedFlavours : function ( )
{
var flavourSet = new FlavourSet ( ) ;
flavourSet . appendFlavour ( 'text/x-moz-url' ) ;
flavourSet . appendFlavour ( 'text/unicode' ) ;
flavourSet . appendFlavour ( 'application/x-moz-file' , 'nsIFile' ) ;
return flavourSet ;
} ,
2007-11-14 14:34:36 -05:00
getDropAction : function ( aEvent , aDragSession )
{
var info = this . getDropActionInternal ( aEvent ) ;
info . canDrop = true ;
2008-02-22 18:31:22 -05:00
if ( aDragSession &&
2007-11-14 14:34:36 -05:00
aDragSession . sourceNode &&
aDragSession . sourceNode . localName == 'tab' ) {
2008-02-24 03:11:17 -05:00
if (
'duplicateTab' in this . mTabBrowser &&
(
( navigator . platform . toLowerCase ( ) . indexOf ( 'mac' ) == 0 ? aEvent . metaKey : aEvent . ctrlKey ) ||
aDragSession . sourceNode . ownerDocument != document
)
) {
2008-02-22 18:31:22 -05:00
info . action = info . action | this . kACTION _DUPLICATE ;
2008-02-24 03:11:17 -05:00
if ( aDragSession . sourceNode . ownerDocument != document )
info . action = info . action | this . kACTION _MOVE _FROM _OTHER _WINDOW ;
}
2008-02-22 18:31:22 -05:00
if ( info . action & this . kACTION _ATTACH ) {
var orig = aDragSession . sourceNode ;
if ( orig == info . parent ) {
2007-11-14 14:34:36 -05:00
info . canDrop = false ;
2008-02-22 18:31:22 -05:00
}
else {
var tab = info . target ;
while ( tab = this . getParentTab ( tab ) )
{
if ( tab != orig ) continue ;
info . canDrop = false ;
break ;
}
2007-11-14 14:34:36 -05:00
}
}
}
return info ;
} ,
2007-11-17 00:20:26 -05:00
2007-11-14 14:34:36 -05:00
getDropActionInternal : function ( aEvent )
{
var tab = aEvent . target ;
var b = this . mTabBrowser ;
var tabs = b . mTabContainer . childNodes ;
2007-11-14 14:43:54 -05:00
var isInverted = this . isVertical ? false : window . getComputedStyle ( b . parentNode , null ) . direction == 'rtl' ;
2007-11-14 14:34:36 -05:00
var info = {
target : null ,
position : null ,
action : null ,
parent : null ,
insertBefore : null
} ;
if ( tab . localName != 'tab' ) {
if ( aEvent [ this . positionProp ] < tabs [ 0 ] . boxObject [ this . positionProp ] ) {
info . target = info . parent = info . insertBefore = tabs [ 0 ] ;
info . position = isInverted ? this . kDROP _AFTER : this . kDROP _BEFORE ;
info . action = this . kACTION _MOVE | this . kACTION _PART ;
return info ;
}
else if ( aEvent [ this . positionProp ] > tabs [ tabs . length - 1 ] . boxObject [ this . positionProp ] + tabs [ tabs . length - 1 ] . boxObject [ this . sizeProp ] ) {
info . target = info . parent = tabs [ tabs . length - 1 ] ;
info . position = isInverted ? this . kDROP _BEFORE : this . kDROP _AFTER ;
info . action = this . kACTION _MOVE | this . kACTION _PART ;
return info ;
}
else {
info . target = tabs [ Math . min ( b . getNewIndex ( aEvent ) , tabs . length - 1 ) ] ;
}
}
else {
info . target = tab ;
}
var boxPos = tab . boxObject [ this . positionProp ] ;
var boxUnit = Math . round ( tab . boxObject [ this . sizeProp ] / 3 ) ;
if ( aEvent [ this . positionProp ] < boxPos + boxUnit ) {
info . position = isInverted ? this . kDROP _AFTER : this . kDROP _BEFORE ;
}
else if ( aEvent [ this . positionProp ] > boxPos + boxUnit + boxUnit ) {
info . position = isInverted ? this . kDROP _BEFORE : this . kDROP _AFTER ;
}
else {
info . position = this . kDROP _ON ;
}
switch ( info . position )
{
case this . kDROP _ON :
info . action = this . kACTION _ATTACH ;
info . parent = tab ;
info . insertBefore = this . getNextVisibleTab ( tab ) ;
break ;
case this . kDROP _BEFORE :
/ *
[ TARGET ] <EFBFBD> <EFBFBD> part from parent , and move
[ ]
[ TARGET ] <EFBFBD> <EFBFBD> attach to the parent of the target , and move
[ ]
[ TARGET ] <EFBFBD> <EFBFBD> attach to the parent of the target , and move
[ ]
[ TARGET ] <EFBFBD> <EFBFBD> attach to the parent of the target ( previous tab ) , and move
* /
var prevTab = this . getPreviousVisibleTab ( tab ) ;
if ( ! prevTab ) {
info . action = this . kACTION _MOVE | this . kACTION _PART ;
info . insertBefore = tabs [ 0 ] ;
}
else {
2007-11-26 17:43:50 -05:00
var prevLevel = Number ( prevTab . getAttribute ( this . kNEST ) ) ;
2007-11-14 14:34:36 -05:00
var targetNest = Number ( tab . getAttribute ( this . kNEST ) ) ;
2007-11-26 17:43:50 -05:00
info . parent = ( prevLevel < targetNest ) ? prevTab : this . getParentTab ( tab ) ;
2007-11-14 14:34:36 -05:00
info . action = this . kACTION _MOVE | ( info . parent ? this . kACTION _ATTACH : this . kACTION _PART ) ;
info . insertBefore = tab ;
}
break ;
case this . kDROP _AFTER :
/ *
[ TARGET ] <EFBFBD> <EFBFBD> if the target has a parent , attach to it and and move
[ TARGET ] <EFBFBD> <EFBFBD> attach to the parent of the target , and move
[ ]
[ TARGET ] <EFBFBD> <EFBFBD> attach to the parent of the target , and move
[ ]
[ TARGET ] <EFBFBD> <EFBFBD> attach to the target , and move
[ ]
* /
var nextTab = this . getNextVisibleTab ( tab ) ;
if ( ! nextTab ) {
info . action = this . kACTION _MOVE | this . kACTION _ATTACH ;
info . parent = this . getParentTab ( tab ) ;
}
else {
var targetNest = Number ( tab . getAttribute ( this . kNEST ) ) ;
2007-11-26 17:43:50 -05:00
var nextLevel = Number ( nextTab . getAttribute ( this . kNEST ) ) ;
info . parent = ( targetNest < nextLevel ) ? tab : this . getParentTab ( tab ) ;
2007-11-14 14:34:36 -05:00
info . action = this . kACTION _MOVE | ( info . parent ? this . kACTION _ATTACH : this . kACTION _PART ) ;
info . insertBefore = nextTab ;
}
break ;
}
return info ;
} ,
2008-02-22 18:31:22 -05:00
processDropAction : function ( aInfo , aDraggedTab )
2007-11-14 14:34:36 -05:00
{
var b = this . mTabBrowser ;
var tabs = b . mTabContainer . childNodes ;
2008-02-22 18:31:22 -05:00
var self = this ;
var draggedTabs = [ aDraggedTab ] ;
2008-02-22 20:42:42 -05:00
var draggedRoots = [ aDraggedTab ] ;
2008-02-22 18:31:22 -05:00
2008-02-24 03:34:45 -05:00
var ownerWindow = aInfo . action & this . kACTION _MOVE _FROM _OTHER _WINDOW ? aDraggedTab . ownerDocument . defaultView : window ;
var ownerBrowser = ownerWindow ? ownerWindow . TreeStyleTabService . getTabBrowserFromChild ( aDraggedTab ) : this . mTabBrowser ;
2008-02-24 04:39:11 -05:00
var moveSelection = (
'MultipleTabService' in ownerWindow &&
ownerWindow . MultipleTabService . isSelected ( aDraggedTab ) &&
MultipleTabService . allowMoveMultipleTabs
) ;
2008-02-24 04:46:17 -05:00
if ( moveSelection ) {
draggedTabs = ownerWindow . MultipleTabService . getSelectedTabs ( ownerBrowser ) ;
if ( ! ( aInfo . action & this . kACTION _DUPLICATE ) ) {
draggedRoots = [ ] ;
draggedTabs . forEach ( function ( aTab ) {
var parent = aTab ,
current ;
do {
current = parent ;
parent = ownerBrowser . treeStyleTab . getParentTab ( parent )
if ( parent && ownerWindow . MultipleTabService . isSelected ( parent ) ) continue ;
draggedRoots . push ( current ) ;
return ;
}
while ( parent ) ;
} ) ;
2008-02-22 20:42:42 -05:00
}
}
2008-02-24 04:46:17 -05:00
else if ( ownerWindow != window ) {
draggedTabs = draggedTabs . concat ( ownerBrowser . treeStyleTab . getDescendantTabs ( aDraggedTab ) ) ;
}
2008-02-22 18:31:22 -05:00
if ( aDraggedTab && aInfo . action & this . kACTION _PART ) {
2008-02-22 19:41:15 -05:00
if ( ! ( aInfo . action & this . kACTION _DUPLICATE ) )
2008-02-22 20:42:42 -05:00
this . partTabsOnDrop ( draggedRoots ) ;
2007-11-14 14:34:36 -05:00
}
else if ( aInfo . action & this . kACTION _ATTACH ) {
2008-02-22 19:41:15 -05:00
if ( ! ( aInfo . action & this . kACTION _DUPLICATE ) )
2008-02-22 20:42:42 -05:00
this . attachTabsOnDrop ( draggedRoots , aInfo . parent ) ;
2007-11-14 14:34:36 -05:00
}
else {
return false ;
}
2008-02-22 19:41:15 -05:00
var newSelection = [ ] ;
2007-11-14 14:34:36 -05:00
if (
2008-02-22 19:41:15 -05:00
(
aInfo . action & this . kACTION _MOVE ||
aInfo . action & this . kACTION _DUPLICATE
) &&
2007-11-14 14:34:36 -05:00
(
! aInfo . insertBefore ||
2008-02-24 03:34:45 -05:00
ownerBrowser . treeStyleTab . getNextVisibleTab ( draggedTabs [ 0 ] ) != aInfo . insertBefore
2007-11-14 14:34:36 -05:00
)
) {
2008-02-24 02:58:12 -05:00
b . duplicatingSelectedTabs = aInfo . action & self . kACTION _DUPLICATE ? true : false ; // Multiple Tab Handler
2008-02-22 19:41:15 -05:00
b . movingSelectedTabs = true ; // Multiple Tab Handler
2008-02-22 18:31:22 -05:00
var tab , newIndex ;
2008-02-22 19:41:15 -05:00
var newRoots = [ ] ;
2008-02-24 03:11:17 -05:00
var windowShouldBeClosed = (
2008-02-24 03:34:45 -05:00
ownerWindow != window &&
ownerBrowser . mTabContainer . childNodes . length == draggedTabs . length
2008-02-24 03:11:17 -05:00
) ;
2008-02-23 04:09:48 -05:00
draggedTabs . forEach ( function ( aTab ) {
2008-02-24 03:11:17 -05:00
var tab = aTab ;
2008-02-23 04:09:48 -05:00
if ( aInfo . action & self . kACTION _DUPLICATE ) {
2008-02-24 03:34:45 -05:00
var parent = ownerBrowser . treeStyleTab . getParentTab ( tab ) ;
2008-02-24 04:39:11 -05:00
if ( moveSelection )
2008-02-24 03:34:45 -05:00
ownerWindow . MultipleTabService . setSelection ( tab , false ) ;
2008-02-24 03:11:17 -05:00
tab = b . duplicateTab ( tab ) ;
2008-02-24 04:39:11 -05:00
if ( moveSelection )
2008-02-24 03:11:17 -05:00
MultipleTabService . setSelection ( tab , true ) ;
2008-02-23 20:06:19 -05:00
if ( ! parent || draggedTabs . indexOf ( parent ) < 0 )
2008-02-24 03:11:17 -05:00
newRoots . push ( tab ) ;
2008-02-22 19:41:15 -05:00
}
2008-02-22 18:31:22 -05:00
newIndex = aInfo . insertBefore ? aInfo . insertBefore . _tPos : tabs . length - 1 ;
2008-02-24 03:11:17 -05:00
if ( aInfo . insertBefore && newIndex > tab . _tPos ) newIndex -- ;
2008-02-22 18:31:22 -05:00
2008-02-23 04:09:48 -05:00
self . internallyTabMoving = true ;
2008-02-24 03:11:17 -05:00
b . moveTabTo ( tab , newIndex ) ;
self . collapseExpandTab ( tab , false ) ;
2008-02-23 04:09:48 -05:00
self . internallyTabMoving = false ;
2008-02-24 03:11:17 -05:00
2008-02-23 04:09:48 -05:00
} ) ;
2008-02-22 19:41:15 -05:00
2008-02-24 05:01:10 -05:00
if ( ownerWindow != window ) {
draggedTabs . forEach ( function ( aTab ) {
ownerBrowser . removeTab ( aTab ) ;
} ) ;
}
2008-02-22 19:41:15 -05:00
if ( aInfo . action & this . kACTION _DUPLICATE &&
aInfo . action & this . kACTION _ATTACH )
this . attachTabsOnDrop ( newRoots , aInfo . parent ) ;
2008-02-24 03:11:17 -05:00
if ( windowShouldBeClosed )
2008-02-24 03:34:45 -05:00
ownerWindow . close ( ) ;
2008-02-24 03:11:17 -05:00
2008-02-22 19:41:15 -05:00
b . movingSelectedTabs = false ; // Multiple Tab Handler
2008-02-24 02:58:12 -05:00
b . duplicatingSelectedTabs = false ; // Multiple Tab Handler
2007-11-14 14:34:36 -05:00
}
2008-02-22 19:41:15 -05:00
2007-11-14 14:34:36 -05:00
return true ;
} ,
2008-02-22 19:41:15 -05:00
attachTabsOnDrop : function ( aTabs , aParent )
{
this . mTabBrowser . movingSelectedTabs = true ; // Multiple Tab Handler
var self = this ;
aTabs . forEach ( function ( aTab ) {
if ( aParent )
self . attachTabTo ( aTab , aParent ) ;
else
self . partTab ( aTab ) ;
self . collapseExpandTab ( aTab , false ) ;
} ) ;
this . mTabBrowser . movingSelectedTabs = false ; // Multiple Tab Handler
} ,
partTabsOnDrop : function ( aTabs )
{
this . mTabBrowser . movingSelectedTabs = true ; // Multiple Tab Handler
var self = this ;
aTabs . forEach ( function ( aTab ) {
self . partTab ( aTab ) ;
self . collapseExpandTab ( aTab , false ) ;
} ) ;
this . mTabBrowser . movingSelectedTabs = false ; // Multiple Tab Handler
} ,
2007-11-14 14:34:36 -05:00
clearDropPosition : function ( )
{
var b = this . mTabBrowser ;
var xpathResult = this . evaluateXPath (
'child::xul:tab[@' + this . kDROP _POSITION + ']' ,
b . mTabContainer
) ;
for ( var i = 0 , maxi = xpathResult . snapshotLength ; i < maxi ; i ++ )
{
xpathResult . snapshotItem ( i ) . removeAttribute ( this . kDROP _POSITION ) ;
}
} ,
2007-11-17 00:20:26 -05:00
/* commands */
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
/* attach/part */
attachTabTo : function ( aChild , aParent , aInfo )
2007-11-14 14:34:36 -05:00
{
2007-11-17 00:20:26 -05:00
if (
! aChild ||
! aParent ||
aChild == aParent ||
this . getParentTab ( aChild ) == aParent
2008-02-28 02:45:39 -05:00
) {
this . attachTabPostProcess ( 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
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 ) ;
if ( ! id || ! aParent . getAttribute ( this . kID ) )
return ; // if the tab is not initialized yet, do nothing.
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
this . partTab ( aChild , true ) ;
var children = aParent . getAttribute ( this . kCHILDREN ) ;
var newIndex ;
if ( children . indexOf ( id ) > - 1 ) {
children = ( '|' + children ) . replace ( '|' + id , '' ) . replace ( /^\|/ ) ;
}
var insertBefore = aInfo . insertBefore ;
var beforeTab = insertBefore ? insertBefore . getAttribute ( this . kID ) : null ;
if ( beforeTab && children . indexOf ( beforeTab ) > - 1 ) {
children = children . replace ( beforeTab , id + '|' + beforeTab ) ;
newIndex = insertBefore . _tPos ;
}
else {
children = ( ( children || '' ) + '|' + id ) . replace ( /^\|/ , '' ) ;
var refTab = aParent ;
var descendant = this . getDescendantTabs ( aParent ) ;
if ( descendant . length ) refTab = descendant [ descendant . length - 1 ] ;
newIndex = refTab . _tPos + 1 ;
}
this . setTabValue ( aParent , this . kCHILDREN , children ) ;
this . setTabValue ( aChild , this . kPARENT , aParent . getAttribute ( this . kID ) ) ;
this . updateTabsCount ( aParent ) ;
if ( newIndex > aChild . _tPos ) newIndex -- ;
this . moveTabSubTreeTo ( aChild , newIndex ) ;
if ( ! aInfo . dontExpand ) {
if (
/ *
(
aParent . getAttribute ( this . kSUBTREE _COLLAPSED ) == 'true' ||
children . indexOf ( '|' ) > - 1 // not a first child
) &&
* /
this . getTreePref ( 'autoCollapseExpandSubTreeOnSelect' )
) {
this . collapseExpandTreesIntelligentlyFor ( aParent ) ;
var p = aParent ;
do {
this . collapseExpandSubtree ( p , false ) ;
}
while ( p = this . getParentTab ( p ) ) ;
}
else if ( aParent . getAttribute ( this . kSUBTREE _COLLAPSED ) == 'true' ) {
if ( this . getTreePref ( 'autoExpandSubTreeOnAppendChild' ) ) {
var p = aParent ;
do {
this . collapseExpandSubtree ( p , false ) ;
}
while ( p = this . getParentTab ( p ) ) ;
}
else
this . collapseExpandTab ( aChild , true ) ;
}
if ( aParent . getAttribute ( this . kCOLLAPSED ) == 'true' )
this . collapseExpandTab ( aChild , true ) ;
}
else if ( aParent . getAttribute ( this . kSUBTREE _COLLAPSED ) == 'true' ||
aParent . getAttribute ( this . kCOLLAPSED ) == 'true' ) {
this . collapseExpandTab ( aChild , true ) ;
}
if ( ! aInfo . dontUpdateIndent ) {
this . updateTabsIndent ( [ aChild ] ) ;
this . checkTabsIndentOverflow ( ) ;
}
2008-02-28 02:45:39 -05:00
this . attachTabPostProcess ( aChild , aParent ) ;
} ,
attachTabPostProcess : function ( aChild , aParent )
{
var self = this ;
this . _attachTabPostProcesses . forEach ( function ( aProcess ) {
aProcess ( aChild , aParent , self ) ;
} ) ;
2007-11-14 14:34:36 -05:00
} ,
2007-11-17 00:20:26 -05:00
partTab : function ( aChild , aDontUpdateIndent )
2007-11-14 14:34:36 -05:00
{
2007-11-17 00:20:26 -05:00
if ( ! aChild ) return ;
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 ) ;
var children = ( '|' + parentTab . getAttribute ( this . kCHILDREN ) )
. replace ( new RegExp ( '\\|' + id ) , '' )
. replace ( /^\|/ , '' ) ;
this . setTabValue ( parentTab , this . kCHILDREN , children ) ;
2007-11-26 16:17:46 -05:00
this . deleteTabValue ( aChild , this . kPARENT ) ;
2007-11-17 00:20:26 -05:00
this . updateTabsCount ( parentTab ) ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
if ( ! aDontUpdateIndent ) {
this . updateTabsIndent ( [ aChild ] ) ;
this . checkTabsIndentOverflow ( ) ;
}
2008-02-28 02:45:39 -05:00
this . attachTabPostProcess ( aChild , null ) ;
2007-11-14 14:34:36 -05:00
} ,
2007-11-17 00:20:26 -05:00
updateTabsIndent : function ( aTabs , aLevel , aProp )
2007-11-14 14:34:36 -05:00
{
2007-11-17 00:20:26 -05:00
if ( ! aTabs || ! aTabs . length ) return ;
if ( aLevel === void ( 0 ) ) {
var parentTab = this . getParentTab ( aTabs [ 0 ] ) ;
var aLevel = 0 ;
while ( parentTab )
2007-11-14 14:34:36 -05:00
{
2007-11-17 00:20:26 -05:00
aLevel ++ ;
parentTab = this . getParentTab ( parentTab ) ;
2007-11-14 14:34:36 -05:00
}
}
2007-11-17 00:20:26 -05:00
var b = this . mTabBrowser ;
if ( ! aProp ) {
aProp = this . getTreePref ( 'enableSubtreeIndent' ) ? this . levelMarginProp : 0 ;
}
var margin = this . levelMargin < 0 ? this . baseLebelMargin : this . levelMargin ;
var indent = margin * aLevel ;
2008-02-22 02:44:06 -05:00
var multirow = this . isMultiRow ( ) ;
var topBottom = this . levelMarginProp . match ( /top|bottom/ ) ;
2008-02-22 03:50:18 -05:00
var innerBoxes ,
j ,
colors ,
maxIndent = parseInt ( aTabs [ 0 ] . boxObject . height / 2 ) ;
2008-02-22 02:44:06 -05:00
2007-11-17 00:20:26 -05:00
for ( var i = 0 , maxi = aTabs . length ; i < maxi ; i ++ )
{
2008-02-22 02:44:06 -05:00
if ( multirow ) {
2008-02-22 03:50:18 -05:00
indent = Math . min ( aLevel * 3 , maxIndent ) ;
2008-02-22 02:44:06 -05:00
innerBoxes = document . getAnonymousNodes ( aTabs [ i ] ) ;
2008-02-22 03:50:18 -05:00
colors = '-moz-border-top-colors:' + ( function ( aNum ) {
var retVal = [ ] ;
for ( var i = 1 ; i < aNum ; i ++ )
{
retVal . push ( 'transparent' ) ;
}
retVal . push ( 'ThreeDShadow' ) ;
return retVal . length == 1 ? 'none' : retVal . join ( ' ' ) ;
} ) ( indent ) + ' !important;' ;
2008-02-22 02:44:06 -05:00
for ( j = 0 , maxj = innerBoxes . length ; j < maxj ; j ++ )
{
if ( innerBoxes [ j ] . nodeType != Node . ELEMENT _NODE ) continue ;
2008-02-22 03:50:18 -05:00
innerBoxes [ j ] . setAttribute ( 'style' , innerBoxes [ j ] . getAttribute ( 'style' ) . replace ( /(-moz-)?border-(top|bottom)(-[^:]*)?.*:[^;]+;?/g , '' ) + '; border-' + topBottom + ': solid transparent ' + indent + 'px !important;' + colors ) ;
2008-02-22 02:44:06 -05:00
}
}
else {
aTabs [ i ] . setAttribute ( 'style' , aTabs [ i ] . getAttribute ( 'style' ) . replace ( /margin(-[^:]+):[^;]+;?/g , '' ) + '; ' + aProp + ':' + indent + 'px !important;' ) ;
}
2007-11-17 00:20:26 -05:00
aTabs [ i ] . setAttribute ( this . kNEST , aLevel ) ;
this . updateTabsIndent ( this . getChildTabs ( aTabs [ i ] ) , aLevel + 1 , aProp ) ;
}
2007-11-14 14:34:36 -05:00
} ,
2007-11-17 00:20:26 -05:00
updateAllTabsIndent : function ( )
2007-11-14 14:34:36 -05:00
{
2007-11-17 00:20:26 -05:00
this . updateTabsIndent ( this . rootTabs , 0 ) ;
// this.checkTabsIndentOverflow();
2007-11-14 14:34:36 -05:00
} ,
2007-11-17 00:20:26 -05:00
checkTabsIndentOverflow : function ( )
2007-11-14 14:34:36 -05:00
{
2007-11-17 00:20:26 -05:00
if ( this . checkTabsIndentOverflowTimer ) {
window . clearTimeout ( this . checkTabsIndentOverflowTimer ) ;
this . checkTabsIndentOverflowTimer = null ;
2007-11-14 14:34:36 -05:00
}
2007-11-17 00:20:26 -05:00
this . checkTabsIndentOverflowTimer = window . setTimeout ( function ( aSelf ) {
aSelf . checkTabsIndentOverflowCallback ( ) ;
} , 100 , this ) ;
2007-11-14 14:34:36 -05:00
} ,
2007-11-17 00:20:26 -05:00
checkTabsIndentOverflowTimer : null ,
checkTabsIndentOverflowCallback : function ( )
2007-11-14 14:34:36 -05:00
{
2007-11-17 00:20:26 -05:00
var b = this . mTabBrowser ;
var tabs = this . getArrayFromXPathResult ( this . evaluateXPath (
'child::xul:tab[@' + this . kNEST + ' and not(@' + this . kNEST + '="0" or @' + this . kNEST + '="")]' ,
b . mTabContainer
) ) ;
if ( ! tabs . length ) return ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
var self = this ;
tabs . sort ( function ( aA , aB ) { return Number ( aA . getAttribute ( self . kNEST ) ) - Number ( aB . getAttribute ( self . kNEST ) ) ; } ) ;
var nest = tabs [ tabs . length - 1 ] . getAttribute ( self . kNEST ) ;
if ( ! nest ) return ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
var oldMargin = this . levelMargin ;
var indent = ( oldMargin < 0 ? this . baseLebelMargin : oldMargin ) * nest ;
2007-11-23 15:45:38 -05:00
var maxIndent = (
b . mTabContainer . childNodes [ 0 ] . boxObject [ this . invertedSizeProp ] ||
b . mTabContainer . boxObject [ this . invertedSizeProp ]
) * 0.33 ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
var marginUnit = Math . max ( Math . floor ( maxIndent / nest ) , 1 ) ;
if ( indent > maxIndent ) {
this . levelMargin = marginUnit ;
}
else {
this . levelMargin = - 1 ;
if ( ( this . baseLebelMargin * nest ) > maxIndent )
this . levelMargin = marginUnit ;
}
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
if ( oldMargin != this . levelMargin ) {
this . updateAllTabsIndent ( ) ;
}
} ,
updateTabsCount : function ( aTab , aDontUpdateAncestor )
{
var count = document . getAnonymousElementByAttribute ( aTab , 'class' , this . kCOUNTER ) ;
if ( count ) {
count . setAttribute ( 'value' , '(' + this . getDescendantTabs ( aTab ) . length + ')' ) ;
}
var parent = this . getParentTab ( aTab ) ;
if ( parent && ! aDontUpdateAncestor )
this . updateTabsCount ( parent ) ;
} ,
/* move */
moveTabSubTreeTo : function ( aTab , aIndex )
{
if ( ! aTab ) return ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
var b = this . mTabBrowser ;
this . isSubTreeMoving = true ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
this . internallyTabMoving = true ;
b . moveTabTo ( aTab , aIndex ) ;
this . internallyTabMoving = false ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
this . isSubTreeChildrenMoving = true ;
this . internallyTabMoving = true ;
var tabs = this . getDescendantTabs ( aTab ) ;
2007-11-14 14:34:36 -05:00
for ( var i = 0 , maxi = tabs . length ; i < maxi ; i ++ )
{
2007-11-17 00:20:26 -05:00
b . moveTabTo ( tabs [ i ] , aTab . _tPos + i + ( aTab . _tPos < tabs [ i ] . _tPos ? 1 : 0 ) ) ;
2007-11-14 14:34:36 -05:00
}
2007-11-17 00:20:26 -05:00
this . internallyTabMoving = false ;
this . isSubTreeChildrenMoving = false ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
this . isSubTreeMoving = false ;
} ,
moveTabLevel : function ( aEvent )
{
var b = this . mTabBrowser ;
var parentTab = this . getParentTab ( b . mCurrentTab ) ;
if ( aEvent . keyCode == KeyEvent . DOM _VK _RIGHT ) {
var prevTab = this . getPreviousSiblingTab ( b . mCurrentTab ) ;
if ( ( ! parentTab && prevTab ) ||
( parentTab && b . mCurrentTab != this . getFirstChildTab ( parentTab ) ) ) {
this . attachTabTo ( b . mCurrentTab , prevTab ) ;
b . mCurrentTab . focus ( ) ;
return true ;
}
}
else if ( aEvent . keyCode == KeyEvent . DOM _VK _LEFT && parentTab ) {
var grandParent = this . getParentTab ( parentTab ) ;
if ( grandParent ) {
this . attachTabTo ( b . mCurrentTab , grandParent , {
insertBefore : this . getNextSiblingTab ( parentTab )
} ) ;
b . mCurrentTab . focus ( ) ;
return true ;
}
else {
var nextTab = this . getNextSiblingTab ( parentTab ) ;
this . partTab ( b . mCurrentTab ) ;
this . internallyTabMoving = true ;
if ( nextTab ) {
b . moveTabTo ( b . mCurrentTab , nextTab . _tPos - 1 ) ;
}
else {
b . moveTabTo ( b . mCurrentTab , b . mTabContainer . lastChild . _tPos ) ;
}
this . internallyTabMoving = false ;
b . mCurrentTab . focus ( ) ;
return true ;
}
}
return false ;
} ,
/* collapse/expand */
collapseExpandSubtree : function ( aTab , aCollapse )
{
if ( ! aTab ) return ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
if ( ( aTab . getAttribute ( this . kSUBTREE _COLLAPSED ) == 'true' ) == 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
2007-11-17 00:20:26 -05:00
var tabs = this . getChildTabs ( aTab ) ;
for ( var i = 0 , maxi = tabs . length ; i < maxi ; i ++ )
{
this . collapseExpandTab ( tabs [ i ] , aCollapse ) ;
2007-11-14 14:34:36 -05:00
}
2007-11-17 00:20:26 -05:00
if ( ! aCollapse )
this . scrollToTabSubTree ( aTab ) ;
this . doingCollapseExpand = false ;
2007-11-14 14:34:36 -05:00
} ,
2007-11-17 00:20:26 -05:00
collapseExpandTab : function ( aTab , aCollapse )
2007-11-14 14:34:36 -05:00
{
2007-11-23 15:45:38 -05:00
if ( ! aTab || ! 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 ) ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
var b = this . mTabBrowser ;
var p ;
if ( aCollapse && aTab == b . selectedTab && ( p = this . getParentTab ( aTab ) ) ) {
b . selectedTab = p ;
2007-11-14 14:34:36 -05:00
}
2007-11-17 00:20:26 -05:00
var isSubTreeCollapsed = ( aTab . getAttribute ( this . kSUBTREE _COLLAPSED ) == 'true' ) ;
var tabs = this . getChildTabs ( aTab ) ;
for ( var i = 0 , maxi = tabs . length ; i < maxi ; i ++ )
{
if ( ! isSubTreeCollapsed )
this . collapseExpandTab ( tabs [ i ] , aCollapse ) ;
2007-11-14 14:34:36 -05:00
}
} ,
2007-11-17 00:20:26 -05:00
collapseExpandTreesIntelligentlyFor : function ( aTab )
2007-11-14 14:34:36 -05:00
{
2007-11-17 00:20:26 -05:00
var b = this . mTabBrowser ;
if ( this . doingCollapseExpand ) return ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
var sameParentTab = this . getParentTab ( aTab ) ;
var expandedParentTabs = [
aTab . getAttribute ( this . kID )
] ;
var parentTab = aTab ;
while ( parentTab = this . getParentTab ( parentTab ) )
{
expandedParentTabs . push ( parentTab . getAttribute ( this . kID ) ) ;
2007-11-14 14:34:36 -05:00
}
2007-11-17 00:20:26 -05:00
expandedParentTabs = expandedParentTabs . join ( '|' ) ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
var xpathResult = this . evaluateXPath (
'child::xul:tab[@' + this . kCHILDREN + ' and not(@' + this . kCOLLAPSED + '="true") and not(@' + this . kSUBTREE _COLLAPSED + '="true") and @' + this . kID + ' and not(contains("' + expandedParentTabs + '", @' + this . kID + '))]' ,
b . mTabContainer
) ;
var collapseTab ;
var dontCollapse ;
for ( var i = 0 , maxi = xpathResult . snapshotLength ; i < maxi ; i ++ )
{
dontCollapse = false ;
collapseTab = xpathResult . snapshotItem ( i ) ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
parentTab = this . getParentTab ( collapseTab ) ;
if ( parentTab ) {
dontCollapse = true ;
if ( parentTab . getAttribute ( this . kSUBTREE _COLLAPSED ) != 'true' ) {
do {
if ( expandedParentTabs . indexOf ( parentTab . getAttribute ( this . kID ) ) < 0 )
continue ;
dontCollapse = false ;
break ;
}
while ( parentTab = this . getParentTab ( parentTab ) ) ;
}
2007-11-14 14:34:36 -05:00
}
2007-11-17 00:20:26 -05:00
if ( ! dontCollapse )
this . collapseExpandSubtree ( collapseTab , true ) ;
2007-11-14 14:34:36 -05:00
}
2007-11-17 00:20:26 -05:00
this . collapseExpandSubtree ( aTab , false ) ;
2007-11-14 14:34:36 -05:00
} ,
2007-11-17 00:20:26 -05:00
collapseExpandAllSubtree : function ( aCollapse )
2007-11-14 14:34:36 -05:00
{
2007-11-17 00:20:26 -05:00
var xpathResult = this . evaluateXPath (
'child::xul:tab[@' + this . kID + ' and @' + this . kCHILDREN +
(
aCollapse ?
' and not(@' + this . kSUBTREE _COLLAPSED + '="true")' :
' and @' + this . kSUBTREE _COLLAPSED + '="true"'
) +
']' ,
this . mTabBrowser . mTabContainer
) ;
for ( var i = 0 , maxi = xpathResult . snapshotLength ; i < maxi ; i ++ )
2007-11-14 14:34:36 -05:00
{
2007-11-17 00:20:26 -05:00
this . collapseExpandSubtree ( xpathResult . snapshotItem ( i ) , aCollapse ) ;
2007-11-14 14:34:36 -05:00
}
2007-11-17 00:20:26 -05:00
} ,
/* scroll */
scrollTo : function ( aEndX , aEndY )
{
if ( this . getTreePref ( 'tabbar.scroll.smooth' ) ) {
this . smoothScrollTo ( aEndX , aEndY ) ;
2007-11-14 14:34:36 -05:00
}
else {
2007-11-17 00:20:26 -05:00
try {
this . mTabBrowser . mTabstrip . scrollBoxObject . scrollTo ( aEndX , aEndY ) ;
}
catch ( e ) {
2007-11-14 14:34:36 -05:00
}
}
} ,
2007-11-17 00:20:26 -05:00
smoothScrollTo : function ( aEndX , aEndY )
2007-11-14 14:34:36 -05:00
{
var b = this . mTabBrowser ;
2007-11-17 00:20:26 -05:00
if ( this . smoothScrollTimer ) {
window . clearInterval ( this . smoothScrollTimer ) ;
this . smoothScrollTimer = null ;
2007-11-14 14:34:36 -05:00
}
2007-11-17 00:20:26 -05:00
var scrollBoxObject = b . mTabContainer . mTabstrip . scrollBoxObject ;
var x = { } , y = { } ;
scrollBoxObject . getPosition ( x , y ) ;
this . smoothScrollTimer = window . setInterval (
this . smoothScrollToCallback ,
10 ,
this ,
x . value ,
y . value ,
aEndX ,
aEndY ,
Date . now ( ) ,
this . getTreePref ( 'tabbar.scroll.timeout' )
) ;
} ,
smoothScrollToCallback : function ( aSelf , aStartX , aStartY , aEndX , aEndY , aStartTime , aTimeout )
{
var newX = aStartX + parseInt (
( aEndX - aStartX ) * ( ( Date . now ( ) - aStartTime ) / aTimeout )
) ;
var newY = aStartY + parseInt (
( aEndY - aStartY ) * ( ( Date . now ( ) - aStartTime ) / aTimeout )
) ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
var scrollBoxObject = aSelf . mTabBrowser . mTabContainer . mTabstrip . scrollBoxObject ;
var x = { } , y = { } ;
scrollBoxObject . getPosition ( x , y ) ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
var w = { } , h = { } ;
scrollBoxObject . getScrolledSize ( w , h ) ;
var maxX = Math . max ( 0 , w . value - scrollBoxObject . width ) ;
var maxY = Math . max ( 0 , h . value - scrollBoxObject . height ) ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
if (
(
aEndX - aStartX > 0 ?
x . value >= Math . min ( aEndX , maxX ) :
x . value <= Math . min ( aEndX , maxX )
) &&
(
aEndY - aStartY > 0 ?
y . value >= Math . min ( aEndY , maxY ) :
y . value <= Math . min ( aEndY , maxY )
)
) {
if ( aSelf . smoothScrollTimer ) {
window . clearInterval ( aSelf . smoothScrollTimer ) ;
aSelf . smoothScrollTimer = null ;
2007-11-14 14:34:36 -05:00
}
2007-11-17 00:20:26 -05:00
return ;
}
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
scrollBoxObject . scrollTo ( newX , newY ) ;
} ,
scrollToTab : function ( aTab )
{
if ( ! aTab || 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
2007-11-17 00:20:26 -05:00
var scrollBoxObject = b . mTabContainer . mTabstrip . scrollBoxObject ;
var w = { } , h = { } ;
try {
scrollBoxObject . getScrolledSize ( w , h ) ;
}
catch ( e ) { // Tab Mix Plus
return ;
2007-11-14 14:34:36 -05:00
}
2007-11-17 00:20:26 -05:00
var targetTabBox = aTab . boxObject ;
var baseTabBox = aTab . parentNode . firstChild . boxObject ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
var targetX = ( aTab . boxObject . screenX < scrollBoxObject . screenX ) ?
( targetTabBox . screenX - baseTabBox . screenX ) - ( targetTabBox . width * 0.5 ) :
( targetTabBox . screenX - baseTabBox . screenX ) - scrollBoxObject . width + ( targetTabBox . width * 1.5 ) ;
var targetY = ( aTab . boxObject . screenY < scrollBoxObject . screenY ) ?
( targetTabBox . screenY - baseTabBox . screenY ) - ( targetTabBox . height * 0.5 ) :
( targetTabBox . screenY - baseTabBox . screenY ) - scrollBoxObject . height + ( targetTabBox . height * 1.5 ) ;
this . scrollTo ( targetX , targetY ) ;
} ,
scrollToTabSubTree : function ( aTab )
{
var b = this . mTabBrowser ;
var descendant = this . getDescendantTabs ( aTab ) ;
var lastVisible = aTab ;
for ( var i = descendant . length - 1 ; i > - 1 ; i -- )
{
if ( descendant [ i ] . getAttribute ( this . kCOLLAPSED ) == 'true' ) continue ;
lastVisible = descendant [ i ] ;
break ;
}
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
var containerPosition = b . mStrip . boxObject [ this . positionProp ] ;
var containerSize = b . mStrip . boxObject [ this . sizeProp ] ;
var parentPosition = aTab . boxObject [ this . positionProp ] ;
var lastPosition = lastVisible . boxObject [ this . positionProp ] ;
var tabSize = lastVisible . boxObject [ this . sizeProp ] ;
2007-11-14 14:34:36 -05:00
2007-11-17 00:20:26 -05:00
if ( this . isTabInViewport ( aTab ) && this . isTabInViewport ( lastVisible ) ) {
return ;
}
if ( lastPosition - parentPosition + tabSize > containerSize - tabSize ) { // out of screen
var endPos = parentPosition - b . mTabContainer . firstChild . boxObject [ this . positionProp ] - tabSize * 0.5 ;
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
}
} ,
2007-11-17 00:20:26 -05:00
2008-03-09 01:36:52 -05:00
/* show/hide tab bar */
2007-11-17 00:20:26 -05:00
tabbarShown : true ,
2008-03-09 23:51:21 -04:00
2007-11-17 00:20:26 -05:00
get tabbarWidth ( )
2007-11-14 14:34:36 -05:00
{
2007-11-17 00:20:26 -05:00
if ( this . tabbarShown ) {
var b = this . mTabBrowser ;
var splitter = document . getAnonymousElementByAttribute ( b , 'class' , this . kSPLITTER ) ;
this . _tabbarWidth = b . mStrip . boxObject . width +
( splitter ? splitter . boxObject . width : 0 ) ;
}
return this . _tabbarWidth ;
} ,
set tabbarWidth ( aNewWidth )
{
this . _tabbarWidth = aNewWidth ;
return this . _tabbarWidth ;
} ,
_tabbarWidth : 0 ,
get tabbarHeight ( )
{
if ( this . tabbarShown ) {
var b = this . mTabBrowser ;
this . _tabbarHeight = b . mStrip . boxObject . height ;
}
return this . _tabbarHeight ;
} ,
set tabbarHeight ( aNewHeight )
{
this . _tabbarHeight = aNewHeight ;
return this . _tabbarHeight ;
} ,
_tabbarHeight : 0 ,
2008-03-08 03:57:17 -05:00
showHideTabbarInternal : function ( aReason )
2007-11-14 14:34:36 -05:00
{
2008-03-08 11:30:52 -05:00
fullScreenCanvas . show ( ) ;
2007-11-17 00:20:26 -05:00
var b = this . mTabBrowser ;
if ( this . tabbarShown ) {
var splitter = document . getAnonymousElementByAttribute ( b , 'class' , this . kSPLITTER ) ;
this . tabbarHeight = b . mStrip . boxObject . height ;
this . tabbarWidth = b . mStrip . boxObject . width +
( splitter ? splitter . boxObject . width : 0 ) ;
this . container . style . margin = 0 ;
2008-03-09 23:51:21 -04:00
b . setAttribute ( this . kAUTOHIDE , 'hidden' ) ;
2008-03-08 03:57:17 -05:00
this . showHideTabbarReason = aReason || this . kSHOWN _BY _UNKNOWN ;
2007-11-17 00:20:26 -05:00
this . tabbarShown = false ;
}
else {
switch ( b . getAttribute ( this . kTABBAR _POSITION ) )
{
case 'left' :
this . container . style . marginRight = '-' + this . tabbarWidth + 'px' ;
break ;
case 'right' :
this . container . style . marginLeft = '-' + this . tabbarWidth + 'px' ;
break ;
case 'bottom' :
this . container . style . marginTop = '-' + this . tabbarHeight + 'px' ;
break ;
default :
this . container . style . marginBottom = '-' + this . tabbarHeight + 'px' ;
break ;
}
2008-03-09 23:51:21 -04:00
if ( this . isGecko18 ) b . setAttribute ( this . kAUTOHIDE , 'show' ) ;
2008-03-08 03:57:17 -05:00
this . showHideTabbarReason = aReason || this . kSHOWN _BY _UNKNOWN ;
2007-11-17 00:20:26 -05:00
this . tabbarShown = true ;
}
this . redrawContentArea ( ) ;
2008-03-08 11:30:52 -05:00
window . setTimeout ( function ( aSelf ) {
2008-03-08 12:40:49 -05:00
if ( ! aSelf . isGecko18 && aSelf . tabbarShown ) {
2008-03-09 23:51:21 -04:00
b . setAttribute ( this . kAUTOHIDE , 'show' ) ;
2008-03-08 11:30:52 -05:00
aSelf . redrawContentArea ( ) ;
}
aSelf . checkTabsIndentOverflow ( ) ;
2008-03-08 05:44:19 -05:00
fullScreenCanvas . hide ( ) ;
2008-03-08 11:30:52 -05:00
} , 0 , this ) ;
2007-11-17 00:20:26 -05:00
} ,
2008-03-08 03:57:17 -05:00
showHideTabbarReason : 0 ,
2008-03-09 23:51:21 -04:00
2008-03-08 03:57:17 -05:00
showTabbar : function ( aReason )
{
if ( ! this . tabbarShown )
this . showHideTabbarInternal ( aReason ) ;
} ,
2008-03-08 05:07:28 -05:00
2008-03-08 03:57:17 -05:00
hideTabbar : function ( aReason )
{
if ( this . tabbarShown )
this . showHideTabbarInternal ( aReason ) ;
} ,
2007-11-17 00:20:26 -05:00
redrawContentArea : function ( )
{
var pos = this . mTabBrowser . getAttribute ( this . kTABBAR _POSITION ) ;
try {
var v = this . mTabBrowser . markupDocumentViewer ;
if ( this . tabbarShown ) {
v . move (
(
! this . tabbarShown ? 0 :
pos == 'left' ? - this . tabbarWidth :
pos == 'right' ? this . tabbarWidth :
0
) ,
(
! this . tabbarShown ? 0 :
pos == 'top' ? - this . tabbarHeight :
pos == 'bottom' ? this . tabbarHeight :
0
)
) ;
2008-03-10 00:11:44 -04:00
if ( this . mTabBrowser . getAttribute ( this . kTRANSPARENT ) == 'true' )
2008-03-09 23:51:21 -04:00
this . drawTabbarCanvas ( ) ;
else
this . clearTabbarCanvas ( ) ;
2007-11-17 00:20:26 -05:00
}
else {
v . move ( window . outerWidth , window . outerHeight ) ;
v . move ( 0 , 0 ) ;
2008-03-09 23:51:21 -04:00
this . clearTabbarCanvas ( ) ;
2007-11-17 00:20:26 -05:00
}
}
catch ( e ) {
}
2008-03-09 01:36:52 -05:00
} ,
2008-03-09 23:51:21 -04:00
drawTabbarCanvas : function ( )
{
if ( ! this . tabbarCanvas ) return ;
var pos = this . mTabBrowser . getAttribute ( this . kTABBAR _POSITION ) ;
var frame = this . mTabBrowser . contentWindow ;
var tabContainerBox = this . mTabBrowser . mTabContainer . boxObject ;
var browserBox = this . mTabBrowser . mCurrentBrowser . boxObject ;
var contentBox = frame . document . getBoxObjectFor ( frame . document . documentElement ) ;
var x = ( pos == 'right' ) ? browserBox . width - this . tabbarWidth : 0 ;
var y = ( pos == 'bottom' ) ? browserBox . height - this . tabbarHeight : 0 ;
var xOffset = ( pos == 'top' || pos == 'bottom' ) ?
contentBox . screenX + frame . scrollX - browserBox . screenX :
0 ;
var yOffset = ( pos == 'left' || pos == 'right' ) ?
contentBox . screenY + frame . scrollY - browserBox . screenY :
0 ;
var w = tabContainerBox . width - xOffset ;
var h = tabContainerBox . height - yOffset ;
this . tabbarCanvas . style . margin = ( yOffset || 0 ) + 'px 0 0 ' + ( xOffset || 0 ) + 'px' ;
this . tabbarCanvas . style . width = ( this . tabbarCanvas . width = w ) + 'px' ;
this . tabbarCanvas . style . height = ( this . tabbarCanvas . height = h ) + 'px' ;
var ctx = this . tabbarCanvas . getContext ( '2d' ) ;
ctx . clearRect ( 0 , 0 , w , h ) ;
ctx . save ( ) ;
ctx . drawWindow ( frame , x + frame . scrollX , y + frame . scrollY , w , h , '-moz-field' ) ;
ctx . restore ( ) ;
} ,
clearTabbarCanvas : function ( )
{
if ( ! this . tabbarCanvas ) return ;
2008-03-09 23:59:49 -04:00
this . tabbarCanvas . style . margin =
this . tabbarCanvas . style . width =
this . tabbarCanvas . style . height =
this . tabbarCanvas . width =
this . tabbarCanvas . height = 0 ;
2008-03-09 23:51:21 -04:00
} ,
2008-03-10 00:11:44 -04:00
updateTabbarTransparency : function ( )
{
var pos = this . mTabBrowser . getAttribute ( this . kTABBAR _POSITION ) ;
if ( pos != 'top' &&
this . getTreePref ( 'tabbar.autoHide.enabled' ) &&
this . getTreePref ( 'tabbar.transparent' ) )
this . mTabBrowser . setAttribute ( this . kTRANSPARENT , true ) ;
else
this . mTabBrowser . removeAttribute ( this . kTRANSPARENT ) ;
} ,
2008-03-09 01:36:52 -05:00
/* auto hide */
autoHideEnabled : false ,
get areaPadding ( )
{
return this . getTreePref ( 'tabbar.autoHide.area' ) ;
} ,
startAutoHide : function ( )
{
if ( this . autoHideEnabled ) return ;
this . autoHideEnabled = true ;
this . mTabBrowser . addEventListener ( 'mousedown' , this , true ) ;
this . mTabBrowser . addEventListener ( 'mouseup' , this , true ) ;
this . mTabBrowser . addEventListener ( 'scroll' , this , true ) ;
this . mTabBrowser . addEventListener ( 'resize' , this , true ) ;
this . mTabBrowser . addEventListener ( 'load' , this , true ) ;
2008-03-09 08:46:19 -04:00
if ( this . getTreePref ( 'tabbar.autoShow.mousemove' ) )
this . startListenMouseMove ( ) ;
2008-03-09 01:36:52 -05:00
2008-03-09 23:51:21 -04:00
this . clearTabbarCanvas ( ) ;
2008-03-10 00:11:44 -04:00
this . updateTabbarTransparency ( ) ;
2008-03-09 23:51:21 -04:00
2008-03-09 01:36:52 -05:00
this . tabbarShown = true ;
this . showHideTabbarInternal ( ) ;
} ,
endAutoHide : function ( )
{
if ( ! this . autoHideEnabled ) return ;
this . autoHideEnabled = false ;
this . mTabBrowser . removeEventListener ( 'mousedown' , this , true ) ;
this . mTabBrowser . removeEventListener ( 'mouseup' , this , true ) ;
this . mTabBrowser . removeEventListener ( 'scroll' , this , true ) ;
this . mTabBrowser . removeEventListener ( 'resize' , this , true ) ;
this . mTabBrowser . removeEventListener ( 'load' , this , true ) ;
2008-03-09 08:46:19 -04:00
this . endListenMouseMove ( ) ;
2008-03-09 01:36:52 -05:00
2008-03-09 23:51:21 -04:00
this . clearTabbarCanvas ( ) ;
2008-03-10 00:11:44 -04:00
this . updateTabbarTransparency ( ) ;
2008-03-09 23:51:21 -04:00
2008-03-09 01:36:52 -05:00
this . container . style . margin = 0 ;
this . mTabBrowser . removeAttribute ( this . kAUTOHIDE ) ;
2008-03-09 23:59:49 -04:00
this . mTabBrowser . removeAttribute ( this . kTRANSPARENT ) ;
2008-03-09 01:36:52 -05:00
this . tabbarShown = true ;
} ,
2008-03-09 08:46:19 -04:00
startListenMouseMove : function ( )
{
if ( this . mouseMoveListening ) return ;
this . mTabBrowser . addEventListener ( 'mousemove' , this , true ) ;
this . mouseMoveListening = true ;
} ,
2008-03-09 23:51:21 -04:00
endListenMouseMove : function ( )
2008-03-09 08:46:19 -04:00
{
if ( ! this . mouseMoveListening ) return ;
this . mTabBrowser . removeEventListener ( 'mousemove' , this , true ) ;
this . mouseMoveListening = false ;
} ,
mouseMoveListening : false ,
2008-03-09 01:36:52 -05:00
showHideTabbarOnMousemove : function ( aEvent )
{
if ( 'gestureInProgress' in window && window . gestureInProgress ) return ;
this . cancelShowHideTabbarOnMousemove ( ) ;
var b = this . mTabBrowser ;
var pos = b . getAttribute ( this . kTABBAR _POSITION ) ;
var expand = this . getTreePref ( 'tabbar.autoHide.expandArea' ) ;
if (
(
! this . tabbarShown ||
this . showHideTabbarReason == this . kSHOWN _BY _FEEDBACK
) &&
(
pos == 'left' ?
( aEvent . screenX <= b . boxObject . screenX + ( expand ? this . tabbarWidth : 0 ) + this . areaPadding ) :
pos == 'right' ?
( aEvent . screenX >= b . boxObject . screenX + b . boxObject . width - ( expand ? this . tabbarWidth : 0 ) - this . areaPadding ) :
pos == 'bottom' ?
( aEvent . screenY >= b . boxObject . screenY + b . boxObject . height - ( expand ? this . tabbarHeight : 0 ) - this . areaPadding ) :
( aEvent . screenY <= b . boxObject . screenY + ( expand ? this . tabbarHeight : 0 ) + this . areaPadding )
) )
this . showHideTabbarOnMousemoveTimer = window . setTimeout (
function ( aSelf ) {
if ( aSelf . showHideTabbarReason == aSelf . kSHOWN _BY _FEEDBACK ) {
aSelf . showHideTabbarReason = aSelf . kSHOWN _BY _MOUSEMOVE ;
aSelf . cancelHideTabbarForFeedback ( ) ;
}
else
aSelf . showTabbar ( aSelf . kSHOWN _BY _MOUSEMOVE ) ;
} ,
this . getTreePref ( 'tabbar.autoHide.delay' ) ,
this
) ;
if ( this . tabbarShown &&
(
pos == 'left' ?
( aEvent . screenX > b . mCurrentBrowser . boxObject . screenX + this . areaPadding ) :
pos == 'right' ?
( aEvent . screenX < b . mCurrentBrowser . boxObject . screenX + b . mCurrentBrowser . boxObject . width - this . areaPadding ) :
pos == 'bottom' ?
( aEvent . screenY < b . mCurrentBrowser . boxObject . screenY + b . mCurrentBrowser . boxObject . height - this . areaPadding ) :
( aEvent . screenY > b . mCurrentBrowser . boxObject . screenY + this . areaPadding )
) )
this . showHideTabbarOnMousemoveTimer = window . setTimeout (
function ( aSelf ) {
if ( aSelf . showHideTabbarReason == aSelf . kSHOWN _BY _MOUSEMOVE )
aSelf . hideTabbar ( aSelf . kSHOWN _BY _MOUSEMOVE ) ;
} ,
this . getTreePref ( 'tabbar.autoHide.delay' ) ,
this
) ;
} ,
showHideTabbarOnMousemoveTimer : null ,
cancelShowHideTabbarOnMousemove : function ( )
{
if ( this . showHideTabbarOnMousemoveTimer ) {
window . clearTimeout ( this . showHideTabbarOnMousemoveTimer ) ;
this . showHideTabbarOnMousemoveTimer = null ;
}
} ,
2008-03-09 23:51:21 -04:00
2008-03-09 01:36:52 -05:00
showTabbarForFeedback : function ( )
{
if ( ! this . autoHideEnabled ||
! this . getTreePref ( 'tabbar.autoShow.feedback' ) )
return ;
if ( this . delayedShowTabbarForFeedbackTimer ) {
window . clearTimeout ( this . delayedShowTabbarForFeedbackTimer ) ;
this . delayedShowTabbarForFeedbackTimer = null ;
}
this . cancelHideTabbarForFeedback ( ) ;
this . delayedShowTabbarForFeedbackTimer = window . setTimeout (
function ( aSelf ) {
aSelf . delayedShowTabbarForFeedbackTimer = null ;
aSelf . delayedShowTabbarForFeedback ( ) ;
} ,
100 ,
this
) ;
} ,
delayedShowTabbarForFeedback : function ( )
{
this . showTabbar ( this . kSHOWN _BY _FEEDBACK ) ;
this . cancelHideTabbarForFeedback ( ) ;
this . delayedHideTabbarForFeedbackTimer = window . setTimeout (
function ( aSelf ) {
aSelf . delayedHideTabbarForFeedbackTimer = null ;
if ( aSelf . showHideTabbarReason == aSelf . kSHOWN _BY _FEEDBACK )
aSelf . hideTabbar ( ) ;
} ,
this . getTreePref ( 'tabbar.autoShow.feedback.delay' ) ,
this
) ;
} ,
cancelHideTabbarForFeedback : function ( )
{
if ( this . delayedHideTabbarForFeedbackTimer ) {
window . clearTimeout ( this . delayedHideTabbarForFeedbackTimer ) ;
this . delayedHideTabbarForFeedbackTimer = null ;
}
2007-11-14 14:34:36 -05:00
}
2008-03-09 01:36:52 -05:00
2007-11-14 14:34:36 -05:00
} ;
TreeStyleTabBrowser . prototype . _ _proto _ _ = TreeStyleTabService ;