diff options
Diffstat (limited to 'browser/extensions/pocket/bootstrap.js')
-rw-r--r-- | browser/extensions/pocket/bootstrap.js | 511 |
1 files changed, 0 insertions, 511 deletions
diff --git a/browser/extensions/pocket/bootstrap.js b/browser/extensions/pocket/bootstrap.js deleted file mode 100644 index c470eb8d3..000000000 --- a/browser/extensions/pocket/bootstrap.js +++ /dev/null @@ -1,511 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* 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/. */ - -const {classes: Cc, interfaces: Ci, utils: Cu, manager: Cm} = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://services-common/utils.js"); -Cu.import("resource://gre/modules/Preferences.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, "AddonManager", - "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"); -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", null, null); -}); - -// 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 = { - enabled: true, // bug 1229937, figure out ui tour support - api: "api.getpocket.com", - site: "getpocket.com", - oAuthConsumerKey: "40249-e88c401e1b1f2242d9e441c4" -}; - -function setDefaultPrefs() { - let branch = Services.prefs.getDefaultBranch(PREF_BRANCH); - for (let [key, val] of Object.entries(PREFS)) { - // If someone beat us to setting a default, don't overwrite it. This can - // happen if distribution.ini sets the default first. - if (branch.getPrefType(key) != branch.PREF_INVALID) - continue; - switch (typeof val) { - case "boolean": - branch.setBoolPref(key, val); - break; - case "number": - branch.setIntPref(key, val); - break; - case "string": - branch.setCharPref(key, val); - break; - } - } -} - -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: - onViewShowing: function() { - return Pocket.onPanelViewShowing.apply(this, arguments); - }, - onViewHiding: function() { - return Pocket.onPanelViewHiding.apply(this, arguments); - }, - onBeforeCreated: function(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); - } - }; - - 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); - } - } - - // Uninstall the Pocket social provider if it exists, but only if we haven't - // already uninstalled it in this manner. That way the user can reinstall - // it if they prefer it without its being uninstalled every time they start - // the browser. - let SocialService; - try { - // For Firefox 51+ - SocialService = Cu.import("resource:///modules/SocialService.jsm", {}).SocialService; - } catch (e) { - SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService; - } - - let origin = "https://getpocket.com"; - SocialService.getProvider(origin, provider => { - if (provider) { - let pref = "social.backup.getpocket-com"; - if (!Services.prefs.prefHasUserValue(pref)) { - let str = Cc["@mozilla.org/supports-string;1"]. - createInstance(Ci.nsISupportsString); - str.data = JSON.stringify(provider.manifest); - Services.prefs.setComplexValue(pref, Ci.nsISupportsString, str); - SocialService.uninstallProvider(origin, () => {}); - } - } - }); - -} - -// PocketContextMenu -// When the context menu is opened check if we need to build and enable pocket UI. -var PocketContextMenu = { - init: function() { - Services.obs.addObserver(this, "on-build-contextmenu", false); - }, - shutdown: function() { - 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) { - let document = win.document; - for (let id of ["context-pocket", "context-savelinktopocket"]) { - let element = document.getElementById(id); - if (element) - element.remove(); - } - } - }, - observe: function(aSubject, aTopic, aData) { - let subject = aSubject.wrappedJSObject; - let document = subject.menu.ownerDocument; - let pocketEnabled = CustomizableUI.getPlacementOfWidget("pocket-button"); - - 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, null, null); - let canPocket = pocketEnabled && (targetURI.schemeIs("http") || targetURI.schemeIs("https") || - (targetURI.schemeIs("about") && ReaderMode.getOriginalUrl(targetUrl))); - - let showSaveLinkToPocket = canPocket && !showSaveCurrentPageToPocket && subject.onLink; - - // create menu entries if necessary - let menu = document.getElementById("context-pocket"); - if (!menu) { - menu = createElementWithAttrs(document, "menuitem", { - "id": "context-pocket", - "label": gPocketBundle.GetStringFromName("saveToPocketCmd.label"), - "accesskey": gPocketBundle.GetStringFromName("saveToPocketCmd.accesskey"), - "oncommand": "Pocket.savePage(gContextMenu.browser, gContextMenu.browser.currentURI.spec, gContextMenu.browser.contentTitle);" - }); - let sibling = document.getElementById("context-savepage"); - if (sibling.nextSibling) { - sibling.parentNode.insertBefore(menu, sibling.nextSibling); - } else { - sibling.parentNode.appendChild(menu); - } - } - menu.hidden = !(canPocket && showSaveCurrentPageToPocket); - - menu = document.getElementById("context-savelinktopocket"); - if (!menu) { - menu = createElementWithAttrs(document, "menuitem", { - "id": "context-savelinktopocket", - "label": gPocketBundle.GetStringFromName("saveLinkToPocketCmd.label"), - "accesskey": gPocketBundle.GetStringFromName("saveLinkToPocketCmd.accesskey"), - "oncommand": "Pocket.savePage(gContextMenu.browser, gContextMenu.linkURL);" - }); - let sibling = document.getElementById("context-savelink"); - if (sibling.nextSibling) { - sibling.parentNode.insertBefore(menu, sibling.nextSibling); - } else { - sibling.parentNode.appendChild(menu); - } - } - menu.hidden = !showSaveLinkToPocket; - } -} - -// PocketReader -// Listen for reader mode setup and add our button to the reader toolbar -var PocketReader = { - _hidden: true, - get hidden() { - return this._hidden; - }, - set hidden(hide) { - hide = !!hide; - if (hide === this._hidden) - return; - this._hidden = hide; - this.update(); - }, - startup: function() { - // Setup the listeners, update will be called when the widget is added, - // no need to do that now. - let mm = Services.mm; - mm.addMessageListener("Reader:OnSetup", this); - mm.addMessageListener("Reader:Clicked-pocket-button", this); - }, - shutdown: function() { - let mm = Services.mm; - mm.removeMessageListener("Reader:OnSetup", this); - mm.removeMessageListener("Reader:Clicked-pocket-button", this); - this.hidden = true; - }, - update: function() { - if (this.hidden) { - Services.mm.broadcastAsyncMessage("Reader:RemoveButton", { id: "pocket-button" }); - } else { - Services.mm.broadcastAsyncMessage("Reader:AddButton", - { id: "pocket-button", - title: gPocketBundle.GetStringFromName("pocket-button.tooltiptext"), - image: "chrome://pocket/content/panels/img/pocket.svg#pocket-mark" }); - } - }, - receiveMessage: function(message) { - switch (message.name) { - case "Reader:OnSetup": { - // Tell the reader about our button. - if (this.hidden) - 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; - 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(); - } - } - break; - } - } - } -} - - -function pktUIGetter(prop, window) { - return { - get: function() { - // delete any getters for properties loaded from main.js so we only load main.js once - delete window.pktUI; - delete window.pktApi; - delete window.pktUIMessaging; - Services.scriptloader.loadSubScript("chrome://pocket/content/main.js", window); - return window[prop]; - }, - configurable: true, - enumerable: true - }; -} - -var PocketOverlay = { - startup: function(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); - PocketContextMenu.init(); - - for (let win of CustomizableUI.windows) { - this.onWindowOpened(win); - } - }, - shutdown: function(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) { - for (let id of ["panelMenu_pocket", "menu_pocket", "BMB_pocket", - "panelMenu_pocketSeparator", "menu_pocketSeparator", - "BMB_pocketSeparator"]) { - 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: function(window) { - if (window.hasOwnProperty("pktUI")) - return; - this.setWindowScripts(window); - this.addStyles(window); - this.updateWindow(window); - }, - setWindowScripts: function(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: function(window) { - // insert our three menu items - let document = window.document; - let hidden = !CustomizableUI.getPlacementOfWidget("pocket-button"); - - // 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 - "oncommand": "openUILink(Pocket.listURL, event);", - "hidden": hidden - }); - let sep = createElementWithAttrs(document, "menuseparator", { - "id": "menu_pocketSeparator", - "hidden": hidden - }); - sib.parentNode.insertBefore(menu, sib); - sib.parentNode.insertBefore(sep, sib); - } - - // add to bookmarks-menu-button - sib = document.getElementById("BMB_bookmarksToolbar"); - if (sib && !document.getElementById("BMB_pocket")) { - let menu = createElementWithAttrs(document, "menuitem", { - "id": "BMB_pocket", - "label": gPocketBundle.GetStringFromName("pocketMenuitem.label"), - "class": "menuitem-iconic bookmark-item subviewbutton", - "oncommand": "openUILink(Pocket.listURL, event);", - "hidden": hidden - }); - let sep = createElementWithAttrs(document, "menuseparator", { - "id": "BMB_pocketSeparator", - "hidden": hidden - }); - sib.parentNode.insertBefore(menu, sib); - sib.parentNode.insertBefore(sep, sib); - } - - // add to PanelUI-bookmarks - sib = document.getElementById("panelMenuBookmarkThisPage"); - if (sib && !document.getElementById("panelMenu_pocket")) { - let menu = createElementWithAttrs(document, "toolbarbutton", { - "id": "panelMenu_pocket", - "label": gPocketBundle.GetStringFromName("pocketMenuitem.label"), - "class": "subviewbutton cui-withicon", - "oncommand": "openUILink(Pocket.listURL, event);", - "hidden": hidden - }); - let sep = createElementWithAttrs(document, "toolbarseparator", { - "id": "panelMenu_pocketSeparator", - "hidden": hidden - }); - // nextSibling is no-id toolbarseparator - // insert separator first then button - sib = sib.nextSibling; - sib.parentNode.insertBefore(sep, sib); - sib.parentNode.insertBefore(menu, sib); - } - }, - onWidgetAfterDOMChange: function(aWidgetNode) { - if (aWidgetNode.id != "pocket-button") { - return; - } - let doc = aWidgetNode.ownerDocument; - let hidden = !CustomizableUI.getPlacementOfWidget("pocket-button"); - for (let prefix of ["panelMenu_", "menu_", "BMB_"]) { - let element = doc.getElementById(prefix + "pocket"); - if (element) { - element.hidden = hidden; - doc.getElementById(prefix + "pocketSeparator").hidden = hidden; - } - } - // enable or disable reader button - PocketReader.hidden = hidden; - }, - - addStyles: function(win) { - let utils = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils); - utils.addSheet(this._cachedSheet, this._sheetType); - }, - - removeStyles: function(win) { - let utils = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils); - utils.removeSheet(gPocketStyleURI, this._sheetType); - } - -} - -// use enabled pref as a way for tests (e.g. test_contextmenu.html) to disable -// the addon when running. -function prefObserver(aSubject, aTopic, aData) { - let enabled = Services.prefs.getBoolPref("extensions.pocket.enabled"); - if (enabled) - PocketOverlay.startup(ADDON_ENABLE); - else - PocketOverlay.shutdown(ADDON_DISABLE); -} - -function startup(data, reason) { - AddonManager.getAddonByID("isreaditlater@ideashower.com", addon => { - if (addon && addon.isActive) - return; - setDefaultPrefs(); - // migrate enabled pref - if (Services.prefs.prefHasUserValue("browser.pocket.enabled")) { - Services.prefs.setBoolPref("extensions.pocket.enabled", Services.prefs.getBoolPref("browser.pocket.enabled")); - Services.prefs.clearUserPref("browser.pocket.enabled"); - } - // watch pref change and enable/disable if necessary - Services.prefs.addObserver("extensions.pocket.enabled", prefObserver, false); - if (!Services.prefs.getBoolPref("extensions.pocket.enabled")) - return; - PocketOverlay.startup(reason); - }); -} - -function shutdown(data, reason) { - // For speed sake, we should only do a shutdown if we're being disabled. - // On an app shutdown, just let it fade away... - if (reason != APP_SHUTDOWN) { - Services.prefs.removeObserver("extensions.pocket.enabled", prefObserver); - PocketOverlay.shutdown(reason); - } -} - -function install() { -} - -function uninstall() { -} |