diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index 63b5c1138788..f05671b7507b 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -1348,8 +1348,10 @@ pref("browser.newtabpage.directory.source", "https://tiles.services.mozilla.com/ // endpoint to send newtab click and view pings pref("browser.newtabpage.directory.ping", "https://tiles.services.mozilla.com/v3/links/"); -// activates the remote-hosted newtab page +#ifndef RELEASE_BUILD +// if true, it activates the remote-hosted newtab page pref("browser.newtabpage.remote", false); +#endif // Enable the DOM fullscreen API. pref("full-screen-api.enabled", true); @@ -1636,4 +1638,4 @@ pref("toolkit.pageThumbs.minHeight", 190); #ifdef NIGHTLY_BUILD // Enable speech synthesis, only Nightly for now pref("media.webspeech.synth.enabled", true); -#endif \ No newline at end of file +#endif diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index b4ed41d3e8db..cb60461a04c8 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -11,7 +11,6 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/NotificationDB.jsm"); Cu.import("resource:///modules/RecentWindow.jsm"); - XPCOMUtils.defineLazyModuleGetter(this, "Preferences", "resource://gre/modules/Preferences.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "Deprecated", @@ -56,9 +55,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "LightweightThemeManager", "resource://gre/modules/LightweightThemeManager.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "Pocket", "resource:///modules/Pocket.jsm"); -XPCOMUtils.defineLazyServiceGetter(this, "gAboutNewTabService", - "@mozilla.org/browser/aboutnewtab-service;1", - "nsIAboutNewTabService"); // Can't use XPCOMUtils for these because the scripts try to define the variables // on window, and so the defineProperty inside defineLazyGetter fails. @@ -2365,11 +2361,8 @@ function URLBarSetURI(aURI) { } catch (e) {} // Replace initial page URIs with an empty string - // 1. only if there's no opener (bug 370555). - // 2. if remote newtab is enabled and it's the default remote newtab page - let defaultRemoteURL = gAboutNewTabService.remoteEnabled && - uri.spec === gAboutNewTabService.newTabURL; - if (gInitialPages.includes(uri.spec) || defaultRemoteURL) + // only if there's no opener (bug 370555). + if (gInitialPages.indexOf(uri.spec) != -1) value = gBrowser.selectedBrowser.hasContentOpener ? uri.spec : ""; else value = losslessDecodeURI(uri); @@ -3566,9 +3559,8 @@ const BrowserSearch = { if (!aSearchBar || document.activeElement != aSearchBar.textbox.inputField) { let url = gBrowser.currentURI.spec.toLowerCase(); let mm = gBrowser.selectedBrowser.messageManager; - let newTabRemoted = Services.prefs.getBoolPref("browser.newtabpage.remote"); - let localNewTabEnabled = url === "about:newtab" && !newTabRemoted && NewTabUtils.allPages.enabled; - if (url === "about:home" || localNewTabEnabled) { + if (url === "about:home" || + (url === "about:newtab" && NewTabUtils.allPages.enabled)) { ContentSearch.focusInput(mm); } else { openUILinkIn("about:home", "current"); diff --git a/browser/base/content/remote-newtab/newTab.css b/browser/base/content/remote-newtab/newTab.css new file mode 100644 index 000000000000..303cafddc5e2 --- /dev/null +++ b/browser/base/content/remote-newtab/newTab.css @@ -0,0 +1,23 @@ +/* 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/. */ + +html { + width: 100%; + height: 100%; +} + +body { + width: 100%; + height: 100%; + padding: 0; + margin: 0; + position: relative; +} + +#remotedoc { + width: 100%; + height: 100%; + border: none; + position: absolute; +} diff --git a/browser/base/content/remote-newtab/newTab.js b/browser/base/content/remote-newtab/newTab.js new file mode 100644 index 000000000000..920830c96767 --- /dev/null +++ b/browser/base/content/remote-newtab/newTab.js @@ -0,0 +1,126 @@ +/* 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/. */ +/*globals XPCOMUtils, Components, sendAsyncMessage, addMessageListener, removeMessageListener, + Services, PrivateBrowsingUtils*/ +"use strict"; + +const {utils: Cu, interfaces: Ci} = Components; +Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils", + "resource://gre/modules/PrivateBrowsingUtils.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "Services", + "resource://gre/modules/Services.jsm"); + +(function() { + let remoteNewTabLocation; + let remoteIFrame; + + /** + * Attempts to handle commands sent from the remote IFrame within this content frame. + * Expected commands below, with data types explained. + * + * @returns {Boolean} whether or not the command was handled + * @param {String} command + * The command passed from the remote IFrame + * @param {Object} data + * Parameters to the command + */ + function handleCommand(command, data) { + let commandHandled = true; + switch (command) { + case "NewTab:UpdateTelemetryProbe": + /** + * Update a given Telemetry histogram + * + * @param {String} data.probe + * Probe name to update + * @param {Number} data.value + * Value to update histogram by + */ + Services.telemetry.getHistogramById(data.probe).add(data.value); + break; + case "NewTab:Register": + registerEvent(data.type); + break; + case "NewTab:GetInitialState": + getInitialState(); + break; + default: + commandHandled = false; + } + return commandHandled; + } + + function initRemotePage(initData) { + // Messages that the iframe sends the browser will be passed onto + // the privileged parent process + remoteNewTabLocation = initData; + remoteIFrame = document.querySelector("#remotedoc"); + + let loadHandler = () => { + if (remoteIFrame.src !== remoteNewTabLocation.href) { + return; + } + + remoteIFrame.removeEventListener("load", loadHandler); + + remoteIFrame.contentDocument.addEventListener("NewTabCommand", (e) => { + // If the commands are not handled within this content frame, the command will be + // passed on to main process, in RemoteAboutNewTab.jsm + let handled = handleCommand(e.detail.command, e.detail.data); + if (!handled) { + sendAsyncMessage(e.detail.command, e.detail.data); + } + }); + registerEvent("NewTab:Observe"); + let ev = new CustomEvent("NewTabCommandReady"); + remoteIFrame.contentDocument.dispatchEvent(ev); + }; + + remoteIFrame.src = remoteNewTabLocation.href; + remoteIFrame.addEventListener("load", loadHandler); + } + + /** + * Allows the content IFrame to register a listener to an event sent by + * the privileged parent process, in RemoteAboutNewTab.jsm + * + * @param {String} eventName + * Event name to listen to + */ + function registerEvent(eventName) { + addMessageListener(eventName, (message) => { + remoteIFrame.contentWindow.postMessage(message, remoteNewTabLocation.origin); + }); + } + + /** + * Sends the initial data payload to a content IFrame so it can bootstrap + */ + function getInitialState() { + let prefs = Services.prefs; + let isPrivate = PrivateBrowsingUtils.isContentWindowPrivate(window); + let state = { + enabled: prefs.getBoolPref("browser.newtabpage.enabled"), + enhanced: prefs.getBoolPref("browser.newtabpage.enhanced"), + rows: prefs.getIntPref("browser.newtabpage.rows"), + columns: prefs.getIntPref("browser.newtabpage.columns"), + introShown: prefs.getBoolPref("browser.newtabpage.introShown"), + windowID: window.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindowUtils).outerWindowID, + privateBrowsingMode: isPrivate + }; + remoteIFrame.contentWindow.postMessage({ + name: "NewTab:State", + data: state + }, remoteNewTabLocation.origin); + } + + addMessageListener("NewTabFrame:Init", function loadHandler(message) { + // Everything is loaded. Initialize the New Tab Page. + removeMessageListener("NewTabFrame:Init", loadHandler); + initRemotePage(message.data); + }); + sendAsyncMessage("NewTabFrame:GetInit"); +}()); diff --git a/browser/base/content/remote-newtab/newTab.xhtml b/browser/base/content/remote-newtab/newTab.xhtml new file mode 100644 index 000000000000..1ae754eedbfd --- /dev/null +++ b/browser/base/content/remote-newtab/newTab.xhtml @@ -0,0 +1,24 @@ + + + + + + %newTabDTD; +]> + + + + &newtab.pageTitle; + + + +