1443 lines
40 KiB
JavaScript
1443 lines
40 KiB
JavaScript
/* ***** BEGIN LICENSE BLOCK *****
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
*
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
* http://www.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
* for the specific language governing rights and limitations under the
|
|
* License.
|
|
*
|
|
* The Original Code is the Tree Style Tab.
|
|
*
|
|
* The Initial Developer of the Original Code is YUKI "Piro" Hiroshi.
|
|
* Portions created by the Initial Developer are Copyright (C) 2010-2014
|
|
* the Initial Developer. All Rights Reserved.
|
|
*
|
|
* Contributor(s): YUKI "Piro" Hiroshi <piro.outsider.reflex@gmail.com>
|
|
* Tetsuharu OHZEKI <https://github.com/saneyuki>
|
|
*
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
* use your version of this file under the terms of the MPL, indicate your
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
* the provisions above, a recipient may use your version of this file under
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
*
|
|
* ***** END LICENSE BLOCK ******/
|
|
|
|
const EXPORTED_SYMBOLS = ['AutoHideBrowser', 'AutoHideWindow'];
|
|
|
|
const DEBUG = false;
|
|
|
|
const Cc = Components.classes;
|
|
const Ci = Components.interfaces;
|
|
const Cu = Components.utils;
|
|
|
|
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
|
Cu.import('resource://gre/modules/Services.jsm');
|
|
Cu.import('resource://treestyletab-modules/lib/inherit.jsm');
|
|
Cu.import('resource://treestyletab-modules/constants.js');
|
|
|
|
XPCOMUtils.defineLazyModuleGetter(this, 'utils', 'resource://treestyletab-modules/utils.js', 'TreeStyleTabUtils');
|
|
|
|
XPCOMUtils.defineLazyGetter(this, 'window', function() {
|
|
Cu.import('resource://treestyletab-modules/lib/namespace.jsm');
|
|
return getNamespaceFor('piro.sakura.ne.jp');
|
|
});
|
|
XPCOMUtils.defineLazyGetter(this, 'prefs', function() {
|
|
Cu.import('resource://treestyletab-modules/lib/prefs.js');
|
|
return window['piro.sakura.ne.jp'].prefs;
|
|
});
|
|
|
|
|
|
function AutoHideBrowser(aTabBrowser)
|
|
{
|
|
this.init(aTabBrowser);
|
|
}
|
|
AutoHideBrowser.prototype = inherit(TreeStyleTabConstants, {
|
|
|
|
kMODE : 'treestyletab-tabbar-autohide-mode',
|
|
kMODE_DISABLED : 0,
|
|
kMODE_HIDE : 1,
|
|
kMODE_SHRINK : 2,
|
|
|
|
kAUTOHIDE : 'treestyletab-tabbar-autohide',
|
|
|
|
kSTATE : 'treestyletab-tabbar-autohide-state',
|
|
kSTATE_HIDDEN : 'hidden',
|
|
kSTATE_EXPANDED : 'expanded',
|
|
kSTATE_SHRUNKEN : 'shrunken',
|
|
|
|
kSHOWN_BY_UNKNOWN : 0,
|
|
kSHOWN_BY_SHORTCUT : 1 << 0,
|
|
kSHOWN_BY_MOUSEMOVE : 1 << 1,
|
|
kSHOWN_BY_FEEDBACK : 1 << 2,
|
|
kSHOWN_BY_ANY_REASON : (1 << 0) | (1 << 1) | (1 << 2),
|
|
kSHOWHIDE_BY_START : 1 << 3,
|
|
kSHOWHIDE_BY_END : 1 << 4,
|
|
kSHOWHIDE_BY_POSITION_CHANGE : 1 << 5,
|
|
kSHOWHIDE_BY_RESIZE : 1 << 6,
|
|
kSHOWHIDE_BY_API : 1 << 8,
|
|
kHIDDEN_BY_CLICK : 1 << 7,
|
|
|
|
get mode() /* PUBLIC API */
|
|
{
|
|
var mode = this.browser.getAttribute(this.kMODE);
|
|
return mode ? parseInt(mode) : this.kMODE_DISABLED ;
|
|
},
|
|
set mode(aValue)
|
|
{
|
|
this.browser.setAttribute(this.kMODE, aValue);
|
|
return aValue;
|
|
},
|
|
|
|
getMode : function AHB_getMode(aTabBrowser)
|
|
{
|
|
var b = aTabBrowser || this.browser;
|
|
var mode = b.getAttribute(this.kMODE);
|
|
return mode ? parseInt(mode) : this.kMODE_DISABLED ;
|
|
},
|
|
getModeForNormal : function AHB_getModeForNormal(aTabBrowser)
|
|
{
|
|
var b = aTabBrowser || this.browser;
|
|
return parseInt(b.getAttribute(this.kMODE+'-normal') || utils.getTreePref('tabbar.autoHide.mode'));
|
|
},
|
|
getModeForFullScreen : function AHB_getModeForFullScreen(aTabBrowser)
|
|
{
|
|
var b = aTabBrowser || this.browser;
|
|
return parseInt(b.getAttribute(this.kMODE+'-fullscreen') || utils.getTreePref('tabbar.autoHide.mode.fullscreen'));
|
|
},
|
|
|
|
get state()
|
|
{
|
|
return this.browser.getAttribute(this.kSTATE) || this.kSTATE_EXPANDED;
|
|
},
|
|
get expanded()
|
|
{
|
|
return this.state == this.kSTATE_EXPANDED;
|
|
},
|
|
get shrunken()
|
|
{
|
|
return this.state == this.kSTATE_SHRUNKEN;
|
|
},
|
|
get hidden()
|
|
{
|
|
return this.state == this.kSTATE_HIDDEN;
|
|
},
|
|
|
|
updateMode : function AHB_updateMode()
|
|
{
|
|
this.end();
|
|
// update internal property after the appearance of the tab bar is updated.
|
|
var w = this.window;
|
|
w.setTimeout(function(aSelf) {
|
|
aSelf.mode = (w.fullScreen && prefs.getPref('browser.fullscreen.autohide')) ?
|
|
aSelf.getModeForFullScreen() :
|
|
aSelf.getModeForNormal() ;
|
|
if (aSelf.mode != aSelf.kMODE_DISABLED)
|
|
aSelf.start();
|
|
}, 0, this);
|
|
},
|
|
|
|
togglerSize : 0,
|
|
sensitiveArea : 7,
|
|
contentAreaScreenEnabled : true,
|
|
|
|
closeButtonsMode : -1,
|
|
CLOSE_BUTTONS_ONLY_ON_CURRENT_TAB : 0,
|
|
CLOSE_BUTTONS_ON_ALL_TABS : 1,
|
|
CLOSE_BUTTONS_DISABLED : 2,
|
|
CLOSE_BUTTONS_ON_TABBAR : 3,
|
|
|
|
get XOffset()
|
|
{
|
|
var sv = this.treeStyleTab;
|
|
switch (this.mode)
|
|
{
|
|
case this.kMODE_DISABLED:
|
|
return 0;
|
|
|
|
case this.kMODE_HIDE:
|
|
let offset = this.width + this.splitterWidth;
|
|
let resizer = this.resizer;
|
|
if (sv.position == 'left') {
|
|
offset += this.togglerSize;
|
|
if (resizer)
|
|
offset += resizer.boxObject.width;
|
|
}
|
|
else if (sv.position == 'right') {
|
|
offset -= this.togglerSize;
|
|
if (resizer)
|
|
offset -= resizer.boxObject.width;
|
|
}
|
|
return offset;
|
|
|
|
default:
|
|
case this.kMODE_SHRINK:
|
|
return utils.getTreePref('tabbar.width')
|
|
- utils.getTreePref('tabbar.shrunkenWidth');
|
|
}
|
|
},
|
|
get YOffset()
|
|
{
|
|
return this.height;
|
|
},
|
|
extraXOffset : 0,
|
|
extraYOffset : 0,
|
|
|
|
get currentXOffset()
|
|
{
|
|
var sv = this.treeStyleTab;
|
|
return (
|
|
sv.position == 'left' &&
|
|
this.mode != this.kMODE_DISABLED &&
|
|
this.expanded
|
|
) ? this.XOffset : 0 ;
|
|
},
|
|
get currentYOffset()
|
|
{
|
|
var sv = this.treeStyleTab;
|
|
return (
|
|
sv.position == 'top' &&
|
|
this.mode != this.kMODE_DISABLED &&
|
|
this.expanded
|
|
) ? this.YOffset : 0 ;
|
|
},
|
|
|
|
get screen()
|
|
{
|
|
return this.document.getElementById('treestyletab-autohide-content-area-screen');
|
|
},
|
|
get resizer()
|
|
{
|
|
return this.document.getElementById('treestyletab-tabbar-resizer-splitter');
|
|
},
|
|
|
|
start : function AHB_start(aReason)
|
|
{
|
|
if (this.enabled) return;
|
|
this.enabled = true;
|
|
aReason = aReason || 0;
|
|
|
|
var sv = this.treeStyleTab;
|
|
var b = this.browser;
|
|
var w = this.window;
|
|
|
|
this.screen.hidePopup();
|
|
|
|
sv.setTabbrowserAttribute(this.kSTATE, this.kSTATE_EXPANDED);
|
|
|
|
if (!(aReason & this.kSHOWHIDE_BY_API)) {
|
|
b.addEventListener('dragover', this, true);
|
|
b.addEventListener('dragleave', this, true);
|
|
sv.tabStripPlaceHolder.addEventListener('mousedown', this, true);
|
|
sv.tabStripPlaceHolder.addEventListener('mouseup', this, true);
|
|
sv.tabStrip.addEventListener('mousedown', this, true);
|
|
sv.tabStrip.addEventListener('mouseup', this, true);
|
|
if (this.shouldListenMouseMove)
|
|
this.startListenMouseMove();
|
|
if (b == w.gBrowser && sv.shouldListenKeyEventsForAutoHide)
|
|
w.TreeStyleTabService.startListenKeyEventsFor(sv.LISTEN_FOR_AUTOHIDE);
|
|
this.userActionListening = true;
|
|
this.notifyStatusToAllTabs();
|
|
}
|
|
w.addEventListener(sv.kEVENT_TYPE_PRINT_PREVIEW_ENTERED, this, false);
|
|
w.addEventListener(sv.kEVENT_TYPE_PRINT_PREVIEW_EXITED, this, false);
|
|
|
|
this.updateTransparency();
|
|
|
|
this.showHideInternal(this.kSHOWHIDE_BY_START | aReason);
|
|
|
|
b.treeStyleTab.fixTooNarrowTabbar();
|
|
},
|
|
|
|
end : function AHB_end()
|
|
{
|
|
if (!this.enabled) return;
|
|
this.enabled = false;
|
|
|
|
var sv = this.treeStyleTab;
|
|
var b = this.browser;
|
|
var w = this.window;
|
|
|
|
this.show(this.kSHOWHIDE_BY_END);
|
|
|
|
this.screen.hidePopup();
|
|
|
|
if (this.userActionListening) {
|
|
b.removeEventListener('dragover', this, true);
|
|
b.removeEventListener('dragleave', this, true);
|
|
sv.tabStripPlaceHolder.removeEventListener('mousedown', this, true);
|
|
sv.tabStripPlaceHolder.removeEventListener('mouseup', this, true);
|
|
sv.tabStrip.removeEventListener('mousedown', this, true);
|
|
sv.tabStrip.removeEventListener('mouseup', this, true);
|
|
this.endListenMouseMove();
|
|
if (b == w.gBrowser)
|
|
w.TreeStyleTabService.endListenKeyEventsFor(sv.LISTEN_FOR_AUTOHIDE);
|
|
this.userActionListening = false;
|
|
this.notifyStatusToAllTabs();
|
|
}
|
|
w.removeEventListener(sv.kEVENT_TYPE_PRINT_PREVIEW_ENTERED, this, false);
|
|
w.removeEventListener(sv.kEVENT_TYPE_PRINT_PREVIEW_EXITED, this, false);
|
|
|
|
this.updateTransparency();
|
|
|
|
sv.removeTabbrowserAttribute(this.kAUTOHIDE);
|
|
sv.removeTabbrowserAttribute(this.kSTATE);
|
|
|
|
if (sv.isVertical)
|
|
sv.setTabStripAttribute('width', this.widthFromMode);
|
|
},
|
|
|
|
notifyStatusToAllTabs : function AHB_notifyStatusToAllTabs()
|
|
{
|
|
let tabs = this.treeStyleTab.getTabs(this.browser);
|
|
tabs.forEach(this.notifyStatusToTab, this);
|
|
},
|
|
notifyStatusToTab : function AHB_notifyStatusToTab(aTab)
|
|
{
|
|
aTab.__treestyletab__contentBridge.sendAsyncCommand(this.COMMAND_NOTIFY_AUTOHIDE_STATUS, {
|
|
basicListening : this.mouseMoveListening || this.userActionListening,
|
|
advanceListening : this.mouseMoveListening
|
|
});
|
|
},
|
|
|
|
// fullscreen
|
|
|
|
startForFullScreen : function AHB_startForFullScreen()
|
|
{
|
|
this.mode = this.getMode();
|
|
this.end();
|
|
this.mode = prefs.getPref('browser.fullscreen.autohide') ?
|
|
this.getModeForFullScreen() :
|
|
this.kMODE_DISABLED ;
|
|
if (this.mode != this.kMODE_DISABLED) {
|
|
this.start();
|
|
this.treeStyleTab.removeTabbrowserAttribute('moz-collapsed');
|
|
}
|
|
},
|
|
|
|
endForFullScreen : function AHB_endForFullScreen()
|
|
{
|
|
this.mode = this.getModeForFullScreen();
|
|
this.end();
|
|
this.mode = utils.getTreePref('tabbar.autoHide.mode');
|
|
this.treeStyleTab.checkTabsIndentOverflow();
|
|
if (this.mode != this.kMODE_DISABLED)
|
|
this.start();
|
|
},
|
|
|
|
// mousemove
|
|
|
|
startListenMouseMove : function AHB_startListenMouseMove()
|
|
{
|
|
if (this.mouseMoveListening) return;
|
|
|
|
this.screen.addEventListener('mousemove', this, true);
|
|
this.treeStyleTab.tabStripPlaceHolder.addEventListener('mousemove', this, true);
|
|
this.treeStyleTab.tabStrip.addEventListener('mousemove', this, true);
|
|
|
|
this.mouseMoveListening = true;
|
|
|
|
this.notifyStatusToAllTabs();
|
|
},
|
|
|
|
endListenMouseMove : function AHB_endListenMouseMove()
|
|
{
|
|
if (!this.mouseMoveListening) return;
|
|
|
|
this.screen.removeEventListener('mousemove', this, true);
|
|
this.treeStyleTab.tabStripPlaceHolder.removeEventListener('mousemove', this, true);
|
|
this.treeStyleTab.tabStrip.removeEventListener('mousemove', this, true);
|
|
|
|
this.mouseMoveListening = false;
|
|
|
|
this.notifyStatusToAllTabs();
|
|
},
|
|
|
|
get shouldListenMouseMove()
|
|
{
|
|
return utils.getTreePref('tabbar.autoShow.mousemove');
|
|
},
|
|
|
|
get shouldListenKeyEventsForAutoHide()
|
|
{
|
|
return utils.getTreePref('tabbar.autoShow.accelKeyDown') ||
|
|
utils.getTreePref('tabbar.autoShow.tabSwitch');
|
|
},
|
|
|
|
showHideOnMouseMove : function AHB_showHideOnMouseMove(aCoordinates)
|
|
{
|
|
var position = this.getMousePosition(aCoordinates);
|
|
if (position == this.MOUSE_POSITION_UNKNOWN)
|
|
return;
|
|
|
|
this.cancelShowHideOnMouseMove();
|
|
this.showHideContentsAreaScreen();
|
|
|
|
var sv = this.treeStyleTab;
|
|
var b = this.browser;
|
|
var w = this.window;
|
|
|
|
var shouldShow = position & this.MOUSE_POSITION_SENSITIVE;
|
|
if (this.expanded) { // currently shown, let's hide it.
|
|
if (shouldShow) {
|
|
this.show(this.kSHOWN_BY_MOUSEMOVE);
|
|
this.cancelDelayedShowForShortcut();
|
|
}
|
|
else if (
|
|
!shouldShow &&
|
|
utils.getTreePref('tabbar.autoShow.mousemove')
|
|
) {
|
|
this.showHideOnMouseMoveTimer = w.setTimeout(
|
|
function(aSelf) {
|
|
aSelf.cancelDelayedShowForShortcut();
|
|
aSelf.hide(aSelf.kSHOWN_BY_MOUSEMOVE);
|
|
},
|
|
utils.getTreePref('tabbar.autoHide.delay'),
|
|
this
|
|
);
|
|
}
|
|
}
|
|
else if (shouldShow) { // currently shown, let's show it.
|
|
this.showHideOnMouseMoveTimer = w.setTimeout(
|
|
function(aSelf) {
|
|
aSelf.cancelDelayedShowForShortcut();
|
|
aSelf.show(aSelf.kSHOWN_BY_MOUSEMOVE);
|
|
},
|
|
utils.getTreePref('tabbar.autoHide.delay'),
|
|
this
|
|
);
|
|
}
|
|
|
|
b = null;
|
|
},
|
|
getMousePosition : function AHB_getMousePosition(aCoordinates)
|
|
{
|
|
var w = this.window;
|
|
if ('gestureInProgress' in w && w.gestureInProgress)
|
|
return this.MOUSE_POSITION_UNKNOWN;
|
|
|
|
var sv = this.treeStyleTab;
|
|
var b = this.browser;
|
|
var pos = sv.position;
|
|
var box = this.getContentsAreaBox();
|
|
|
|
var sensitiveArea = this.sensitiveArea;
|
|
if (this.shrunken) {
|
|
let clickable;
|
|
let resizable = !sv.fixed;
|
|
if (resizable &
|
|
this.widthFromMode > 24 &&
|
|
(clickable = this.getNearestClickableBox(aCoordinates))) {
|
|
/* For resizing of shrunken tab bar and clicking closeboxes,
|
|
we have to shrink sensitive area. */
|
|
sensitiveArea = -(clickable.width + clickable.padding);
|
|
}
|
|
else if (resizable && this.resizer)
|
|
sensitiveArea = -this.resizer.boxObject.width;
|
|
else
|
|
sensitiveArea = 0;
|
|
}
|
|
|
|
if (
|
|
pos == 'left' ?
|
|
(aCoordinates.screenX > box.screenX + sensitiveArea) :
|
|
pos == 'right' ?
|
|
(aCoordinates.screenX < box.screenX + box.width - sensitiveArea) :
|
|
pos == 'bottom' ?
|
|
(aCoordinates.screenY < box.screenY + box.height - sensitiveArea) :
|
|
(aCoordinates.screenY > box.screenY + sensitiveArea)
|
|
) {
|
|
return this.MOUSE_POSITION_OUTSIDE;
|
|
}
|
|
|
|
if (
|
|
pos == 'left' ?
|
|
(aCoordinates.screenX <= box.screenX - sensitiveArea) :
|
|
pos == 'right' ?
|
|
(aCoordinates.screenX >= box.screenX + box.width + sensitiveArea) :
|
|
pos == 'bottom' ?
|
|
(aCoordinates.screenY >= box.screenY + box.height + sensitiveArea) :
|
|
(aCoordinates.screenY <= box.screenY - sensitiveArea)
|
|
) {
|
|
return this.MOUSE_POSITION_INSIDE;
|
|
}
|
|
|
|
return this.MOUSE_POSITION_NEAR;
|
|
},
|
|
getContentsAreaBox : function AHB_getContentsAreaBox()
|
|
{
|
|
var sv = this.treeStyleTab;
|
|
var b = this.browser;
|
|
var box = b.mCurrentBrowser.boxObject;
|
|
var xoffset = (this.shrunken || this.hidden) ? 0 : this.XOffset ;
|
|
box = {
|
|
screenX : box.screenX + (sv.position == 'left' ? xoffset : 0 ),
|
|
screenY : box.screenY,
|
|
width : box.width - xoffset,
|
|
height : box.height
|
|
};
|
|
return box;
|
|
},
|
|
MOUSE_POSITION_UNKNOWN : 0,
|
|
MOUSE_POSITION_OUTSIDE : (1 << 0),
|
|
MOUSE_POSITION_INSIDE : (1 << 1),
|
|
MOUSE_POSITION_NEAR : (1 << 2),
|
|
MOUSE_POSITION_SENSITIVE : (1 << 1) | (1 << 2),
|
|
getNearestClickableBox : function AHB_getNearestClickableBox(aCoordinates)
|
|
{
|
|
var sv = this.treeStyleTab;
|
|
var tab = sv.getTabFromCoordinates(aCoordinates);
|
|
if (!tab)
|
|
return null;
|
|
|
|
var position = sv.invertedScreenPositionProp;
|
|
var size = sv.invertedSizeProp;
|
|
var coordinate = aCoordinates[sv.invertedScreenPositionProp];
|
|
var tabbox = tab.boxObject;
|
|
|
|
var closebox;
|
|
if (this.closeButtonsMode != this.CLOSE_BUTTONS_DISABLED &&
|
|
this.closeButtonsMode != this.CLOSE_BUTTONS_ON_TABBAR &&
|
|
(closebox = sv.getTabClosebox(tab)) &&
|
|
(closebox = closebox.boxObject) &&
|
|
closebox.width && closebox.height) {
|
|
let padding = Math.min(
|
|
closebox[position] - tabbox[position],
|
|
(tabbox[position] + tabbox[size]) - (closebox[position] + closebox[size])
|
|
);
|
|
if (closebox[position] - padding <= coordinate &&
|
|
closebox[position] + closebox[size] + padding >= coordinate)
|
|
return this.cloneBoxObject(closebox, { padding : padding });
|
|
}
|
|
|
|
var twisty;
|
|
if (sv.canCollapseSubtree(tab) &&
|
|
(twisty = sv.getTabTwisty(tab)) &&
|
|
(twisty = twisty.boxObject) &&
|
|
twisty.width && twisty.height) {
|
|
let padding = Math.min(
|
|
twisty[position] - tabbox[position],
|
|
(tabbox[position] + tabbox[size]) - (twisty[position] + twisty[size])
|
|
);
|
|
if (twisty[position] - padding <= coordinate &&
|
|
twisty[position] + twisty[size] + padding >= coordinate)
|
|
return this.cloneBoxObject(twisty, { padding : padding });
|
|
}
|
|
|
|
return null;
|
|
},
|
|
cloneBoxObject : function AHB_cloneBoxObject(aBoxObject, aOverride)
|
|
{
|
|
var box = {};
|
|
for (let i in aBoxObject)
|
|
{
|
|
if (typeof aBoxObject[i] != 'function')
|
|
box[i] = aBoxObject[i];
|
|
}
|
|
Object.keys(aOverride).forEach(function(aKey) {
|
|
box[aKey] = aOverride[aKey];
|
|
});
|
|
return box;
|
|
},
|
|
|
|
cancelShowHideOnMouseMove : function AHB_cancelShowHideOnMouseMove()
|
|
{
|
|
if (this.showHideOnMouseMoveTimer) {
|
|
this.window.clearTimeout(this.showHideOnMouseMoveTimer);
|
|
this.showHideOnMouseMoveTimer = null;
|
|
}
|
|
},
|
|
|
|
// feedback
|
|
|
|
showForFeedback : function AHB_showForFeedback()
|
|
{
|
|
if (!this.enabled ||
|
|
!utils.getTreePref('tabbar.autoShow.feedback'))
|
|
return;
|
|
|
|
var w = this.window;
|
|
if (this.delayedShowForFeedbackTimer) {
|
|
w.clearTimeout(this.delayedShowForFeedbackTimer);
|
|
this.delayedShowForFeedbackTimer = null;
|
|
}
|
|
this.cancelHideForFeedback();
|
|
this.delayedShowForFeedbackTimer = w.setTimeout(
|
|
function(aSelf) {
|
|
aSelf.delayedShowForFeedbackTimer = null;
|
|
aSelf.delayedShowForFeedback();
|
|
},
|
|
100,
|
|
this
|
|
);
|
|
},
|
|
|
|
delayedShowForFeedback : function AHB_delayedShowForFeedback()
|
|
{
|
|
this.show(this.kSHOWN_BY_FEEDBACK);
|
|
this.cancelHideForFeedback();
|
|
this.delayedHideTabbarForFeedbackTimer = this.window.setTimeout(
|
|
function(aSelf) {
|
|
aSelf.delayedHideTabbarForFeedbackTimer = null;
|
|
aSelf.hide(aSelf.kSHOWN_BY_FEEDBACK);
|
|
},
|
|
utils.getTreePref('tabbar.autoShow.feedback.delay'),
|
|
this
|
|
);
|
|
},
|
|
|
|
cancelHideForFeedback : function AHB_cancelHideForFeedback()
|
|
{
|
|
if (this.delayedHideTabbarForFeedbackTimer) {
|
|
this.window.clearTimeout(this.delayedHideTabbarForFeedbackTimer);
|
|
this.delayedHideTabbarForFeedbackTimer = null;
|
|
}
|
|
},
|
|
|
|
setWidth : function AHB_setWidth(aWidth, aForceExpanded)
|
|
{
|
|
if (aForceExpanded ||
|
|
this.expanded ||
|
|
this.mode != this.kMODE_SHRINK)
|
|
utils.setTreePref('tabbar.width', this.treeStyleTab.maxTabbarWidth(aWidth));
|
|
else
|
|
utils.setTreePref('tabbar.shrunkenWidth', this.treeStyleTab.maxTabbarWidth(aWidth));
|
|
},
|
|
|
|
updateMenuItem : function AHB_updateMenuItem(aNode)
|
|
{
|
|
if (!aNode) return;
|
|
|
|
if (this.mode != this.kMODE_DISABLED)
|
|
aNode.setAttribute('checked', true);
|
|
else
|
|
aNode.removeAttribute('checked');
|
|
},
|
|
|
|
// show/hide tabbar
|
|
|
|
get width()
|
|
{
|
|
if (this.expanded) {
|
|
this._width = this.treeStyleTab.tabStrip.boxObject.width || this._width;
|
|
}
|
|
return this._width;
|
|
},
|
|
set width(aNewWidth)
|
|
{
|
|
this._width = aNewWidth;
|
|
return this._width;
|
|
},
|
|
_width : 0,
|
|
|
|
get widthFromMode()
|
|
{
|
|
return (this.shrunken) ?
|
|
utils.getTreePref('tabbar.shrunkenWidth') :
|
|
utils.getTreePref('tabbar.width') ;
|
|
},
|
|
get placeHolderWidthFromMode()
|
|
{
|
|
return (this.mode == this.kMODE_SHRINK) ?
|
|
utils.getTreePref('tabbar.shrunkenWidth') :
|
|
utils.getTreePref('tabbar.width') ;
|
|
},
|
|
|
|
get height()
|
|
{
|
|
if (this.expanded) {
|
|
this._height = this.treeStyleTab.tabStrip.boxObject.height;
|
|
}
|
|
return this._height;
|
|
},
|
|
set height(aNewHeight)
|
|
{
|
|
this._height = aNewHeight;
|
|
return this._height;
|
|
},
|
|
_height : 0,
|
|
|
|
get splitterWidth()
|
|
{
|
|
if (this.expanded) {
|
|
var splitter = this.document.getAnonymousElementByAttribute(this.browser, 'class', this.treeStyleTab.kSPLITTER);
|
|
this._splitterWidth = (splitter ? splitter.boxObject.width : 0 );
|
|
}
|
|
return this._splitterWidth;
|
|
},
|
|
set splitterWidth(aNewWidth)
|
|
{
|
|
this._splitterWidth = aNewWidth;
|
|
return this._splitterWidth;
|
|
},
|
|
_splitterWidth : 0,
|
|
|
|
showHideInternal : function AHB_showHideInternal(aReason)
|
|
{
|
|
var sv = this.treeStyleTab;
|
|
var b = this.browser;
|
|
var pos = sv.position;
|
|
|
|
aReason = aReason || 0;
|
|
|
|
if (this.expanded) { // to be hidden or shrunken
|
|
let reason = this.kSHOWN_BY_UNKNOWN;
|
|
if (aReason & this.kSHOWHIDE_BY_API)
|
|
reason = aReason;
|
|
this.onHiding();
|
|
this.showHideReason = reason;
|
|
}
|
|
else { // to be shown or expanded
|
|
this.onShowing();
|
|
this.showHideReason = aReason || this.showHideReason || this.kSHOWN_BY_UNKNOWN;
|
|
}
|
|
|
|
if (DEBUG) {
|
|
let humanReadableReason =
|
|
(aReason & this.kSHOWN_BY_SHORTCUT ? 'shortcut ' : '' ) +
|
|
(aReason & this.kSHOWN_BY_MOUSEMOVE ? 'mousemove ' : '' ) +
|
|
(aReason & this.kSHOWN_BY_FEEDBACK ? 'feedback ' : '' ) +
|
|
(aReason & this.kSHOWHIDE_BY_START ? 'start ' : '' ) +
|
|
(aReason & this.kSHOWHIDE_BY_END ? 'end ' : '' ) +
|
|
(aReason & this.kSHOWHIDE_BY_POSITION_CHANGE ? 'positionchange ' : '' ) +
|
|
(aReason & this.kSHOWHIDE_BY_RESIZE ? 'resize ' : '' ) +
|
|
(aReason & this.kHIDDEN_BY_CLICK ? 'click ' : '' );
|
|
if (this.expanded)
|
|
dump('autoHide: show by ' + humanReadableReason + '\n');
|
|
else
|
|
dump('autoHide: hide by ' + humanReadableReason + '\n');
|
|
}
|
|
|
|
this.fireStateChangingEvent();
|
|
|
|
if (this.expanded)
|
|
sv.setTabbrowserAttribute(this.kAUTOHIDE, 'show');
|
|
b.mTabContainer.adjustTabstrip();
|
|
sv.checkTabsIndentOverflow();
|
|
|
|
this.window.setTimeout(function(aSelf) {
|
|
aSelf.fireStateChangeEvent();
|
|
aSelf.showHideContentsAreaScreen();
|
|
}, 0, this);
|
|
},
|
|
showHideContentsAreaScreen : function AHB_showHideContentsAreaScreen()
|
|
{
|
|
if (
|
|
this.expanded &&
|
|
this.contentAreaScreenEnabled &&
|
|
Services.focus.activeWindow &&
|
|
Services.focus.activeWindow.top == this.window
|
|
) {
|
|
this.browser.selectedTab.__treestyletab__contentBridge.checkPluginAreaExistence()
|
|
.then((function(aExistence) {
|
|
if (aExistence)
|
|
this.showContentsAreaScreen();
|
|
else
|
|
this.hideContentsAreaScreen();
|
|
}).bind(this))
|
|
.catch((function(aError) {
|
|
this.hideContentsAreaScreen();
|
|
Components.utils.reportError(aError);
|
|
}).bind(this));
|
|
|
|
}
|
|
else {
|
|
this.hideContentsAreaScreen();
|
|
}
|
|
},
|
|
showContentsAreaScreen : function AHB_showContentsAreaScreen()
|
|
{
|
|
let box = this.getContentsAreaBox();
|
|
let style = this.screen.style;
|
|
let width = Math.min(box.width, this.window.screen.availWidth - box.screenX);
|
|
let height = Math.min(box.height, this.window.screen.availHeight - box.screenY);
|
|
style.width = width+'px';
|
|
style.height = height+'px';
|
|
if (this.screen.state == 'open')
|
|
this.screen.moveTo(box.screenX, box.screenY);
|
|
else
|
|
this.screen.openPopupAtScreen(box.screenX, box.screenY, false);
|
|
this.screen.setAttribute('popup-shown', true);
|
|
},
|
|
hideContentsAreaScreen : function AHB_hideContentsAreaScreen()
|
|
{
|
|
this.screen.removeAttribute('popup-shown');
|
|
if (this.screen.state != 'close')
|
|
this.screen.hidePopup();
|
|
},
|
|
|
|
|
|
show : function AHB_show(aReason) /* PUBLIC API */
|
|
{
|
|
if (this.showHideReason & this.kSHOWHIDE_BY_API) {
|
|
this.end();
|
|
return;
|
|
}
|
|
|
|
if (aReason) {
|
|
this.showHideReason |= aReason;
|
|
}
|
|
if (!this.expanded)
|
|
this.showHideInternal();
|
|
},
|
|
|
|
hide : function AHB_hide(aReason) /* PUBLIC API */
|
|
{
|
|
if (!this.enabled) {
|
|
this.start(aReason | this.kSHOWHIDE_BY_API);
|
|
return;
|
|
}
|
|
|
|
if (aReason) {
|
|
if (aReason == this.kSHOWN_BY_ANY_REASON)
|
|
this.showHideReason &= ~this.kSHOWN_BY_ANY_REASON;
|
|
else if (this.showHideReason & aReason)
|
|
this.showHideReason ^= aReason;
|
|
|
|
if (this.showHideReason & this.kSHOWN_BY_ANY_REASON)
|
|
return;
|
|
}
|
|
if (this.expanded)
|
|
this.showHideInternal();
|
|
},
|
|
|
|
onShowing : function AHB_onShowing()
|
|
{
|
|
var sv = this.treeStyleTab;
|
|
var b = this.browser;
|
|
var pos = sv.position;
|
|
|
|
sv.setTabbrowserAttribute(this.kSTATE, this.kSTATE_EXPANDED);
|
|
|
|
switch (this.mode)
|
|
{
|
|
case this.kMODE_DISABLED:
|
|
break;
|
|
|
|
case this.kMODE_HIDE:
|
|
sv.updateFloatingTabbar(sv.kTABBAR_UPDATE_BY_AUTOHIDE);
|
|
break;
|
|
|
|
default:
|
|
case this.kMODE_SHRINK:
|
|
if (pos == 'left' || pos == 'right') {
|
|
let width = sv.maxTabbarWidth(utils.getTreePref('tabbar.width'));
|
|
sv.updateFloatingTabbar(sv.kTABBAR_UPDATE_BY_AUTOHIDE);
|
|
}
|
|
break;
|
|
}
|
|
},
|
|
|
|
onHiding : function AHB_onHiding()
|
|
{
|
|
var sv = this.treeStyleTab;
|
|
var b = this.browser;
|
|
var pos = sv.position;
|
|
|
|
var box = (sv.tabStripPlaceHolder || sv.tabStrip).boxObject;
|
|
|
|
this.tabbarHeight = box.height;
|
|
this.width = box.width || this.width;
|
|
var splitter = this.document.getAnonymousElementByAttribute(b, 'class', sv.kSPLITTER);
|
|
this.splitterWidth = (splitter ? splitter.boxObject.width : 0 );
|
|
|
|
switch (this.mode)
|
|
{
|
|
case this.kMODE_DISABLED:
|
|
sv.setTabbrowserAttribute(this.kAUTOHIDE, 'hidden');
|
|
sv.setTabbrowserAttribute(this.kSTATE, this.kSTATE_HIDDEN);
|
|
break;
|
|
|
|
case this.kMODE_HIDE:
|
|
sv.updateLastScrollPosition();
|
|
sv.setTabbrowserAttribute(this.kAUTOHIDE, 'hidden');
|
|
sv.setTabbrowserAttribute(this.kSTATE, this.kSTATE_HIDDEN);
|
|
sv.updateFloatingTabbar(sv.kTABBAR_UPDATE_BY_AUTOHIDE);
|
|
break;
|
|
|
|
default:
|
|
case this.kMODE_SHRINK:
|
|
sv.setTabbrowserAttribute(this.kAUTOHIDE, 'show');
|
|
sv.setTabbrowserAttribute(this.kSTATE, this.kSTATE_SHRUNKEN);
|
|
if (pos == 'left' || pos == 'right')
|
|
sv.setTabStripAttribute('width', utils.getTreePref('tabbar.shrunkenWidth'));
|
|
sv.updateFloatingTabbar(sv.kTABBAR_UPDATE_BY_AUTOHIDE);
|
|
break;
|
|
}
|
|
},
|
|
|
|
fireStateChangingEvent : function AHB_fireStateChangingEvent()
|
|
{
|
|
var data = {
|
|
shown : this.expanded,
|
|
state : this.state
|
|
};
|
|
|
|
/* PUBLIC API */
|
|
this.treeStyleTab.fireCustomEvent(this.treeStyleTab.kEVENT_TYPE_AUTO_HIDE_STATE_CHANGING, this.browser, true, false, data);
|
|
// for backward compatibility
|
|
this.treeStyleTab.fireCustomEvent(this.treeStyleTab.kEVENT_TYPE_AUTO_HIDE_STATE_CHANGING.replace(/^nsDOM/, ''), this.browser, true, false, data);
|
|
},
|
|
|
|
fireStateChangeEvent : function AHB_fireStateChangeEvent()
|
|
{
|
|
var data = {
|
|
shown : this.expanded,
|
|
state : this.state,
|
|
xOffset : this.XOffset,
|
|
yOffset : this.YOffset
|
|
};
|
|
|
|
/* PUBLIC API */
|
|
this.treeStyleTab.fireCustomEvent(this.treeStyleTab.kEVENT_TYPE_AUTO_HIDE_STATE_CHANGE, this.browser, true, false, data);
|
|
// for backward compatibility
|
|
this.treeStyleTab.fireCustomEvent(this.treeStyleTab.kEVENT_TYPE_AUTO_HIDE_STATE_CHANGE.replace(/^nsDOM/, ''), this.browser, true, false, data);
|
|
},
|
|
|
|
|
|
|
|
|
|
updateTransparency : function AHB_updateTransparency()
|
|
{
|
|
var sv = this.treeStyleTab;
|
|
sv.updateFloatingTabbar(sv.kTABBAR_UPDATE_BY_APPEARANCE_CHANGE);
|
|
},
|
|
|
|
// event handling
|
|
|
|
observe : function AHB_observe(aSubject, aTopic, aData)
|
|
{
|
|
switch (aTopic)
|
|
{
|
|
case 'nsPref:changed':
|
|
this.onPrefChange(aData);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
},
|
|
|
|
domains : [
|
|
'extensions.treestyletab.',
|
|
'browser.fullscreen.autohide',
|
|
'browser.tabs.closeButtons'
|
|
],
|
|
|
|
onPrefChange : function AHB_onPrefChange(aPrefName)
|
|
{
|
|
// ignore after destruction
|
|
if (!this.window || !this.window.TreeStyleTabService)
|
|
return;
|
|
|
|
var value = prefs.getPref(aPrefName);
|
|
switch (aPrefName)
|
|
{
|
|
case 'extensions.treestyletab.tabbar.autoHide.mode':
|
|
if (!this.window.TreeStyleTabService.shouldApplyNewPref) return;
|
|
this.browser.setAttribute(this.kMODE+'-normal', value);
|
|
this.updateMode();
|
|
return;
|
|
|
|
case 'extensions.treestyletab.tabbar.autoHide.mode.fullscreen':
|
|
if (!this.window.TreeStyleTabService.shouldApplyNewPref) return;
|
|
this.browser.setAttribute(this.kMODE+'-fullscreen', value);
|
|
this.updateMode();
|
|
return;
|
|
|
|
case 'extensions.treestyletab.tabbar.autoShow.mousemove':
|
|
case 'extensions.treestyletab.tabbar.autoShow.accelKeyDown':
|
|
case 'extensions.treestyletab.tabbar.autoShow.feedback':
|
|
if (this.enabled && this.shouldListenMouseMove)
|
|
this.startListenMouseMove();
|
|
else
|
|
this.endListenMouseMove();
|
|
return;
|
|
|
|
case 'extensions.treestyletab.tabbar.autoHide.area':
|
|
this.sensitiveArea = value;
|
|
return;
|
|
|
|
case 'extensions.treestyletab.tabbar.togglerSize':
|
|
this.togglerSize = value;
|
|
var toggler = this.document.getAnonymousElementByAttribute(this.browser, 'class', this.treeStyleTab.kTABBAR_TOGGLER);
|
|
toggler.style.minWidth = toggler.style.minHeight = value+'px';
|
|
if (this.togglerSize <= 0)
|
|
toggler.setAttribute('collapsed', true);
|
|
else
|
|
toggler.removeAttribute('collapsed');
|
|
return;
|
|
|
|
case 'extensions.treestyletab.tabbar.autoHide.contentAreaScreen.enabled':
|
|
return this.contentAreaScreenEnabled = value;
|
|
|
|
case 'browser.fullscreen.autohide':
|
|
if (!this.window.fullScreen) return;
|
|
this.end();
|
|
this.mode = value ?
|
|
this.getModeForFullScreen() :
|
|
this.kMODE_DISABLED ;
|
|
if (this.mode != this.kMODE_DISABLED)
|
|
this.start();
|
|
return;
|
|
|
|
case 'browser.tabs.closeButtons':
|
|
return this.closeButtonsMode = value;
|
|
|
|
default:
|
|
return;
|
|
}
|
|
},
|
|
|
|
handleEvent : function AHB_handleEvent(aEvent)
|
|
{
|
|
switch (aEvent.type)
|
|
{
|
|
case 'mousedown':
|
|
return this.onMouseDown(aEvent);
|
|
|
|
case 'mouseup':
|
|
return this.onMouseUp(aEvent);
|
|
|
|
case 'mousemove':
|
|
return this.handleMouseMove(aEvent);
|
|
|
|
case 'TabOpen':
|
|
case 'TabClose':
|
|
return this.showForFeedback();
|
|
|
|
case 'TabMove':
|
|
if (!this.treeStyleTab.subTreeMovingCount && !this.treeStyleTab.internallyTabMovingCount)
|
|
this.showForFeedback();
|
|
return;
|
|
|
|
case 'select':
|
|
if (!this.window.TreeStyleTabService.accelKeyPressed)
|
|
this.showForFeedback();
|
|
return;
|
|
|
|
case 'dragover':
|
|
return this.onDragOver(aEvent);
|
|
|
|
case 'dragleave':
|
|
return this.onDragLeave(aEvent);
|
|
|
|
case this.treeStyleTab.kEVENT_TYPE_TABBAR_POSITION_CHANGING:
|
|
this.isResizing = false;
|
|
return;
|
|
|
|
case this.treeStyleTab.kEVENT_TYPE_TABBAR_POSITION_CHANGED:
|
|
if (this.enabled)
|
|
this.window.setTimeout(function(aSelf) {
|
|
aSelf.show(this.kSHOWHIDE_BY_POSITION_CHANGE);
|
|
aSelf.hide(this.kSHOWHIDE_BY_POSITION_CHANGE);
|
|
}, 0, this);
|
|
this.updateTransparency();
|
|
return;
|
|
|
|
case this.treeStyleTab.kEVENT_TYPE_TAB_FOCUS_SWITCHING_KEY_DOWN:
|
|
return this.onKeyDown(aEvent.detail.sourceEvent);
|
|
|
|
case this.treeStyleTab.kEVENT_TYPE_TAB_FOCUS_SWITCHING_START:
|
|
this.cancelDelayedShowForShortcut();
|
|
if (this.enabled &&
|
|
utils.getTreePref('tabbar.autoShow.tabSwitch') &&
|
|
(
|
|
aEvent.detail.scrollDown ||
|
|
aEvent.detail.scrollUp ||
|
|
( // when you release "shift" key
|
|
this.expanded &&
|
|
aEvent.detail.standBy &&
|
|
aEvent.detail.onlyShiftKey
|
|
)
|
|
))
|
|
this.show(this.kSHOWN_BY_SHORTCUT);
|
|
return;
|
|
|
|
case this.treeStyleTab.kEVENT_TYPE_TAB_FOCUS_SWITCHING_END:
|
|
this.cancelDelayedShowForShortcut();
|
|
if (this.enabled)
|
|
this.hide(this.kSHOWN_BY_SHORTCUT);
|
|
return;
|
|
|
|
case this.treeStyleTab.kEVENT_TYPE_PRINT_PREVIEW_ENTERED:
|
|
this.hide(this.kSHOWHIDE_BY_END);
|
|
this.endListenMouseMove();
|
|
return;
|
|
|
|
case this.treeStyleTab.kEVENT_TYPE_PRINT_PREVIEW_EXITED:
|
|
if (this.enabled && this.shouldListenMouseMove)
|
|
this.startListenMouseMove();
|
|
return;
|
|
}
|
|
},
|
|
|
|
onMouseDown : function AHB_onMouseDown(aEvent)
|
|
{
|
|
var sv = this.treeStyleTab;
|
|
var w = this.window;
|
|
if (
|
|
aEvent.target &&
|
|
!this.isResizing &&
|
|
sv.evaluateXPath(
|
|
'ancestor-or-self::*[@class="'+sv.kSPLITTER+'"]',
|
|
aEvent.originalTarget || aEvent.target,
|
|
Ci.nsIDOMXPathResult.BOOLEAN_TYPE
|
|
).booleanValue
|
|
) {
|
|
this.isResizing = true;
|
|
sv.setTabbrowserAttribute(sv.kRESIZING, true);
|
|
}
|
|
this.cancelShowHideOnMouseMove();
|
|
if (
|
|
this.enabled &&
|
|
this.expanded &&
|
|
(
|
|
!aEvent.originalTarget ||
|
|
aEvent.originalTarget.ownerDocument != this.document ||
|
|
!sv.getTabBrowserFromChild(aEvent.originalTarget)
|
|
)
|
|
)
|
|
this.hide(this.kHIDDEN_BY_CLICK);
|
|
this.lastMouseDownTarget = (
|
|
aEvent.originalTargetLocalName ||
|
|
(aEvent.originalTarget && aEvent.originalTarget.localName) ||
|
|
''
|
|
);
|
|
},
|
|
|
|
onMouseUp : function AHB_onMouseUp(aEvent)
|
|
{
|
|
var sv = this.treeStyleTab;
|
|
if (aEvent.originalTarget &&
|
|
sv.evaluateXPath(
|
|
'ancestor-or-self::*[@class="'+sv.kSPLITTER+'"]',
|
|
aEvent.originalTarget,
|
|
Ci.nsIDOMXPathResult.BOOLEAN_TYPE
|
|
).booleanValue) {
|
|
this.isResizing = false;
|
|
sv.removeTabbrowserAttribute(sv.kRESIZING);
|
|
}
|
|
this.cancelShowHideOnMouseMove();
|
|
this.lastMouseDownTarget = null;
|
|
},
|
|
|
|
handleMouseMove : function AHB_handleMouseMove(aEvent)
|
|
{
|
|
var sv = this.treeStyleTab;
|
|
if (this.isResizing &&
|
|
/^(scrollbar|thumb|slider|scrollbarbutton)$/i.test(this.lastMouseDownTarget || ''))
|
|
return true;
|
|
|
|
if (
|
|
!aEvent.shiftKey &&
|
|
!sv.isPopupShown() &&
|
|
(
|
|
!this.expanded ||
|
|
this.showHideReason & this.kSHOWN_BY_ANY_REASON
|
|
) &&
|
|
!this.lastMouseDownTarget
|
|
)
|
|
this.showHideOnMouseMove(aEvent);
|
|
return true;
|
|
},
|
|
|
|
onDragOver : function AHB_onDragOver(aEvent)
|
|
{
|
|
if (this.expanded)
|
|
return;
|
|
|
|
var position = this.getMousePosition(aEvent);
|
|
if (!(position & this.MOUSE_POSITION_SENSITIVE))
|
|
return;
|
|
|
|
var draggedTabs = this.window['piro.sakura.ne.jp'].tabsDragUtils.getSelectedTabs(aEvent);
|
|
if (
|
|
draggedTabs.length ||
|
|
this.treeStyleTab.tabbarDNDObserver.retrieveURLsFromDataTransfer(aEvent.dataTransfer).length
|
|
) {
|
|
this.show(this.kSHOWN_BY_MOUSEMOVE);
|
|
|
|
if (this._autoHideOnDragLeaveTimer) {
|
|
this.window.clearTimeout(this._autoHideOnDragLeaveTimer);
|
|
delete this._autoHideOnDragLeaveTimer;
|
|
}
|
|
}
|
|
},
|
|
|
|
onDragLeave : function AHB_onDragLeave(aEvent)
|
|
{
|
|
if (!this.expanded)
|
|
return;
|
|
|
|
if (this._autoHideOnDragLeaveTimer)
|
|
this.window.clearTimeout(this._autoHideOnDragLeaveTimer);
|
|
|
|
var position = this.getMousePosition(aEvent);
|
|
if (position & this.MOUSE_POSITION_SENSITIVE)
|
|
return;
|
|
|
|
this._autoHideOnDragLeaveTimer = this.window.setTimeout(function(aSelf) {
|
|
delete aSelf._autoHideOnDragLeaveTimer;
|
|
aSelf.hide(aSelf.kSHOWN_BY_MOUSEMOVE);
|
|
}, 100, this);
|
|
},
|
|
|
|
onKeyDown : function AHB_onKeyDown(aEvent)
|
|
{
|
|
var sv = this.treeStyleTab;
|
|
var b = this.browser;
|
|
var w = this.window;
|
|
|
|
if (this.delayedShowForShortcutDone)
|
|
this.cancelDelayedShowForShortcut();
|
|
|
|
if (
|
|
sv.getTabs(b).length > 1 &&
|
|
!aEvent.altKey &&
|
|
w.TreeStyleTabService.accelKeyPressed
|
|
) {
|
|
if (this.enabled &&
|
|
utils.getTreePref('tabbar.autoShow.accelKeyDown') &&
|
|
!this.delayedAutoShowTimer &&
|
|
!this.delayedShowForShortcutTimer) {
|
|
this.delayedShowForShortcutTimer = w.setTimeout(
|
|
function(aSelf) {
|
|
aSelf.delayedShowForShortcutDone = true;
|
|
aSelf.show(aSelf.kSHOWN_BY_SHORTCUT);
|
|
sv = null;
|
|
b = null;
|
|
},
|
|
utils.getTreePref('tabbar.autoShow.accelKeyDown.delay'),
|
|
this
|
|
);
|
|
this.delayedShowForShortcutDone = false;
|
|
}
|
|
}
|
|
else {
|
|
if (this.enabled)
|
|
this.hide(this.kSHOWN_BY_SHORTCUT);
|
|
}
|
|
},
|
|
|
|
cancelDelayedShowForShortcut : function AHB_cancelDelayedShowForShortcut()
|
|
{
|
|
if (this.delayedShowForShortcutTimer) {
|
|
this.window.clearTimeout(this.delayedShowForShortcutTimer);
|
|
this.delayedShowForShortcutTimer = null;
|
|
}
|
|
},
|
|
|
|
delayedShowForShortcutTimer : null,
|
|
delayedShowForShortcutDone : true,
|
|
|
|
init : function AHB_init(aTabBrowser)
|
|
{
|
|
this.browser = aTabBrowser;
|
|
this.document = aTabBrowser.ownerDocument;
|
|
this.window = this.document.defaultView;
|
|
this.treeStyleTab = aTabBrowser.treeStyleTab;
|
|
|
|
var sv = this.treeStyleTab;
|
|
var b = this.browser;
|
|
|
|
this.enabled = false;
|
|
this.mouseMoveListening = false;
|
|
this.showHideReason = this.kSHOWN_BY_UNKNOWN;
|
|
this.lastMouseDownTarget = null;
|
|
this.isResizing = false;
|
|
|
|
this.showHideOnMouseMoveTimer = null;
|
|
this.delayedShowForFeedbackTimer = null;
|
|
|
|
b.setAttribute(this.kMODE+'-normal', utils.getTreePref('tabbar.autoHide.mode'));
|
|
b.setAttribute(this.kMODE+'-fullscreen', utils.getTreePref('tabbar.autoHide.mode.fullscreen'));
|
|
prefs.addPrefListener(this);
|
|
this.onPrefChange('browser.tabs.closeButtons');
|
|
this.onPrefChange('extensions.treestyletab.tabbar.autoHide.area');
|
|
this.onPrefChange('extensions.treestyletab.tabbar.togglerSize');
|
|
this.onPrefChange('extensions.treestyletab.tabbar.autoHide.contentAreaScreen.enabled');
|
|
this.window.setTimeout(function(aSelf) {
|
|
aSelf.onPrefChange('extensions.treestyletab.tabbar.autoHide.mode');
|
|
}, 0, this);
|
|
|
|
b.mTabContainer.addEventListener('TabOpen', this, false);
|
|
b.mTabContainer.addEventListener('TabClose', this, false);
|
|
b.mTabContainer.addEventListener('TabMove', this, false);
|
|
b.mTabContainer.addEventListener('select', this, false);
|
|
b.addEventListener(sv.kEVENT_TYPE_TABBAR_POSITION_CHANGING, this, false);
|
|
b.addEventListener(sv.kEVENT_TYPE_TABBAR_POSITION_CHANGED, this, false);
|
|
b.addEventListener(sv.kEVENT_TYPE_TAB_FOCUS_SWITCHING_KEY_DOWN, this, false);
|
|
b.addEventListener(sv.kEVENT_TYPE_TAB_FOCUS_SWITCHING_START, this, false);
|
|
b.addEventListener(sv.kEVENT_TYPE_TAB_FOCUS_SWITCHING_END, this, false);
|
|
},
|
|
|
|
destroy : function AHB_destroy()
|
|
{
|
|
this.end();
|
|
prefs.removePrefListener(this);
|
|
|
|
var sv = this.treeStyleTab;
|
|
var b = this.browser;
|
|
b.mTabContainer.removeEventListener('TabOpen', this, false);
|
|
b.mTabContainer.removeEventListener('TabClose', this, false);
|
|
b.mTabContainer.removeEventListener('TabMove', this, false);
|
|
b.mTabContainer.removeEventListener('select', this, false);
|
|
b.removeEventListener(sv.kEVENT_TYPE_TABBAR_POSITION_CHANGING, this, false);
|
|
b.removeEventListener(sv.kEVENT_TYPE_TABBAR_POSITION_CHANGED, this, false);
|
|
b.removeEventListener(sv.kEVENT_TYPE_TAB_FOCUS_SWITCHING_KEY_DOWN, this, false);
|
|
b.removeEventListener(sv.kEVENT_TYPE_TAB_FOCUS_SWITCHING_START, this, false);
|
|
b.removeEventListener(sv.kEVENT_TYPE_TAB_FOCUS_SWITCHING_END, this, false);
|
|
|
|
delete this.treeStyleTab;
|
|
delete this.browser;
|
|
delete this.document;
|
|
delete this.window;
|
|
},
|
|
|
|
saveCurrentState : function AHB_saveCurrentState()
|
|
{
|
|
var b = this.browser;
|
|
var prefs = {
|
|
'tabbar.autoHide.mode' : this.getModeForNormal(b),
|
|
'tabbar.autoHide.mode.fullscreen' : this.getModeForFullScreen(b),
|
|
};
|
|
for (var i in prefs)
|
|
{
|
|
if (utils.getTreePref(i) != prefs[i])
|
|
utils.setTreePref(i, prefs[i]);
|
|
}
|
|
}
|
|
|
|
});
|
|
|
|
function AutoHideWindow(aWindow)
|
|
{
|
|
this.init(aWindow);
|
|
}
|
|
AutoHideWindow.prototype = {
|
|
get browser()
|
|
{
|
|
return this.treeStyleTab.browser;
|
|
},
|
|
|
|
// mode
|
|
|
|
getMode : function AHW_getMode(aTabBrowser)
|
|
{
|
|
var b = aTabBrowser || this.browser;
|
|
var mode = b.getAttribute(AutoHideBrowser.prototype.kMODE);
|
|
return mode ? parseInt(mode) : AutoHideBrowser.prototype.kMODE_DISABLED ;
|
|
},
|
|
|
|
get mode() /* PUBLIC API */
|
|
{
|
|
var mode = this.getMode();
|
|
if (mode == AutoHideBrowser.prototype.kMODE_SHRINK &&
|
|
this.treeStyleTab.position != 'left' &&
|
|
this.treeStyleTab.position != 'right')
|
|
return AutoHideBrowser.prototype.kMODE_HIDE;
|
|
return mode;
|
|
},
|
|
|
|
set mode(aValue)
|
|
{
|
|
var b = aTabBrowser || this.browser;
|
|
b.setAttribute(AutoHideBrowser.prototype.kMODE, aValue);
|
|
return aValue;
|
|
},
|
|
|
|
toggleMode : function AHW_toggleMode(aTabBrowser) /* PUBLIC API */
|
|
{
|
|
var b = aTabBrowser || this.browser;
|
|
var w = this.window;
|
|
|
|
var key = 'tabbar.autoHide.mode';
|
|
var toggleKey = 'tabbar.autoHide.mode.toggle';
|
|
if (w.fullScreen) {
|
|
key += '.fullscreen';
|
|
toggleKey += '.fullscreen';
|
|
}
|
|
|
|
var mode = this.getMode(b) == AutoHideBrowser.prototype.kMODE_DISABLED ?
|
|
utils.getTreePref(toggleKey) :
|
|
AutoHideBrowser.prototype.kMODE_DISABLED ;
|
|
|
|
utils.setTreePref(key, mode);
|
|
b.setAttribute(AutoHideBrowser.prototype.kMODE+'-'+(w.fullScreen ? 'fullscreen' : 'normal' ), mode);
|
|
b.treeStyleTab.autoHide.updateMode();
|
|
},
|
|
|
|
// for shortcuts
|
|
|
|
updateKeyListeners : function AHW_updateKeyListeners()
|
|
{
|
|
// ignore after destruction
|
|
if (!this.window || !this.window.TreeStyleTabService)
|
|
return;
|
|
|
|
if (
|
|
this.getMode() &&
|
|
this.shouldListenKeyEvents
|
|
) {
|
|
this.treeStyleTab.startListenKeyEventsFor(this.treeStyleTab.LISTEN_FOR_AUTOHIDE);
|
|
}
|
|
else {
|
|
this.treeStyleTab.endListenKeyEventsFor(this.treeStyleTab.LISTEN_FOR_AUTOHIDE);
|
|
}
|
|
var w = this.window;
|
|
w.setTimeout(function() {
|
|
if (w.windowState != Ci.nsIDOMChromeWindow.STATE_NORMAL)
|
|
return;
|
|
var count = 0;
|
|
var resizeTimer = w.setInterval(function(){
|
|
if (w.windowState != Ci.nsIDOMChromeWindow.STATE_NORMAL)
|
|
return w.clearInterval(resizeTimer);
|
|
|
|
if (++count > 100 || w.innerHeight > 0) {
|
|
w.clearInterval(resizeTimer);
|
|
w.resizeBy(-1,-1);
|
|
w.resizeBy(1,1);
|
|
}
|
|
}, 250);
|
|
}, 0);
|
|
},
|
|
|
|
get shouldListenKeyEvents()
|
|
{
|
|
return !this.treeStyleTab.ctrlTabPreviewsEnabled &&
|
|
(
|
|
utils.getTreePref('tabbar.autoShow.accelKeyDown') ||
|
|
utils.getTreePref('tabbar.autoShow.tabSwitch') ||
|
|
utils.getTreePref('tabbar.autoShow.feedback')
|
|
);
|
|
},
|
|
|
|
init : function AHB_init(aWindow)
|
|
{
|
|
this.window = aWindow;
|
|
this.document = aWindow.document;
|
|
this.treeStyleTab = aWindow.TreeStyleTabService;
|
|
},
|
|
|
|
destroy : function AHB_destroy()
|
|
{
|
|
delete this.treeStyleTab;
|
|
delete this.document;
|
|
delete this.window;
|
|
}
|
|
|
|
};
|
|
|