2013-05-07 11:38:08 -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/. */
|
|
|
|
"use strict";
|
|
|
|
|
2013-02-12 12:51:25 -08:00
|
|
|
var Appbar = {
|
|
|
|
get starButton() { return document.getElementById('star-button'); },
|
|
|
|
get pinButton() { return document.getElementById('pin-button'); },
|
2013-06-14 16:29:12 -07:00
|
|
|
get menuButton() { return document.getElementById('menu-button'); },
|
2013-02-12 12:51:25 -08:00
|
|
|
|
|
|
|
// track selected/active richgrid/tilegroup - the context for contextual action buttons
|
|
|
|
activeTileset: null,
|
|
|
|
|
|
|
|
init: function Appbar_init() {
|
2013-06-27 17:37:11 -07:00
|
|
|
// fired from appbar bindings
|
2013-05-15 17:21:06 -07:00
|
|
|
Elements.contextappbar.addEventListener('MozAppbarShowing', this, false);
|
|
|
|
Elements.contextappbar.addEventListener('MozAppbarDismissing', this, false);
|
2013-06-27 17:37:11 -07:00
|
|
|
|
|
|
|
// fired when a context sensitive item (bookmarks) changes state
|
2013-04-03 14:16:14 -07:00
|
|
|
window.addEventListener('MozContextActionsChange', this, false);
|
2013-06-27 17:37:11 -07:00
|
|
|
|
|
|
|
// browser events we need to update button state on
|
2013-04-04 09:18:10 -07:00
|
|
|
Elements.browsers.addEventListener('URLChanged', this, true);
|
|
|
|
Elements.tabList.addEventListener('TabSelect', this, true);
|
2013-02-12 12:51:25 -08:00
|
|
|
|
|
|
|
// tilegroup selection events for all modules get bubbled up
|
|
|
|
window.addEventListener("selectionchange", this, false);
|
|
|
|
},
|
|
|
|
|
|
|
|
handleEvent: function Appbar_handleEvent(aEvent) {
|
|
|
|
switch (aEvent.type) {
|
2013-05-31 08:55:53 -07:00
|
|
|
case 'URLChanged':
|
|
|
|
case 'TabSelect':
|
2013-04-04 09:18:06 -07:00
|
|
|
case 'MozAppbarShowing':
|
2013-06-27 17:37:11 -07:00
|
|
|
this.update();
|
2013-02-12 12:51:25 -08:00
|
|
|
break;
|
2013-06-27 17:37:11 -07:00
|
|
|
|
2013-05-07 11:38:08 -07:00
|
|
|
case 'MozAppbarDismissing':
|
|
|
|
if (this.activeTileset) {
|
|
|
|
this.activeTileset.clearSelection();
|
|
|
|
}
|
|
|
|
this.clearContextualActions();
|
|
|
|
this.activeTileset = null;
|
|
|
|
break;
|
2013-06-27 17:37:11 -07:00
|
|
|
|
2013-04-03 14:16:14 -07:00
|
|
|
case 'MozContextActionsChange':
|
|
|
|
let actions = aEvent.actions;
|
|
|
|
// could transition in old, new buttons?
|
|
|
|
this.showContextualActions(actions);
|
|
|
|
break;
|
2013-06-27 17:37:11 -07:00
|
|
|
|
2013-02-12 12:51:25 -08:00
|
|
|
case "selectionchange":
|
|
|
|
let nodeName = aEvent.target.nodeName;
|
|
|
|
if ('richgrid' === nodeName) {
|
|
|
|
this._onTileSelectionChanged(aEvent);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2013-05-31 08:55:53 -07:00
|
|
|
/*
|
|
|
|
* Called from various places when the visible content
|
|
|
|
* has changed such that button states may need to be
|
|
|
|
* updated.
|
|
|
|
*/
|
|
|
|
update: function update() {
|
|
|
|
this._updatePinButton();
|
|
|
|
this._updateStarButton();
|
|
|
|
},
|
|
|
|
|
2013-02-12 12:51:25 -08:00
|
|
|
onDownloadButton: function() {
|
|
|
|
PanelUI.show("downloads-container");
|
|
|
|
ContextUI.dismiss();
|
|
|
|
},
|
|
|
|
|
|
|
|
onPinButton: function() {
|
|
|
|
if (this.pinButton.checked) {
|
|
|
|
Browser.pinSite();
|
|
|
|
} else {
|
|
|
|
Browser.unpinSite();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
onStarButton: function(aValue) {
|
|
|
|
if (aValue === undefined) {
|
|
|
|
aValue = this.starButton.checked;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aValue) {
|
|
|
|
Browser.starSite(function () {
|
|
|
|
Appbar._updateStarButton();
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
Browser.unstarSite(function () {
|
|
|
|
Appbar._updateStarButton();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2013-06-14 16:29:12 -07:00
|
|
|
onMenuButton: function(aEvent) {
|
2013-02-12 12:51:25 -08:00
|
|
|
var typesArray = ["find-in-page"];
|
2013-06-25 12:20:17 -07:00
|
|
|
|
|
|
|
if (ConsolePanelView.enabled) typesArray.push("open-error-console");
|
|
|
|
if (!MetroUtils.immersive) typesArray.push("open-jsshell");
|
|
|
|
|
2013-02-12 12:51:25 -08:00
|
|
|
try {
|
|
|
|
// If we have a valid http or https URI then show the view on desktop
|
|
|
|
// menu item.
|
|
|
|
var uri = Services.io.newURI(Browser.selectedBrowser.currentURI.spec,
|
|
|
|
null, null);
|
|
|
|
if (uri.schemeIs('http') || uri.schemeIs('https')) {
|
|
|
|
typesArray.push("view-on-desktop");
|
|
|
|
}
|
|
|
|
} catch(ex) {
|
|
|
|
}
|
|
|
|
|
2013-06-14 16:29:12 -07:00
|
|
|
var x = this.menuButton.getBoundingClientRect().left;
|
2013-07-10 12:14:00 -07:00
|
|
|
var y = Elements.toolbar.getBoundingClientRect().top;
|
2013-02-12 12:51:25 -08:00
|
|
|
ContextMenuUI.showContextMenu({
|
|
|
|
json: {
|
|
|
|
types: typesArray,
|
|
|
|
string: '',
|
|
|
|
xPos: x,
|
|
|
|
yPos: y,
|
|
|
|
leftAligned: true,
|
|
|
|
bottomAligned: true
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
|
|
|
onViewOnDesktop: function() {
|
|
|
|
try {
|
|
|
|
// Make sure we have a valid URI so Windows doesn't prompt
|
|
|
|
// with an unrecognized command, select default program window
|
|
|
|
var uri = Services.io.newURI(Browser.selectedBrowser.currentURI.spec,
|
|
|
|
null, null);
|
|
|
|
if (uri.schemeIs('http') || uri.schemeIs('https')) {
|
|
|
|
MetroUtils.launchInDesktop(Browser.selectedBrowser.currentURI.spec, "");
|
|
|
|
}
|
|
|
|
} catch(ex) {
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
dispatchContextualAction: function(aActionName){
|
|
|
|
let activeTileset = this.activeTileset;
|
|
|
|
if (activeTileset) {
|
|
|
|
// fire event on the richgrid, others can listen
|
|
|
|
// but we keep coupling loose so grid doesn't need to know about appbar
|
|
|
|
let event = document.createEvent("Events");
|
|
|
|
event.action = aActionName;
|
2013-04-03 14:16:14 -07:00
|
|
|
event.initEvent("context-action", true, true); // is cancelable
|
2013-02-12 12:51:25 -08:00
|
|
|
activeTileset.dispatchEvent(event);
|
2013-04-03 14:16:14 -07:00
|
|
|
if (!event.defaultPrevented) {
|
|
|
|
activeTileset.clearSelection();
|
2013-05-15 17:21:06 -07:00
|
|
|
Elements.contextappbar.dismiss();
|
2013-04-03 14:16:14 -07:00
|
|
|
}
|
2013-02-12 12:51:25 -08:00
|
|
|
}
|
|
|
|
},
|
2013-05-07 11:38:08 -07:00
|
|
|
|
|
|
|
showContextualActions: function(aVerbs) {
|
2013-05-14 00:27:04 -07:00
|
|
|
if (aVerbs.length)
|
2013-05-15 17:21:06 -07:00
|
|
|
Elements.contextappbar.show();
|
2013-05-14 00:27:04 -07:00
|
|
|
else
|
2013-05-15 17:21:06 -07:00
|
|
|
Elements.contextappbar.hide();
|
2013-05-14 00:27:04 -07:00
|
|
|
|
2013-02-12 12:51:25 -08:00
|
|
|
let doc = document;
|
|
|
|
// button element id to action verb lookup
|
|
|
|
let buttonsMap = new Map();
|
|
|
|
for (let verb of aVerbs) {
|
|
|
|
let id = verb + "-selected-button";
|
2013-04-09 04:04:47 -07:00
|
|
|
if (!doc.getElementById(id)) {
|
|
|
|
throw new Error("Appbar.showContextualActions: no button for " + verb);
|
2013-02-12 12:51:25 -08:00
|
|
|
}
|
2013-04-09 04:04:47 -07:00
|
|
|
buttonsMap.set(id, verb);
|
2013-02-12 12:51:25 -08:00
|
|
|
}
|
|
|
|
|
2013-04-09 04:04:47 -07:00
|
|
|
// sort buttons into 2 buckets - needing showing and needing hiding
|
|
|
|
let toHide = [],
|
|
|
|
toShow = [];
|
2013-05-15 17:21:06 -07:00
|
|
|
for (let btnNode of Elements.contextappbar.querySelectorAll("#contextualactions-tray > toolbarbutton")) {
|
2013-04-09 04:04:47 -07:00
|
|
|
// correct the hidden state for each button;
|
|
|
|
// .. buttons present in the map should be visible, otherwise not
|
|
|
|
if (buttonsMap.has(btnNode.id)) {
|
|
|
|
if (btnNode.hidden) toShow.push(btnNode);
|
|
|
|
} else if (!btnNode.hidden) {
|
|
|
|
toHide.push(btnNode);
|
2013-02-12 12:51:25 -08:00
|
|
|
}
|
|
|
|
}
|
2013-04-09 04:04:47 -07:00
|
|
|
return Task.spawn(function() {
|
|
|
|
if (toHide.length) {
|
|
|
|
yield Util.transitionElementVisibility(toHide, false);
|
|
|
|
}
|
|
|
|
if (toShow.length) {
|
|
|
|
yield Util.transitionElementVisibility(toShow, true);
|
|
|
|
}
|
|
|
|
});
|
2013-02-12 12:51:25 -08:00
|
|
|
},
|
2013-05-07 11:38:08 -07:00
|
|
|
|
|
|
|
clearContextualActions: function() {
|
|
|
|
this.showContextualActions([]);
|
|
|
|
},
|
|
|
|
|
2013-02-12 12:51:25 -08:00
|
|
|
_onTileSelectionChanged: function _onTileSelectionChanged(aEvent){
|
|
|
|
let activeTileset = aEvent.target;
|
|
|
|
|
|
|
|
// deselect tiles in other tile groups
|
|
|
|
if (this.activeTileset && this.activeTileset !== activeTileset) {
|
|
|
|
this.activeTileset.clearSelection();
|
|
|
|
}
|
|
|
|
// keep track of which view is the target/scope for the contextual actions
|
|
|
|
this.activeTileset = activeTileset;
|
|
|
|
|
|
|
|
// ask the view for the list verbs/action-names it thinks are
|
|
|
|
// appropriate for the tiles selected
|
|
|
|
let contextActions = activeTileset.contextActions;
|
|
|
|
let verbs = [v for (v of contextActions)];
|
|
|
|
|
2013-04-03 14:16:14 -07:00
|
|
|
// fire event with these verbs as payload
|
|
|
|
let event = document.createEvent("Events");
|
|
|
|
event.actions = verbs;
|
|
|
|
event.initEvent("MozContextActionsChange", true, false);
|
2013-05-15 17:21:06 -07:00
|
|
|
Elements.contextappbar.dispatchEvent(event);
|
2013-02-12 12:51:25 -08:00
|
|
|
|
|
|
|
if (verbs.length) {
|
2013-05-15 17:21:06 -07:00
|
|
|
Elements.contextappbar.show(); // should be no-op if we're already showing
|
2013-02-12 12:51:25 -08:00
|
|
|
} else {
|
2013-05-15 17:21:06 -07:00
|
|
|
Elements.contextappbar.dismiss();
|
2013-02-12 12:51:25 -08:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
_updatePinButton: function() {
|
|
|
|
this.pinButton.checked = Browser.isSitePinned();
|
|
|
|
},
|
|
|
|
|
|
|
|
_updateStarButton: function() {
|
|
|
|
Browser.isSiteStarredAsync(function (isStarred) {
|
|
|
|
this.starButton.checked = isStarred;
|
|
|
|
}.bind(this));
|
|
|
|
},
|
2013-06-25 12:20:17 -07:00
|
|
|
};
|