michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: "use strict"; michael@0: michael@0: let Cc = Components.classes; michael@0: let Ci = Components.interfaces; michael@0: let Cu = Components.utils; michael@0: michael@0: this.EXPORTED_SYMBOLS = [ "AboutHomeUtils", "AboutHome" ]; michael@0: michael@0: Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); michael@0: Components.utils.import("resource://gre/modules/Services.jsm"); michael@0: michael@0: XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils", michael@0: "resource://gre/modules/PrivateBrowsingUtils.jsm"); michael@0: XPCOMUtils.defineLazyModuleGetter(this, "fxAccounts", michael@0: "resource://gre/modules/FxAccounts.jsm"); michael@0: michael@0: // Url to fetch snippets, in the urlFormatter service format. michael@0: const SNIPPETS_URL_PREF = "browser.aboutHomeSnippets.updateUrl"; michael@0: michael@0: // Should be bumped up if the snippets content format changes. michael@0: const STARTPAGE_VERSION = 4; michael@0: michael@0: this.AboutHomeUtils = { michael@0: get snippetsVersion() STARTPAGE_VERSION, michael@0: michael@0: /* michael@0: * showKnowYourRights - Determines if the user should be shown the michael@0: * about:rights notification. The notification should *not* be shown if michael@0: * we've already shown the current version, or if the override pref says to michael@0: * never show it. The notification *should* be shown if it's never been seen michael@0: * before, if a newer version is available, or if the override pref says to michael@0: * always show it. michael@0: */ michael@0: get showKnowYourRights() { michael@0: // Look for an unconditional override pref. If set, do what it says. michael@0: // (true --> never show, false --> always show) michael@0: try { michael@0: return !Services.prefs.getBoolPref("browser.rights.override"); michael@0: } catch (e) { } michael@0: // Ditto, for the legacy EULA pref. michael@0: try { michael@0: return !Services.prefs.getBoolPref("browser.EULA.override"); michael@0: } catch (e) { } michael@0: michael@0: #ifndef MOZILLA_OFFICIAL michael@0: // Non-official builds shouldn't show the notification. michael@0: return false; michael@0: #endif michael@0: michael@0: // Look to see if the user has seen the current version or not. michael@0: var currentVersion = Services.prefs.getIntPref("browser.rights.version"); michael@0: try { michael@0: return !Services.prefs.getBoolPref("browser.rights." + currentVersion + ".shown"); michael@0: } catch (e) { } michael@0: michael@0: // Legacy: If the user accepted a EULA, we won't annoy them with the michael@0: // equivalent about:rights page until the version changes. michael@0: try { michael@0: return !Services.prefs.getBoolPref("browser.EULA." + currentVersion + ".accepted"); michael@0: } catch (e) { } michael@0: michael@0: // We haven't shown the notification before, so do so now. michael@0: return true; michael@0: } michael@0: }; michael@0: michael@0: /** michael@0: * Returns the URL to fetch snippets from, in the urlFormatter service format. michael@0: */ michael@0: XPCOMUtils.defineLazyGetter(AboutHomeUtils, "snippetsURL", function() { michael@0: let updateURL = Services.prefs michael@0: .getCharPref(SNIPPETS_URL_PREF) michael@0: .replace("%STARTPAGE_VERSION%", STARTPAGE_VERSION); michael@0: return Services.urlFormatter.formatURL(updateURL); michael@0: }); michael@0: michael@0: /** michael@0: * This code provides services to the about:home page. Whenever michael@0: * about:home needs to do something chrome-privileged, it sends a michael@0: * message that's handled here. michael@0: */ michael@0: let AboutHome = { michael@0: MESSAGES: [ michael@0: "AboutHome:RestorePreviousSession", michael@0: "AboutHome:Downloads", michael@0: "AboutHome:Bookmarks", michael@0: "AboutHome:History", michael@0: "AboutHome:Apps", michael@0: "AboutHome:Addons", michael@0: "AboutHome:Sync", michael@0: "AboutHome:Settings", michael@0: "AboutHome:RequestUpdate", michael@0: "AboutHome:Search", michael@0: ], michael@0: michael@0: init: function() { michael@0: let mm = Cc["@mozilla.org/globalmessagemanager;1"].getService(Ci.nsIMessageListenerManager); michael@0: michael@0: for (let msg of this.MESSAGES) { michael@0: mm.addMessageListener(msg, this); michael@0: } michael@0: michael@0: Services.obs.addObserver(this, "browser-search-engine-modified", false); michael@0: }, michael@0: michael@0: observe: function(aEngine, aTopic, aVerb) { michael@0: switch (aTopic) { michael@0: case "browser-search-engine-modified": michael@0: this.sendAboutHomeData(null); michael@0: break; michael@0: } michael@0: }, michael@0: michael@0: receiveMessage: function(aMessage) { michael@0: let window = aMessage.target.ownerDocument.defaultView; michael@0: michael@0: switch (aMessage.name) { michael@0: case "AboutHome:RestorePreviousSession": michael@0: let ss = Cc["@mozilla.org/browser/sessionstore;1"]. michael@0: getService(Ci.nsISessionStore); michael@0: if (ss.canRestoreLastSession) { michael@0: ss.restoreLastSession(); michael@0: } michael@0: break; michael@0: michael@0: case "AboutHome:Downloads": michael@0: window.BrowserDownloadsUI(); michael@0: break; michael@0: michael@0: case "AboutHome:Bookmarks": michael@0: window.PlacesCommandHook.showPlacesOrganizer("AllBookmarks"); michael@0: break; michael@0: michael@0: case "AboutHome:History": michael@0: window.PlacesCommandHook.showPlacesOrganizer("History"); michael@0: break; michael@0: michael@0: case "AboutHome:Apps": michael@0: window.openUILinkIn("https://marketplace.mozilla.org/", "tab"); michael@0: break; michael@0: michael@0: case "AboutHome:Addons": michael@0: window.BrowserOpenAddonsMgr(); michael@0: break; michael@0: michael@0: case "AboutHome:Sync": michael@0: let weave = Cc["@mozilla.org/weave/service;1"] michael@0: .getService(Ci.nsISupports) michael@0: .wrappedJSObject; michael@0: michael@0: if (weave.fxAccountsEnabled) { michael@0: fxAccounts.getSignedInUser().then(userData => { michael@0: if (userData) { michael@0: window.openPreferences("paneSync"); michael@0: } else { michael@0: window.loadURI("about:accounts"); michael@0: } michael@0: }); michael@0: } else { michael@0: window.openPreferences("paneSync"); michael@0: } michael@0: break; michael@0: michael@0: case "AboutHome:Settings": michael@0: window.openPreferences(); michael@0: break; michael@0: michael@0: case "AboutHome:RequestUpdate": michael@0: this.sendAboutHomeData(aMessage.target); michael@0: break; michael@0: michael@0: case "AboutHome:Search": michael@0: let data; michael@0: try { michael@0: data = JSON.parse(aMessage.data.searchData); michael@0: } catch(ex) { michael@0: Cu.reportError(ex); michael@0: break; michael@0: } michael@0: let engine = Services.search.currentEngine; michael@0: #ifdef MOZ_SERVICES_HEALTHREPORT michael@0: window.BrowserSearch.recordSearchInHealthReport(engine, "abouthome"); michael@0: #endif michael@0: // Trigger a search through nsISearchEngine.getSubmission() michael@0: let submission = engine.getSubmission(data.searchTerms, null, "homepage"); michael@0: window.loadURI(submission.uri.spec, null, submission.postData); michael@0: break; michael@0: } michael@0: }, michael@0: michael@0: // Send all the chrome-privileged data needed by about:home. This michael@0: // gets re-sent when the search engine changes. michael@0: sendAboutHomeData: function(target) { michael@0: let wrapper = {}; michael@0: Components.utils.import("resource:///modules/sessionstore/SessionStore.jsm", michael@0: wrapper); michael@0: let ss = wrapper.SessionStore; michael@0: ss.promiseInitialized.then(function() { michael@0: let data = { michael@0: showRestoreLastSession: ss.canRestoreLastSession, michael@0: snippetsURL: AboutHomeUtils.snippetsURL, michael@0: showKnowYourRights: AboutHomeUtils.showKnowYourRights, michael@0: snippetsVersion: AboutHomeUtils.snippetsVersion, michael@0: defaultEngineName: Services.search.defaultEngine.name michael@0: }; michael@0: michael@0: if (AboutHomeUtils.showKnowYourRights) { michael@0: // Set pref to indicate we've shown the notification. michael@0: let currentVersion = Services.prefs.getIntPref("browser.rights.version"); michael@0: Services.prefs.setBoolPref("browser.rights." + currentVersion + ".shown", true); michael@0: } michael@0: michael@0: if (target) { michael@0: target.messageManager.sendAsyncMessage("AboutHome:Update", data); michael@0: } else { michael@0: let mm = Cc["@mozilla.org/globalmessagemanager;1"].getService(Ci.nsIMessageListenerManager); michael@0: mm.broadcastAsyncMessage("AboutHome:Update", data); michael@0: } michael@0: }).then(null, function onError(x) { michael@0: Cu.reportError("Error in AboutHome.sendAboutHomeData: " + x); michael@0: }); michael@0: }, michael@0: };