--- a/browser/extensions/pocket/bootstrap.js
+++ b/browser/extensions/pocket/bootstrap.js
@@ -11,16 +11,18 @@ Cu.import("resource://gre/modules/XPCOMU
Cu.import("resource://services-common/utils.js");
Cu.import("resource://gre/modules/AppConstants.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Services",
"resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "RecentWindow",
"resource:///modules/RecentWindow.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "CustomizableUI",
"resource:///modules/CustomizableUI.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "PageActions",
+ "resource:///modules/PageActions.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AddonManagerPrivate",
"resource://gre/modules/AddonManager.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ReaderMode",
"resource://gre/modules/ReaderMode.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Pocket",
"chrome://pocket/content/Pocket.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AboutPocket",
"chrome://pocket/content/AboutPocket.jsm");
@@ -145,39 +147,88 @@ function CreatePocketWidget(reason) {
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");
+}
+
+var PocketPageAction = {
+ pageAction: 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,
+ _insertBeforeActionID: PageActions.ACTION_ID_BOOKMARK_SEPARATOR,
+ onPlacedInPanel(panelNode, urlbarNode) {
+ PocketOverlay.onWindowOpened(panelNode.ownerGlobal);
+ },
+ onIframeShown(iframe, panel) {
+ Pocket.onShownInPhotonPageActionPanel(panel, iframe);
+ },
+ }));
+ }
+ },
+
+ shutdown() {
+ if (!this.pageAction) {
+ return;
+ }
+ this.pageAction.remove();
+ this.pageAction = null;
+ },
+};
+
// PocketContextMenu
// When the context menu is opened check if we need to build and enable pocket UI.
var PocketContextMenu = {
init() {
Services.obs.addObserver(this, "on-build-contextmenu");
},
shutdown() {
Services.obs.removeObserver(this, "on-build-contextmenu");
// loop through windows and remove context menus
// iterate through all windows and add pocket to them
- for (let win of CustomizableUI.windows) {
+ for (let win of browserWindows()) {
let document = win.document;
for (let id of ["context-pocket", "context-savelinktopocket"]) {
let element = document.getElementById(id);
if (element)
element.remove();
}
}
},
observe(aSubject, aTopic, aData) {
let subject = aSubject.wrappedJSObject;
let document = subject.menu.ownerDocument;
- let pocketEnabled = CustomizableUI.getPlacementOfWidget("pocket-button");
+ let pocketEnabled = isPocketEnabled();
let showSaveCurrentPageToPocket = !(subject.onTextInput || subject.onLink ||
subject.isContentSelected || subject.onImage ||
subject.onCanvas || subject.onVideo || subject.onAudio);
let targetUrl = subject.onLink ? subject.linkUrl : subject.pageUrl;
let targetURI = Services.io.newURI(targetUrl);
let canPocket = pocketEnabled && (targetURI.schemeIs("http") || targetURI.schemeIs("https") ||
(targetURI.schemeIs("about") && ReaderMode.getOriginalUrl(targetUrl)));
@@ -267,27 +318,34 @@ var PocketReader = {
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;
- 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");
+ 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();
- });
- } else {
- pocketWidget.doCommand();
+ }
}
}
break;
}
}
}
}
@@ -311,75 +369,87 @@ 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();
- CustomizableUI.addListener(this);
- CreatePocketWidget(reason);
+ if (PocketPageAction.shouldUse) {
+ PocketPageAction.init();
+ } else {
+ CustomizableUI.addListener(this);
+ CreatePocketWidget(reason);
+ }
PocketContextMenu.init();
-
- for (let win of CustomizableUI.windows) {
+ 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();
- CustomizableUI.removeListener(this);
- for (let window of CustomizableUI.windows) {
+ if (PocketPageAction.shouldUse) {
+ PocketPageAction.shutdown();
+ } else {
+ CustomizableUI.removeListener(this);
+ CustomizableUI.destroyWidget("pocket-button");
+ }
+
+ 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);
if (element)
element.remove();
}
this.removeStyles(window);
// remove script getters/objects
delete window.Pocket;
delete window.pktApi;
delete window.pktUI;
delete window.pktUIMessaging;
}
- CustomizableUI.destroyWidget("pocket-button");
+
PocketContextMenu.shutdown();
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));
Object.defineProperty(window, "pktUIMessaging", pktUIGetter("pktUIMessaging", window));
},
// called for each window as it is opened
updateWindow(window) {
// insert our three menu items
let document = window.document;
- let hidden = !CustomizableUI.getPlacementOfWidget("pocket-button");
+ let hidden = !isPocketEnabled();
// add to bookmarksMenu
let sib = document.getElementById("menu_bookmarkThisPage");
if (sib && !document.getElementById("menu_pocket")) {
let menu = createElementWithAttrs(document, "menuitem", {
"id": "menu_pocket",
"label": gPocketBundle.GetStringFromName("pocketMenuitem.label"),
"class": "menuitem-iconic", // OSX only
@@ -445,18 +515,22 @@ var PocketOverlay = {
});
sib.parentNode.insertBefore(menu, sib);
}
},
onWidgetAfterDOMChange(aWidgetNode) {
if (aWidgetNode.id != "pocket-button") {
return;
}
- let doc = aWidgetNode.ownerDocument;
- let hidden = !CustomizableUI.getPlacementOfWidget("pocket-button");
+ 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);
@@ -520,8 +594,15 @@ function shutdown(data, reason) {
}
}
function install() {
}
function uninstall() {
}
+
+function* browserWindows() {
+ let windows = Services.wm.getEnumerator("navigator:browser");
+ while (windows.hasMoreElements()) {
+ yield windows.getNext();
+ }
+}
--- a/browser/extensions/pocket/content/Pocket.jsm
+++ b/browser/extensions/pocket/content/Pocket.jsm
@@ -23,19 +23,28 @@ var Pocket = {
/**
* Functions related to the Pocket panel UI.
*/
onBeforeCommand(event) {
BrowserUtils.setToolbarButtonHeightProperty(event.target);
},
+ onShownInPhotonPageActionPanel(panel, iframe) {
+ let window = panel.ownerGlobal;
+ window.pktUI.setPhotonPageActionPanelFrame(iframe);
+ Pocket._initPanelView(window);
+ },
+
onPanelViewShowing(event) {
- let document = event.target.ownerDocument;
- let window = document.defaultView;
+ Pocket._initPanelView(event.target.ownerGlobal);
+ },
+
+ _initPanelView(window) {
+ let document = window.document;
let iframe = window.pktUI.getPanelFrame();
let libraryButton = document.getElementById("library-button");
if (libraryButton) {
BrowserUtils.setToolbarButtonHeightProperty(libraryButton);
}
let urlToSave = Pocket._urlToSave;
--- a/browser/extensions/pocket/content/main.js
+++ b/browser/extensions/pocket/content/main.js
@@ -562,36 +562,54 @@ var pktUI = (function() {
var frame = getPanelFrame();
var panel = frame;
while (panel && panel.localName != "panel") {
panel = panel.parentNode;
}
return panel;
}
+ 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;
}
function isInOverflowMenu() {
+ if (photonPageActionPanelFrame) {
+ return false;
+ }
+
var subview = getSubview();
return !!subview;
}
function getFirefoxAccountSignedInUser(callback) {
fxAccounts.getSignedInUser().then(userData => {
callback(userData);
}).then(null, error => {
@@ -602,16 +620,17 @@ var pktUI = (function() {
function getUILocale() {
return Services.locale.getAppLocaleAsLangTag();
}
/**
* Public functions
*/
return {
+ setPhotonPageActionPanelFrame,
getPanelFrame,
openTabWithUrl,
pocketPanelDidShow,
pocketPanelDidHide,
tryToSaveUrl,
--- a/browser/extensions/pocket/skin/shared/pocket.css
+++ b/browser/extensions/pocket/skin/shared/pocket.css
@@ -243,8 +243,13 @@ toolbar[brighttext] #pocket-button {
#BMB_pocket {
list-style-image: url("chrome://pocket/content/panels/img/pocketmenuitem16@2x.png");
}
#panelMenu_pocket > .toolbarbutton-icon {
width: 16px;
}
}
+
+#pageAction-panel-pocket,
+#pageAction-urlbar-pocket {
+ list-style-image: url("chrome://pocket-shared/skin/pocket.svg");
+}
--- a/browser/extensions/pocket/skin/shared/pocket.svg
+++ b/browser/extensions/pocket/skin/shared/pocket.svg
@@ -1,6 +1,6 @@
<!-- 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/. -->
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18">
- <path fill="context-fill" d="M9,15.969a8,8,0,0,1-8-8v-4a2,2,0,0,1,2-2H15a2,2,0,0,1,2,2v4A8,8,0,0,1,9,15.969ZM12.985,5.937a0.99,0.99,0,0,0-.725.319L8.978,9.539,5.755,6.305A0.984,0.984,0,0,0,5,5.937a1,1,0,0,0-.714,1.7L4.27,7.648l3.293,3.306h0l0.707,0.707a1,1,0,0,0,1.414,0l0.707-.707h0L13.7,7.648l0,0A1,1,0,0,0,12.985,5.937Z"/>
+ <path fill-opacity="context-fill-opacity" fill="context-fill" d="M9,15.969a8,8,0,0,1-8-8v-4a2,2,0,0,1,2-2H15a2,2,0,0,1,2,2v4A8,8,0,0,1,9,15.969ZM12.985,5.937a0.99,0.99,0,0,0-.725.319L8.978,9.539,5.755,6.305A0.984,0.984,0,0,0,5,5.937a1,1,0,0,0-.714,1.7L4.27,7.648l3.293,3.306h0l0.707,0.707a1,1,0,0,0,1.414,0l0.707-.707h0L13.7,7.648l0,0A1,1,0,0,0,12.985,5.937Z"/>
</svg>
--- a/testing/profiles/prefs_general.js
+++ b/testing/profiles/prefs_general.js
@@ -388,8 +388,12 @@ 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);