2013-06-27 17:37:10 -07:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
2013-06-27 17:37:11 -07:00
|
|
|
// Fired when the tabtray is displayed
|
|
|
|
const kContextUITabsShowEvent = "MozContextUITabsShow";
|
|
|
|
// add more as needed...
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Manages context UI (navbar, tabbar, appbar) and track visibility. Also
|
|
|
|
* tracks events that summon and hide the context UI.
|
2013-06-27 17:37:10 -07:00
|
|
|
*/
|
|
|
|
var ContextUI = {
|
|
|
|
_expandable: true,
|
|
|
|
_hidingId: 0,
|
|
|
|
|
|
|
|
/*******************************************
|
|
|
|
* init
|
|
|
|
*/
|
|
|
|
|
|
|
|
init: function init() {
|
|
|
|
Elements.browsers.addEventListener("mousedown", this, true);
|
|
|
|
Elements.browsers.addEventListener("touchstart", this, true);
|
|
|
|
Elements.browsers.addEventListener("AlertActive", this, true);
|
2013-06-27 17:37:11 -07:00
|
|
|
|
|
|
|
Elements.browsers.addEventListener('URLChanged', this, true);
|
|
|
|
Elements.tabList.addEventListener('TabSelect', this, true);
|
|
|
|
Elements.panelUI.addEventListener('ToolPanelShown', this, false);
|
|
|
|
Elements.panelUI.addEventListener('ToolPanelHidden', this, false);
|
|
|
|
|
2013-06-27 17:37:10 -07:00
|
|
|
window.addEventListener("MozEdgeUIStarted", this, true);
|
|
|
|
window.addEventListener("MozEdgeUICanceled", this, true);
|
|
|
|
window.addEventListener("MozEdgeUICompleted", this, true);
|
|
|
|
window.addEventListener("keypress", this, true);
|
|
|
|
window.addEventListener("KeyboardChanged", this, false);
|
|
|
|
|
|
|
|
Elements.tray.addEventListener("transitionend", this, true);
|
|
|
|
|
|
|
|
Appbar.init();
|
|
|
|
},
|
|
|
|
|
|
|
|
/*******************************************
|
|
|
|
* Context UI state getters & setters
|
|
|
|
*/
|
|
|
|
|
2013-06-27 17:37:11 -07:00
|
|
|
// any visiblilty
|
2013-06-27 17:37:10 -07:00
|
|
|
get isVisible() {
|
2013-06-27 17:37:11 -07:00
|
|
|
return this.navbarVisible || this.tabbarVisible || this.contextAppbarVisible;
|
|
|
|
},
|
|
|
|
|
|
|
|
// navbar visiblilty
|
|
|
|
get navbarVisible() {
|
2013-06-27 17:37:10 -07:00
|
|
|
return (Elements.navbar.hasAttribute("visible") ||
|
|
|
|
Elements.navbar.hasAttribute("startpage"));
|
|
|
|
},
|
|
|
|
|
2013-06-27 17:37:11 -07:00
|
|
|
// tabbar visiblilty
|
|
|
|
get tabbarVisible() {
|
|
|
|
return Elements.tray.hasAttribute("expanded");
|
|
|
|
},
|
|
|
|
|
|
|
|
// appbar visiblilty
|
|
|
|
get contextAppbarVisible() {
|
|
|
|
return Elements.contextappbar.isShowing;
|
|
|
|
},
|
|
|
|
|
|
|
|
// currently not in use, for the always show tabs feature
|
|
|
|
get isExpandable() { return this._expandable; },
|
2013-06-27 17:37:10 -07:00
|
|
|
set isExpandable(aFlag) {
|
|
|
|
this._expandable = aFlag;
|
|
|
|
if (!this._expandable)
|
|
|
|
this.dismiss();
|
|
|
|
},
|
|
|
|
|
|
|
|
/*******************************************
|
2013-06-27 17:37:11 -07:00
|
|
|
* Public api
|
2013-06-27 17:37:10 -07:00
|
|
|
*/
|
|
|
|
|
2013-06-27 17:37:11 -07:00
|
|
|
/*
|
|
|
|
* Toggle the current nav UI state. Fires context ui events.
|
|
|
|
*/
|
|
|
|
toggleNavUI: function () {
|
|
|
|
// The navbar is forced open when the start page is visible. appbar.js
|
|
|
|
// controls the "visible" property, and browser-ui controls the "startpage"
|
|
|
|
// property. Hence we rely on the tabbar for current toggle state.
|
|
|
|
if (this.tabbarVisible) {
|
|
|
|
this.dismiss();
|
|
|
|
} else {
|
|
|
|
this.displayNavUI();
|
2013-06-27 17:37:10 -07:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2013-06-27 17:37:11 -07:00
|
|
|
/*
|
|
|
|
* Show the nav and tabs bar. Returns true if any non-visible UI
|
|
|
|
* was shown. Fires context ui events.
|
|
|
|
*/
|
|
|
|
displayNavUI: function () {
|
2013-06-27 17:37:10 -07:00
|
|
|
let shown = false;
|
2013-06-27 17:37:11 -07:00
|
|
|
|
|
|
|
if (!this.navbarVisible) {
|
|
|
|
this.displayNavbar();
|
2013-06-27 17:37:10 -07:00
|
|
|
shown = true;
|
|
|
|
}
|
2013-06-27 17:37:11 -07:00
|
|
|
|
|
|
|
if (!this.tabbarVisible) {
|
|
|
|
this.displayTabs();
|
2013-06-27 17:37:10 -07:00
|
|
|
shown = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (shown) {
|
|
|
|
ContentAreaObserver.update(window.innerWidth, window.innerHeight);
|
|
|
|
}
|
2013-06-27 17:37:11 -07:00
|
|
|
|
2013-06-27 17:37:10 -07:00
|
|
|
return shown;
|
|
|
|
},
|
|
|
|
|
2013-06-27 17:37:11 -07:00
|
|
|
/*
|
|
|
|
* Dismiss any context UI currently visible. Returns true if any
|
|
|
|
* visible UI was dismissed. Fires context ui events.
|
|
|
|
*/
|
|
|
|
dismiss: function () {
|
|
|
|
let dismissed = false;
|
2013-06-27 17:37:10 -07:00
|
|
|
|
|
|
|
this._clearDelayedTimeout();
|
2013-06-27 17:37:11 -07:00
|
|
|
|
|
|
|
// No assurances this will hide the nav bar. It may have the
|
|
|
|
// 'startpage' property set. This removes the 'visible' property.
|
|
|
|
if (this.navbarVisible) {
|
|
|
|
this.dismissNavbar();
|
|
|
|
dismissed = true;
|
|
|
|
}
|
|
|
|
if (this.tabbarVisible) {
|
|
|
|
this.dismissTabs();
|
|
|
|
dismissed = true;
|
|
|
|
}
|
|
|
|
if (Elements.contextappbar.isShowing) {
|
|
|
|
this.dismissContextAppbar();
|
|
|
|
dismissed = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dismissed) {
|
|
|
|
ContentAreaObserver.update(window.innerWidth, window.innerHeight);
|
|
|
|
}
|
|
|
|
|
|
|
|
return dismissed;
|
2013-06-27 17:37:10 -07:00
|
|
|
},
|
|
|
|
|
2013-06-27 17:37:11 -07:00
|
|
|
/*
|
|
|
|
* Briefly show the tab bar and then hide it. Fires context ui events.
|
|
|
|
*/
|
2013-07-12 17:12:46 -07:00
|
|
|
peekTabs: function peekTabs(aDelay) {
|
|
|
|
if (!this.tabbarVisible)
|
2013-06-27 17:37:10 -07:00
|
|
|
this.displayTabs();
|
2013-07-12 17:12:46 -07:00
|
|
|
|
|
|
|
ContextUI.dismissTabsWithDelay(aDelay);
|
2013-06-27 17:37:10 -07:00
|
|
|
},
|
|
|
|
|
2013-06-27 17:37:11 -07:00
|
|
|
/*
|
2013-07-09 16:17:22 -07:00
|
|
|
* Dismiss tab bar after a delay. Fires context ui events.
|
2013-06-27 17:37:11 -07:00
|
|
|
*/
|
2013-07-09 16:17:22 -07:00
|
|
|
dismissTabsWithDelay: function (aDelay) {
|
2013-07-12 17:12:46 -07:00
|
|
|
aDelay = aDelay || kNewTabAnimationDelayMsec;
|
2013-06-27 17:37:10 -07:00
|
|
|
this._clearDelayedTimeout();
|
|
|
|
this._hidingId = setTimeout(function () {
|
2013-07-09 16:17:22 -07:00
|
|
|
ContextUI.dismissTabs();
|
2013-06-27 17:37:10 -07:00
|
|
|
}, aDelay);
|
|
|
|
},
|
|
|
|
|
2013-06-27 17:37:11 -07:00
|
|
|
// Display the nav bar
|
|
|
|
displayNavbar: function () {
|
|
|
|
this._clearDelayedTimeout();
|
|
|
|
Elements.navbar.show();
|
|
|
|
},
|
|
|
|
|
|
|
|
// Display the tab tray
|
|
|
|
displayTabs: function () {
|
|
|
|
this._clearDelayedTimeout();
|
|
|
|
this._setIsExpanded(true);
|
|
|
|
},
|
|
|
|
|
|
|
|
// Dismiss the navbar if visible.
|
|
|
|
dismissNavbar: function dismissNavbar() {
|
|
|
|
Elements.navbar.dismiss();
|
|
|
|
},
|
|
|
|
|
|
|
|
// Dismiss the tabstray if visible.
|
2013-06-27 17:37:10 -07:00
|
|
|
dismissTabs: function dimissTabs() {
|
|
|
|
this._clearDelayedTimeout();
|
2013-06-27 17:37:11 -07:00
|
|
|
this._setIsExpanded(false);
|
2013-06-27 17:37:10 -07:00
|
|
|
},
|
|
|
|
|
2013-06-27 17:37:11 -07:00
|
|
|
// Dismiss the appbar if visible.
|
|
|
|
dismissContextAppbar: function dismissContextAppbar() {
|
|
|
|
Elements.contextappbar.dismiss();
|
2013-06-27 17:37:10 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
/*******************************************
|
2013-06-27 17:37:11 -07:00
|
|
|
* Internal utils
|
2013-06-27 17:37:10 -07:00
|
|
|
*/
|
|
|
|
|
2013-06-27 17:37:11 -07:00
|
|
|
// tabtray state
|
2013-06-27 17:37:10 -07:00
|
|
|
_setIsExpanded: function _setIsExpanded(aFlag, setSilently) {
|
|
|
|
// if the tray can't be expanded, don't expand it.
|
2013-06-27 17:37:11 -07:00
|
|
|
if (!this.isExpandable || this.tabbarVisible == aFlag)
|
2013-06-27 17:37:10 -07:00
|
|
|
return;
|
|
|
|
|
|
|
|
if (aFlag)
|
|
|
|
Elements.tray.setAttribute("expanded", "true");
|
|
|
|
else
|
|
|
|
Elements.tray.removeAttribute("expanded");
|
|
|
|
|
|
|
|
if (!setSilently)
|
2013-06-27 17:37:11 -07:00
|
|
|
this._fire(kContextUITabsShowEvent);
|
2013-06-27 17:37:10 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
_clearDelayedTimeout: function _clearDelayedTimeout() {
|
|
|
|
if (this._hidingId) {
|
|
|
|
clearTimeout(this._hidingId);
|
|
|
|
this._hidingId = 0;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
/*******************************************
|
|
|
|
* Events
|
|
|
|
*/
|
|
|
|
|
|
|
|
_onEdgeUIStarted: function(aEvent) {
|
|
|
|
this._hasEdgeSwipeStarted = true;
|
|
|
|
this._clearDelayedTimeout();
|
|
|
|
|
|
|
|
if (StartUI.hide()) {
|
|
|
|
this.dismiss();
|
|
|
|
return;
|
|
|
|
}
|
2013-06-27 17:37:11 -07:00
|
|
|
this.toggleNavUI();
|
2013-06-27 17:37:10 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
_onEdgeUICanceled: function(aEvent) {
|
|
|
|
this._hasEdgeSwipeStarted = false;
|
|
|
|
StartUI.hide();
|
|
|
|
this.dismiss();
|
|
|
|
},
|
|
|
|
|
|
|
|
_onEdgeUICompleted: function(aEvent) {
|
|
|
|
if (this._hasEdgeSwipeStarted) {
|
|
|
|
this._hasEdgeSwipeStarted = false;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this._clearDelayedTimeout();
|
|
|
|
if (StartUI.hide()) {
|
|
|
|
this.dismiss();
|
|
|
|
return;
|
|
|
|
}
|
2013-06-27 17:37:11 -07:00
|
|
|
this.toggleNavUI();
|
2013-06-27 17:37:10 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
handleEvent: function handleEvent(aEvent) {
|
|
|
|
switch (aEvent.type) {
|
|
|
|
case "MozEdgeUIStarted":
|
|
|
|
this._onEdgeUIStarted(aEvent);
|
|
|
|
break;
|
|
|
|
case "MozEdgeUICanceled":
|
|
|
|
this._onEdgeUICanceled(aEvent);
|
|
|
|
break;
|
|
|
|
case "MozEdgeUICompleted":
|
|
|
|
this._onEdgeUICompleted(aEvent);
|
|
|
|
break;
|
|
|
|
case "keypress":
|
|
|
|
if (String.fromCharCode(aEvent.which) == "z" &&
|
|
|
|
aEvent.getModifierState("Win"))
|
2013-06-27 17:37:11 -07:00
|
|
|
this.toggleNavUI();
|
2013-06-27 17:37:10 -07:00
|
|
|
break;
|
|
|
|
case "transitionend":
|
|
|
|
setTimeout(function () {
|
|
|
|
ContentAreaObserver.updateContentArea();
|
|
|
|
}, 0);
|
|
|
|
break;
|
|
|
|
case "KeyboardChanged":
|
|
|
|
this.dismissTabs();
|
|
|
|
break;
|
2013-06-27 17:37:11 -07:00
|
|
|
case "mousedown":
|
|
|
|
if (aEvent.button == 0 && this.isVisible)
|
|
|
|
this.dismiss();
|
|
|
|
break;
|
2013-07-09 16:17:22 -07:00
|
|
|
|
2013-07-12 17:12:46 -07:00
|
|
|
case "ToolPanelShown":
|
|
|
|
case "ToolPanelHidden":
|
2013-06-27 17:37:11 -07:00
|
|
|
case "touchstart":
|
|
|
|
case "AlertActive":
|
|
|
|
this.dismiss();
|
|
|
|
break;
|
2013-06-27 17:37:10 -07:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
_fire: function (name) {
|
|
|
|
let event = document.createEvent("Events");
|
|
|
|
event.initEvent(name, true, true);
|
|
|
|
window.dispatchEvent(event);
|
|
|
|
}
|
|
|
|
};
|