2007-11-14 14:34:36 -05:00
function TreeStyleTabBrowser ( aTabBrowser )
{
this . mTabBrowser = aTabBrowser ;
2008-05-29 04:26:11 -04:00
if ( TreeStyleTabService . isGecko19 ) {
this . isPlatformNotSupported = false ;
this . isTimerSupported = true ;
}
2007-11-14 14:34:36 -05:00
}
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' ,
2008-10-14 13:48:19 -04:00
kMENUITEM _BOOKMARKSUBTREE : 'context-item-bookmarkTabSubTree' ,
2008-12-01 03:30:36 -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 ,
2008-06-20 01:57:38 -04:00
get scrollBox ( )
{
return this . mTabBrowser . mTabContainer . mTabstrip ;
} ,
2008-10-17 13:16:16 -04:00
get scrollBoxObject ( )
2008-06-20 01:57:38 -04:00
{
return this . scrollBox . scrollBoxObject ;
} ,
2007-11-14 14:34:36 -05:00
/* utils */
2008-03-09 23:51:21 -04:00
2008-02-22 02:44:06 -05:00
/* get tab contents */
2008-12-01 03:30:36 -05:00
2007-11-17 00:20:26 -05:00
getTabLabel : function ( aTab )
{
2008-05-29 04:59:41 -04:00
var label = document . getAnonymousElementByAttribute ( aTab , 'class' , 'tab-text-stack' ) || // Mac OS X
document . getAnonymousElementByAttribute ( aTab , 'class' , 'tab-text-container' ) || // Tab Mix Plus
2007-11-17 00:20:26 -05:00
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 ;
2008-06-20 01:57:38 -04:00
var box = this . scrollBox || b . mTabContainer ;
2007-11-14 14:34:36 -05:00
return ( box . getAttribute ( 'orient' ) || window . getComputedStyle ( box , '' ) . getPropertyValue ( '-moz-box-orient' ) ) == 'vertical' ;
} ,
isTabInViewport : function ( aTab )
{
if ( ! aTab ) return false ;
var tabBox = aTab . boxObject ;
2008-06-20 01:57:38 -04:00
var barBox = this . scrollBox . boxObject ;
2007-11-14 14:34:36 -05:00
return ( tabBox . screenX >= barBox . screenX &&
tabBox . screenX + tabBox . width <= barBox . screenX + barBox . width &&
tabBox . screenY >= barBox . screenY &&
tabBox . screenY + tabBox . height <= barBox . screenY + barBox . height ) ;
} ,
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-12-01 03:30:36 -05: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 ) ;
2008-06-18 20:15:57 -04:00
b . mTabContainer . addEventListener ( 'scroll' , this , true ) ;
2007-11-14 14:34:36 -05:00
2009-03-04 15:42:41 -05:00
2009-03-04 14:48:22 -05:00
var container = document . getAnonymousElementByAttribute ( b . mTabContainer , 'class' , 'tabs-container' ) ;
if ( container ) container . removeAttribute ( 'overflow' ) ;
2009-03-04 15:42:41 -05:00
var inner = document . getAnonymousElementByAttribute ( b . mTabContainer , 'class' , 'tabbrowser-arrowscrollbox' ) ;
if ( inner ) {
2009-03-08 12:12:19 -04:00
inner . addEventListener ( 'overflow' , this , true ) ;
inner . addEventListener ( 'underflow' , this , true ) ;
2009-03-04 15:42:41 -05:00
window . setTimeout ( function ( ) {
inner = document . getAnonymousElementByAttribute ( inner , 'anonid' , 'scrollbox' ) ;
if ( inner ) inner = document . getAnonymousNodes ( inner ) [ 0 ] ;
if (
inner &&
(
inner . boxObject . width > container . boxObject . width ||
inner . boxObject . height > container . boxObject . height
)
) {
container . setAttribute ( 'overflow' , true ) ;
}
} , 100 ) ;
}
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 (
'{' ,
2009-01-24 00:39:22 -05:00
< ! [ CDATA [ $ &
if ( ! val ) {
2009-01-26 01:37:29 -05:00
val = TreeStyleTabService . getLastTab ( this ) ;
2009-01-24 00:39:22 -05:00
}
] ] > . toString ( )
2007-11-29 11:49:18 -05:00
) ) ;
/ * 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 ) ;
2009-01-24 00:39:22 -05:00
var selectNewTab = '_selectNewTab' in b . mTabContainer ?
'_selectNewTab' : // Firefox 3
'selectNewTab' ; // Firefox 2
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 ) {
2009-01-26 01:13:37 -05:00
nextTab = TreeStyleTabService . evaluateXPath (
'child::xul:tab[not(@' + TreeStyleTabService . kCOLLAPSED + '="true")][' +
( aDir < 0 ? 'last()' : '1' ) +
']' ,
2009-02-22 12:33:32 -05:00
aSelf ,
XPathResult . FIRST _ORDERED _NODE _TYPE
2009-01-26 01:13:37 -05:00
) . singleNodeValue ;
2008-03-03 04:07:02 -05:00
}
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 ;
2008-06-18 11:04:37 -04:00
var ensureTabVisibleByTST = function ( aTab ) {
if ( ! treeStyleTab . isTabInViewport ( aTab ) ) {
treeStyleTab . scrollToTab ( aTab ) ;
return true ;
}
return false ;
} ;
2008-06-18 20:15:57 -04:00
if ( ensureTabVisibleByTST ( this . selectedItem ) ) {
2008-03-03 04:07:02 -05:00
return ;
}
2007-11-17 00:20:26 -05:00
] ] > < / >
)
) ;
2007-11-14 14:34:36 -05:00
2008-06-18 11:04:37 -04:00
/ *
if ( 'ensureElementIsVisible' in b . mTabContainer . mTabstrip &&
'_smoothScrollByPixels' in b . mTabContainer . mTabstrip ) {
eval ( 'b.mTabContainer.mTabstrip.ensureElementIsVisible = ' +
b . mTabContainer . mTabstrip . ensureElementIsVisible . toSource ( ) . replace (
'{' ,
< > < ! [ CDATA [ $ &
var browser = TreeStyleTabService . getTabBrowserFromChild ( this ) ;
var startProp = browser . treeStyleTab . isVertical ? 'top' : 'left' ;
var endProp = browser . treeStyleTab . isVertical ? 'bottom' : 'right' ;
] ] > < / >
) . replace (
/\.left/g , '[startProp]'
) . replace (
/\.right/g , '[endProp]'
) . replace (
'|| this.getAttribute("orient") == "vertical"' , ''
)
) ;
eval ( 'b.mTabContainer.mTabstrip._smoothScrollByPixels = ' +
b . mTabContainer . mTabstrip . _smoothScrollByPixels . toSource ( ) . replace (
'{' ,
< > < ! [ CDATA [ $ &
var TST = TreeStyleTabService . getTabBrowserFromChild ( this ) ;
] ] > < / >
) . replace (
'scrollBy(distance, 0)' ,
< > < ! [ CDATA [ scrollBy (
( TST . isVertical ? 0 : distance ) ,
( TST . isVertical ? distance : 0 )
) ] ] > < / >
)
) ;
}
* /
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)'
)
) ;
2008-10-14 10:45:57 -04:00
eval ( 'b.warnAboutClosingTabs = ' +
b . warnAboutClosingTabs . toSource ( ) . replace (
'var numTabs = ' , 'var numTabs = this.__treestyletab__closedTabsNum || '
)
) ;
2008-12-01 04:14:05 -05:00
if ( '_onDragEnd' in b ) {
eval ( 'b._onDragEnd = ' + b . _onDragEnd . toSource ( ) . replace (
'this._replaceTabWithWindow(' ,
'if (this.treeStyleTab.isDraggingAllTabs(draggedTab)) return; $&'
) ) ;
}
2008-12-01 21:51:41 -05:00
// https://bugzilla.mozilla.org/show_bug.cgi?id=406216
if ( '_beginRemoveTab' in b ) {
eval ( 'b._beginRemoveTab = ' + b . _beginRemoveTab . toSource ( ) . replace (
'for (let i = 0; i < l; ++i) {' ,
'l = this.mTabs.length; $&'
) ) ;
}
2009-01-24 00:39:22 -05:00
var tabs = this . getTabs ( b ) ;
for ( var i = 0 , maxi = tabs . snapshotLength ; i < maxi ; i ++ )
2007-11-17 00:20:26 -05:00
{
2009-01-24 00:39:22 -05:00
this . initTab ( tabs . snapshotItem ( 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' ) ;
2008-12-01 22:50:34 -05:00
this . observe ( null , 'nsPref:changed' , 'extensions.treestyletab.tabbar.hideNewTabButton' ) ;
2007-11-17 00:20:26 -05:00
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-13 19:51:54 -04:00
this . observe ( null , 'nsPref:changed' , 'extensions.treestyletab.tabbar.transparent.style' ) ;
2009-03-04 21:22:23 -05:00
this . observe ( null , 'nsPref:changed' , 'extensions.treestyletab.tabbar.dropshadow' ) ;
2007-11-17 00:20:26 -05:00
window . setTimeout ( function ( ) {
2008-06-17 02:22:49 -04:00
b . treeStyleTab . observe ( null , 'nsPref:changed' , 'extensions.treestyletab.tabbar.autoHide.mode' ) ;
2007-11-17 00:20:26 -05:00
} , 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 ) {
2008-10-14 14:06:59 -04:00
var suffix = '-tabbrowser-' + ( b . id || 'instance-' + 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 ) ;
} ) ;
2008-10-14 13:48:19 -04:00
var item = document . getElementById ( aSelf . kMENUITEM _BOOKMARKSUBTREE ) . cloneNode ( true ) ;
item . setAttribute ( 'id' , item . getAttribute ( 'id' ) + suffix ) ;
var refNodes = tabContext . getElementsByAttribute ( 'command' , 'Browser:BookmarkAllTabs' ) ;
2009-02-04 08:51:14 -05:00
tabContext . insertBefore (
item ,
( refNodes && refNodes . length ) ?
( aSelf . getNextTab ( refNodes [ 0 ] ) || refNodes [ 0 ] ) :
null
) ;
2007-11-17 00:20:26 -05:00
} , 0 , this ) ;
var allTabPopup = document . getAnonymousElementByAttribute ( b . mTabContainer , 'anonid' , 'alltabs-popup' ) ;
2008-11-14 03:10:33 -05:00
if ( allTabPopup ) {
allTabPopup . addEventListener ( 'popupshowing' , this , false ) ;
}
2007-11-17 00:20:26 -05:00
/ * 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' ) ;
2008-03-10 03:21:32 -04:00
canvas . setAttribute ( 'style' , 'display:none;width:1;height:1;' ) ;
2008-03-09 23:51:21 -04:00
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
} ,
2008-12-01 03:30: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 ) ) {
2008-11-09 23:48:11 -05:00
var id = this . getTabValue ( aTab , this . kID ) || this . makeNewId ( ) ;
this . setTabValue ( aTab , this . kID , id ) ;
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 ) {
2009-02-04 08:51:14 -05:00
label . parentNode . insertBefore ( counter , label . nextSibling ) ;
2007-11-17 00:20:26 -05:00
}
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
}
2008-06-20 01:57:38 -04:00
if ( counter )
counter . setAttribute ( 'ordinal' , parseInt ( label . getAttribute ( 'ordinal' ) ) + 1 ) ;
2007-11-17 00:20:26 -05:00
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 ) {
2009-01-24 00:39:22 -05:00
aSelf . getTabsArray ( b ) . forEach ( function ( aTab ) {
2008-03-03 04:21:33 -05:00
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
{
2008-06-17 06:16:57 -04:00
this . clearTabbarCanvas ( ) ;
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
2008-10-17 11:47:45 -04:00
if ( b . getAttribute ( 'id' ) != 'content' &&
! this . getTreePref ( 'tabbar.position.subbrowser.enabled' ) ) {
2007-11-17 00:20:26 -05:00
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
2008-10-17 11:47:45 -04:00
b . mTabBox . orient = splitter . orient = 'horizontal' ;
2007-11-17 00:20:26 -05:00
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' ) ;
}
2008-11-06 23:38:21 -05:00
if ( allTabsButton . hasChildNodes ( ) ) {
allTabsButton . firstChild . setAttribute ( 'position' , 'before_start' ) ;
}
2007-11-17 00:20:26 -05:00
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
2008-10-17 11:47:45 -04:00
b . mTabBox . orient = splitter . orient = 'vertical' ;
2007-11-17 00:20:26 -05:00
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' ) ;
}
2008-11-06 23:38:21 -05:00
if ( allTabsButton . hasChildNodes ( ) ) {
allTabsButton . firstChild . setAttribute ( 'position' , 'after_end' ) ;
}
2007-11-17 00:20:26 -05:00
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 ;
2009-01-24 00:39:22 -05:00
var tabs = this . getTabs ( b ) ;
for ( var i = 0 , maxi = tabs . snapshotLength ; i < maxi ; i ++ )
2007-11-17 00:20:26 -05:00
{
2009-01-24 00:39:22 -05:00
this . destroyTab ( tabs . snapshotItem ( 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 ) ;
2008-06-18 20:15:57 -04:00
b . mTabContainer . removeEventListener ( 'scroll' , this , true ) ;
2007-11-14 14:34:36 -05:00
2009-03-08 12:12:19 -04:00
var inner = document . getAnonymousElementByAttribute ( b . mTabContainer , 'class' , 'tabbrowser-arrowscrollbox' ) ;
if ( inner ) {
inner . removeEventListener ( 'overflow' , this , true ) ;
inner . removeEventListener ( 'underflow' , this , true ) ;
}
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' ) ;
2008-11-14 03:10:33 -05:00
if ( allTabPopup ) {
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-12-01 03:30:36 -05: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 ;
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 ;
2009-01-24 00:39:22 -05:00
var tabs = this . getTabsArray ( b ) ;
2007-11-14 14:34:36 -05:00
switch ( aData )
{
case 'extensions.treestyletab.tabbar.position' :
2008-03-08 05:15:58 -05:00
// if (value != 'left' && value != 'right') {
// this.endAutoHide();
// }
2008-06-17 02:22:49 -04:00
if ( this . autoHideEnabled && this . autoHideShown ) this . hideTabbar ( ) ;
2007-11-14 14:34:36 -05:00
this . initTabbar ( ) ;
tabs . forEach ( function ( aTab ) {
2008-10-17 08:35:55 -04:00
this . initTabAttributes ( aTab ) ;
} , this ) ;
2007-11-14 14:34:36 -05:00
this . updateAllTabsIndent ( ) ;
tabs . forEach ( function ( aTab ) {
2008-10-17 08:35:55 -04:00
this . initTabContents ( aTab ) ;
} , this ) ;
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 ) {
2008-10-17 08:35:55 -04:00
this . initTabContents ( aTab ) ;
} , this ) ;
2007-11-14 14:34:36 -05:00
break ;
case 'extensions.treestyletab.enableSubtreeIndent' :
this . updateAllTabsIndent ( ) ;
break ;
case 'extensions.treestyletab.tabbar.style' :
2008-06-18 12:48:11 -04:00
if ( value )
b . setAttribute ( this . kSTYLE , value ) ;
else
b . removeAttribute ( this . kSTYLE ) ;
2007-11-14 14:34:36 -05:00
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 ;
2008-12-01 22:50:34 -05:00
case 'extensions.treestyletab.tabbar.hideNewTabButton' :
var pos = b . getAttribute ( this . kTABBAR _POSITION ) ;
if ( value && ( pos == 'left' || pos == 'right' ) )
b . setAttribute ( this . kHIDE _NEWTAB , true ) ;
else
b . removeAttribute ( this . kHIDE _NEWTAB ) ;
break ;
2007-11-14 14:34:36 -05:00
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 ;
2008-06-17 02:22:49 -04:00
case 'extensions.treestyletab.tabbar.autoHide.mode' :
this . endAutoHide ( ) ;
2008-06-17 08:55:05 -04:00
// update internal property after the appearance of the tab bar is updated.
window . setTimeout ( function ( aSelf ) {
aSelf . autoHideMode = value ;
if ( value != aSelf . kAUTOHIDE _MODE _DISABLED )
aSelf . startAutoHide ( ) ;
} , 0 , this ) ;
2007-11-14 14:34:36 -05:00
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-13 19:51:54 -04:00
case 'extensions.treestyletab.tabbar.transparent.style' :
2008-03-10 00:11:44 -04:00
this . updateTabbarTransparency ( ) ;
break ;
2008-09-17 23:01:13 -04:00
case 'extensions.treestyletab.tabbar.width' :
case 'extensions.treestyletab.tabbar.shrunkenWidth' :
this . checkTabsIndentOverflow ( ) ;
break ;
2009-03-04 21:22:23 -05:00
case 'extensions.treestyletab.tabbar.dropshadow' :
if ( value )
b . setAttribute ( this . kDROP _SHADOW , true ) ;
else
b . removeAttribute ( this . kDROP _SHADOW ) ;
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 ) ;
2008-06-18 20:20:04 -04:00
if ( this . isVertical ) {
var x = { } , y = { } ;
2008-06-20 01:57:38 -04:00
var scrollBoxObject = this . scrollBoxObject ;
if ( ! scrollBoxObject ) return ;
2008-06-18 20:20:04 -04:00
scrollBoxObject . getPosition ( x , y ) ;
this . lastScrollX = x . value ;
this . lastScrollY = y . value ;
// var tab = aEvent.originalTarget;
// var delta = tab.boxObject.height;
// scrollBoxObject.scrollTo(x.value, y.value-delta);
}
2007-11-14 14:34:36 -05:00
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 &&
2008-04-29 14:17:44 -04:00
this . hasChildTabs ( tab ) &&
2007-11-14 14:34:36 -05:00
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-06-17 07:05:45 -04:00
if (
! this . tabbarResizing &&
(
aEvent . originalTarget . getAttribute ( 'class' ) == this . kSPLITTER ||
aEvent . originalTarget . parentNode . getAttribute ( 'class' ) == this . kSPLITTER
)
) {
2007-11-14 14:34:36 -05:00
this . tabbarResizing = true ;
2008-06-17 06:16:57 -04:00
this . clearTabbarCanvas ( ) ;
2008-03-09 23:51:21 -04:00
this . mTabBrowser . setAttribute ( this . kRESIZING , true ) ;
2008-06-17 07:05:45 -04:00
if ( this . isGecko19 ) {
2008-06-17 07:11:57 -04:00
/ * c a n v a s <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> \ <EFBFBD> <EFBFBD> <EFBFBD> ɂ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ̂ Ɠ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ^ <EFBFBD> C <EFBFBD> ~ <EFBFBD> <EFBFBD> <EFBFBD> O <EFBFBD> Ń <EFBFBD> <EFBFBD> T <EFBFBD> C <EFBFBD> Y <EFBFBD> <EFBFBD> <EFBFBD> s <EFBFBD> <EFBFBD> <EFBFBD> Ɓ A
<EFBFBD> ܂ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> I <EFBFBD> <EFBFBD> canvas <EFBFBD> ̑ 傫 <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ܂ ܂ Ȃ ̂ ŁA <EFBFBD> <EFBFBD> <EFBFBD> ̑ 傫 <EFBFBD> <EFBFBD> <EFBFBD> ȉ <EFBFBD> <EFBFBD> <EFBFBD>
<EFBFBD> ^ <EFBFBD> u <EFBFBD> o <EFBFBD> [ <EFBFBD> ̕ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> k <EFBFBD> ߂ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ȃ <EFBFBD> <EFBFBD> Ȃ <EFBFBD> <EFBFBD> B <EFBFBD> 蓮 <EFBFBD> ŃC <EFBFBD> x <EFBFBD> <EFBFBD> <EFBFBD> g <EFBFBD> <EFBFBD> <EFBFBD> đ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ă <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
<EFBFBD> <EFBFBD> <EFBFBD> ̖ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> h <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ƃ <EFBFBD> <EFBFBD> ł <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> B * /
2008-06-17 07:05:45 -04:00
aEvent . preventDefault ( ) ;
aEvent . stopPropagation ( ) ;
var flags = 0 ;
const nsIDOMNSEvent = Components . interfaces . nsIDOMNSEvent ;
if ( aEvent . altKey ) flags |= nsIDOMNSEvent . ALT _MASK ;
if ( aEvent . ctrlKey ) flags |= nsIDOMNSEvent . CONTROL _MASK ;
if ( aEvent . shiftKey ) flags |= nsIDOMNSEvent . SHIFT _MASK ;
if ( aEvent . metaKey ) flags |= nsIDOMNSEvent . META _MASK ;
window . setTimeout ( function ( aX , aY , aButton , aDetail ) {
window
. QueryInterface ( Components . interfaces . nsIInterfaceRequestor )
. getInterface ( Components . interfaces . nsIDOMWindowUtils )
. sendMouseEvent ( 'mousedown' , aX , aY , aButton , aDetail , flags ) ;
} , 0 , aEvent . clientX , aEvent . clientY , aEvent . button , aEvent . detail ) ;
}
2008-03-09 23:51:21 -04:00
}
2008-03-09 01:36:52 -05:00
this . cancelShowHideTabbarOnMousemove ( ) ;
if (
this . autoHideEnabled &&
2008-06-17 02:22:49 -04:00
this . autoHideShown &&
2008-03-09 01:36:52 -05:00
(
aEvent . originalTarget . ownerDocument != document ||
! this . getTabBrowserFromChild ( aEvent . originalTarget )
)
)
this . hideTabbar ( ) ;
2008-03-13 20:13:34 -04:00
this . lastMouseDownTarget = aEvent . originalTarget . localName ;
2007-11-14 14:34:36 -05:00
}
return ;
case 'mouseup' :
2008-06-17 07:05:45 -04:00
if ( aEvent . originalTarget . getAttribute ( 'class' ) == this . kSPLITTER ||
aEvent . originalTarget . parentNode . 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-06-17 06:16:57 -04:00
if ( this . autoHideShown ) this . redrawContentArea ( ) ;
2008-03-09 23:51:21 -04:00
}
2008-03-09 01:36:52 -05:00
this . cancelShowHideTabbarOnMousemove ( ) ;
2008-03-13 20:13:34 -04:00
this . lastMouseDownTarget = null ;
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 &&
(
2008-06-17 02:22:49 -04:00
! this . autoHideShown ||
2008-03-09 01:36:52 -05:00
this . showHideTabbarReason == this . kSHOWN _BY _MOUSEMOVE
)
)
this . showHideTabbarOnMousemove ( aEvent ) ;
2007-11-14 14:34:36 -05:00
return ;
}
2008-03-13 20:13:34 -04:00
if ( /^(scrollbar|thumb|slider|scrollbarbutton)$/i . test ( this . lastMouseDownTarget ) )
return ;
2007-11-14 14:34:36 -05:00
case 'resize' :
2008-06-17 02:22:49 -04:00
if ( this . autoHideShown ) {
2007-11-14 14:34:36 -05:00
switch ( this . mTabBrowser . getAttribute ( this . kTABBAR _POSITION ) )
{
case 'left' :
2008-06-17 02:22:49 -04:00
this . container . style . marginRight = '-' + this . autoHideXOffset + 'px' ;
2007-11-14 14:34:36 -05:00
break ;
case 'right' :
2008-06-17 02:22:49 -04:00
this . container . style . marginLeft = '-' + this . autoHideXOffset + 'px' ;
2007-11-14 14:34:36 -05:00
break ;
case 'bottom' :
2008-06-17 02:22:49 -04:00
this . container . style . marginTop = '-' + this . autoHideYOffset + 'px' ;
2007-11-14 14:34:36 -05:00
break ;
default :
2008-06-17 02:22:49 -04:00
this . container . style . marginBottom = '-' + this . autoHideYOffset + 'px' ;
2007-11-14 14:34:36 -05:00
break ;
}
this . redrawContentArea ( ) ;
}
return ;
case 'scroll' :
2008-06-18 20:15:57 -04:00
var node = aEvent . originalTarget ;
if ( node && node . ownerDocument == document ) {
if ( this . lastScrollX < 0 || this . lastScrollY < 0 ) return ;
var x = { } , y = { } ;
2008-06-20 01:57:38 -04:00
var scrollBoxObject = this . scrollBoxObject ;
2008-06-18 20:15:57 -04:00
scrollBoxObject . getPosition ( x , y ) ;
if ( x . value != this . lastScrollX || y . value != this . lastScrollY )
scrollBoxObject . scrollTo ( this . lastScrollX , this . lastScrollY ) ;
this . lastScrollX = - 1 ;
this . lastScrollY = - 1 ;
}
else if ( this . autoHideEnabled ) {
this . redrawContentArea ( ) ;
}
2007-11-14 14:34:36 -05:00
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 ;
2009-03-08 12:12:19 -04:00
case 'overflow' :
case 'underflow' :
var box = aEvent . currentTarget ;
var tabs = this . mTabBrowser . mTabContainer ;
var horizontal = tabs . orient == 'horizontal' ;
if ( horizontal ) return ;
aEvent . stopPropagation ( ) ;
if ( aEvent . type == 'overflow' ) {
tabs . setAttribute ( 'overflow' , 'true' ) ;
box . scrollBoxObject . ensureElementIsVisible ( tabs . selectedItem ) ;
}
else {
tabs . removeAttribute ( 'overflow' ) ;
}
return ;
2007-11-14 14:34:36 -05:00
}
} ,
2008-06-18 20:15:57 -04:00
lastScrollX : - 1 ,
lastScrollY : - 1 ,
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 ] ) ;
}
2009-01-24 00:39:22 -05:00
if ( this . getTabs ( b ) . snapshotLength == 1 ) { // this is the last tab
2007-11-14 14:34:36 -05:00
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 ) ;
2009-01-26 01:37:29 -05:00
self . moveTabSubTreeTo ( aTab , self . getLastTab ( b ) . _tPos ) ;
2007-11-14 14:34:36 -05:00
} :
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 ) ;
2009-02-05 03:38:01 -05:00
if ( tab == lastSibling && ! nextFocusedTab ) {
2007-11-14 14:34:36 -05:00
if ( tab == firstSibling ) { // there is only one child
nextFocusedTab = parentTab ;
}
else { // previous sibling tab
nextFocusedTab = this . getPreviousSiblingTab ( tab ) ;
}
}
2007-11-26 14:55:58 -05:00
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
2008-04-29 14:17:44 -04:00
if ( this . hasChildTabs ( tab ) && ! this . isSubTreeMoving ) {
2007-11-14 14:34:36 -05:00
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 ) ;
2009-01-24 00:39:22 -05:00
var oldPos = this . getChildIndex ( this . getTabs ( this . mTabBrowser ) . snapshotItem ( 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
2009-01-24 00:39:22 -05:00
var prevTab = this . getPreviousTab ( aTab ) ;
var nextTab = this . getNextTab ( aTab ) ;
2007-11-26 21:42:02 -05:00
var tabs = this . getDescendantTabs ( aTab ) ;
if ( tabs . length ) {
2009-01-24 00:39:22 -05:00
nextTab = this . getNextTab ( tabs [ tabs . length - 1 ] ) ;
2007-11-26 21:42:02 -05:00
}
var prevParent = this . getParentTab ( prevTab ) ;
var nextParent = this . getParentTab ( nextTab ) ;
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 ) {
2009-01-24 00:39:22 -05:00
newParent = this . getParentTab ( aTab ) ;
2007-11-26 17:43:50 -05:00
}
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 ; } ) ;
2008-10-17 08:35:55 -04:00
this . setTabValue (
aTab ,
this . kCHILDREN ,
children
. map ( function ( aItem ) {
return aItem . getAttribute ( this . kID ) ;
} , this )
. join ( '|' )
) ;
2007-11-14 14:34:36 -05:00
} ,
onTabRestored : function ( aEvent )
{
2008-11-09 23:48:11 -05:00
this . restoreStructure ( aEvent . originalTarget ) ;
} ,
restoreStructure : function ( aTab )
{
var tab = aTab ;
2007-11-14 14:34:36 -05:00
var b = this . mTabBrowser ;
2007-11-15 08:11:26 -05:00
2008-11-10 00:21:34 -05:00
var maybeDuplicated = false ;
2007-11-17 07:50:36 -05:00
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!
2008-11-10 00:21:34 -05:00
maybeDuplicated = true ;
id = this . redirectId ( id ) ;
2007-11-17 07:50:36 -05:00
}
2008-11-10 00:21:34 -05:00
if ( ! maybeDuplicated ) {
2007-11-23 16:34:43 -05:00
/ * 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 ( '|' ) ;
2008-11-10 00:21:34 -05:00
if ( maybeDuplicated )
2008-02-23 20:06:19 -05:00
children = children . map ( function ( aChild ) {
2008-11-10 00:21:34 -05:00
return this . redirectId ( aChild ) ;
2008-10-17 08:35:55 -04:00
} , this ) ;
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 ] ) ;
}
}
}
2008-04-29 14:17:44 -04:00
var nextTab = this . getTabValue ( tab , this . kINSERT _BEFORE ) ;
2008-11-10 00:21:34 -05:00
if ( nextTab && maybeDuplicated ) {
nextTab = this . redirectId ( nextTab ) ;
2008-02-23 20:06:19 -05:00
}
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-11-10 00:21:34 -05:00
if ( maybeDuplicated ) ancestors [ i ] = this . redirectId ( 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 ,
2008-04-29 14:17:44 -04:00
insertBefore : ( nextTab ? this . getTabById ( nextTab ) : null ) ,
2007-11-14 14:34:36 -05:00
dontUpdateIndent : true
} ) ;
this . updateTabsIndent ( [ tab ] ) ;
this . checkTabsIndentOverflow ( ) ;
}
else {
this . deleteTabValue ( tab , this . kPARENT ) ;
}
}
else if ( children ) {
this . updateTabsIndent ( tabs ) ;
this . checkTabsIndentOverflow ( ) ;
}
2008-04-29 14:17:44 -04:00
if ( ! parent ) {
nextTab = this . getTabById ( nextTab ) ;
2009-01-24 00:39:22 -05:00
if ( ! nextTab ) nextTab = this . getNextTab ( tab ) ;
2008-04-29 14:17:44 -04:00
var parentOfNext = this . getParentTab ( nextTab ) ;
var newPos = - 1 ;
if ( parentOfNext ) {
var descendants = this . getDescendantTabs ( parentOfNext ) ;
newPos = descendants [ descendants . length - 1 ] . _tPos ;
}
else if ( nextTab ) {
var newPos = nextTab . _tPos ;
if ( newPos > tab . _tPos ) newPos -- ;
}
if ( newPos > - 1 )
b . moveTabTo ( tab , newPos ) ;
2007-11-14 14:34:36 -05:00
}
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-11-10 00:21:34 -05:00
if ( maybeDuplicated ) this . clearRedirectionTable ( ) ;
2008-02-23 20:06:19 -05:00
} ,
2008-03-08 03:57:17 -05:00
2008-11-10 00:21:34 -05:00
redirectId : function ( aId )
2008-02-23 20:06:19 -05:00
{
2008-11-10 00:21:34 -05:00
if ( ! ( aId in this . _redirectionTable ) )
this . _redirectionTable [ aId ] = this . makeNewId ( ) ;
return this . _redirectionTable [ aId ] ;
2008-02-23 20:06:19 -05:00
} ,
2008-11-10 00:21:34 -05:00
_redirectionTable : { } ,
2008-02-24 02:58:12 -05:00
2008-11-10 00:21:34 -05:00
clearRedirectionTable : function ( )
2008-02-23 20:06:19 -05:00
{
2008-11-10 00:21:34 -05:00
if ( this . _clearRedirectionTableTimer ) {
window . clearTimeout ( this . _clearRedirectionTableTimer ) ;
this . _clearRedirectionTableTimer = null ;
2008-02-23 20:06:19 -05:00
}
2008-11-10 00:21:34 -05:00
this . _clearRedirectionTableTimer = window . setTimeout ( function ( aSelf ) {
aSelf . _redirectionTable = { } ;
2008-02-23 20:06:19 -05:00
} , 1000 , this ) ;
} ,
2008-11-10 00:21:34 -05:00
_clearRedirectionTableTimer : null ,
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
}
}
2008-04-29 14:17:44 -04:00
else if ( this . hasChildTabs ( tab ) &&
2007-11-14 14:34:36 -05:00
( tab . getAttribute ( this . kSUBTREE _COLLAPSED ) == 'true' ) &&
this . getTreePref ( 'autoCollapseExpandSubTreeOnSelect' ) ) {
this . collapseExpandTreesIntelligentlyFor ( tab ) ;
}
2008-06-17 02:22:49 -04:00
if ( this . autoHideEnabled && this . autoHideShown )
2007-11-14 14:34:36 -05:00
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 )
{
2008-12-03 07:48:42 -05:00
if ( aEvent . button != 0 ) return ;
2007-11-14 14:34:36 -05:00
2008-12-03 07:48:42 -05:00
if ( this . isEventFiredOnTwisty ( aEvent ) ) {
var tab = this . getTabFromEvent ( aEvent ) ;
this . collapseExpandSubtree ( tab , tab . getAttribute ( this . kSUBTREE _COLLAPSED ) != 'true' ) ;
}
else if ( ! this . getTabFromEvent ( aEvent ) ) {
2008-12-03 08:05:01 -05:00
var tab = this . getTabFromTabbarEvent ( aEvent ) ;
2008-12-03 08:11:08 -05:00
if ( tab ) this . mTabBrowser . selectedTab = tab ;
2008-12-03 07:48:42 -05:00
}
else {
return ;
}
2007-11-14 14:34:36 -05:00
aEvent . preventDefault ( ) ;
aEvent . stopPropagation ( ) ;
} ,
2008-12-03 08:05:01 -05:00
getTabFromTabbarEvent : function ( aEvent )
{
2008-12-14 21:59:51 -05:00
if (
! this . shouldDetectClickOnIndentSpaces ||
this . isEventFiredOnClickable ( aEvent )
)
return null ;
2008-12-03 08:17:40 -05:00
2008-12-03 08:05:01 -05:00
var tab = null ;
var clickedPoint = aEvent [ this . positionProp ] ;
2009-01-24 00:39:22 -05:00
this . getTabsArray ( this . mTabBrowser ) . some ( function ( aTab ) {
2008-12-03 08:05:01 -05:00
var box = aTab . boxObject ;
if ( box [ this . positionProp ] > clickedPoint ||
box [ this . positionProp ] + box [ this . sizeProp ] < clickedPoint ) {
return false ;
}
tab = aTab ;
return true ;
} , this ) ;
return tab ;
} ,
2007-11-14 14:34:36 -05:00
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 ) ;
2008-10-14 13:48:19 -04:00
this . showHideSubTreeMenuItem ( item , [ b . mContextTab ] ) ;
2007-11-14 14:34:36 -05:00
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 ) ;
2008-10-14 13:48:19 -04:00
this . showHideSubTreeMenuItem ( item , [ b . mContextTab ] ) ;
2007-11-26 10:07:10 -05:00
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' ) ;
2008-06-17 07:57:29 -04:00
if ( this . autoHideMode != this . kAUTOHIDE _MODE _DISABLED )
2008-02-22 12:55:35 -05:00
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 ) ;
}
2008-10-14 13:48:19 -04:00
// bookmark
item = this . evaluateXPath (
'descendant::xul:menuitem[starts-with(@id, "' + this . kMENUITEM _BOOKMARKSUBTREE + '")]' ,
aEvent . currentTarget ,
XPathResult . FIRST _ORDERED _NODE _TYPE
) . singleNodeValue ;
if ( this . getTreePref ( 'show.' + this . kMENUITEM _BOOKMARKSUBTREE ) )
item . removeAttribute ( 'hidden' ) ;
else
item . setAttribute ( 'hidden' , true ) ;
this . showHideSubTreeMenuItem ( item , [ b . mContextTab ] ) ;
2007-11-14 14:34:36 -05:00
} ,
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 ;
2009-01-24 00:39:22 -05:00
var tabs = this . getTabs ( this . mTabBrowser ) ;
2007-11-17 00:20:26 -05:00
for ( var i = 0 , maxi = items . length ; i < maxi ; i ++ )
{
2009-01-24 00:39:22 -05:00
items [ i ] . style . paddingLeft = tabs . snapshotItem ( i ) . getAttribute ( this . kNEST ) + 'em' ;
2007-11-17 00:20:26 -05:00
}
} ,
/* drag and drop */
2008-05-29 04:26:11 -04:00
isPlatformNotSupported : /* !this.isGecko19 && */ navigator . platform . indexOf ( 'Mac' ) != - 1 , // see bug 136524
2008-05-22 23:30:49 -04:00
isTimerSupported : /* this.isGecko19 || */ navigator . platform . indexOf ( 'Win' ) == - 1 , // see bug 232795.
2007-11-17 12:21:33 -05:00
autoExpandTimer : null ,
autoExpandTarget : null ,
2007-11-17 12:52:51 -05:00
autoExpandedTabs : [ ] ,
2008-12-01 03:30:36 -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' ) ) {
this . autoExpandedTabs . forEach ( function ( aTarget ) {
2008-10-17 08:35:55 -04:00
this . collapseExpandSubtree ( this . getTabById ( aTarget ) , true ) ;
} , this ) ;
2007-11-17 12:52:51 -05:00
}
this . autoExpandedTabs = [ ] ;
} ,
2007-11-23 10:43:40 -05:00
canDrop : function ( aEvent , aDragSession )
{
2008-11-30 19:01:12 -05:00
var dropAction = this . getDropAction ( aEvent , aDragSession ) ;
2008-12-01 20:54:16 -05:00
if ( 'dataTransfer' in aEvent ) {
2008-11-30 19:01:12 -05:00
var dt = aEvent . dataTransfer ;
2008-12-01 20:54:16 -05:00
if ( dropAction . action & this . kACTION _NEWTAB ) {
2008-12-03 13:41:58 -05:00
dt . effectAllowed = dt . dropEffect = (
! dropAction . source ? 'link' :
this . isAccelKeyPressed ( aEvent ) ? 'copy' :
'move'
) ;
2008-12-01 20:54:16 -05:00
}
2008-11-30 19:01:12 -05:00
}
return dropAction . canDrop ;
2007-11-23 10:43:40 -05:00
} ,
2007-11-17 12:21:33 -05:00
getSupportedFlavours : function ( )
{
var flavourSet = new FlavourSet ( ) ;
2008-12-01 20:54:16 -05:00
flavourSet . appendFlavour ( 'application/x-moz-tabbrowser-tab' ) ;
2007-11-17 12:21:33 -05:00
flavourSet . appendFlavour ( 'text/x-moz-url' ) ;
flavourSet . appendFlavour ( 'text/unicode' ) ;
2008-10-01 21:32:31 -04:00
flavourSet . appendFlavour ( 'text/plain' ) ;
2007-11-17 12:21:33 -05:00
flavourSet . appendFlavour ( 'application/x-moz-file' , 'nsIFile' ) ;
return flavourSet ;
} ,
2008-10-01 21:32:31 -04:00
getCurrentDragSession : function ( )
{
return Components
. classes [ '@mozilla.org/widget/dragservice;1' ]
. getService ( Components . interfaces . nsIDragService )
. getCurrentSession ( ) ;
} ,
2007-11-14 14:34:36 -05:00
getDropAction : function ( aEvent , aDragSession )
{
2008-10-01 21:32:31 -04:00
if ( ! aDragSession )
aDragSession = this . getCurrentDragSession ( ) ;
2008-10-17 08:35:55 -04:00
var tab = aDragSession ? this . getTabFromChild ( aDragSession . sourceNode ) : null ;
var info = this . getDropActionInternal ( aEvent , tab ) ;
2007-11-14 14:34:36 -05:00
info . canDrop = true ;
2008-12-03 13:41:58 -05:00
info . source = tab ;
2008-10-17 08:35:55 -04:00
if ( tab ) {
var isCopy = this . isAccelKeyPressed ( aEvent ) ;
if ( isCopy && 'duplicateTab' in this . mTabBrowser ) {
2008-10-17 13:16:16 -04:00
info . action |= this . kACTION _DUPLICATE ;
2008-10-17 08:35:55 -04:00
}
2008-02-24 03:11:17 -05:00
if (
2008-10-17 08:35:55 -04:00
! isCopy &&
2008-10-17 13:16:16 -04:00
this . getTabBrowserFromChild ( tab ) != this . mTabBrowser &&
2008-02-24 03:11:17 -05:00
(
2008-10-17 08:35:55 -04:00
( 'duplicateTab' in this . mTabBrowser ) ||
( 'swapBrowsersAndCloseOther' in this . mTabBrowser )
2008-02-24 03:11:17 -05:00
)
) {
2008-10-17 13:16:16 -04:00
info . action |= this . kACTION _IMPORT ;
}
if ( info . action & this . kACTIONS _FOR _DESTINATION ) {
if ( info . action & this . kACTION _MOVE ) info . action ^= this . kACTION _MOVE ;
if ( info . action & this . kACTION _STAY ) info . action ^= this . kACTION _STAY ;
2008-02-24 03:11:17 -05:00
}
2008-02-22 18:31:22 -05:00
if ( info . action & this . kACTION _ATTACH ) {
2008-10-17 13:16:16 -04:00
if ( info . parent == tab ) {
2007-11-14 14:34:36 -05:00
info . canDrop = false ;
2008-02-22 18:31:22 -05:00
}
else {
2008-10-17 13:16:16 -04:00
var orig = tab ;
tab = info . target ;
2008-02-22 18:31:22 -05:00
while ( tab = this . getParentTab ( tab ) )
{
if ( tab != orig ) continue ;
info . canDrop = false ;
break ;
}
2007-11-14 14:34:36 -05:00
}
}
}
return info ;
} ,
2008-10-17 13:16:16 -04:00
2008-10-17 08:35:55 -04:00
getDropActionInternal : function ( aEvent , aSourceTab )
2007-11-14 14:34:36 -05:00
{
var tab = aEvent . target ;
var b = this . mTabBrowser ;
2009-01-24 00:39:22 -05:00
var tabs = this . getTabsArray ( b ) ;
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
} ;
2008-10-17 08:35:55 -04:00
var isTabMoveFromOtherWindow = aSourceTab && aSourceTab . ownerDocument != document ;
2008-11-30 19:01:12 -05:00
var isNewTabAction = ! aSourceTab || aSourceTab . ownerDocument != document ;
2008-10-17 08:35:55 -04:00
2007-11-14 14:34:36 -05:00
if ( tab . localName != 'tab' ) {
2008-10-17 13:16:16 -04:00
var action = isTabMoveFromOtherWindow ? this . kACTION _STAY : ( this . kACTION _MOVE | this . kACTION _PART ) ;
2008-11-30 19:01:12 -05:00
if ( isNewTabAction ) action |= this . kACTION _NEWTAB ;
2007-11-14 14:34:36 -05:00
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 ;
2008-10-17 08:35:55 -04:00
info . action = action ;
2007-11-14 14:34:36 -05:00
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 ;
2008-10-17 08:35:55 -04:00
info . action = action ;
2007-11-14 14:34:36 -05:00
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 :
2009-03-04 22:13:56 -05:00
info . action = this . kACTION _MOVE | this . kACTION _ATTACH ;
2007-11-14 14:34:36 -05:00
info . parent = tab ;
2009-03-04 22:13:56 -05:00
info . insertBefore = this . getNextSiblingTab ( tab ) ;
2007-11-14 14:34:36 -05:00
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 ;
2009-03-04 22:13:56 -05:00
/ *
[ TARGET ] <EFBFBD> <EFBFBD> attach dragged tab to the parent of the target as its next sibling
[ DRAGGED ]
* /
if ( aSourceTab == nextTab && this . getDescendantTabs ( info . parent ) . length == 1 ) {
info . action = this . kACTION _MOVE | this . kACTION _ATTACH ;
info . parent = this . getParentTab ( tab ) ;
info . insertBefore = this . getNextTab ( nextTab ) ;
}
2007-11-14 14:34:36 -05:00
}
break ;
}
2008-11-30 19:01:12 -05:00
if ( isNewTabAction ) action |= this . kACTION _NEWTAB ;
2007-11-14 14:34:36 -05:00
return info ;
} ,
2008-10-17 13:16:16 -04:00
performDrop : function ( aInfo , aDraggedTab )
2007-11-14 14:34:36 -05:00
{
2008-12-01 03:30:36 -05:00
var tabsInfo = this . getDraggedTabsInfoFromOneTab ( aInfo , aDraggedTab ) ;
aDraggedTab = tabsInfo . draggedTab ;
var draggedTabs = tabsInfo . draggedTabs ;
var draggedRoots = tabsInfo . draggedRoots ;
2008-10-17 08:35:55 -04:00
var targetBrowser = this . mTabBrowser ;
2009-01-24 00:39:22 -05:00
var tabs = this . getTabsArray ( targetBrowser ) ;
2008-02-22 18:31:22 -05:00
2008-10-17 08:35:55 -04:00
var sourceWindow = aDraggedTab . ownerDocument . defaultView ;
var sourceBrowser = this . getTabBrowserFromChild ( aDraggedTab ) ;
2008-02-24 03:34:45 -05:00
2008-10-17 13:16:16 -04:00
if ( aInfo . action & this . kACTIONS _FOR _SOURCE ) {
if ( aInfo . action & this . kACTION _PART ) {
2008-02-22 20:42:42 -05:00
this . partTabsOnDrop ( draggedRoots ) ;
2008-10-17 13:16:16 -04:00
}
else if ( aInfo . action & this . kACTION _ATTACH ) {
2008-02-22 20:42:42 -05:00
this . attachTabsOnDrop ( draggedRoots , aInfo . parent ) ;
2008-10-17 13:16:16 -04:00
}
else {
return false ;
}
if ( // if this move will cause no change...
sourceBrowser == targetBrowser &&
sourceBrowser . treeStyleTab . getNextVisibleTab ( draggedTabs [ draggedTabs . length - 1 ] ) == aInfo . insertBefore
) {
// then, do nothing
return true ;
}
2007-11-14 14:34:36 -05:00
}
2008-02-22 19:41:15 -05:00
2008-10-17 13:16:16 -04:00
// prevent Multiple Tab Handler feature
targetBrowser . duplicatingSelectedTabs = true ;
targetBrowser . movingSelectedTabs = true ;
2008-10-17 08:35:55 -04:00
2008-02-22 18:31:22 -05:00
2008-10-17 13:16:16 -04:00
var newRoots = [ ] ;
var shouldClose = (
aInfo . action & this . kACTION _IMPORT &&
2009-01-24 00:39:22 -05:00
this . getTabs ( sourceBrowser ) . snapshotLength == draggedTabs . length
2008-10-17 13:16:16 -04:00
) ;
var oldTabs = [ ] ;
var newTabs = [ ] ;
var treeStructure = draggedTabs . map ( function ( aTab ) {
var parent = sourceBrowser . treeStyleTab . getParentTab ( aTab ) ;
return parent ? draggedTabs . indexOf ( parent ) : - 1 ;
} ) ;
2008-02-22 18:31:22 -05:00
2008-10-17 13:16:16 -04:00
draggedTabs . forEach ( function ( aTab ) {
var tab = aTab ;
if ( aInfo . action & this . kACTIONS _FOR _DESTINATION ) {
var parent = sourceBrowser . treeStyleTab . getParentTab ( aTab ) ;
2008-12-01 03:30:36 -05:00
if ( tabsInfo . isSelectionMove )
2008-10-17 13:16:16 -04:00
sourceWindow . MultipleTabService . setSelection ( aTab , false ) ;
if ( aInfo . action & this . kACTION _IMPORT &&
'swapBrowsersAndCloseOther' in targetBrowser ) {
tab = targetBrowser . addTab ( ) ;
tab . linkedBrowser . stop ( ) ;
tab . linkedBrowser . docShell ;
targetBrowser . swapBrowsersAndCloseOther ( tab , aTab ) ;
targetBrowser . setTabTitle ( tab ) ;
}
else {
tab = targetBrowser . duplicateTab ( aTab ) ;
this . deleteTabValue ( tab , this . kCHILDREN ) ;
this . deleteTabValue ( tab , this . kPARENT ) ;
if ( aInfo . action & this . kACTION _IMPORT )
oldTabs . push ( aTab ) ;
}
newTabs . push ( tab ) ;
2008-12-01 03:30:36 -05:00
if ( tabsInfo . isSelectionMove )
2008-10-17 13:16:16 -04:00
MultipleTabService . setSelection ( tab , true ) ;
if ( ! parent || draggedTabs . indexOf ( parent ) < 0 )
newRoots . push ( tab ) ;
}
2008-02-24 03:11:17 -05:00
2008-10-17 13:16:16 -04:00
var newIndex = aInfo . insertBefore ? aInfo . insertBefore . _tPos : tabs . length - 1 ;
if ( aInfo . insertBefore && newIndex > tab . _tPos ) newIndex -- ;
2008-10-17 08:35:55 -04:00
2008-10-17 13:16:16 -04:00
this . internallyTabMoving = true ;
targetBrowser . moveTabTo ( tab , newIndex ) ;
this . collapseExpandTab ( tab , false ) ;
this . internallyTabMoving = false ;
2008-02-22 19:41:15 -05:00
2008-10-17 13:16:16 -04:00
} , this ) ;
2008-02-24 05:01:10 -05:00
2008-10-17 13:16:16 -04:00
// close imported tabs from the source browser
oldTabs . forEach ( function ( aTab ) {
sourceBrowser . removeTab ( aTab ) ;
} ) ;
if ( shouldClose ) this . closeOwner ( sourceBrowser ) ;
2008-02-22 19:41:15 -05:00
2008-10-17 13:16:16 -04:00
// restore tree structure for newly opened tabs
newTabs . forEach ( function ( aTab , aIndex ) {
var index = treeStructure [ aIndex ] ;
if ( index < 0 ) return ;
targetBrowser . treeStyleTab . attachTabTo ( aTab , newTabs [ index ] ) ;
} ) ;
2008-02-24 03:11:17 -05:00
2008-10-17 13:16:16 -04:00
if ( aInfo . action & this . kACTIONS _FOR _DESTINATION &&
aInfo . action & this . kACTION _ATTACH )
this . attachTabsOnDrop ( newRoots , aInfo . parent ) ;
// Multiple Tab Handler
targetBrowser . movingSelectedTabs = false ;
targetBrowser . duplicatingSelectedTabs = false ;
2008-02-22 19:41:15 -05:00
2007-11-14 14:34:36 -05:00
return true ;
} ,
2008-10-17 13:16:16 -04:00
2008-12-01 03:30:36 -05:00
getDraggedTabsInfoFromOneTab : function ( aInfo , aTab )
{
aTab = this . getTabFromChild ( aTab ) ;
var targetBrowser = this . mTabBrowser ;
2009-01-24 00:39:22 -05:00
var tabs = this . getTabsArray ( targetBrowser ) ;
2008-12-01 03:30:36 -05:00
var draggedTabs = [ aTab ] ;
var draggedRoots = [ aTab ] ;
var sourceWindow = aTab . ownerDocument . defaultView ;
var sourceBrowser = this . getTabBrowserFromChild ( aTab ) ;
var isSelectionMove = (
'MultipleTabService' in sourceWindow &&
sourceWindow . MultipleTabService . isSelected ( aTab ) &&
MultipleTabService . allowMoveMultipleTabs
) ;
if ( isSelectionMove ) {
draggedTabs = sourceWindow . MultipleTabService . getSelectedTabs ( sourceBrowser ) ;
if ( ! ( aInfo . action & this . kACTIONS _FOR _DESTINATION ) ) {
draggedRoots = [ ] ;
draggedTabs . forEach ( function ( aTab ) {
var parent = aTab ,
current ;
do {
current = parent ;
parent = sourceBrowser . treeStyleTab . getParentTab ( parent )
if ( parent && sourceWindow . MultipleTabService . isSelected ( parent ) ) continue ;
draggedRoots . push ( current ) ;
return ;
}
while ( parent ) ;
} , this ) ;
}
}
else if ( aInfo . action & this . kACTIONS _FOR _DESTINATION ) {
draggedTabs = draggedTabs . concat ( sourceBrowser . treeStyleTab . getDescendantTabs ( aTab ) ) ;
}
return {
draggedTab : aTab ,
draggedTabs : draggedTabs ,
draggedRoots : draggedRoots ,
isSelectionMove : isSelectionMove
} ;
} ,
2008-10-17 13:16:16 -04:00
attachTabsOnDrop : function ( aTabs , aParent )
2008-02-22 19:41:15 -05:00
{
this . mTabBrowser . movingSelectedTabs = true ; // Multiple Tab Handler
aTabs . forEach ( function ( aTab ) {
if ( aParent )
2008-10-17 08:35:55 -04:00
this . attachTabTo ( aTab , aParent ) ;
2008-02-22 19:41:15 -05:00
else
2008-10-17 08:35:55 -04:00
this . partTab ( aTab ) ;
this . collapseExpandTab ( aTab , false ) ;
} , this ) ;
2008-02-22 19:41:15 -05:00
this . mTabBrowser . movingSelectedTabs = false ; // Multiple Tab Handler
} ,
2008-10-17 13:16:16 -04:00
partTabsOnDrop : function ( aTabs )
2008-02-22 19:41:15 -05:00
{
this . mTabBrowser . movingSelectedTabs = true ; // Multiple Tab Handler
aTabs . forEach ( function ( aTab ) {
2008-10-17 08:35:55 -04:00
this . partTab ( aTab ) ;
this . collapseExpandTab ( aTab , false ) ;
} , this ) ;
2008-02-22 19:41:15 -05:00
this . mTabBrowser . movingSelectedTabs = false ; // Multiple Tab Handler
} ,
2008-10-17 13:16:16 -04:00
closeOwner : function ( aTabOwner )
2008-10-17 08:35:55 -04:00
{
var w = aTabOwner . ownerDocument . defaultView ;
2008-10-17 13:30:10 -04:00
if ( ! w ) return ;
2008-10-17 08:35:55 -04:00
if ( 'SplitBrowser' in w &&
'getSubBrowserFromChild' in w . SplitBrowser ) {
var subbrowser = w . SplitBrowser . getSubBrowserFromChild ( aTabOwner ) ;
if ( subbrowser ) {
subbrowser . close ( ) ;
return ;
}
}
w . close ( ) ;
} ,
2008-12-01 03:30:36 -05:00
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 ) ;
}
} ,
2008-12-01 04:14:05 -05:00
isDraggingAllTabs : function ( aTab )
{
var actionInfo = {
action : this . kACTIONS _FOR _DESTINATION | this . kACTION _IMPORT
} ;
var tabsInfo = this . getDraggedTabsInfoFromOneTab ( actionInfo , aTab ) ;
2009-01-24 00:39:22 -05:00
return tabsInfo . draggedTabs . length == this . getTabs ( this . mTabBrowser ) . snapshotLength ;
2008-12-01 04:14:05 -05:00
} ,
2007-11-14 14:34:36 -05:00
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 )
{
this . _attachTabPostProcesses . forEach ( function ( aProcess ) {
2008-10-17 08:35:55 -04:00
aProcess ( aChild , aParent , this ) ;
} , this ) ;
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 ) ) ; } ) ;
2008-10-17 08:35:55 -04:00
var nest = tabs [ tabs . length - 1 ] . getAttribute ( this . kNEST ) ;
2007-11-17 00:20:26 -05:00
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 = (
2009-01-26 01:39:51 -05:00
this . getFirstTab ( b ) . boxObject [ this . invertedSizeProp ] ||
2007-11-23 15:45:38 -05:00
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 {
2009-01-26 01:37:29 -05:00
b . moveTabTo ( b . mCurrentTab , this . getLastTab ( b ) . _tPos ) ;
2007-11-17 00:20:26 -05:00
}
this . internallyTabMoving = false ;
b . mCurrentTab . focus ( ) ;
return true ;
}
}
return false ;
} ,
/* collapse/expand */
2008-12-01 03:30:36 -05:00
2008-07-30 14:03:44 -04:00
collapseExpandSubtree : function ( aTab , aCollapse )
2007-11-17 00:20:26 -05:00
{
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 ++ )
{
2008-07-30 14:03:44 -04:00
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
2008-07-30 14:03:44 -04: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 ;
2008-07-30 14:03:44 -04:00
var parent ;
if ( aCollapse && aTab == b . selectedTab && ( parent = this . getParentTab ( aTab ) ) ) {
var newSelection = parent ;
while ( parent . getAttribute ( this . kCOLLAPSED ) == 'true' )
{
parent = this . getParentTab ( parent ) ;
if ( ! parent ) break ;
newSelection = parent ;
}
b . selectedTab = newSelection ;
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 )
2008-07-30 14:03:44 -04:00
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 */
2008-12-01 03:30:36 -05:00
2007-11-17 00:20:26 -05:00
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 {
2008-06-20 01:57:38 -04:00
this . scrollBoxObject . scrollTo ( aEndX , aEndY ) ;
2007-11-17 00:20:26 -05:00
}
catch ( e ) {
2007-11-14 14:34:36 -05:00
}
}
} ,
2008-12-01 03:30:36 -05:00
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
}
2008-06-20 01:57:38 -04:00
var scrollBoxObject = this . scrollBoxObject ;
2007-11-17 00:20:26 -05:00
var x = { } , y = { } ;
scrollBoxObject . getPosition ( x , y ) ;
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 )
{
2008-06-18 22:11:00 -04:00
var past = Date . now ( ) - aStartTime ;
2007-11-17 00:20:26 -05:00
var newX = aStartX + parseInt (
2008-06-18 22:11:00 -04:00
( aEndX - aStartX ) * ( past / aTimeout )
2007-11-17 00:20:26 -05:00
) ;
var newY = aStartY + parseInt (
2008-06-18 22:11:00 -04:00
( aEndY - aStartY ) * ( past / aTimeout )
2007-11-17 00:20:26 -05:00
) ;
2007-11-14 14:34:36 -05:00
2008-06-20 01:57:38 -04:00
var scrollBoxObject = aSelf . scrollBoxObject ;
2007-11-17 00:20:26 -05:00
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 (
2008-06-18 22:11:00 -04:00
( past > aTimeout ) ||
(
2007-11-17 00:20:26 -05:00
(
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 )
)
2008-06-18 22:11:00 -04:00
)
2007-11-17 00:20:26 -05:00
) {
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
2008-06-20 01:57:38 -04:00
var scrollBoxObject = this . scrollBoxObject ;
2007-11-17 00:20:26 -05:00
var w = { } , h = { } ;
try {
scrollBoxObject . getScrolledSize ( w , h ) ;
}
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
2008-06-18 22:11:00 -04:00
if ( this . isTabInViewport ( aTab ) && this . isTabInViewport ( lastVisible ) ) {
return ;
}
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 ( lastPosition - parentPosition + tabSize > containerSize - tabSize ) { // out of screen
2009-01-26 01:39:51 -05:00
var endPos = parentPosition - this . getFirstTab ( b ) . boxObject [ this . positionProp ] - tabSize * 0.5 ;
2007-11-17 00:20:26 -05:00
var endX = this . isVertical ? 0 : endPos ;
var endY = this . isVertical ? endPos : 0 ;
this . scrollTo ( endX , endY ) ;
}
else if ( ! this . isTabInViewport ( aTab ) && this . isTabInViewport ( lastVisible ) ) {
this . scrollToTab ( aTab ) ;
}
else if ( this . isTabInViewport ( aTab ) && ! this . isTabInViewport ( lastVisible ) ) {
this . scrollToTab ( lastVisible ) ;
}
else if ( parentPosition < containerPosition ) {
this . scrollToTab ( aTab ) ;
}
else {
this . scrollToTab ( lastVisible ) ;
2007-11-14 14:34:36 -05:00
}
} ,
2007-11-17 00:20:26 -05:00
2008-03-09 01:36:52 -05:00
/* show/hide tab bar */
2008-06-17 02:22:49 -04:00
tabbarShown : true ,
tabbarExpanded : true ,
2008-10-17 13:16:16 -04:00
2007-11-17 00:20:26 -05:00
get tabbarWidth ( )
2007-11-14 14:34:36 -05:00
{
2008-06-17 02:22:49 -04:00
if ( this . autoHideShown ) {
this . _tabbarWidth = this . mTabBrowser . mStrip . boxObject . width ;
2007-11-17 00:20:26 -05:00
}
return this . _tabbarWidth ;
} ,
set tabbarWidth ( aNewWidth )
{
this . _tabbarWidth = aNewWidth ;
return this . _tabbarWidth ;
} ,
_tabbarWidth : 0 ,
2008-06-17 02:22:49 -04:00
get splitterWidth ( )
{
if ( this . tabbarShown ) {
var splitter = document . getAnonymousElementByAttribute ( this . mTabBrowser , 'class' , this . kSPLITTER ) ;
this . _splitterWidth = ( splitter ? splitter . boxObject . width : 0 ) ;
}
return this . _splitterWidth ;
} ,
set splitterWidth ( aNewWidth )
{
this . _splitterWidth = aNewWidth ;
return this . _splitterWidth ;
} ,
_splitterWidth : 0 ,
2007-11-17 00:20:26 -05:00
get tabbarHeight ( )
{
if ( this . tabbarShown ) {
2008-06-17 02:22:49 -04:00
this . _tabbarHeight = this . mTabBrowser . mStrip . boxObject . height ;
2007-11-17 00:20:26 -05:00
}
return this . _tabbarHeight ;
} ,
set tabbarHeight ( aNewHeight )
{
this . _tabbarHeight = aNewHeight ;
return this . _tabbarHeight ;
} ,
_tabbarHeight : 0 ,
2008-06-17 02:22:49 -04:00
get autoHideShown ( )
{
switch ( this . autoHideMode )
{
case this . kAUTOHIDE _MODE _HIDE :
return this . tabbarShown ;
default :
case this . kAUTOHIDE _MODE _SHRINK :
return this . tabbarExpanded ;
}
} ,
2008-10-17 13:16:16 -04:00
set autoHideShown ( aValue )
2008-06-17 02:22:49 -04:00
{
switch ( this . autoHideMode )
{
case this . kAUTOHIDE _MODE _HIDE :
this . tabbarShown = aValue ;
break ;
default :
case this . kAUTOHIDE _MODE _SHRINK :
this . tabbarExpanded = aValue ;
break ;
}
return aValue ;
} ,
get autoHideXOffset ( )
{
switch ( this . autoHideMode )
{
case this . kAUTOHIDE _MODE _HIDE :
return this . tabbarWidth + this . splitterWidth ;
break ;
default :
case this . kAUTOHIDE _MODE _SHRINK :
return this . getTreePref ( 'tabbar.width' )
- this . getTreePref ( 'tabbar.shrunkenWidth' ) ;
break ;
}
} ,
2008-06-17 07:57:29 -04:00
get autoHideYOffset ( )
2008-06-17 02:22:49 -04:00
{
return this . tabbarHeight ;
} ,
2008-06-17 07:57:29 -04:00
get autoHideMode ( )
{
return TreeStyleTabService . autoHideMode ;
} ,
set autoHideMode ( aValue )
{
TreeStyleTabService . autoHideMode = aValue ;
return aValue ;
} ,
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 ;
2008-06-17 02:22:49 -04:00
2008-06-17 06:16:57 -04:00
var pos = this . mTabBrowser . getAttribute ( this . kTABBAR _POSITION ) ;
2008-06-17 02:22:49 -04:00
if ( this . autoHideShown ) { // to be hidden or shrunken
2008-06-16 22:06:52 -04:00
this . tabbarHeight = b . mStrip . boxObject . height ;
2008-06-17 02:22:49 -04:00
this . tabbarWidth = b . mStrip . boxObject . width ;
var splitter = document . getAnonymousElementByAttribute ( b , 'class' , this . kSPLITTER ) ;
this . splitterWidth = ( splitter ? splitter . boxObject . width : 0 ) ;
2008-06-16 22:06:52 -04:00
this . container . style . margin = 0 ;
2008-06-17 02:22:49 -04:00
switch ( this . autoHideMode )
{
case this . kAUTOHIDE _MODE _HIDE :
b . setAttribute ( this . kAUTOHIDE , 'hidden' ) ;
break ;
default :
case this . kAUTOHIDE _MODE _SHRINK :
b . setAttribute ( this . kAUTOHIDE , 'show' ) ;
2008-06-17 06:16:57 -04:00
if ( pos == 'left' || pos == 'right' )
b . mStrip . width = this . getTreePref ( 'tabbar.shrunkenWidth' ) ;
2008-06-17 02:22:49 -04:00
break ;
}
2008-06-16 22:06:52 -04:00
this . showHideTabbarReason = aReason || this . kSHOWN _BY _UNKNOWN ;
2008-06-17 02:22:49 -04:00
this . autoHideShown = false ;
2008-06-16 22:06:52 -04:00
}
2008-06-17 02:22:49 -04:00
else { // to be shown or expanded
2008-06-16 22:06:52 -04:00
switch ( b . getAttribute ( this . kTABBAR _POSITION ) )
{
case 'left' :
2008-06-17 02:22:49 -04:00
this . container . style . marginRight = '-' + this . autoHideXOffset + 'px' ;
2008-06-16 22:06:52 -04:00
break ;
case 'right' :
2008-06-17 02:22:49 -04:00
this . container . style . marginLeft = '-' + this . autoHideXOffset + 'px' ;
2008-06-16 22:06:52 -04:00
break ;
case 'bottom' :
2008-06-17 02:22:49 -04:00
this . container . style . marginTop = '-' + this . autoHideYOffset + 'px' ;
2008-06-16 22:06:52 -04:00
break ;
default :
2008-06-17 02:22:49 -04:00
this . container . style . marginBottom = '-' + this . autoHideYOffset + 'px' ;
2008-06-16 22:06:52 -04:00
break ;
}
if ( this . isGecko18 ) b . setAttribute ( this . kAUTOHIDE , 'show' ) ;
2008-06-17 02:22:49 -04:00
switch ( this . autoHideMode )
{
case this . kAUTOHIDE _MODE _HIDE :
break ;
default :
case this . kAUTOHIDE _MODE _SHRINK :
2008-06-17 06:16:57 -04:00
if ( pos == 'left' || pos == 'right' )
b . mStrip . width = this . getTreePref ( 'tabbar.width' ) ;
2008-06-17 02:22:49 -04:00
break ;
}
2008-06-16 22:06:52 -04:00
this . showHideTabbarReason = aReason || this . kSHOWN _BY _UNKNOWN ;
2008-06-17 02:22:49 -04:00
this . autoHideShown = true ;
2007-11-17 00:20:26 -05:00
}
2008-03-08 11:30:52 -05:00
window . setTimeout ( function ( aSelf ) {
2008-06-17 02:22:49 -04:00
if (
aSelf . autoHideShown &&
(
aSelf . autoHideMode == aSelf . kAUTOHIDE _MODE _SHRINK ||
! aSelf . isGecko18
)
) {
2008-03-10 01:21:14 -04:00
b . setAttribute ( aSelf . kAUTOHIDE , 'show' ) ;
2008-03-08 11:30:52 -05:00
aSelf . redrawContentArea ( ) ;
}
aSelf . checkTabsIndentOverflow ( ) ;
2008-06-17 02:22:49 -04:00
aSelf . redrawContentArea ( ) ;
2008-03-08 05:44:19 -05:00
fullScreenCanvas . hide ( ) ;
2008-06-25 07:31:55 -04:00
var event = document . createEvent ( 'Events' ) ;
event . initEvent ( 'TreeStyleTabAutoHideStateChange' , true , true ) ;
event . shown = aSelf . autoHideShown ;
2008-06-25 07:34:47 -04:00
event . xOffset = aSelf . autoHideXOffset ;
event . yOffset = aSelf . autoHideYOffset ;
2008-06-25 07:31:55 -04:00
aSelf . mTabBrowser . dispatchEvent ( event ) ;
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-12-01 03:30:36 -05:00
2008-03-08 03:57:17 -05:00
showTabbar : function ( aReason )
{
2008-06-17 02:22:49 -04:00
if ( ! this . autoHideShown )
2008-03-08 03:57:17 -05:00
this . showHideTabbarInternal ( aReason ) ;
} ,
2008-03-08 05:07:28 -05:00
2008-03-08 03:57:17 -05:00
hideTabbar : function ( aReason )
{
2008-06-17 02:22:49 -04:00
if ( this . autoHideShown )
2008-03-08 03:57:17 -05:00
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 ;
2008-06-17 02:22:49 -04:00
if ( this . autoHideShown ) {
2007-11-17 00:20:26 -05:00
v . move (
(
2008-06-17 02:22:49 -04:00
! this . autoHideShown ? 0 :
pos == 'left' ? - this . autoHideXOffset :
pos == 'right' ? this . autoHideXOffset :
2007-11-17 00:20:26 -05:00
0
) ,
(
2008-06-17 02:22:49 -04:00
! this . autoHideShown ? 0 :
pos == 'top' ? - this . autoHideYOffset :
pos == 'bottom' ? this . autoHideYOffset :
2007-11-17 00:20:26 -05:00
0
)
) ;
2008-03-13 19:58:21 -04:00
if ( this . mTabBrowser . hasAttribute ( this . kTRANSPARENT ) &&
2008-06-16 22:06:52 -04:00
this . mTabBrowser . getAttribute ( this . kTRANSPARENT ) != this . kTRANSPARENT _STYLE [ this . kTRANSPARENT _NONE ] )
2008-03-09 23:51:21 -04:00
this . drawTabbarCanvas ( ) ;
2008-06-16 22:06:52 -04:00
else
2008-03-09 23:51:21 -04:00
this . clearTabbarCanvas ( ) ;
2007-11-17 00:20:26 -05:00
}
else {
v . move ( window . outerWidth , window . outerHeight ) ;
v . move ( 0 , 0 ) ;
2008-06-16 22:06:52 -04:00
this . clearTabbarCanvas ( ) ;
2007-11-17 00:20:26 -05:00
}
}
catch ( e ) {
}
2008-03-09 01:36:52 -05:00
} ,
2008-10-17 13:16:16 -04:00
2008-03-09 23:51:21 -04:00
drawTabbarCanvas : function ( )
{
2008-06-17 06:16:57 -04:00
if ( ! this . tabbarCanvas || this . tabbarResizing ) return ;
2008-03-09 23:51:21 -04:00
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 ) ;
2008-06-17 08:32:27 -04:00
var zoom = this . getZoomForFrame ( frame ) ;
2008-06-17 02:22:49 -04:00
var x = ( pos == 'right' ) ? browserBox . width - this . autoHideXOffset : 0 ;
2008-06-17 06:34:03 -04:00
var y = ( pos == 'bottom' ) ? browserBox . height - this . autoHideYOffset : 0 ;
2008-06-17 08:32:27 -04:00
var xOffset = ( zoom == 1 && ( pos == 'top' || pos == 'bottom' ) ) ?
2008-03-09 23:51:21 -04:00
contentBox . screenX + frame . scrollX - browserBox . screenX :
0 ;
2008-06-17 08:32:27 -04:00
var yOffset = ( zoom == 1 && ( pos == 'left' || pos == 'right' ) ) ?
2008-03-09 23:51:21 -04:00
contentBox . screenY + frame . scrollY - browserBox . screenY :
0 ;
2008-03-10 03:21:32 -04:00
// zero width (heigh) canvas becomes wrongly size!!
var w = Math . max ( 1 , ( tabContainerBox . width - xOffset ) ) ;
var h = Math . max ( 1 , ( tabContainerBox . height - yOffset ) ) ;
2008-03-09 23:51:21 -04:00
2008-03-10 03:21:32 -04:00
this . tabbarCanvas . style . display = 'inline' ;
2008-03-09 23:51:21 -04:00
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 ) ;
2008-06-17 02:22:49 -04:00
ctx . save ( ) ;
if ( this . autoHideMode == this . kAUTOHIDE _MODE _SHRINK ) {
var offset = this . getTreePref ( 'tabbar.shrunkenWidth' ) + this . splitterWidth ;
2008-06-17 04:27:16 -04:00
if ( pos == 'left' )
ctx . translate ( offset , 0 ) ;
else
x += this . splitterWidth ;
w -= offset ;
2008-06-17 08:38:22 -04:00
}
2008-03-11 00:43:38 -04:00
ctx . globalAlpha = 1 ;
2008-06-17 04:27:16 -04:00
if ( pos == 'left' || pos == 'right' ) {
2008-06-17 05:07:51 -04:00
ctx . fillStyle = this . splitterBorderColor ;
ctx . fillRect ( ( pos == 'left' ? - 1 : w + 1 ) , 0 , 1 , h ) ;
2008-06-17 04:27:16 -04:00
}
2008-06-17 08:32:27 -04:00
ctx . save ( ) ;
ctx . scale ( zoom , zoom ) ;
2008-06-17 08:38:22 -04:00
ctx . drawWindow (
frame ,
( x / zoom ) + frame . scrollX ,
( y / zoom ) + frame . scrollY ,
w / zoom ,
h / zoom ,
'-moz-field'
) ;
2008-06-17 08:32:27 -04:00
ctx . restore ( ) ;
2008-06-17 08:38:22 -04:00
if ( this . mTabBrowser . getAttribute ( this . kTRANSPARENT ) != this . kTRANSPARENT _STYLE [ this . kTRANSPARENT _FULL ] ) {
var alpha = Number ( this . getTreePref ( 'tabbar.transparent.partialTransparency' ) ) ;
2008-03-11 00:43:38 -04:00
if ( isNaN ( alpha ) ) alpha = 0.25 ;
2008-06-17 04:27:16 -04:00
ctx . globalAlpha = alpha ;
2008-06-17 08:38:22 -04:00
ctx . fillStyle = 'black' ;
ctx . fillRect ( 0 , 0 , w , h ) ;
2008-03-11 00:43:38 -04:00
}
2008-03-09 23:51:21 -04:00
ctx . restore ( ) ;
} ,
2008-06-17 05:07:51 -04:00
get splitterBorderColor ( )
{
var borderNode = this . getTreePref ( 'tabbar.fixed' ) ?
this . mTabBrowser . mStrip :
document . getAnonymousElementByAttribute ( this . mTabBrowser , 'class' , this . kSPLITTER ) ;
var pos = this . mTabBrowser . getAttribute ( this . kTABBAR _POSITION ) ;
var prop = pos == 'left' ? 'right' :
pos == 'right' ? 'left' :
pos == 'top' ? 'bottom' :
'top' ;
var borderColor = window . getComputedStyle ( borderNode , null ) . getPropertyValue ( '-moz-border-' + prop + '-colors' ) ;
if ( borderColor == 'none' )
borderRight = window . getComputedStyle ( borderNode , null ) . getPropertyValue ( 'border-' + prop + '-color' ) ;
/rgba?\(([^,]+),([^,]+),([^,]+)(,.*)?\)/ . test ( borderColor ) ;
return 'rgb(' + [
parseInt ( parseInt ( RegExp . $1 ) * 0.8 ) ,
parseInt ( parseInt ( RegExp . $2 ) * 0.8 ) ,
parseInt ( parseInt ( RegExp . $3 ) * 0.8 )
] . join ( ',' ) + ')' ;
} ,
2008-06-17 08:32:27 -04:00
getZoomForFrame : function ( aFrame )
{
if ( ! this . getPref ( 'browser.zoom.full' ) ) return 1 ;
return aFrame
. QueryInterface ( Components . interfaces . nsIInterfaceRequestor )
. getInterface ( Components . interfaces . nsIWebNavigation )
. QueryInterface ( Components . interfaces . nsIDocShell )
. contentViewer
. QueryInterface ( Components . interfaces . nsIMarkupDocumentViewer )
. fullZoom ;
} ,
2008-03-09 23:51:21 -04:00
clearTabbarCanvas : function ( )
{
if ( ! this . tabbarCanvas ) return ;
2008-03-10 03:21:32 -04:00
this . tabbarCanvas . style . display = 'none' ;
this . tabbarCanvas . style . margin = 0 ;
// zero width (heigh) canvas becomes wrongly size!!
this . tabbarCanvas . style . width = this . tabbarCanvas . style . height = '1px' ;
this . tabbarCanvas . width = this . tabbarCanvas . height = 1 ;
2008-03-09 23:51:21 -04:00
} ,
2008-03-10 00:11:44 -04:00
updateTabbarTransparency : function ( )
{
2008-10-17 13:16:16 -04:00
var pos = this . mTabBrowser . getAttribute ( this . kTABBAR _POSITION ) ;
var style = this . kTRANSPARENT _STYLE [
Math . max (
this . kTRANSPARENT _NONE ,
Math . min (
this . kTRANSPARENT _FULL ,
this . getTreePref ( 'tabbar.transparent.style' )
)
)
2008-03-11 00:43:38 -04:00
] ;
2008-06-16 22:06:52 -04:00
if ( pos != 'top' &&
2008-06-17 07:57:29 -04:00
this . autoHideMode != this . kAUTOHIDE _MODE _DISABLED &&
2008-06-16 22:06:52 -04:00
style != this . kTRANSPARENT _STYLE [ this . kTRANSPARENT _NONE ] )
2008-03-11 00:43:38 -04:00
this . mTabBrowser . setAttribute ( this . kTRANSPARENT , style ) ;
2008-03-10 00:11:44 -04:00
else
this . mTabBrowser . removeAttribute ( this . kTRANSPARENT ) ;
} ,
2008-03-09 01:36:52 -05:00
/* auto hide */
2008-06-16 22:06:52 -04:00
autoHideEnabled : false ,
2008-10-17 13:16:16 -04:00
2008-06-17 02:22:49 -04:00
get sensitiveArea ( )
2008-03-09 01:36:52 -05:00
{
2008-06-17 02:22:49 -04:00
var b = this . mTabBrowser ;
2008-06-17 03:43:21 -04:00
var area = Math . abs ( this . getTreePref ( 'tabbar.autoHide.area' ) ) ;
2008-06-17 02:22:49 -04:00
var pos = b . getAttribute ( this . kTABBAR _POSITION ) ;
switch ( this . autoHideMode )
{
case this . kAUTOHIDE _MODE _HIDE :
if ( ! this . tabbarShown &&
this . getTreePref ( 'tabbar.autoHide.expandArea' ) )
area += ( pos == 'left' || pos == 'right' ) ?
this . autoHideXOffset + this . splitterWidth :
this . autoHideYOffset ;
break ;
default :
case this . kAUTOHIDE _MODE _SHRINK :
if ( pos == 'left' || pos == 'right' ) {
2008-06-17 03:43:21 -04:00
if ( ! this . tabbarExpanded )
area = b . mStrip . boxObject . width - area ;
2008-06-17 02:22:49 -04:00
}
break ;
}
return area ;
2008-03-09 01:36:52 -05:00
} ,
startAutoHide : function ( )
{
if ( this . autoHideEnabled ) return ;
this . autoHideEnabled = true ;
this . mTabBrowser . addEventListener ( 'mousedown' , this , true ) ;
this . mTabBrowser . addEventListener ( 'mouseup' , this , true ) ;
this . mTabBrowser . addEventListener ( 'resize' , this , true ) ;
this . mTabBrowser . addEventListener ( 'load' , this , true ) ;
2008-06-18 20:15:57 -04:00
this . mTabBrowser . mPanelContainer . addEventListener ( 'scroll' , 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 ;
2008-06-17 02:22:49 -04:00
this . tabbarExpanded = true ;
2008-03-09 01:36:52 -05:00
this . showHideTabbarInternal ( ) ;
} ,
endAutoHide : function ( )
{
if ( ! this . autoHideEnabled ) return ;
this . autoHideEnabled = false ;
2008-06-17 08:55:05 -04:00
if ( ! this . autoHideShown )
this . showHideTabbarInternal ( ) ;
2008-03-09 01:36:52 -05:00
this . mTabBrowser . removeEventListener ( 'mousedown' , this , true ) ;
this . mTabBrowser . removeEventListener ( 'mouseup' , this , true ) ;
this . mTabBrowser . removeEventListener ( 'resize' , this , true ) ;
this . mTabBrowser . removeEventListener ( 'load' , this , true ) ;
2008-06-18 20:15:57 -04:00
this . mTabBrowser . mPanelContainer . removeEventListener ( 'scroll' , 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-06-17 02:22:49 -04:00
this . tabbarExpanded = true ;
2008-03-09 01:36:52 -05:00
} ,
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 ( ) ;
2008-06-17 02:22:49 -04:00
var b = this . mTabBrowser ;
var pos = b . getAttribute ( this . kTABBAR _POSITION ) ;
2008-03-09 01:36:52 -05:00
if (
(
2008-06-17 02:22:49 -04:00
! this . autoHideShown ||
2008-03-09 01:36:52 -05:00
this . showHideTabbarReason == this . kSHOWN _BY _FEEDBACK
) &&
(
pos == 'left' ?
2008-06-17 02:22:49 -04:00
( aEvent . screenX <= b . boxObject . screenX + this . sensitiveArea ) :
2008-03-09 01:36:52 -05:00
pos == 'right' ?
2008-06-17 02:22:49 -04:00
( aEvent . screenX >= b . boxObject . screenX + b . boxObject . width - this . sensitiveArea ) :
2008-03-09 01:36:52 -05:00
pos == 'bottom' ?
2008-06-17 02:22:49 -04:00
( aEvent . screenY >= b . boxObject . screenY + b . boxObject . height - this . sensitiveArea ) :
( aEvent . screenY <= b . boxObject . screenY + this . sensitiveArea )
2008-03-09 01:36:52 -05:00
) )
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
) ;
2008-06-17 02:22:49 -04:00
if ( this . autoHideShown &&
2008-03-09 01:36:52 -05:00
(
pos == 'left' ?
2008-06-17 02:22:49 -04:00
( aEvent . screenX > b . mCurrentBrowser . boxObject . screenX + this . sensitiveArea ) :
2008-03-09 01:36:52 -05:00
pos == 'right' ?
2008-06-17 02:22:49 -04:00
( aEvent . screenX < b . mCurrentBrowser . boxObject . screenX + b . mCurrentBrowser . boxObject . width - this . sensitiveArea ) :
2008-03-09 01:36:52 -05:00
pos == 'bottom' ?
2008-06-17 02:22:49 -04:00
( aEvent . screenY < b . mCurrentBrowser . boxObject . screenY + b . mCurrentBrowser . boxObject . height - this . sensitiveArea ) :
( aEvent . screenY > b . mCurrentBrowser . boxObject . screenY + this . sensitiveArea )
2008-03-09 01:36:52 -05:00
) )
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 ,
2008-12-01 03:30:36 -05:00
2008-03-09 01:36:52 -05:00
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
) ;
} ,
2008-12-01 03:30:36 -05:00
2008-03-09 01:36:52 -05:00
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 ;