--- a/browser/base/content/browser-pageActions.js
+++ b/browser/base/content/browser-pageActions.js
@@ -130,17 +130,17 @@ var BrowserPageActions = {
}
buttonNode.addEventListener("command", event => {
if (panelViewNode) {
action.subview.onShowing(panelViewNode);
this.multiViewNode.showSubView(panelViewNode, buttonNode);
return;
}
if (action.wantsIframe) {
- this._toggleTempPanelForAction(action);
+ this._toggleActivatedActionPanelForAction(action);
return;
}
this.panelNode.hidePopup();
action.onCommand(event, buttonNode);
});
return [buttonNode, panelViewNode];
},
@@ -167,27 +167,55 @@ var BrowserPageActions = {
buttonNode.addEventListener("command", event => {
button.onCommand(event, buttonNode);
});
bodyNode.appendChild(buttonNode);
}
return panelViewNode;
},
- _toggleTempPanelForAction(action) {
- let panelNodeID = this._tempPanelID;
- let panelNode = document.getElementById(panelNodeID);
+ _toggleActivatedActionPanelForAction(action) {
+ let panelNode = this.activatedActionPanelNode;
if (panelNode) {
panelNode.hidePopup();
return null;
}
+ // Before creating the panel, find the best anchor node for it because we'll
+ // bail if there isn't one. Try each of the following nodes in order, using
+ // the first that's visible.
+ let anchorNode = null;
+ let potentialAnchorNodeIDs = [
+ action.anchorIDOverride || null,
+ this._urlbarButtonNodeIDForActionID(action.id),
+ this.mainButtonNode.id,
+ "identity-icon",
+ ];
+ let dwu = window.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindowUtils);
+ for (let id of potentialAnchorNodeIDs) {
+ if (id) {
+ let node = document.getElementById(id);
+ if (node && !node.hidden) {
+ let bounds = dwu.getBoundsWithoutFlushing(node);
+ if (bounds.height > 0 && bounds.width > 0) {
+ anchorNode = node;
+ break;
+ }
+ }
+ }
+ }
+ if (!anchorNode) {
+ throw new Error(`PageActions: No anchor node for '${action.id}'`);
+ }
+
panelNode = document.createElement("panel");
- panelNode.id = panelNodeID;
+ panelNode.id = this._activatedActionPanelID;
panelNode.classList.add("cui-widget-panel");
+ panelNode.setAttribute("actionID", action.id);
panelNode.setAttribute("role", "group");
panelNode.setAttribute("type", "arrow");
panelNode.setAttribute("flip", "slide");
panelNode.setAttribute("noautofocus", "true");
panelNode.setAttribute("tabspecific", "true");
let panelViewNode = null;
let iframeNode = null;
@@ -218,39 +246,34 @@ var BrowserPageActions = {
}
}, { once: true });
if (panelViewNode) {
action.subview.onPlaced(panelViewNode);
action.subview.onShowing(panelViewNode);
}
+ // Hide the main page action panel before showing the activated-action
+ // panel.
this.panelNode.hidePopup();
-
- let urlbarNodeID = this._urlbarButtonNodeIDForActionID(action.id);
- let urlbarNode = document.getElementById(urlbarNodeID);
- let anchorNode;
- if (urlbarNode && !urlbarNode.hidden) {
- anchorNode = action.anchorIDOverride ?
- document.getElementById(action.anchorIDOverride) :
- urlbarNode;
- } else {
- anchorNode = this.mainButtonNode;
- }
panelNode.openPopup(anchorNode, "bottomcenter topright");
if (iframeNode) {
action.onIframeShown(iframeNode, panelNode);
}
return panelNode;
},
- get _tempPanelID() {
- return "pageActionTempPanel";
+ get activatedActionPanelNode() {
+ return document.getElementById(this._activatedActionPanelID);
+ },
+
+ get _activatedActionPanelID() {
+ return "pageActionActivatedActionPanel";
},
/**
* Adds or removes as necessary a DOM node for the given action in the urlbar.
*
* @param action (PageActions.Action, required)
* The action to place.
* @param insertBeforeID (string, required)
@@ -327,17 +350,17 @@ var BrowserPageActions = {
buttonNode.setAttribute(name, action.nodeAttributes[name]);
}
}
buttonNode.addEventListener("click", event => {
if (event.button != 0) {
return;
}
if (action.subview || action.wantsIframe) {
- this._toggleTempPanelForAction(action);
+ this._toggleActivatedActionPanelForAction(action);
return;
}
action.onCommand(event, buttonNode);
});
return buttonNode;
},
_appendPanelSeparator(action) {
@@ -427,17 +450,17 @@ var BrowserPageActions = {
let node = document.getElementById(id);
if (node) {
node.setAttribute("label", action.title);
}
},
doCommandForAction(action) {
if (action.subview || action.wantsIframe) {
- this._toggleTempPanelForAction(action);
+ this._toggleActivatedActionPanelForAction(action);
return;
}
action.onCommand();
},
/**
* Returns the action for a node.
*
@@ -523,20 +546,21 @@ var BrowserPageActions = {
mainButtonClicked(event) {
event.stopPropagation();
if ((event.type == "click" && event.button != 0) ||
(event.type == "keypress" && event.charCode != KeyEvent.DOM_VK_SPACE &&
event.keyCode != KeyEvent.DOM_VK_RETURN)) {
return;
}
- // If the temp panel is open and anchored to the main button, close it.
- let tempPanel = document.getElementById(this._tempPanelID);
- if (tempPanel && tempPanel.anchorNode.id == this.mainButtonNode.id) {
- tempPanel.hidePopup();
+ // If the activated-action panel is open and anchored to the main button,
+ // close it.
+ let panelNode = this.activatedActionPanelNode;
+ if (panelNode && panelNode.anchorNode.id == this.mainButtonNode.id) {
+ panelNode.hidePopup();
return;
}
if (this.panelNode.state == "open") {
this.panelNode.hidePopup();
} else if (this.panelNode.state == "closed") {
this.showPanel(event);
}
--- a/browser/base/content/test/performance/browser_startup_images.js
+++ b/browser/base/content/test/performance/browser_startup_images.js
@@ -32,16 +32,20 @@ const whitelist = [
{
file: "chrome://browser/skin/bookmark-hollow.svg",
platforms: ["linux", "win", "macosx"],
},
{
file: "chrome://browser/skin/page-action.svg",
platforms: ["linux", "win", "macosx"],
},
+ {
+ file: "chrome://pocket-shared/skin/pocket.svg",
+ platforms: ["linux", "win", "macosx"],
+ },
// Shared entries
{
file: "chrome://browser/skin/arrow-left.svg",
platforms: ["linux", "win", "macosx"],
},
{
file: "chrome://browser/skin/arrow-dropdown-16.svg",
--- a/browser/base/content/theme-vars.inc.css
+++ b/browser/base/content/theme-vars.inc.css
@@ -121,20 +121,16 @@
:root[lwthemeicons~="--email_link-icon"] #email-link-button:-moz-lwtheme {
list-style-image: var(--email_link-icon) !important;
}
:root[lwthemeicons~="--forget-icon"] #panic-button:-moz-lwtheme {
list-style-image: var(--forget-icon) !important;
}
-:root[lwthemeicons~="--pocket-icon"] #pocket-button:-moz-lwtheme {
- list-style-image: var(--pocket-icon) !important;
-}
-
:root[lwthemeicons~="--bookmark_star-icon"] #star-button:-moz-lwtheme,
:root[lwthemeicons~="--bookmark_menu-icon"] #bookmarks-menu-button:-moz-lwtheme,
:root[lwthemeicons~="--back-icon"] #back-button:-moz-lwtheme,
:root[lwthemeicons~="--forward-icon"] #forward-button:-moz-lwtheme,
:root[lwthemeicons~="--reload-icon"] #reload-button:-moz-lwtheme,
:root[lwthemeicons~="--stop-icon"] #stop-button:-moz-lwtheme,
:root[lwthemeicons~="--bookmark_star-icon"] #bookmarks-menu-button:-moz-lwtheme,
:root[lwthemeicons~="--bookmark_menu-icon"] #bookmarks-menu-button[cui-areatype='toolbar'] > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon:-moz-lwtheme,
@@ -156,12 +152,11 @@
:root[lwthemeicons~="--developer-icon"] #developer-button:-moz-lwtheme,
:root[lwthemeicons~="--synced_tabs-icon"] #sync-button:-moz-lwtheme,
:root[lwthemeicons~="--open_file-icon"] #open-file-button:-moz-lwtheme,
:root[lwthemeicons~="--sidebars-icon"] #sidebar-button:-moz-lwtheme,
:root[lwthemeicons~="--share_page-icon"] #social-share-button:-moz-lwtheme,
:root[lwthemeicons~="--subscribe-icon"] #feed-button:-moz-lwtheme,
:root[lwthemeicons~="--text_encoding-icon"] #characterencoding-button:-moz-lwtheme,
:root[lwthemeicons~="--email_link-icon"] #email-link-button:-moz-lwtheme,
-:root[lwthemeicons~="--forget-icon"] #panic-button:-moz-lwtheme,
-:root[lwthemeicons~="--pocket-icon"] #pocket-button:-moz-lwtheme {
+:root[lwthemeicons~="--forget-icon"] #panic-button:-moz-lwtheme {
-moz-image-region: rect(0, 16px, 16px, 0) !important;
}
--- a/browser/components/customizableui/CustomizableUI.jsm
+++ b/browser/components/customizableui/CustomizableUI.jsm
@@ -60,17 +60,16 @@ const kSubviewEvents = [
var kVersion = 10;
/**
* Buttons removed from built-ins by version they were removed. kVersion must be
* bumped any time a new id is added to this. Use the button id as key, and
* version the button is removed in as the value. e.g. "pocket-button": 5
*/
var ObsoleteBuiltinButtons = {
- "pocket-button": 6
};
/**
* gPalette is a map of every widget that CustomizableUI.jsm knows about, keyed
* on their IDs.
*/
var gPalette = new Map();
@@ -200,23 +199,16 @@ var CustomizableUIInternal = {
"library-button",
"sidebar-button",
];
if (AppConstants.MOZ_DEV_EDITION) {
navbarPlacements.splice(2, 0, "developer-button");
}
- // Place this last, when createWidget is called for pocket, it will
- // append to the toolbar.
- if (Services.prefs.getBoolPref("extensions.pocket.enabled", false) &&
- Services.prefs.getBoolPref("extensions.pocket.disablePageAction", false)) {
- navbarPlacements.push("pocket-button");
- }
-
this.registerArea(CustomizableUI.AREA_NAVBAR, {
legacy: true,
type: CustomizableUI.TYPE_TOOLBAR,
overflowable: true,
defaultPlacements: navbarPlacements,
defaultCollapsed: false,
}, true);
--- a/browser/components/extensions/test/browser/browser_ext_themes_icons.js
+++ b/browser/components/extensions/test/browser/browser_ext_themes_icons.js
@@ -133,17 +133,16 @@ async function runTestWithIcons(icons) {
["synced_tabs", "#sync-button", "sync-button"],
["open_file", "#open-file-button", "open-file-button"],
["sidebars", "#sidebar-button", "sidebar-button"],
["share_page", "#social-share-button", "social-share-button"],
["subscribe", "#feed-button", "feed-button"],
["text_encoding", "#characterencoding-button", "characterencoding-button"],
["email_link", "#email-link-button", "email-link-button"],
["forget", "#panic-button", "panic-button"],
- ["pocket", "#pocket-button", "pocket-button"],
];
// We add these at the beginning because adding them at the end can end up
// putting them in the overflow panel, where they aren't displayed the same way.
ICON_INFO.unshift(["bookmark_star", "#star-button"]);
ICON_INFO.unshift(["bookmark_menu", "#bookmarks-menu-button", "bookmarks-menu-button"]);
window.maximize();
@@ -207,17 +206,16 @@ add_task(async function test_all_icons()
["synced_tabs", "fox.svg"],
["open_file", "fox.svg"],
["sidebars", "fox.svg"],
["share_page", "fox.svg"],
["subscribe", "fox.svg"],
["text_encoding", "fox.svg"],
["email_link", "fox.svg"],
["forget", "fox.svg"],
- ["pocket", "fox.svg"],
];
await runTestWithIcons(icons);
});
add_task(async function teardown() {
CustomizableUI.reset();
window.restore();
});
@@ -249,17 +247,16 @@ add_task(async function test_some_icons(
["synced_tabs", ""],
["open_file", ""],
["sidebars", ""],
["share_page", ""],
["subscribe", ""],
["text_encoding", ""],
["email_link", ""],
["forget", ""],
- ["pocket", "fox.svg"],
];
await runTestWithIcons(icons);
});
add_task(async function teardown() {
CustomizableUI.reset();
window.restore();
});
--- a/browser/components/uitour/UITour.jsm
+++ b/browser/components/uitour/UITour.jsm
@@ -27,16 +27,18 @@ XPCOMUtils.defineLazyModuleGetter(this,
XPCOMUtils.defineLazyModuleGetter(this, "BrowserUITelemetry",
"resource:///modules/BrowserUITelemetry.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ProfileAge",
"resource://gre/modules/ProfileAge.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ReaderParent",
"resource:///modules/ReaderParent.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "PageActions",
+ "resource:///modules/PageActions.jsm");
// See LOG_LEVELS in Console.jsm. Common examples: "All", "Info", "Warn", & "Error".
const PREF_LOG_LEVEL = "browser.uitour.loglevel";
const PREF_SEENPAGEIDS = "browser.uitour.seenPageIDs";
const BACKGROUND_PAGE_ACTIONS_ALLOWED = new Set([
"forceShowReaderIcon",
"getConfiguration",
@@ -146,17 +148,16 @@ this.UITour = {
widgetName: "panic-button",
}],
["help", {query: "#appMenu-help-button"}],
["home", {query: "#home-button"}],
["library", {query: "#appMenu-library-button"}],
["pocket", {
allowAdd: true,
query: "#pocket-button",
- widgetName: "pocket-button",
}],
["privateWindow", {query: "#appMenu-private-window-button"}],
["quit", {query: "#appMenu-quit-button"}],
["readerMode-urlBar", {query: "#reader-mode-button"}],
["search", {
infoPanelOffsetX: 18,
infoPanelPosition: "after_start",
query: "#searchbar",
@@ -1411,54 +1412,22 @@ this.UITour = {
this.recreatePopup(popup);
// Open the control center
if (aOpenCallback) {
popup.addEventListener("popupshown", aOpenCallback, { once: true });
}
aWindow.document.getElementById("identity-box").click();
} else if (aMenuName == "pocket") {
- this.getTarget(aWindow, "pocket").then(async function onPocketTarget(target) {
- let widgetGroupWrapper = CustomizableUI.getWidget(target.widgetName);
- if (widgetGroupWrapper.type != "view" || !widgetGroupWrapper.viewId) {
- log.error("Can't open the pocket menu without a view");
- return;
- }
- let placement = CustomizableUI.getPlacementOfWidget(target.widgetName);
- if (!placement || !placement.area) {
- log.error("Can't open the pocket menu without a placement");
- return;
- }
-
- if (placement.area == CustomizableUI.AREA_PANEL) {
- // Open the appMenu and wait for it if it's not already opened or showing a subview.
- await new Promise((resolve, reject) => {
- if (aWindow.PanelUI.panel.state != "closed") {
- if (aWindow.PanelUI.multiView.showingSubView) {
- reject("A subview is already showing");
- return;
- }
-
- resolve();
- return;
- }
-
- aWindow.PanelUI.panel.addEventListener("popupshown", function() {
- resolve();
- }, {once: true});
-
- aWindow.PanelUI.show();
- });
- }
-
- let widgetWrapper = widgetGroupWrapper.forWindow(aWindow);
- aWindow.PanelUI.showSubView(widgetGroupWrapper.viewId,
- widgetWrapper.anchor,
- placement.area);
- }).catch(log.error);
+ let pageAction = PageActions.actionForID("pocket");
+ if (!pageAction) {
+ log.error("Can't open the pocket menu without a page action");
+ return;
+ }
+ pageAction.doCommand(aWindow);
} else if (aMenuName == "urlbar") {
this.getTarget(aWindow, "urlbar").then(target => {
let urlbar = target.node;
if (aOpenCallback) {
urlbar.popup.addEventListener("popupshown", aOpenCallback, { once: true });
}
urlbar.focus();
// To demonstrate the ability of searching, we type "Firefox" in advance
--- a/browser/components/uitour/test/browser_UITour_pocket.js
+++ b/browser/components/uitour/test/browser_UITour_pocket.js
@@ -1,82 +1,34 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
var gTestTab;
var gContentAPI;
var gContentWindow;
-var button;
-function test() {
- UITourTest();
-}
-
-var tests = [
- taskify(async function test_menu_show_navbar() {
- is(button.open, false, "Menu should initially be closed");
- gContentAPI.showMenu("pocket");
+add_task(setup_UITourTest);
- // The panel gets created dynamically.
- let widgetPanel = null;
- await waitForConditionPromise(() => {
- widgetPanel = document.getElementById("customizationui-widget-panel");
- return widgetPanel && widgetPanel.state == "open";
- }, "Menu should be visible after showMenu()");
-
- ok(button.open, "Button should know its view is open");
- ok(!widgetPanel.hasAttribute("noautohide"), "@noautohide shouldn't be on the pocket panel");
- ok(button.hasAttribute("open"), "Pocket button should know that the menu is open");
-
- widgetPanel.hidePopup();
- checkPanelIsHidden(widgetPanel);
- }),
- taskify(async function test_menu_show_appMenu() {
- CustomizableUI.addWidgetToArea("pocket-button", CustomizableUI.AREA_PANEL);
-
- is(PanelUI.multiView.hasAttribute("panelopen"), false, "Multiview should initially be closed");
- gContentAPI.showMenu("pocket");
-
- await waitForConditionPromise(() => {
- return PanelUI.panel.state == "open";
- }, "Menu should be visible after showMenu()");
+add_UITour_task(async function test_menu_show() {
+ let panel = BrowserPageActions.activatedActionPanelNode;
+ Assert.ok(!panel || panel.state == "closed",
+ "Pocket panel should initially be closed");
+ gContentAPI.showMenu("pocket");
- ok(!PanelUI.panel.hasAttribute("noautohide"), "@noautohide shouldn't be on the pocket panel");
- ok(PanelUI.multiView.showingSubView, "Subview should be open");
- ok(PanelUI.multiView.hasAttribute("panelopen"), "Multiview should know it's open");
+ // The panel gets created dynamically.
+ panel = null;
+ await waitForConditionPromise(() => {
+ panel = BrowserPageActions.activatedActionPanelNode;
+ return panel && panel.state == "open";
+ }, "Menu should be visible after showMenu()");
- PanelUI.showMainView();
- PanelUI.panel.hidePopup();
- checkPanelIsHidden(PanelUI.panel);
- }),
-];
-
-// End tests
+ Assert.ok(!panel.hasAttribute("noautohide"), "@noautohide shouldn't be on the pocket panel");
-function checkPanelIsHidden(aPanel) {
- if (aPanel.parentElement) {
- is_hidden(aPanel);
- } else {
- ok(!aPanel.parentElement, "Widget panel should have been removed");
- }
- is(button.hasAttribute("open"), false, "Pocket button should know that the panel is closed");
-}
-
-if (Services.prefs.getBoolPref("extensions.pocket.enabled")) {
- let placement = CustomizableUI.getPlacementOfWidget("pocket-button");
-
- // Add the button to the nav-bar by default.
- if (!placement || placement.area != CustomizableUI.AREA_NAVBAR) {
- CustomizableUI.addWidgetToArea("pocket-button", CustomizableUI.AREA_NAVBAR);
- }
- registerCleanupFunction(() => {
- CustomizableUI.reset();
+ panel.hidePopup();
+ await new Promise(resolve => {
+ panel = BrowserPageActions.activatedActionPanelNode;
+ if (!panel || panel.state == "closed") {
+ resolve();
+ }
});
-
- let widgetGroupWrapper = CustomizableUI.getWidget("pocket-button");
- button = widgetGroupWrapper.forWindow(window).node;
- ok(button, "Got button node");
-} else {
- todo(false, "Pocket is disabled so skip its UITour tests");
- tests = [];
-}
+});
--- a/browser/extensions/pocket/bootstrap.js
+++ b/browser/extensions/pocket/bootstrap.js
@@ -11,33 +11,31 @@ Cu.import("resource://gre/modules/XPCOMU
Cu.import("resource://services-common/utils.js");
Cu.import("resource://gre/modules/AppConstants.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AboutPocket",
"chrome://pocket/content/AboutPocket.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AddonManagerPrivate",
"resource://gre/modules/AddonManager.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "BrowserUtils",
"resource://gre/modules/BrowserUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "CustomizableUI",
- "resource:///modules/CustomizableUI.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PageActions",
"resource:///modules/PageActions.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Pocket",
"chrome://pocket/content/Pocket.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ReaderMode",
"resource://gre/modules/ReaderMode.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "RecentWindow",
"resource:///modules/RecentWindow.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Services",
"resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyGetter(this, "gPocketBundle", function() {
return Services.strings.createBundle("chrome://pocket/locale/pocket.properties");
});
XPCOMUtils.defineLazyGetter(this, "gPocketStyleURI", function() {
- return Services.io.newURI("chrome://pocket/skin/pocket.css");
+ return Services.io.newURI("chrome://pocket-shared/skin/pocket.css");
});
// Due to bug 1051238 frame scripts are cached forever, so we can't update them
// as a restartless add-on. The Math.random() is the work around for this.
const PROCESS_SCRIPT = "chrome://pocket/content/pocket-content-process.js?" + Math.random();
const PREF_BRANCH = "extensions.pocket.";
const PREFS = {
@@ -71,115 +69,30 @@ function setDefaultPrefs() {
function createElementWithAttrs(document, type, attrs) {
let element = document.createElement(type);
Object.keys(attrs).forEach(function(attr) {
element.setAttribute(attr, attrs[attr]);
})
return element;
}
-function CreatePocketWidget(reason) {
- let id = "pocket-button"
- let widget = CustomizableUI.getWidget(id);
- // The widget is only null if we've created then destroyed the widget.
- // Once we've actually called createWidget the provider will be set to
- // PROVIDER_API.
- if (widget && widget.provider == CustomizableUI.PROVIDER_API)
- return;
- // if upgrading from builtin version and the button was placed in ui,
- // seenWidget will not be null
- let seenWidget = CustomizableUI.getPlacementOfWidget("pocket-button", false, true);
- let pocketButton = {
- id: "pocket-button",
- defaultArea: CustomizableUI.AREA_NAVBAR,
- introducedInVersion: "pref",
- type: "view",
- tabSpecific: true,
- viewId: "PanelUI-pocketView",
- label: gPocketBundle.GetStringFromName("pocket-button.label"),
- tooltiptext: gPocketBundle.GetStringFromName("pocket-button.tooltiptext"),
- // Use forwarding functions here to avoid loading Pocket.jsm on startup:
- onBeforeCommand() {
- // We need to use onBeforeCommand to calculate the height
- // of the pocket-button before it is opened since we need
- // the height of the button to perform the animation that is
- // triggered off of [open="true"].
- return Pocket.onBeforeCommand.apply(this, arguments);
- },
- onViewShowing() {
- return Pocket.onPanelViewShowing.apply(this, arguments);
- },
- onViewHiding() {
- return Pocket.onPanelViewHiding.apply(this, arguments);
- },
- onBeforeCreated(doc) {
- // Bug 1223127,CUI should make this easier to do.
- if (doc.getElementById("PanelUI-pocketView"))
- return;
- let view = doc.createElement("panelview");
- view.id = "PanelUI-pocketView";
- let panel = doc.createElement("vbox");
- panel.setAttribute("class", "panel-subview-body");
- view.appendChild(panel);
- doc.getElementById("PanelUI-multiView").appendChild(view);
- },
- onCreated(node) {
- if (Services.prefs.getBoolPref("toolkit.cosmeticAnimations.enabled")) {
- let doc = node.ownerDocument;
- let box = doc.createElement("box");
- box.classList.add("toolbarbutton-animatable-box");
- let image = doc.createElement("image");
- image.classList.add("toolbarbutton-animatable-image");
- box.appendChild(image);
- node.appendChild(box);
- node.setAttribute("animationsenabled", "true");
- }
- },
- };
-
- CustomizableUI.createWidget(pocketButton);
- CustomizableUI.addListener(pocketButton);
- // placed is null if location is palette
- let placed = CustomizableUI.getPlacementOfWidget("pocket-button");
-
- // a first time install will always have placed the button somewhere, and will
- // not have a placement prior to creating the widget. Thus, !seenWidget &&
- // placed.
- if (reason == ADDON_ENABLE && !seenWidget && placed) {
- // initially place the button after the bookmarks button if it is in the UI
- let widgets = CustomizableUI.getWidgetIdsInArea(CustomizableUI.AREA_NAVBAR);
- let bmbtn = widgets.indexOf("bookmarks-menu-button");
- if (bmbtn > -1) {
- CustomizableUI.moveWidgetWithinArea("pocket-button", bmbtn + 1);
- }
- }
-}
function isPocketEnabled() {
- return PocketPageAction.shouldUse ? PocketPageAction.enabled :
- !!CustomizableUI.getPlacementOfWidget("pocket-button");
+ return PocketPageAction.enabled;
}
var PocketPageAction = {
pageAction: null,
urlbarNode: null,
- get shouldUse() {
- return !Services.prefs.getBranch(PREF_BRANCH)
- .getBoolPref("disablePageAction", false);
- },
-
get enabled() {
return !!this.pageAction;
},
init() {
- if (!this.shouldUse) {
- return;
- }
let id = "pocket";
this.pageAction = PageActions.actionForID(id);
if (!this.pageAction) {
this.pageAction = PageActions.addAction(new PageActions.Action({
id,
title: gPocketBundle.GetStringFromName("pocket-button.label"),
shownInUrlbar: true,
wantsIframe: true,
@@ -210,32 +123,38 @@ var PocketPageAction = {
pocketButton.classList.add("urlbar-icon");
wrapper.appendChild(pocketButton);
wrapper.appendChild(animatableBox);
animatableBox.appendChild(animatableImage);
let iconBox = doc.getElementById("page-action-buttons");
iconBox.appendChild(wrapper);
wrapper.hidden = true;
+
wrapper.addEventListener("click", event => {
- PocketPageAction.onUrlbarNodeClicked(event);
+ if (event.type == "click" && event.button != 0) {
+ return;
+ }
+ this.doCommand(event.target.ownerGlobal);
});
},
onPlacedInPanel(panelNode, urlbarNode) {
PocketOverlay.onWindowOpened(panelNode.ownerGlobal);
},
onIframeShown(iframe, panel) {
Pocket.onShownInPhotonPageActionPanel(panel, iframe);
let doc = panel.ownerDocument;
let urlbarNode = doc.getElementById("pocket-button-box");
if (!urlbarNode || urlbarNode.hidden) {
return;
}
+ BrowserUtils.setToolbarButtonHeightProperty(urlbarNode);
+
PocketPageAction.urlbarNode = urlbarNode;
PocketPageAction.urlbarNode.setAttribute("open", "true");
if (Services.prefs.getBoolPref("toolkit.cosmeticAnimations.enabled")) {
PocketPageAction.urlbarNode.setAttribute("animate", "true");
}
},
onIframeHiding(iframe, panel) {
if (iframe.getAttribute("itemAdded") == "true") {
@@ -247,16 +166,17 @@ var PocketPageAction = {
return;
}
PocketPageAction.urlbarNode.removeAttribute("animate");
PocketPageAction.urlbarNode.removeAttribute("open");
PocketPageAction.urlbarNode = null;
},
}));
}
+ Pocket.pageAction = this.pageAction;
},
shutdown() {
if (!this.pageAction) {
return;
}
for (let win of browserWindows()) {
@@ -266,28 +186,16 @@ var PocketPageAction = {
pocketButtonBox.remove();
}
}
this.pageAction.remove();
this.pageAction = null;
},
- onUrlbarNodeClicked(event) {
- if (event.type == "click" && event.button != 0) {
- return;
- }
-
- BrowserUtils.setToolbarButtonHeightProperty(event.target);
-
- let win = event.target.ownerGlobal;
- let browserPageActions = win.BrowserPageActions;
- browserPageActions.doCommandForAction(PocketPageAction.pageAction);
- },
-
startLibraryAnimation(doc) {
var libraryButton = doc.getElementById("library-button");
if (!Services.prefs.getBoolPref("toolkit.cosmeticAnimations.enabled") ||
!libraryButton ||
libraryButton.getAttribute("cui-areatype") == "menu-panel" ||
libraryButton.getAttribute("overflowedItem") == "true" ||
!libraryButton.closest("#nav-bar")) {
return;
@@ -426,36 +334,18 @@ var PocketReader = {
break;
message.target.messageManager.
sendAsyncMessage("Reader:AddButton", { id: "pocket-button",
title: gPocketBundle.GetStringFromName("pocket-button.tooltiptext"),
image: "chrome://pocket/content/panels/img/pocket.svg#pocket-mark"});
break;
}
case "Reader:Clicked-pocket-button": {
- let doc = message.target.ownerDocument;
- if (PocketPageAction.shouldUse) {
- // TODO: PageActions should make this easier.
- let event = new doc.defaultView.CustomEvent("command");
- let panelButton = doc.getElementById("pageAction-panel-pocket");
- panelButton.dispatchEvent(event);
- } else {
- let pocketWidget = doc.getElementById("pocket-button");
- let placement = CustomizableUI.getPlacementOfWidget("pocket-button");
- if (placement) {
- if (placement.area == CustomizableUI.AREA_PANEL) {
- doc.defaultView.PanelUI.show().then(function() {
- // The DOM node might not exist yet if the panel wasn't opened before.
- pocketWidget = doc.getElementById("pocket-button");
- pocketWidget.doCommand();
- });
- } else {
- pocketWidget.doCommand();
- }
- }
+ if (PocketPageAction.pageAction) {
+ PocketPageAction.pageAction.doCommand(message.target.ownerGlobal);
}
break;
}
}
}
}
@@ -478,43 +368,33 @@ var PocketOverlay = {
startup(reason) {
let styleSheetService = Cc["@mozilla.org/content/style-sheet-service;1"]
.getService(Ci.nsIStyleSheetService);
this._sheetType = styleSheetService.AUTHOR_SHEET;
this._cachedSheet = styleSheetService.preloadSheet(gPocketStyleURI,
this._sheetType);
Services.ppmm.loadProcessScript(PROCESS_SCRIPT, true);
PocketReader.startup();
- if (PocketPageAction.shouldUse) {
- PocketPageAction.init();
- } else {
- CustomizableUI.addListener(this);
- CreatePocketWidget(reason);
- }
+ PocketPageAction.init();
PocketContextMenu.init();
for (let win of browserWindows()) {
this.onWindowOpened(win);
}
},
shutdown(reason) {
let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
.getService(Ci.nsIMessageBroadcaster);
ppmm.broadcastAsyncMessage("PocketShuttingDown");
// Although the ppmm loads the scripts into the chrome process as well,
// we need to manually unregister here anyway to ensure these aren't part
// of the chrome process and avoid errors.
AboutPocket.aboutSaved.unregister();
AboutPocket.aboutSignup.unregister();
- if (PocketPageAction.shouldUse) {
- PocketPageAction.shutdown();
- } else {
- CustomizableUI.removeListener(this);
- CustomizableUI.destroyWidget("pocket-button");
- }
+ PocketPageAction.shutdown();
for (let window of browserWindows()) {
for (let id of ["panelMenu_pocket", "menu_pocket", "BMB_pocket",
"panelMenu_pocketSeparator", "menu_pocketSeparator",
"BMB_pocketSeparator", "appMenu-library-pocket-button"]) {
let element = window.document.getElementById(id) ||
window.gNavToolbox.palette.querySelector("#" + id);
if (element)
@@ -532,19 +412,16 @@ var PocketOverlay = {
PocketReader.shutdown();
},
onWindowOpened(window) {
if (window.hasOwnProperty("pktUI"))
return;
this.setWindowScripts(window);
this.addStyles(window);
this.updateWindow(window);
- if (PocketPageAction.shouldUse) {
- this.updateWindowAfterWidgetPlaced(window);
- }
},
setWindowScripts(window) {
XPCOMUtils.defineLazyModuleGetter(window, "Pocket",
"chrome://pocket/content/Pocket.jsm");
// Can't use XPCOMUtils for these because the scripts try to define the variables
// on window, and so the defineProperty inside defineLazyGetter fails.
Object.defineProperty(window, "pktApi", pktUIGetter("pktApi", window));
Object.defineProperty(window, "pktUI", pktUIGetter("pktUI", window));
@@ -623,43 +500,17 @@ var PocketOverlay = {
"id": "appMenu-library-pocket-button",
"label": gPocketBundle.GetStringFromName("pocketMenuitem.label"),
"class": "subviewbutton subviewbutton-iconic",
"oncommand": "openUILink(Pocket.listURL, event);",
"hidden": hidden
});
sib.parentNode.insertBefore(menu, sib);
}
- },
- onWidgetAfterDOMChange(aWidgetNode) {
- if (aWidgetNode.id != "pocket-button") {
- return;
- }
- this.updateWindowAfterWidgetPlaced(aWidgetNode.ownerGlobal);
- },
- updateWindowAfterWidgetPlaced(browserWindow) {
- let doc = browserWindow.document;
- let hidden = !isPocketEnabled();
- let elementIds = [
- "panelMenu_pocket",
- "menu_pocket",
- "BMB_pocket",
- "appMenu-library-pocket-button",
- ];
- for (let elementId of elementIds) {
- let element = doc.getElementById(elementId);
- if (element) {
- element.hidden = hidden;
- let sep = doc.getElementById(elementId + "Separator");
- if (sep) {
- sep.hidden = hidden;
- }
- }
- }
// enable or disable reader button
PocketReader.hidden = hidden;
},
addStyles(win) {
let utils = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
utils.addSheet(this._cachedSheet, this._sheetType);
},
--- a/browser/extensions/pocket/content/Pocket.jsm
+++ b/browser/extensions/pocket/content/Pocket.jsm
@@ -7,18 +7,16 @@ const {classes: Cc, interfaces: Ci, util
this.EXPORTED_SYMBOLS = ["Pocket"];
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "BrowserUtils",
"resource://gre/modules/BrowserUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "CustomizableUI",
- "resource:///modules/CustomizableUI.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ReaderMode",
"resource://gre/modules/ReaderMode.jsm");
var Pocket = {
get site() { return Services.prefs.getCharPref("extensions.pocket.site"); },
get listURL() { return "https://" + Pocket.site + "/?src=ff_ext"; },
/**
@@ -87,27 +85,23 @@ var Pocket = {
onPanelViewHiding(event) {
let window = event.target.ownerGlobal;
window.pktUI.pocketPanelDidHide(event);
},
_urlToSave: null,
_titleToSave: null,
savePage(browser, url, title) {
- let document = browser.ownerDocument;
- let pocketWidget = document.getElementById("pocket-button");
- let placement = CustomizableUI.getPlacementOfWidget("pocket-button");
- if (!placement)
- return;
-
- this._urlToSave = url;
- this._titleToSave = title;
- if (placement.area == CustomizableUI.AREA_PANEL) {
- let win = document.defaultView;
- win.PanelUI.show().then(function() {
- pocketWidget = document.getElementById("pocket-button");
- pocketWidget.doCommand();
- });
- } else {
- pocketWidget.doCommand();
+ if (this.pageAction) {
+ this._urlToSave = url;
+ this._titleToSave = title;
+ this.pageAction.doCommand(browser.ownerGlobal);
}
},
+
+ get pageAction() {
+ return this._pageAction;
+ },
+ set pageAction(pageAction) {
+ return this._pageAction = pageAction;
+ },
+ _pageAction: null,
};
--- a/browser/extensions/pocket/content/main.js
+++ b/browser/extensions/pocket/content/main.js
@@ -333,27 +333,20 @@ var pktUI = (function() {
* options = {
* width: ,
* height: ,
* animate [default false]
* }
*/
function resizePanel(options) {
var iframe = getPanelFrame();
- var subview = getSubview();
- if (subview) {
- // Use the subview's size
- iframe.style.width = "100%";
- iframe.style.height = subview.parentNode.clientHeight + "px";
- } else {
- // Set an explicit size, panel will adapt.
- iframe.style.width = options.width + "px";
- iframe.style.height = options.height + "px";
- }
+ // Set an explicit size, panel will adapt.
+ iframe.style.width = options.width + "px";
+ iframe.style.height = options.height + "px";
}
/**
* Called when the signup and saved panel was hidden
*/
function panelDidHide() {
// clear the onShow and onHide values
_currentPanelDidShow = null;
@@ -572,49 +565,21 @@ var pktUI = (function() {
var photonPageActionPanelFrame;
function setPhotonPageActionPanelFrame(frame) {
photonPageActionPanelFrame = frame;
}
function getPanelFrame() {
- if (photonPageActionPanelFrame) {
- return photonPageActionPanelFrame;
- }
-
- var frame = document.getElementById("pocket-panel-iframe");
- if (!frame) {
- var frameParent = document.getElementById("PanelUI-pocketView").firstChild;
- frame = document.createElement("iframe");
- frame.id = "pocket-panel-iframe";
- frame.setAttribute("type", "content");
- frameParent.appendChild(frame);
- }
- return frame;
- }
-
- function getSubview() {
- if (photonPageActionPanelFrame) {
- return null;
- }
-
- var view = document.getElementById("PanelUI-pocketView");
- if (view && view.getAttribute("current") == "true" && !view.getAttribute("mainview"))
- return view;
- return null;
+ return photonPageActionPanelFrame;
}
function isInOverflowMenu() {
- if (photonPageActionPanelFrame) {
- return false;
- }
-
- var subview = getSubview();
- return !!subview;
+ return false;
}
function getFirefoxAccountSignedInUser(callback) {
fxAccounts.getSignedInUser().then(userData => {
callback(userData);
}).then(null, error => {
callback();
});
--- a/browser/extensions/pocket/jar.mn
+++ b/browser/extensions/pocket/jar.mn
@@ -7,23 +7,20 @@
% skin pocket classic/1.0 %skin/linux/ os=LikeUnix
% skin pocket classic/1.0 %skin/osx/ os=Darwin
% skin pocket classic/1.0 %skin/windows/ os=WINNT
% skin pocket-shared classic/1.0 %skin/shared/
content/ (content/*)
skin/shared (skin/shared/*)
#ifdef XP_WIN
skin/windows/ (skin/windows/*.png)
- skin/windows/pocket.css (skin/windows/pocket.css)
#elifdef XP_MACOSX
skin/osx/ (skin/osx/*.png)
- skin/osx/pocket.css (skin/osx/pocket.css)
#else
skin/linux/ (skin/linux/*.png)
- skin/linux/pocket.css (skin/linux/pocket.css)
#endif
# windows overrides
% override chrome://pocket/skin/menuPanel.png chrome://pocket/skin/menuPanel-aero.png os=WINNT osversion=6
% override chrome://pocket/skin/menuPanel.png chrome://pocket/skin/menuPanel-aero.png os=WINNT osversion=6.1
% override chrome://pocket/skin/menuPanel@2x.png chrome://pocket/skin/menuPanel-aero@2x.png os=WINNT osversion=6
% override chrome://pocket/skin/menuPanel@2x.png chrome://pocket/skin/menuPanel-aero@2x.png os=WINNT osversion=6.1
% override chrome://pocket/skin/menuPanel.png chrome://pocket/skin/menuPanel-yosemite.png os=Darwin osversion>=10.10
deleted file mode 100644
--- a/browser/extensions/pocket/skin/linux/pocket.css
+++ /dev/null
@@ -1,10 +0,0 @@
-@import url("chrome://pocket-shared/skin/pocket.css");
-
-#nav-bar #pocket-button > .toolbarbutton-icon {
- padding: calc(var(--toolbarbutton-inner-padding) - 1px);
-}
-
-:-moz-any(#TabsToolbar, .widget-overflow-list) #pocket-button > .toolbarbutton-icon {
- max-width: 18px;
- padding: 0;
-}
deleted file mode 100644
--- a/browser/extensions/pocket/skin/osx/pocket.css
+++ /dev/null
@@ -1,9 +0,0 @@
-@import url("chrome://pocket-shared/skin/pocket.css");
-
-#nav-bar #pocket-button > .toolbarbutton-icon {
- padding: calc(var(--toolbarbutton-inner-padding) - 1px);
-}
-
-#PanelUI-pocketView[mainview=true] > .panel-subview-body > #pocket-panel-iframe {
- border-radius: var(--arrowpanel-border-radius);
-}
--- a/browser/extensions/pocket/skin/shared/pocket.css
+++ b/browser/extensions/pocket/skin/shared/pocket.css
@@ -1,23 +1,13 @@
-/* Bug 1164419 - increase Pocket panel size to accomidate wider Russian text. */
-panelmultiview[mainViewId=PanelUI-pocketView] > .panel-viewcontainer > .panel-viewstack > .panel-mainview:not([panelid="PanelUI-popup"]) {
- max-width: 33em; /* standaloneSubviewWidth + 3 */
-}
-
-.cui-widget-panel[viewId="PanelUI-pocketView"] > .panel-arrowcontainer > .panel-arrowcontent {
+#pageActionActivatedActionPanel[actionID="pocket"] > .panel-arrowcontainer > .panel-arrowcontent {
padding-top: 0;
padding-bottom: 0;
}
-#PanelUI-pocketView > .panel-subview-body,
-#PanelUI-pocketView {
- overflow: visible;
-}
-
#pocket-button {
list-style-image: url("chrome://pocket-shared/skin/pocket.svg");
}
#pocket-button-box[animate="true"] > #pocket-button,
#pocket-button[open="true"][animationsenabled] > .toolbarbutton-icon {
fill: transparent;
}
deleted file mode 100644
--- a/browser/extensions/pocket/skin/windows/pocket.css
+++ /dev/null
@@ -1,10 +0,0 @@
-@import url("chrome://pocket-shared/skin/pocket.css");
-
-#nav-bar #pocket-button > .toolbarbutton-icon {
- padding: calc(var(--toolbarbutton-inner-padding) - 1px);
-}
-
-:-moz-any(#TabsToolbar, .widget-overflow-list) #pocket-button > .toolbarbutton-icon {
- max-width: 18px;
- padding: 0;
-}
--- a/browser/extensions/pocket/test/head.js
+++ b/browser/extensions/pocket/test/head.js
@@ -7,58 +7,40 @@ let enabledOnStartup = false;
// Enabled/Disabled, and false if it need to Enable/Disable.
function promisePocketEnabled() {
if (Services.prefs.getPrefType("extensions.pocket.enabled") != Services.prefs.PREF_INVALID &&
Services.prefs.getBoolPref("extensions.pocket.enabled")) {
info( "pocket was already enabled, assuming enabled by default for tests");
enabledOnStartup = true;
return Promise.resolve(true);
}
- info( "pocket is not enabled");
- return new Promise((resolve, reject) => {
- let listener = {
- onWidgetAfterCreation(widgetid) {
- if (widgetid == "pocket-button") {
- info("pocket-button created");
- CustomizableUI.removeListener(listener);
- resolve(false);
- }
- }
- }
- CustomizableUI.addListener(listener);
- Services.prefs.setBoolPref("extensions.pocket.enabled", true);
+ info("pocket is not enabled");
+ Services.prefs.setBoolPref("extensions.pocket.enabled", true);
+ return BrowserTestUtils.waitForCondition(() => {
+ return PageActions.actionForID("pocket");
});
}
function promisePocketDisabled() {
if (Services.prefs.getPrefType("extensions.pocket.enabled") == Services.prefs.PREF_INVALID ||
!Services.prefs.getBoolPref("extensions.pocket.enabled")) {
info("pocket-button already disabled");
return Promise.resolve(true);
}
- return new Promise((resolve, reject) => {
- let listener = {
- onWidgetDestroyed(widgetid) {
- if (widgetid == "pocket-button") {
- CustomizableUI.removeListener(listener);
- info( "pocket-button destroyed");
- // wait for a full unload of pocket
- BrowserTestUtils.waitForCondition(() => {
- return !window.hasOwnProperty("pktUI");
- }, "pocket properties removed from window").then(() => {
- resolve(false);
- })
- }
- }
- }
- CustomizableUI.addListener(listener);
- info("reset pocket enabled pref");
- // testing/profiles/prefs_general.js uses user_pref to disable pocket, set
- // back to false.
- Services.prefs.setBoolPref("extensions.pocket.enabled", false);
+ info("reset pocket enabled pref");
+ // testing/profiles/prefs_general.js uses user_pref to disable pocket, set
+ // back to false.
+ Services.prefs.setBoolPref("extensions.pocket.enabled", false);
+ return BrowserTestUtils.waitForCondition(() => {
+ return !PageActions.actionForID("pocket");
+ }).then(() => {
+ // wait for a full unload of pocket
+ return BrowserTestUtils.waitForCondition(() => {
+ return !window.hasOwnProperty("pktUI");
+ });
});
}
function promisePocketReset() {
if (enabledOnStartup) {
info("reset is enabling pocket addon");
return promisePocketEnabled();
}
--- a/browser/modules/PageActions.jsm
+++ b/browser/modules/PageActions.jsm
@@ -387,53 +387,56 @@ this.PageActions = {
* The URL of the action's icon. Usually you want to specify an
* icon in CSS, but this option is useful if that would be a pain
* for some reason -- like your code is in an embedded
* WebExtension.
* @param nodeAttributes (object, optional)
* An object of name-value pairs. Each pair will be added as
* an attribute to DOM nodes created for this action.
* @param onBeforePlacedInWindow (function, optional)
- * Called before the action is placed in the window. Passed the
- * following arguments:
+ * Called before the action is placed in the window:
+ * onBeforePlacedInWindow(window)
* * window: The window that the action will be placed in.
* @param onCommand (function, optional)
* Called when the action is clicked, but only if it has neither
- * a subview nor an iframe. Passed the following arguments:
+ * a subview nor an iframe:
+ * onCommand(event, buttonNode)
* * event: The triggering event.
* * buttonNode: The button node that was clicked.
* @param onIframeHiding (function, optional)
- * Called when the action's iframe is hiding. Passed the
- * following arguments:
+ * Called when the action's iframe is hiding:
+ * onIframeHiding(iframeNode, parentPanelNode)
* * iframeNode: The iframe.
* * parentPanelNode: The panel node in which the iframe is
* shown.
* @param onIframeHidden (function, optional)
- * Called when the action's iframe is hidden. Passed the
- * following arguments:
+ * Called when the action's iframe is hidden:
+ * onIframeHidden(iframeNode, parentPanelNode)
* * iframeNode: The iframe.
* * parentPanelNode: The panel node in which the iframe is
* shown.
* @param onIframeShown (function, optional)
- * Called when the action's iframe is shown to the user. Passed
- * the following arguments:
+ * Called when the action's iframe is shown to the user:
+ * onIframeShown(iframeNode, parentPanelNode)
* * iframeNode: The iframe.
* * parentPanelNode: The panel node in which the iframe is
* shown.
* @param onPlacedInPanel (function, optional)
* Called when the action is added to the page action panel in
- * a browser window. Passed the following arguments:
+ * a browser window:
+ * onPlacedInPanel(buttonNode)
* * buttonNode: The action's node in the page action panel.
* @param onPlacedInUrlbar (function, optional)
* Called when the action is added to the urlbar in a browser
- * window. Passed the following arguments:
+ * window:
+ * onPlacedInUrlbar(buttonNode)
* * buttonNode: The action's node in the urlbar.
* @param onShowingInPanel (function, optional)
- * Called when a browser window's page action panel is showing.
- * Passed the following arguments:
+ * Called when a browser window's page action panel is showing:
+ * onShowingInPanel(buttonNode)
* * buttonNode: The action's node in the page action panel.
* @param shownInUrlbar (bool, optional)
* Pass true to show the action in the urlbar, false otherwise.
* False by default.
* @param subview (object, optional)
* An options object suitable for passing to the Subview
* constructor, if you'd like the action to have a subview. See
* the subview constructor for info on this object's properties.
@@ -578,24 +581,36 @@ Action.prototype = {
/**
* A Subview object if the action wants a subview (Subview, nullable)
*/
get subview() {
return this._subview;
},
/**
+ * Performs the command for an action. If the action has an onCommand
+ * handler, then it's called. If the action has a subview or iframe, then a
+ * panel is opened, displaying the subview or iframe.
+ *
+ * @param browserWindow (DOM window, required)
+ * The browser window in which to perform the action.
+ */
+ doCommand(browserWindow) {
+ browserPageActions(browserWindow).doCommandForAction(this);
+ },
+
+ /**
* Call this when before placing the action in the window.
*
- * @param window (DOM window, required)
- * The window the action will be placed in.
+ * @param browserWindow (DOM window, required)
+ * The browser window the action will be placed in.
*/
- onBeforePlacedInWindow(window) {
+ onBeforePlacedInWindow(browserWindow) {
if (this._onBeforePlacedInWindow) {
- this._onBeforePlacedInWindow(window);
+ this._onBeforePlacedInWindow(browserWindow);
}
},
/**
* Call this when the user activates the action.
*
* @param event (DOM event, required)
* The triggering event.
@@ -709,22 +724,23 @@ this.PageActions.Action = Action;
* An object with the following properties:
* @param buttons (array, optional)
* An array of buttons to show in the subview. Each item in the
* array must be an options object suitable for passing to the
* Button constructor. See the Button constructor for
* information on these objects' properties.
* @param onPlaced (function, optional)
* Called when the subview is added to its parent panel in a
- * browser window. Passed the following arguments:
+ * browser window:
+ * onPlaced(panelViewNode)
* * panelViewNode: The panelview node represented by this
* Subview.
* @param onShowing (function, optional)
- * Called when the subview is showing in a browser window.
- * Passed the following arguments:
+ * Called when the subview is showing in a browser window:
+ * onShowing(panelViewNode)
* * panelViewNode: The panelview node represented by this
* Subview.
*/
function Subview(options) {
setProperties(this, options, {
buttons: false,
onPlaced: false,
onShowing: false,
@@ -780,18 +796,18 @@ this.PageActions.Subview = Subview;
* itself, but it will be used to generate DOM node IDs. But in
* terms of spaces and weird characters and such, do treat this
* like a DOM node ID.
* @param title (string, required)
* The button's title.
* @param disabled (bool, required)
* Pass true to disable the button.
* @param onCommand (function, optional)
- * Called when the button is clicked. Passed the following
- * arguments:
+ * Called when the button is clicked:
+ * onCommand(event, buttonNode)
* * event: The triggering event.
* * buttonNode: The node that was clicked.
* @param shortcut (string, optional)
* The button's shortcut text.
*/
function Button(options) {
setProperties(this, options, {
id: true,
--- a/browser/modules/test/browser/browser_PageActions.js
+++ b/browser/modules/test/browser/browser_PageActions.js
@@ -340,32 +340,32 @@ add_task(async function withSubview() {
// EventUtils.synthesizeMouseAtCenter(panelViewButtonNodePanel, {});
panelViewButtonNodePanel.click();
await promisePageActionPanelHidden();
Assert.equal(onActionCommandCallCount, 0,
"onActionCommandCallCount should remain 0");
Assert.equal(onButtonCommandCallCount, 1,
"onButtonCommandCallCount should be inc'ed");
- // Click the action's urlbar button, which should open the temp panel showing
- // the subview, and click the subview's first button.
+ // Click the action's urlbar button, which should open the activated-action
+ // panel showing the subview, and click the subview's first button.
onSubviewPlacedExpectedPanelViewID = panelViewIDUrlbar;
onSubviewShowingExpectedPanelViewID = panelViewIDUrlbar;
EventUtils.synthesizeMouseAtCenter(urlbarButtonNode, {});
- await promisePanelShown(BrowserPageActions._tempPanelID);
+ await promisePanelShown(BrowserPageActions._activatedActionPanelID);
Assert.equal(onSubviewPlacedCount, 2,
"onSubviewPlacedCount should be inc'ed");
Assert.equal(onSubviewShowingCount, 2,
"onSubviewShowingCount should be inc'ed");
let panelViewButtonNodeUrlbar =
document.getElementById(panelViewButtonIDUrlbar);
Assert.notEqual(panelViewButtonNodeUrlbar, null, "panelViewButtonNodeUrlbar");
onButtonCommandExpectedButtonID = panelViewButtonIDUrlbar;
EventUtils.synthesizeMouseAtCenter(panelViewButtonNodeUrlbar, {});
- await promisePanelHidden(BrowserPageActions._tempPanelID);
+ await promisePanelHidden(BrowserPageActions._activatedActionPanelID);
Assert.equal(onButtonCommandCallCount, 2,
"onButtonCommandCallCount should be inc'ed");
// Remove the action.
action.remove();
panelButtonNode = document.getElementById(panelButtonID);
Assert.equal(panelButtonNode, null, "panelButtonNode");
urlbarButtonNode = document.getElementById(urlbarButtonID);
@@ -398,17 +398,17 @@ add_task(async function withIframe() {
onCommand(event, buttonNode) {
onCommandCallCount++;
},
onIframeShown(iframeNode, panelNode) {
onIframeShownCount++;
Assert.ok(iframeNode, "iframeNode should be non-null: " + iframeNode);
Assert.equal(iframeNode.localName, "iframe", "iframe localName");
Assert.ok(panelNode, "panelNode should be non-null: " + panelNode);
- Assert.equal(panelNode.id, BrowserPageActions._tempPanelID,
+ Assert.equal(panelNode.id, BrowserPageActions._activatedActionPanelID,
"panelNode.id");
},
onPlacedInPanel(buttonNode) {
onPlacedInPanelCallCount++;
Assert.ok(buttonNode, "buttonNode should be non-null: " + buttonNode);
Assert.equal(buttonNode.id, panelButtonID, "buttonNode.id");
},
onPlacedInUrlbar(buttonNode) {
@@ -437,63 +437,63 @@ add_task(async function withIframe() {
// The action's urlbar button should have been created.
let urlbarButtonNode = document.getElementById(urlbarButtonID);
Assert.notEqual(urlbarButtonNode, null, "urlbarButtonNode");
// Open the panel, click the action's button.
await promisePageActionPanelOpen();
Assert.equal(onIframeShownCount, 0, "onIframeShownCount should remain 0");
EventUtils.synthesizeMouseAtCenter(panelButtonNode, {});
- await promisePanelShown(BrowserPageActions._tempPanelID);
+ await promisePanelShown(BrowserPageActions._activatedActionPanelID);
Assert.equal(onCommandCallCount, 0, "onCommandCallCount should remain 0");
Assert.equal(onIframeShownCount, 1, "onIframeShownCount should be inc'ed");
- // The temp panel should have opened, anchored to the action's urlbar button.
- let tempPanel = document.getElementById(BrowserPageActions._tempPanelID);
- Assert.notEqual(tempPanel, null, "tempPanel");
- Assert.equal(tempPanel.anchorNode.id, urlbarButtonID,
- "tempPanel.anchorNode.id");
+ // The activated-action panel should have opened, anchored to the action's
+ // urlbar button.
+ let aaPanel =
+ document.getElementById(BrowserPageActions._activatedActionPanelID);
+ Assert.notEqual(aaPanel, null, "activated-action panel");
+ Assert.equal(aaPanel.anchorNode.id, urlbarButtonID, "aaPanel.anchorNode.id");
EventUtils.synthesizeMouseAtCenter(urlbarButtonNode, {});
- await promisePanelHidden(BrowserPageActions._tempPanelID);
+ await promisePanelHidden(BrowserPageActions._activatedActionPanelID);
// Click the action's urlbar button.
EventUtils.synthesizeMouseAtCenter(urlbarButtonNode, {});
- await promisePanelShown(BrowserPageActions._tempPanelID);
+ await promisePanelShown(BrowserPageActions._activatedActionPanelID);
Assert.equal(onCommandCallCount, 0, "onCommandCallCount should remain 0");
Assert.equal(onIframeShownCount, 2, "onIframeShownCount should be inc'ed");
- // The temp panel should have opened, again anchored to the action's urlbar
- // button.
- tempPanel = document.getElementById(BrowserPageActions._tempPanelID);
- Assert.notEqual(tempPanel, null, "tempPanel");
- Assert.equal(tempPanel.anchorNode.id, urlbarButtonID,
- "tempPanel.anchorNode.id");
+ // The activated-action panel should have opened, again anchored to the
+ // action's urlbar button.
+ aaPanel = document.getElementById(BrowserPageActions._activatedActionPanelID);
+ Assert.notEqual(aaPanel, null, "aaPanel");
+ Assert.equal(aaPanel.anchorNode.id, urlbarButtonID, "aaPanel.anchorNode.id");
EventUtils.synthesizeMouseAtCenter(urlbarButtonNode, {});
- await promisePanelHidden(BrowserPageActions._tempPanelID);
+ await promisePanelHidden(BrowserPageActions._activatedActionPanelID);
// Hide the action's button in the urlbar.
action.shownInUrlbar = false;
urlbarButtonNode = document.getElementById(urlbarButtonID);
Assert.equal(urlbarButtonNode, null, "urlbarButtonNode");
// Open the panel, click the action's button.
await promisePageActionPanelOpen();
EventUtils.synthesizeMouseAtCenter(panelButtonNode, {});
- await promisePanelShown(BrowserPageActions._tempPanelID);
+ await promisePanelShown(BrowserPageActions._activatedActionPanelID);
Assert.equal(onCommandCallCount, 0, "onCommandCallCount should remain 0");
Assert.equal(onIframeShownCount, 3, "onIframeShownCount should be inc'ed");
- // The temp panel should have opened, this time anchored to the main page
- // action button in the urlbar.
- tempPanel = document.getElementById(BrowserPageActions._tempPanelID);
- Assert.notEqual(tempPanel, null, "tempPanel");
- Assert.equal(tempPanel.anchorNode.id, BrowserPageActions.mainButtonNode.id,
- "tempPanel.anchorNode.id");
+ // The activated-action panel should have opened, this time anchored to the
+ // main page action button in the urlbar.
+ aaPanel = document.getElementById(BrowserPageActions._activatedActionPanelID);
+ Assert.notEqual(aaPanel, null, "aaPanel");
+ Assert.equal(aaPanel.anchorNode.id, BrowserPageActions.mainButtonNode.id,
+ "aaPanel.anchorNode.id");
EventUtils.synthesizeMouseAtCenter(BrowserPageActions.mainButtonNode, {});
- await promisePanelHidden(BrowserPageActions._tempPanelID);
+ await promisePanelHidden(BrowserPageActions._activatedActionPanelID);
// Remove the action.
action.remove();
panelButtonNode = document.getElementById(panelButtonID);
Assert.equal(panelButtonNode, null, "panelButtonNode");
urlbarButtonNode = document.getElementById(urlbarButtonID);
Assert.equal(urlbarButtonNode, null, "urlbarButtonNode");
});
--- a/testing/profiles/prefs_general.js
+++ b/testing/profiles/prefs_general.js
@@ -389,12 +389,8 @@ user_pref("marionette.prefs.recommended"
// Disable Screenshots by default for now
user_pref("extensions.screenshots.system-disabled", true);
// Set places maintenance far in the future to avoid it kicking in during tests.
// The maintenance can take a relatively long time which may cause unnecessary
// intermittents and slow down tests.
user_pref("places.database.lastMaintenance", 7258114800);
-
-// Disable the Pocket page action and enable the CUI widget until bug 1385418 is
-// fixed.
-user_pref("extensions.pocket.disablePageAction", true);