Bug 1280128: [webext] Use transparent backgrounds and padding for popup browsers. r?bwinton ui-r?maritz
MozReview-Commit-ID: 9jmuxdSLmBM
--- a/browser/components/extensions/ext-utils.js
+++ b/browser/components/extensions/ext-utils.js
@@ -1,17 +1,23 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
XPCOMUtils.defineLazyModuleGetter(this, "CustomizableUI",
"resource:///modules/CustomizableUI.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
+ "resource://gre/modules/NetUtil.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
+XPCOMUtils.defineLazyServiceGetter(this, "styleSheetService",
+ "@mozilla.org/content/style-sheet-service;1",
+ "nsIStyleSheetService");
+
Cu.import("resource://gre/modules/ExtensionUtils.jsm");
Cu.import("resource://gre/modules/AppConstants.jsm");
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
// Minimum time between two resizes.
const RESIZE_TIMEOUT = 100;
@@ -37,35 +43,49 @@ function promisePopupShown(popup) {
popup.addEventListener("popupshown", function onPopupShown(event) {
popup.removeEventListener("popupshown", onPopupShown);
resolve();
});
}
});
}
-XPCOMUtils.defineLazyGetter(global, "stylesheets", () => {
- let styleSheetService = Cc["@mozilla.org/content/style-sheet-service;1"]
- .getService(Components.interfaces.nsIStyleSheetService);
- let styleSheetURI = Services.io.newURI("chrome://browser/content/extension.css",
- null, null);
+XPCOMUtils.defineLazyGetter(this, "stylesheets", () => {
+ let styleSheetURI = NetUtil.newURI("chrome://browser/content/extension.css");
let styleSheet = styleSheetService.preloadSheet(styleSheetURI,
styleSheetService.AGENT_SHEET);
let stylesheets = [styleSheet];
if (AppConstants.platform === "macosx") {
- styleSheetURI = Services.io.newURI("chrome://browser/content/extension-mac.css",
- null, null);
+ styleSheetURI = NetUtil.newURI("chrome://browser/content/extension-mac.css");
let macStyleSheet = styleSheetService.preloadSheet(styleSheetURI,
styleSheetService.AGENT_SHEET);
stylesheets.push(macStyleSheet);
}
return stylesheets;
});
+XPCOMUtils.defineLazyGetter(this, "standaloneStylesheets", () => {
+ let stylesheets = [];
+
+ if (AppConstants.platform === "macosx") {
+ let styleSheetURI = NetUtil.newURI("chrome://browser/content/extension-mac-panel.css");
+ let macStyleSheet = styleSheetService.preloadSheet(styleSheetURI,
+ styleSheetService.AGENT_SHEET);
+ stylesheets.push(macStyleSheet);
+ }
+ if (AppConstants.platform === "win") {
+ let styleSheetURI = NetUtil.newURI("chrome://browser/content/extension-win-panel.css");
+ let winStyleSheet = styleSheetService.preloadSheet(styleSheetURI,
+ styleSheetService.AGENT_SHEET);
+ stylesheets.push(winStyleSheet);
+ }
+ return stylesheets;
+});
+
class BasePopup {
constructor(extension, viewNode, popupURL, browserStyle) {
let popupURI = Services.io.newURI(popupURL, null, extension.baseURI);
Services.scriptSecurityManager.checkLoadURIWithPrincipal(
extension.principal, popupURI,
Services.scriptSecurityManager.DISALLOW_SCRIPT);
@@ -118,21 +138,30 @@ class BasePopup {
handleEvent(event) {
switch (event.type) {
case this.DESTROY_EVENT:
this.destroy();
break;
case "DOMWindowCreated":
- if (this.browserStyle && event.target === this.browser.contentDocument) {
+ if (event.target === this.browser.contentDocument) {
let winUtils = this.browser.contentWindow
- .QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
- for (let stylesheet of global.stylesheets) {
- winUtils.addSheet(stylesheet, winUtils.AGENT_SHEET);
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindowUtils);
+
+ if (this.browserStyle) {
+ for (let stylesheet of stylesheets) {
+ winUtils.addSheet(stylesheet, winUtils.AGENT_SHEET);
+ }
+ }
+ if (!this.fixedWidth) {
+ for (let stylesheet of standaloneStylesheets) {
+ winUtils.addSheet(stylesheet, winUtils.AGENT_SHEET);
+ }
}
}
break;
case "DOMWindowClose":
if (event.target === this.browser.contentWindow) {
event.preventDefault();
this.closePopup();
@@ -169,16 +198,18 @@ class BasePopup {
}
}
createBrowser(viewNode, popupURI) {
let document = viewNode.ownerDocument;
this.browser = document.createElementNS(XUL_NS, "browser");
this.browser.setAttribute("type", "content");
this.browser.setAttribute("disableglobalhistory", "true");
+ this.browser.setAttribute("transparent", "true");
+ this.browser.setAttribute("class", "webextension-popup-browser");
this.browser.setAttribute("webextension-view-type", "popup");
// We only need flex sizing for the sake of the slide-in sub-views of the
// main menu panel, so that the browser occupies the full width of the view,
// and also takes up any extra height that's available to it.
this.browser.setAttribute("flex", "1");
// Note: When using noautohide panels, the popup manager will add width and
new file mode 100644
--- /dev/null
+++ b/browser/components/extensions/extension-mac-panel.css
@@ -0,0 +1,3 @@
+body {
+ border-radius: 3.5px;
+}
new file mode 100644
--- /dev/null
+++ b/browser/components/extensions/extension-win-panel.css
@@ -0,0 +1,7 @@
+@media (-moz-os-version: windows-xp),
+ (-moz-os-version: windows-vista),
+ (-moz-os-version: windows-win7) {
+ body {
+ border-radius: 4px;
+ }
+}
--- a/browser/components/extensions/extension.css
+++ b/browser/components/extensions/extension.css
@@ -6,17 +6,17 @@ select,
option,
input {
-moz-appearance: none;
}
/* Variables */
html,
body {
- background-color: #fcfcfc;
+ background: transparent;
box-sizing: border-box;
color: #222426;
cursor: default;
display: flex;
flex-direction: column;
font: caption;
margin: 0;
padding: 0;
--- a/browser/components/extensions/jar.mn
+++ b/browser/components/extensions/jar.mn
@@ -1,15 +1,21 @@
# 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/.
browser.jar:
content/browser/extension.css
+#ifdef XP_MACOSX
content/browser/extension-mac.css
+ content/browser/extension-mac-panel.css
+#endif
+#ifdef XP_WIN
+ content/browser/extension-win-panel.css
+#endif
content/browser/extension.svg
content/browser/ext-bookmarks.js
content/browser/ext-browserAction.js
content/browser/ext-commands.js
content/browser/ext-contextMenus.js
content/browser/ext-desktop-runtime.js
content/browser/ext-history.js
content/browser/ext-pageAction.js
--- a/browser/components/extensions/test/browser/browser.ini
+++ b/browser/components/extensions/test/browser/browser.ini
@@ -38,16 +38,17 @@ support-files =
[browser_ext_incognito_popup.js]
[browser_ext_lastError.js]
[browser_ext_optionsPage_privileges.js]
[browser_ext_pageAction_context.js]
[browser_ext_pageAction_popup.js]
[browser_ext_pageAction_popup_resize.js]
[browser_ext_pageAction_simple.js]
[browser_ext_popup_api_injection.js]
+[browser_ext_popup_corners.js]
[browser_ext_runtime_openOptionsPage.js]
[browser_ext_runtime_openOptionsPage_uninstall.js]
[browser_ext_runtime_setUninstallURL.js]
[browser_ext_simple.js]
[browser_ext_tab_runtimeConnect.js]
[browser_ext_tabs_audio.js]
[browser_ext_tabs_captureVisibleTab.js]
[browser_ext_tabs_create.js]
new file mode 100644
--- /dev/null
+++ b/browser/components/extensions/test/browser/browser_ext_popup_corners.js
@@ -0,0 +1,101 @@
+/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set sts=2 sw=2 et tw=80: */
+"use strict";
+
+function* awaitPanel(extension, win = window) {
+ let {target} = yield BrowserTestUtils.waitForEvent(win.document, "load", true, (event) => {
+ return event.target.location && event.target.location.href.endsWith("popup.html");
+ });
+
+ return target.defaultView
+ .QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDocShell)
+ .chromeEventHandler;
+}
+
+add_task(function* testPopupBorderRadius() {
+ let extension = ExtensionTestUtils.loadExtension({
+ background() {
+ browser.tabs.query({active: true, currentWindow: true}, tabs => {
+ browser.pageAction.show(tabs[0].id);
+ });
+ },
+
+ manifest: {
+ "browser_action": {
+ "default_popup": "popup.html",
+ "browser_style": false,
+ },
+
+ "page_action": {
+ "default_popup": "popup.html",
+ "browser_style": false,
+ },
+ },
+
+ files: {
+ "popup.html": `<!DOCTYPE html>
+ <html>
+ <head><meta charset="utf-8"></head>
+ <body style="width: 100px; height: 100px;"></body>
+ </html>`,
+ },
+ });
+
+ yield extension.startup();
+
+ function* testPanel(browser, standAlone = true) {
+ let panel = getPanelForNode(browser);
+ let arrowContent = document.getAnonymousElementByAttribute(panel, "class", "panel-arrowcontent");
+
+ let panelStyle = getComputedStyle(arrowContent);
+
+ let viewNode = browser.parentNode === panel ? browser : browser.parentNode;
+ let viewStyle = getComputedStyle(viewNode);
+
+ let win = browser.contentWindow;
+ let bodyStyle = win.getComputedStyle(win.document.body);
+
+ for (let prop of ["borderTopLeftRadius", "borderTopRightRadius",
+ "borderBottomRightRadius", "borderBottomLeftRadius"]) {
+ if (standAlone) {
+ is(viewStyle[prop], panelStyle[prop], `Panel and view ${prop} should be the same`);
+ is(bodyStyle[prop], panelStyle[prop], `Panel and body ${prop} should be the same`);
+ } else {
+ is(viewStyle[prop], "0px", `View node ${prop} should be 0px`);
+ is(bodyStyle[prop], "0px", `Body node ${prop} should be 0px`);
+ }
+ }
+ }
+
+ {
+ info("Test stand-alone browserAction popup");
+
+ clickBrowserAction(extension);
+ let browser = yield awaitPanel(extension);
+ yield testPanel(browser);
+ yield closeBrowserAction(extension);
+ }
+
+ {
+ info("Test menu panel browserAction popup");
+
+ let widget = getBrowserActionWidget(extension);
+ CustomizableUI.addWidgetToArea(widget.id, CustomizableUI.AREA_PANEL);
+
+ clickBrowserAction(extension);
+ let browser = yield awaitPanel(extension);
+ yield testPanel(browser, false);
+ yield closeBrowserAction(extension);
+ }
+
+ {
+ info("Test pageAction popup");
+
+ clickPageAction(extension);
+ let browser = yield awaitPanel(extension);
+ yield testPanel(browser);
+ yield closePageAction(extension);
+ }
+
+ yield extension.unload();
+});
--- a/browser/themes/linux/browser.css
+++ b/browser/themes/linux/browser.css
@@ -1945,11 +1945,20 @@ notification.pluginVulnerable > .notific
margin-inline-end: 0 !important;
}
.browser-extension-panel > .panel-arrowcontainer > .panel-arrowcontent {
padding: 0;
overflow: hidden;
}
+.webextension-popup-browser {
+ margin-right: -1px;
+ border-radius: inherit;
+}
+
+#PanelUI-popup .webextension-popup-browser {
+ margin: 0;
+}
+
.menuitem-iconic[usercontextid] > .menu-iconic-left > .menu-iconic-icon {
visibility: visible;
}
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -3457,8 +3457,21 @@ menulist.translate-infobar-element > .me
padding-left: 0;
padding-right: 0;
}
.browser-extension-panel > .panel-arrowcontainer > .panel-arrowcontent {
padding: 0;
overflow: hidden;
}
+
+.cui-widget-panelview[id^=PanelUI-webext-] {
+ border-radius: 3.5px;
+}
+
+.webextension-popup-browser {
+ margin-right: -1px;
+ border-radius: inherit;
+}
+
+#PanelUI-popup .webextension-popup-browser {
+ margin: 0;
+}
--- a/browser/themes/shared/customizableui/panelUI.inc.css
+++ b/browser/themes/shared/customizableui/panelUI.inc.css
@@ -268,20 +268,16 @@ panelmultiview[nosubviews=true] > .panel
.cui-widget-panel[viewId^=PanelUI-webext-] .panel-mainview {
max-width: 800px;
}
.cui-widget-panel[viewId^=PanelUI-webext-] > .panel-arrowcontainer > .panel-arrowcontent {
padding: 0;
}
-.cui-widget-panelview[id^=PanelUI-webext-] {
- border-radius: 3.5px;
-}
-
panelview[id^=PanelUI-webext-] {
overflow: hidden;
}
panelview:not([mainview]) .toolbarbutton-text,
.cui-widget-panel toolbarbutton > .toolbarbutton-text {
text-align: start;
display: -moz-box;
--- a/browser/themes/windows/browser.css
+++ b/browser/themes/windows/browser.css
@@ -2704,8 +2704,25 @@ notification.pluginVulnerable > .notific
@media not all and (-moz-os-version: windows-xp) {
%include browser-aero.css
}
.browser-extension-panel > .panel-arrowcontainer > .panel-arrowcontent {
padding: 0;
overflow: hidden;
}
+
+@media (-moz-os-version: windows-xp),
+ (-moz-os-version: windows-vista),
+ (-moz-os-version: windows-win7) {
+ .cui-widget-panelview[id^=PanelUI-webext-] {
+ border-radius: 4px;
+ }
+}
+
+.webextension-popup-browser {
+ margin-right: -1px;
+ border-radius: inherit;
+}
+
+#PanelUI-popup .webextension-popup-browser {
+ margin: 0;
+}