2013-03-26 14:23:23 -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/. */
|
|
|
|
|
|
|
|
XPCOMUtils.defineLazyModuleGetter(this, "CustomizableUI",
|
|
|
|
"resource:///modules/CustomizableUI.jsm");
|
|
|
|
/**
|
|
|
|
* Maintains the state and dispatches events for the main menu panel.
|
|
|
|
*/
|
|
|
|
|
|
|
|
const PanelUI = {
|
|
|
|
/** Panel events that we listen for. **/
|
|
|
|
get kEvents() ["popupshowing", "popupshown", "popuphiding", "popuphidden"],
|
|
|
|
/**
|
|
|
|
* Used for lazily getting and memoizing elements from the document. Lazy
|
|
|
|
* getters are set in init, and memoizing happens after the first retrieval.
|
|
|
|
*/
|
|
|
|
get kElements() {
|
|
|
|
return {
|
|
|
|
contents: "PanelUI-contents",
|
|
|
|
mainView: "PanelUI-mainView",
|
2013-05-09 09:00:33 -07:00
|
|
|
multiView: "PanelUI-multiView",
|
2013-05-17 01:41:12 -07:00
|
|
|
helpView: "PanelUI-help",
|
2013-03-26 14:23:23 -07:00
|
|
|
menuButton: "PanelUI-menu-button",
|
|
|
|
panel: "PanelUI-popup",
|
2013-05-14 09:55:21 -07:00
|
|
|
zoomResetButton: "PanelUI-zoomReset-btn"
|
2013-03-26 14:23:23 -07:00
|
|
|
};
|
|
|
|
},
|
|
|
|
|
|
|
|
init: function() {
|
|
|
|
for (let [k, v] of Iterator(this.kElements)) {
|
|
|
|
// Need to do fresh let-bindings per iteration
|
|
|
|
let getKey = k;
|
|
|
|
let id = v;
|
|
|
|
this.__defineGetter__(getKey, function() {
|
|
|
|
delete this[getKey];
|
|
|
|
return this[getKey] = document.getElementById(id);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
for (let event of this.kEvents) {
|
|
|
|
this.panel.addEventListener(event, this);
|
|
|
|
}
|
2013-05-14 09:55:21 -07:00
|
|
|
|
|
|
|
// Register ourselves with the service so we know when the zoom prefs change.
|
|
|
|
Services.obs.addObserver(this, "browser-fullZoom:zoomChange", false);
|
|
|
|
Services.obs.addObserver(this, "browser-fullZoom:zoomReset", false);
|
|
|
|
|
|
|
|
this._updateZoomResetButton();
|
2013-05-17 01:41:12 -07:00
|
|
|
|
|
|
|
this.helpView.addEventListener("ViewShowing", this._onHelpViewShow, false);
|
|
|
|
this.helpView.addEventListener("ViewHiding", this._onHelpViewHide, false);
|
2013-03-26 14:23:23 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
uninit: function() {
|
|
|
|
for (let event of this.kEvents) {
|
|
|
|
this.panel.removeEventListener(event, this);
|
|
|
|
}
|
2013-05-17 01:41:12 -07:00
|
|
|
this.helpView.removeEventListener("ViewShowing", this._onHelpViewShow);
|
|
|
|
this.helpView.removeEventListener("ViewHiding", this._onHelpViewHide);
|
2013-05-14 09:55:21 -07:00
|
|
|
Services.obs.removeObserver(this, "browser-fullZoom:zoomChange");
|
|
|
|
Services.obs.removeObserver(this, "browser-fullZoom:zoomReset");
|
2013-03-26 14:23:23 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Customize mode extracts the mainView and puts it somewhere else while the
|
|
|
|
* user customizes. Upon completion, this function can be called to put the
|
|
|
|
* panel back to where it belongs in normal browsing mode.
|
|
|
|
*
|
|
|
|
* @param aMainView
|
|
|
|
* The mainView node to put back into place.
|
|
|
|
*/
|
2013-05-31 09:50:01 -07:00
|
|
|
replaceMainView: function(aMainView) {
|
|
|
|
this.multiView.insertBefore(aMainView, this.multiView.firstChild);
|
2013-03-26 14:23:23 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Opens the menu panel if it's closed, or closes it if it's
|
|
|
|
* open. If the event target has a child with the toolbarbutton-icon
|
|
|
|
* attribute, the panel will be anchored on that child. Otherwise, the panel
|
|
|
|
* is anchored on the event target itself.
|
|
|
|
*
|
|
|
|
* @param aEvent the event that triggers the toggle.
|
|
|
|
*/
|
|
|
|
toggle: function(aEvent) {
|
|
|
|
if (this.panel.state == "open") {
|
|
|
|
this.hide();
|
|
|
|
} else if (this.panel.state == "closed") {
|
2013-05-09 09:00:33 -07:00
|
|
|
this.ensureRegistered();
|
|
|
|
|
2013-03-26 14:23:23 -07:00
|
|
|
let anchor = aEvent.target;
|
|
|
|
let iconAnchor =
|
|
|
|
document.getAnonymousElementByAttribute(anchor, "class",
|
|
|
|
"toolbarbutton-icon");
|
|
|
|
this.panel.openPopup(iconAnchor || anchor, "bottomcenter topright");
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* If the menu panel is being shown, hide it.
|
|
|
|
*/
|
|
|
|
hide: function() {
|
|
|
|
this.panel.hidePopup();
|
|
|
|
},
|
|
|
|
|
|
|
|
handleEvent: function(aEvent) {
|
|
|
|
switch (aEvent.type) {
|
|
|
|
case "popupshowing":
|
|
|
|
// Fall through
|
|
|
|
case "popupshown":
|
|
|
|
// Fall through
|
|
|
|
case "popuphiding":
|
|
|
|
// Fall through
|
|
|
|
case "popuphidden": {
|
|
|
|
this._updatePanelButton(aEvent.target);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2013-05-14 09:55:21 -07:00
|
|
|
/**
|
|
|
|
* nsIObserver implementation, responding to zoom pref changes
|
|
|
|
*/
|
|
|
|
observe: function (aSubject, aTopic, aData) {
|
|
|
|
this._updateZoomResetButton();
|
|
|
|
},
|
|
|
|
|
2013-03-28 12:47:31 -07:00
|
|
|
/**
|
|
|
|
* Registering the menu panel is done lazily for performance reasons. This
|
|
|
|
* method is exposed so that CustomizationMode can force registration in the
|
|
|
|
* event that customization mode is started before the panel has had a chance
|
|
|
|
* to register itself.
|
|
|
|
*/
|
|
|
|
ensureRegistered: function() {
|
|
|
|
CustomizableUI.registerMenuPanel(this.contents);
|
|
|
|
},
|
|
|
|
|
2013-03-26 14:23:23 -07:00
|
|
|
/**
|
|
|
|
* Switch the panel to the main view if it's not already
|
|
|
|
* in that view.
|
|
|
|
*/
|
|
|
|
showMainView: function() {
|
2013-05-09 09:00:33 -07:00
|
|
|
this.multiView.showMainView();
|
2013-03-26 14:23:23 -07:00
|
|
|
},
|
|
|
|
|
2013-05-17 01:41:12 -07:00
|
|
|
/**
|
|
|
|
* Switch the panel to the help view if it's not already
|
|
|
|
* in that view.
|
|
|
|
*/
|
|
|
|
showHelpView: function(aAnchor) {
|
|
|
|
this.multiView.showSubView("PanelUI-help", aAnchor);
|
|
|
|
},
|
|
|
|
|
2013-03-26 14:23:23 -07:00
|
|
|
/**
|
|
|
|
* Shows a subview in the panel with a given ID.
|
|
|
|
*
|
|
|
|
* @param aViewId the ID of the subview to show.
|
2013-04-30 14:20:00 -07:00
|
|
|
* @param aAnchor the element that spawned the subview.
|
|
|
|
* @param aPlacementArea the CustomizableUI area that aAnchor is in.
|
2013-03-26 14:23:23 -07:00
|
|
|
*/
|
2013-04-30 14:20:00 -07:00
|
|
|
showSubView: function(aViewId, aAnchor, aPlacementArea) {
|
2013-03-26 14:23:23 -07:00
|
|
|
let viewNode = document.getElementById(aViewId);
|
|
|
|
if (!viewNode) {
|
|
|
|
Cu.reportError("Could not show panel subview with id: " + aViewId);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!aAnchor) {
|
|
|
|
Cu.reportError("Expected an anchor when opening subview with id: " + aViewId);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-04-30 14:20:00 -07:00
|
|
|
if (aPlacementArea == CustomizableUI.AREA_PANEL) {
|
2013-05-09 09:00:33 -07:00
|
|
|
this.multiView.showSubView(aViewId, aAnchor);
|
2013-04-30 14:20:00 -07:00
|
|
|
} else {
|
|
|
|
// Emit the ViewShowing event so that the widget definition has a chance
|
|
|
|
// to lazily populate the subview with things.
|
|
|
|
let evt = document.createEvent("CustomEvent");
|
|
|
|
evt.initCustomEvent("ViewShowing", true, true, viewNode);
|
|
|
|
viewNode.dispatchEvent(evt);
|
|
|
|
|
2013-05-09 09:00:33 -07:00
|
|
|
let tempPanel = document.createElement("panel");
|
2013-05-31 09:50:01 -07:00
|
|
|
tempPanel.appendChild(viewNode);
|
2013-05-09 09:00:33 -07:00
|
|
|
tempPanel.setAttribute("type", "arrow");
|
|
|
|
tempPanel.setAttribute("id", "customizationui-widget-panel");
|
|
|
|
document.getElementById(CustomizableUI.AREA_NAVBAR).appendChild(tempPanel);
|
|
|
|
tempPanel.addEventListener("popuphidden", function panelRemover() {
|
|
|
|
tempPanel.removeEventListener("popuphidden", panelRemover);
|
|
|
|
this.multiView.appendChild(viewNode);
|
|
|
|
tempPanel.parentElement.removeChild(tempPanel);
|
|
|
|
}.bind(this));
|
|
|
|
|
2013-05-31 09:50:01 -07:00
|
|
|
tempPanel.openPopup(aAnchor, "bottomcenter topright");
|
2013-04-30 14:20:00 -07:00
|
|
|
}
|
2013-03-26 14:23:23 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets the anchor node into the open or closed state, depending
|
|
|
|
* on the state of the panel.
|
|
|
|
*/
|
|
|
|
_updatePanelButton: function() {
|
|
|
|
this.menuButton.open = this.panel.state == "open" ||
|
|
|
|
this.panel.state == "showing";
|
2013-05-14 09:55:21 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
_updateZoomResetButton: function() {
|
|
|
|
this.zoomResetButton.setAttribute("label", gNavigatorBundle
|
|
|
|
.getFormattedString("zoomReset.label", [Math.floor(ZoomManager.zoom * 100)]));
|
2013-05-17 01:41:12 -07:00
|
|
|
},
|
|
|
|
|
2013-05-31 09:50:01 -07:00
|
|
|
// Button onclick handler which hides the whole PanelUI
|
|
|
|
_onHelpViewClick: function(aEvent) {
|
|
|
|
if (aEvent.button == 0 && !aEvent.target.hasAttribute("disabled")) {
|
2013-05-17 01:41:12 -07:00
|
|
|
PanelUI.hide();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
_onHelpViewShow: function(aEvent) {
|
|
|
|
// Call global menu setup function
|
|
|
|
buildHelpMenu();
|
|
|
|
|
|
|
|
let helpMenu = document.getElementById("menu_HelpPopup");
|
|
|
|
let items = this.getElementsByTagName("vbox")[0];
|
|
|
|
let attrs = ["oncommand", "onclick", "label", "key", "disabled"];
|
|
|
|
let NSXUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
|
|
|
|
|
|
|
// Remove all buttons from the view
|
|
|
|
while (items.firstChild) {
|
|
|
|
items.removeChild(items.firstChild);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add the current set of menuitems of the Help menu to this view
|
|
|
|
let menuItems = Array.prototype.slice.call(helpMenu.getElementsByTagName("menuitem"));
|
|
|
|
let fragment = document.createDocumentFragment();
|
|
|
|
for (let node of menuItems) {
|
|
|
|
if (node.hidden)
|
|
|
|
continue;
|
|
|
|
let button = document.createElementNS(NSXUL, "toolbarbutton");
|
|
|
|
// Copy specific attributes from a menuitem of the Help menu
|
|
|
|
for (let attrName of attrs) {
|
|
|
|
if (!node.hasAttribute(attrName))
|
|
|
|
continue;
|
|
|
|
button.setAttribute(attrName, node.getAttribute(attrName));
|
|
|
|
}
|
|
|
|
fragment.appendChild(button);
|
|
|
|
}
|
|
|
|
items.appendChild(fragment);
|
|
|
|
|
2013-05-31 09:50:01 -07:00
|
|
|
this.addEventListener("click", PanelUI._onHelpViewClick, false);
|
2013-05-17 01:41:12 -07:00
|
|
|
},
|
|
|
|
|
|
|
|
_onHelpViewHide: function(aEvent) {
|
2013-05-31 09:50:01 -07:00
|
|
|
this.removeEventListener("click", PanelUI._onHelpViewClick);
|
2013-05-09 09:00:33 -07:00
|
|
|
}
|
2013-03-26 14:23:23 -07:00
|
|
|
};
|