Bug 1217129: Part 5 - [webext] Use CustomizableUI views for BrowserAction popups. r=gijs ui-r=bwinton

This version addresses some popup sizing bugs, and also a few other issues I
ran into when debugging Blake's problems:

 * The standalone popup needs a max width of 800px for Chrome compatibility,
   which is wider than our default max width.

 * I added a flex attribute to our browser so that it fills the entire space
   of the slide-in panel. This is only necessary for browsers with content
   that is shorter than the height of the panel when it gets its desired
   width, but becomes longer when it doesn't, so it didn't show up in my
   initial tests.

 * I also added an extra pixel to the width calculations, since I noticed that
   a lot of single lines of text were unexpectedly wrapping without it. I'll
   look into this more in a follow-up bug.

I also added some comments, and renamed a couple of variables, where things
seemed unclear.

The test changes are mostly just updates to older browser action tests to use
newer helpers, rather than ad-hoc events, to open/close/click the widgets. A
few tests also needed updates to explicitly close the panel when they were
done with it.
This commit is contained in:
Kris Maglione
2016-01-15 15:14:25 -08:00
parent 46afafe21a
commit 9c47f8c68d
13 changed files with 321 additions and 167 deletions

View File

@@ -13,6 +13,8 @@ var {
runSafe,
} = ExtensionUtils;
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
// WeakMap[Extension -> BrowserAction]
var browserActionMap = new WeakMap();
@@ -24,7 +26,10 @@ function browserActionOf(extension) {
// as the associated popup.
function BrowserAction(options, extension) {
this.extension = extension;
this.id = makeWidgetId(extension.id) + "-browser-action";
let widgetId = makeWidgetId(extension.id);
this.id = `${widgetId}-browser-action`;
this.viewId = `PanelUI-webext-${widgetId}-browser-action-view`;
this.widget = null;
this.tabManager = TabManager.for(extension);
@@ -55,31 +60,60 @@ BrowserAction.prototype = {
build() {
let widget = CustomizableUI.createWidget({
id: this.id,
type: "custom",
viewId: this.viewId,
type: "view",
removable: true,
label: this.defaults.title || this.extension.name,
tooltiptext: this.defaults.title || "",
defaultArea: CustomizableUI.AREA_NAVBAR,
onBuild: document => {
let node = document.createElement("toolbarbutton");
node.id = this.id;
node.setAttribute("class", "toolbarbutton-1 chromeclass-toolbar-additional badged-button");
onBeforeCreated: document => {
let view = document.createElementNS(XUL_NS, "panelview");
view.id = this.viewId;
view.setAttribute("flex", "1");
document.getElementById("PanelUI-multiView").appendChild(view);
},
onDestroyed: document => {
let view = document.getElementById(this.viewId);
if (view) {
view.remove();
}
},
onCreated: node => {
node.classList.add("badged-button");
node.setAttribute("constrain-size", "true");
this.updateButton(node, this.defaults);
},
onViewShowing: event => {
let document = event.target.ownerDocument;
let tabbrowser = document.defaultView.gBrowser;
node.addEventListener("command", event => { // eslint-disable-line mozilla/balanced-listeners
let tab = tabbrowser.selectedTab;
let popup = this.getProperty(tab, "popup");
this.tabManager.addActiveTabPermission(tab);
if (popup) {
this.togglePopup(node, popup);
} else {
this.emit("click");
}
});
let tab = tabbrowser.selectedTab;
let popupURL = this.getProperty(tab, "popup");
this.tabManager.addActiveTabPermission(tab);
return node;
// If the widget has a popup URL defined, we open a popup, but do not
// dispatch a click event to the extension.
// If it has no popup URL defined, we dispatch a click event, but do not
// open a popup.
if (popupURL) {
try {
new ViewPopup(this.extension, event.target, popupURL);
} catch (e) {
Cu.reportError(e);
event.preventDefault();
}
} else {
// This isn't not a hack, but it seems to provide the correct behavior
// with the fewest complications.
event.preventDefault();
this.emit("click");
}
},
});
@@ -89,10 +123,6 @@ BrowserAction.prototype = {
this.widget = widget;
},
togglePopup(node, popupResource) {
openPanel(node, popupResource, this.extension);
},
// Update the toolbar button |node| with the tab context data
// in |tabData|.
updateButton(node, tabData) {