Bug 1518632: Show the first-run experience for users that get pushed to a new profile. r=Gijs, r=flod, r=stomlinson

On startup of a fresh dedicated profile show a welcome page and a modal dialog
to explain what has happened.

--HG--
extra : rebase_source : a033baf831aa8b9fcfa95d1f921364632a837390
This commit is contained in:
Dave Townsend 2019-01-30 11:31:13 -08:00
parent 1fb2dfc2ee
commit 93581af510
28 changed files with 549 additions and 46 deletions

View File

@ -242,6 +242,8 @@ pref("browser.startup.homepage", "about:home");
// Whether we should skip the homepage when opening the first-run page
pref("browser.startup.firstrunSkipsHomepage", true);
pref("browser.dedicatedprofile.welcome.accounts.endpoint", "https://accounts.firefox.com/");
// Show an about:blank window as early as possible for quick startup feedback.
// Held to nightly on Linux due to bug 1450626.
// Disabled on Mac because the bouncing dock icon already provides feedback.

View File

@ -333,6 +333,13 @@ async function gLazyFindCommand(cmd, ...args) {
}
}
var gPageIcons = {
"about:home": "chrome://branding/content/icon32.png",
"about:newtab": "chrome://branding/content/icon32.png",
"about:welcome": "chrome://branding/content/icon32.png",
"about:newinstall": "chrome://branding/content/icon32.png",
"about:privatebrowsing": "chrome://browser/skin/privatebrowsing/favicon.svg",
};
var gInitialPages = [
"about:blank",
@ -342,10 +349,20 @@ var gInitialPages = [
"about:welcomeback",
"about:sessionrestore",
"about:welcome",
"about:newinstall",
];
function isInitialPage(url) {
return gInitialPages.includes(url) || url == BROWSER_NEW_TAB_URL;
if (!(url instanceof Ci.nsIURI)) {
try {
url = Services.io.newURI(url);
} catch (ex) {
return false;
}
}
let nonQuery = url.prePath + url.filePath;
return gInitialPages.includes(nonQuery) || nonQuery == BROWSER_NEW_TAB_URL;
}
function browserWindows() {
@ -1294,13 +1311,18 @@ var gBrowserInit = {
}
BrowserSearch.initPlaceHolder();
// Hack to ensure that the about:home favicon is loaded
// Hack to ensure that the various initial pages favicon is loaded
// instantaneously, to avoid flickering and improve perceived performance.
this._callWithURIToLoad(uriToLoad => {
if (uriToLoad == "about:home" || uriToLoad == "about:newtab" || uriToLoad == "about:welcome") {
gBrowser.setIcon(gBrowser.selectedTab, "chrome://branding/content/icon32.png");
} else if (uriToLoad == "about:privatebrowsing") {
gBrowser.setIcon(gBrowser.selectedTab, "chrome://browser/skin/privatebrowsing/favicon.svg");
let url;
try {
url = Services.io.newURI(uriToLoad);
} catch (e) {
return;
}
let nonQuery = url.prePath + url.filePath;
if (nonQuery in gPageIcons) {
gBrowser.setIcon(gBrowser.selectedTab, gPageIcons[nonQuery]);
}
});
@ -2644,7 +2666,7 @@ function URLBarSetURI(aURI, updatePopupNotifications) {
// Replace initial page URIs with an empty string
// only if there's no opener (bug 370555).
if (isInitialPage(uri.spec) &&
if (isInitialPage(uri) &&
checkEmptyPageOrigin(gBrowser.selectedBrowser, uri)) {
value = "";
} else {

View File

@ -0,0 +1,50 @@
/* 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 { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm", {});
function init() {
document.querySelector("button").addEventListener("command", () => {
window.close();
});
if (navigator.platform == "MacIntel") {
hideMenus();
window.addEventListener("unload", showMenus);
}
}
let gHidden = [];
let gCollapsed = [];
let hiddenDoc = Services.appShell.hiddenDOMWindow.document;
function hideItem(id) {
let element = hiddenDoc.getElementById(id);
element.hidden = true;
gHidden.push(element);
}
function collapseItem(id) {
let element = hiddenDoc.getElementById(id);
element.collapsed = true;
gCollapsed.push(element);
}
function hideMenus() {
hideItem("macDockMenuNewWindow");
hideItem("macDockMenuNewPrivateWindow");
collapseItem("aboutName");
collapseItem("menu_preferences");
collapseItem("menu_mac_services");
}
function showMenus() {
for (let menu of gHidden) {
menu.hidden = false;
}
for (let menu of gCollapsed) {
menu.collapsed = false;
}
}

View File

@ -0,0 +1,28 @@
<!-- 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/. -->
<!DOCTYPE window [
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
%brandDTD;
<!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd">
%syncBrandDTD;
<!ENTITY % newInstallDTD SYSTEM "chrome://browser/locale/newInstall.dtd">
%newInstallDTD;
]>
<?xml-stylesheet href="chrome://global/skin/"?>
<?xml-stylesheet href="chrome://browser/skin/newInstall.css"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="init()" title="&window.title;" style="&window.style;">
<script src="chrome://browser/content/newInstall.js"></script>
<hbox align="start" flex="1">
<image id="alert" role="presentation"/>
<vbox align="end" flex="1">
<description class="main-text">&mainText;</description>
<description>&sync;</description>
<button label="&continue-button;"/>
</vbox>
</hbox>
</window>

View File

@ -0,0 +1,55 @@
<!DOCTYPE html>
<!-- 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>
<head>
<meta http-equiv="Content-Security-Policy" content="connect-src https:; default-src chrome:">
<meta name="referrer" content="no-referrer">
<link rel="stylesheet" type="text/css" href="chrome://global/skin/in-content/common.css">
<link rel="stylesheet" type="text/css" href="chrome://browser/skin/newInstallPage.css">
<link rel="localization" href="branding/brand.ftl">
<link rel="localization" href="browser/branding/sync-brand.ftl">
<link rel="localization" href="browser/newInstallPage.ftl">
<link rel="icon" type="image/png" href="chrome://branding/content/icon32.png">
<title data-l10n-id="title"></title>
<script type="text/javascript" src="chrome://browser/content/newInstallPage.js"></script>
</head>
<body>
<div id="main">
<div id="header">
<img role="presentation" src="chrome://branding/content/horizontal-lockup.svg">
</div>
<div id="content">
<div id="info">
<h1 data-l10n-id="heading"></h1>
<h3 data-l10n-id="changed-title"></h3>
<p data-l10n-id="changed-desc-profiles"></p>
<p data-l10n-id="changed-desc-dedicated"></p>
<p data-l10n-id="lost"></p>
<h3 data-l10n-id="options-title"></h3>
<p data-l10n-id="options-do-nothing"></p>
<p data-l10n-id="options-use-sync"></p>
<p>
<span data-l10n-id="resources"></span><br>
<a data-l10n-id="support-link" href="https://support.mozilla.org/kb/profile-manager-create-and-remove-firefox-profiles" target="_blank" rel="noopener"></a>
</p>
</div>
<form id="sync">
<h1 id="sync-header" data-l10n-id="sync-header"></h1>
<p id="sync-label"><label data-l10n-id="sync-label" for="sync-input"></label></p>
<p id="sync-input-container"><input id="sync-input" type="email" required name="email" placeholder="Email"></p>
<p id="sync-terms" data-l10n-id="sync-terms">
<a data-l10n-name="terms" href="https://accounts.firefox.com/legal/terms" target="_blank" rel="noopener"></a>
<a data-l10n-name="privacy" href="https://accounts.firefox.com/legal/privacy" target="_blank" rel="noopener"></a>
</p>
<p id="sync-button-container"><button id="sync-button" type="submit" data-l10n-id="sync-button"></button></p>
<p id="sync-first" data-l10n-id="sync-first"></p>
<p id="sync-learn"><a href="https://support.mozilla.org/kb/how-do-i-set-sync-my-computer" target="_blank" rel="noopener" data-l10n-id="sync-learn"></a></p>
</form>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,68 @@
/* 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 PARAMS = new URL(location).searchParams;
const ENTRYPOINT = "new-install-page";
const SOURCE = `new-install-page-${PARAMS.get("channel")}`;
const CAMPAIGN = "dedicated-profiles";
const ENDPOINT = PARAMS.get("endpoint");
const CONTEXT = "fx_desktop_v3";
function appendAccountsParams(url) {
url.searchParams.set("entrypoint", ENTRYPOINT);
url.searchParams.set("utm_source", SOURCE);
url.searchParams.set("utm_campaign", CAMPAIGN);
}
function appendParams(url, params) {
appendAccountsParams(url);
for (let [key, value] of Object.entries(params)) {
url.searchParams.set(key, value);
}
}
async function requestFlowMetrics() {
let requestURL = new URL(`${ENDPOINT}metrics-flow`);
appendParams(requestURL, {
"form_type": "email",
});
let response = await fetch(requestURL, { credentials: "omit" });
if (response.status === 200) {
return response.json();
}
throw new Error(`Failed to retrieve metrics: ${response.status}`);
}
async function submitForm(event) {
// We never want to submit the form.
event.preventDefault();
let input = document.getElementById("sync-input");
input.disabled = true;
document.getElementById("sync-button").disabled = true;
let { flowId, flowBeginTime } = await metrics;
let requestURL = new URL(ENDPOINT);
appendParams(requestURL, {
"service": "sync",
"action": "email",
"utm_campaign": CAMPAIGN,
"email": input.value,
"flow_id": flowId,
"flow_begin_time": flowBeginTime,
});
window.open(requestURL, "_blank", "noopener");
}
// This must come before the CSP is set or it will be blocked.
const metrics = requestFlowMetrics();
document.addEventListener("DOMContentLoaded", () => {
document.getElementById("sync").addEventListener("submit", submitForm);
}, { once: true });

View File

@ -117,6 +117,10 @@ browser.jar:
% override chrome://global/content/license.html chrome://browser/content/license.html
content/browser/blockedSite.xhtml (content/blockedSite.xhtml)
content/browser/blockedSite.js (content/blockedSite.js)
content/browser/newInstall.xul (content/newInstall.xul)
content/browser/newInstall.js (content/newInstall.js)
content/browser/newInstallPage.html (content/newInstallPage.html)
content/browser/newInstallPage.js (content/newInstallPage.js)
% override chrome://global/content/netError.xhtml chrome://browser/content/aboutNetError.xhtml

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 53 KiB

View File

@ -15,3 +15,4 @@ browser.jar:
content/branding/icon128.png (../default128.png)
content/branding/identity-icons-brand.svg
content/branding/aboutDialog.css
content/branding/horizontal-lockup.svg

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -15,3 +15,4 @@ browser.jar:
content/branding/icon128.png (../default128.png)
content/branding/identity-icons-brand.svg
content/branding/aboutDialog.css
content/branding/horizontal-lockup.svg

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -15,3 +15,4 @@ browser.jar:
content/branding/icon128.png (../default128.png)
content/branding/identity-icons-brand.svg
content/branding/aboutDialog.css
content/branding/horizontal-lockup.svg

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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" viewBox="0 0 1011.2 346"><path d="M497.6 247.9l-58.5-122.3c1 11.9 2.7 29.5 2.7 56.2v66h-18.6v-144h25.9l59.1 122.5c-.4-3.3-2.7-26.3-2.7-43.9v-78.6h18.6v144h-26.5v.1zm80.1-138.4c0 7.3-5.4 13-13.6 13-7.9 0-13.4-5.6-13.4-13 0-7.5 5.4-13.2 13.4-13.2 8.1 0 13.6 5.7 13.6 13.2zm-23 28.3h19.2v110.1h-19.2V137.8zm105.3 8.4c13 5.9 19.4 15 19.4 27.8 0 21.7-15.7 37.4-42 37.4-5 0-9.4-.6-14-2.1-3.1 2.3-5.4 6.3-5.4 10.2 0 5 3.1 9 14.4 9H650c22.6 0 37.6 13 37.6 30.5 0 21.3-17.6 33.4-51.6 33.4-35.9 0-47.2-11.1-47.2-33.4h17.3c0 12.5 5.6 18.4 29.9 18.4 23.8 0 32.2-6.1 32.2-17.1 0-10.5-8.4-15.7-22.2-15.7h-17.3c-19.6 0-28.4-9.8-28.4-20.9 0-7.1 4.2-14.2 12.1-19.4-12.7-6.7-18.6-16.3-18.6-30.5 0-22.6 18.2-38.5 42.4-38.5 27.4.6 37.4-4 50.4-9.8l5.6 17.3c-9.2 2.9-19.6 3.4-32.2 3.4zm-46.6 27.5c0 14.6 8.2 24.9 23.2 24.9s23.2-9.2 23.2-25.1c0-16.1-7.9-24.5-23.6-24.5-14.8.1-22.8 10.3-22.8 24.7zm172.2-4.8v79h-19.2v-76.3c0-16.5-7.1-21.3-17.6-21.3-11.9 0-20.5 7.7-27.8 19.2v78.4h-19.2V93.7l19.2-2.1V153c7.9-10.9 18.8-17.8 32.6-17.8 20.1.1 32 13 32 33.7zm59.4 81.5c-18.6 0-29.7-10.9-29.7-31.3v-66.5h-19.2v-14.8h19.2v-24.9l19.2-2.3v27.2h26.1l-2.1 14.8h-24v65.6c0 11.1 3.6 16.3 13.2 16.3 4.8 0 9.2-1.5 14.6-4.8l7.3 13.2c-7.3 5-15.2 7.5-24.6 7.5zm59.3-15.8c2.7 0 5-.4 7.1-1.3l5 13.4c-5.2 2.5-10.7 3.8-16.3 3.8-14 0-21.9-8.4-21.9-24.2V93.5l19.2-2.3v134.6c0 5.8 1.9 8.8 6.9 8.8zm18.9 57.9l-2.1-15c22.4-3.8 28.6-12.3 34.9-29.5h-6.5l-37-110.1H933l29.5 96.1 28.8-96.1h19.9l-36.8 110.8c-7.8 23.3-20.7 40.4-51.2 43.8z" fill="#363959"/><radialGradient id="a" cx="-7592.893" cy="-8773.69" r="306.995" gradientTransform="matrix(1.23 0 0 1.22 9568.41 10762.02)" gradientUnits="userSpaceOnUse"><stop offset=".02" stop-color="#005fe7"/><stop offset=".18" stop-color="#0042b4"/><stop offset=".32" stop-color="#002989"/><stop offset=".4" stop-color="#002079"/><stop offset=".47" stop-color="#131d78"/><stop offset=".66" stop-color="#3b1676"/><stop offset=".75" stop-color="#4a1475"/></radialGradient><path d="M172 346c95.2 0 172.2-77.5 172.2-173S267.1 0 172.1 0 0 77.3 0 172.9C-.2 268.6 77 346 172 346z" fill="url(#a)"/></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -15,3 +15,4 @@ browser.jar:
content/branding/icon128.png (../default128.png)
content/branding/identity-icons-brand.svg
content/branding/aboutDialog.css
content/branding/horizontal-lockup.svg

View File

@ -104,6 +104,10 @@ static const RedirEntry kRedirMap[] = {
nsIAboutModule::HIDE_FROM_ABOUTABOUT},
{"restartrequired", "chrome://browser/content/aboutRestartRequired.xhtml",
nsIAboutModule::ALLOW_SCRIPT | nsIAboutModule::HIDE_FROM_ABOUTABOUT},
{"newinstall", "chrome://browser/content/newInstallPage.html",
nsIAboutModule::URI_MUST_LOAD_IN_CHILD |
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
nsIAboutModule::ALLOW_SCRIPT | nsIAboutModule::HIDE_FROM_ABOUTABOUT},
};
static nsAutoCString GetAboutModuleName(nsIURI* aURI) {

View File

@ -112,6 +112,7 @@ static const mozilla::Module::ContractIDEntry kBrowserContracts[] = {
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "policies", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "pocket-saved", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "pocket-signup", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "newinstall", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
#if defined(XP_WIN)
{ NS_IEHISTORYENUMERATOR_CONTRACTID, &kNS_WINIEHISTORYENUMERATOR_CID },
#endif

View File

@ -21,6 +21,7 @@ XPCOMUtils.defineLazyServiceGetter(this, "WindowsUIUtils",
XPCOMUtils.defineLazyGetter(this, "gSystemPrincipal",
() => Services.scriptSecurityManager.getSystemPrincipal());
XPCOMUtils.defineLazyGlobalGetters(this, [URL]);
function shouldLoadURI(aURI) {
if (aURI && !aURI.schemeIs("chrome"))
@ -59,12 +60,21 @@ function resolveURIInternal(aCmdLine, aArgument) {
return uri;
}
function getNewInstallPage() {
let url = new URL("about:newinstall");
let endpoint = Services.prefs.getCharPref("browser.dedicatedprofile.welcome.accounts.endpoint");
url.searchParams.set("endpoint", endpoint);
url.searchParams.set("channel", AppConstants.MOZ_UPDATE_CHANNEL);
return url.toString();
}
var gFirstWindow = false;
const OVERRIDE_NONE = 0;
const OVERRIDE_NEW_PROFILE = 1;
const OVERRIDE_NEW_MSTONE = 2;
const OVERRIDE_NEW_BUILD_ID = 3;
const OVERRIDE_ALTERNATE_PROFILE = 4;
/**
* Determines whether a home page override is needed.
* Returns:
@ -76,6 +86,11 @@ const OVERRIDE_NEW_BUILD_ID = 3;
* OVERRIDE_NONE otherwise.
*/
function needHomepageOverride(prefb) {
let pService = Cc["@mozilla.org/toolkit/profile-service;1"].
getService(Ci.nsIToolkitProfileService);
if (pService.createdAlternateProfile) {
return OVERRIDE_ALTERNATE_PROFILE;
}
var savedmstone = prefb.getCharPref("browser.startup.homepage_override.mstone", "");
if (savedmstone == "ignore")
@ -188,39 +203,53 @@ function openBrowserWindow(cmdLine, triggeringPrincipal, urlOrUrlList, postData
if (!urlOrUrlList) {
// Just pass in the defaultArgs directly. We'll use system principal on the other end.
args = [gBrowserContentHandler.defaultArgs];
} else if (Array.isArray(urlOrUrlList)) {
// There isn't an explicit way to pass a principal here, so we load multiple URLs
// with system principal when we get to actually loading them.
if (!triggeringPrincipal || !triggeringPrincipal.equals(gSystemPrincipal)) {
throw new Error("Can't open multiple URLs with something other than system principal.");
}
// Passing an nsIArray for the url disables the "|"-splitting behavior.
let uriArray = Cc["@mozilla.org/array;1"]
.createInstance(Ci.nsIMutableArray);
urlOrUrlList.forEach(function(uri) {
var sstring = Cc["@mozilla.org/supports-string;1"]
.createInstance(Ci.nsISupportsString);
sstring.data = uri;
uriArray.appendElement(sstring);
});
args = [uriArray];
} else {
// Always pass at least 3 arguments to avoid the "|"-splitting behavior,
// ie. avoid the loadOneOrMoreURIs function.
// Also, we need to pass the triggering principal.
args = [urlOrUrlList,
null, // charset
null, // referer
postData,
undefined, // allowThirdPartyFixup; this would be `false` but that
// needs a conversion. Hopefully bug 1485961 will fix.
undefined, // referrer policy
undefined, // user context id
null, // origin principal
triggeringPrincipal];
let pService = Cc["@mozilla.org/toolkit/profile-service;1"].
getService(Ci.nsIToolkitProfileService);
if (cmdLine && cmdLine.state == Ci.nsICommandLine.STATE_INITIAL_LAUNCH &&
pService.createdAlternateProfile) {
let url = getNewInstallPage();
if (Array.isArray(urlOrUrlList)) {
urlOrUrlList.unshift(url);
} else {
urlOrUrlList = [url, urlOrUrlList];
}
}
if (Array.isArray(urlOrUrlList)) {
// There isn't an explicit way to pass a principal here, so we load multiple URLs
// with system principal when we get to actually loading them.
if (!triggeringPrincipal || !triggeringPrincipal.equals(gSystemPrincipal)) {
throw new Error("Can't open multiple URLs with something other than system principal.");
}
// Passing an nsIArray for the url disables the "|"-splitting behavior.
let uriArray = Cc["@mozilla.org/array;1"]
.createInstance(Ci.nsIMutableArray);
urlOrUrlList.forEach(function(uri) {
var sstring = Cc["@mozilla.org/supports-string;1"]
.createInstance(Ci.nsISupportsString);
sstring.data = uri;
uriArray.appendElement(sstring);
});
args = [uriArray];
} else {
// Always pass at least 3 arguments to avoid the "|"-splitting behavior,
// ie. avoid the loadOneOrMoreURIs function.
// Also, we need to pass the triggering principal.
args = [urlOrUrlList,
null, // charset
null, // referer
postData,
undefined, // allowThirdPartyFixup; this would be `false` but that
// needs a conversion. Hopefully bug 1485961 will fix.
undefined, // referrer policy
undefined, // user context id
null, // origin principal
triggeringPrincipal];
}
}
if (cmdLine.state == Ci.nsICommandLine.STATE_INITIAL_LAUNCH) {
if (cmdLine && cmdLine.state == Ci.nsICommandLine.STATE_INITIAL_LAUNCH) {
let win = Services.wm.getMostRecentWindow("navigator:blank");
if (win) {
// Remove the windowtype of our blank window so that we don't close it
@ -513,6 +542,12 @@ nsBrowserContentHandler.prototype = {
override = needHomepageOverride(prefb);
if (override != OVERRIDE_NONE) {
switch (override) {
case OVERRIDE_ALTERNATE_PROFILE:
// Override the welcome page to explain why the user has a new
// profile. nsBrowserGlue.css will be responsible for showing the
// modal dialog.
overridePage = getNewInstallPage();
break;
case OVERRIDE_NEW_PROFILE:
// New profile.
overridePage = Services.urlFormatter.formatURLPref("startup.homepage_welcome_url");
@ -575,7 +610,7 @@ nsBrowserContentHandler.prototype = {
if (startPage == "about:blank")
startPage = "";
let skipStartPage = override == OVERRIDE_NEW_PROFILE &&
let skipStartPage = ((override == OVERRIDE_NEW_PROFILE) || (override == OVERRIDE_ALTERNATE_PROFILE)) &&
prefb.getBoolPref("browser.startup.firstrunSkipsHomepage");
// Only show the startPage if we're not restoring an update session and are
// not set to skip the start page on this profile
@ -591,15 +626,17 @@ nsBrowserContentHandler.prototype = {
if (this.mFeatures === null) {
this.mFeatures = "";
try {
var width = cmdLine.handleFlagWithParam("width", false);
var height = cmdLine.handleFlagWithParam("height", false);
if (cmdLine) {
try {
var width = cmdLine.handleFlagWithParam("width", false);
var height = cmdLine.handleFlagWithParam("height", false);
if (width)
this.mFeatures += ",width=" + width;
if (height)
this.mFeatures += ",height=" + height;
} catch (e) {
if (width)
this.mFeatures += ",width=" + width;
if (height)
this.mFeatures += ",height=" + height;
} catch (e) {
}
}
// The global PB Service consumes this flag, so only eat it in per-window

View File

@ -1487,6 +1487,22 @@ BrowserGlue.prototype = {
});
},
_showNewInstallModal() {
// Allow other observers of the same topic to run while we open the dialog.
Services.tm.dispatchToMainThread(() => {
let win = BrowserWindowTracker.getTopWindow();
let stack = win.gBrowser.getPanel().querySelector(".browserStack");
let mask = win.document.createElementNS(XULNS, "box");
mask.setAttribute("id", "content-mask");
stack.appendChild(mask);
Services.ww.openWindow(win, "chrome://browser/content/newInstall.xul",
"_blank", "chrome,modal,resizable=no,centerscreen", null);
mask.remove();
});
},
// All initial windows have opened.
_onWindowsRestored: function BG__onWindowsRestored() {
if (this._windowsWereRestored) {
@ -1541,6 +1557,12 @@ BrowserGlue.prototype = {
this._monitorScreenshotsPref();
this._monitorWebcompatReporterPref();
let pService = Cc["@mozilla.org/toolkit/profile-service;1"].
getService(Ci.nsIToolkitProfileService);
if (pService.createdAlternateProfile) {
this._showNewInstallModal();
}
},
/**

View File

@ -0,0 +1,32 @@
# 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/.
### For this feature, "installation" is used to mean "this discrete download of
### Firefox" and "version" is used to mean "the specific revision number of a
### given Firefox channel". These terms are not synonymous.
title = Important News
heading = Changes to your { -brand-short-name } profile
changed-title = What changed?
changed-desc-profiles = This installation of { -brand-short-name } has a new profile. A profile is the set of files where Firefox saves information such as bookmarks, passwords, and user preferences.
changed-desc-dedicated = In order to make it easier and safer to switch between installations of Firefox (including Firefox, Firefox ESR, Firefox Beta, Firefox Developer Edition, and Firefox Nightly), this installation now has a dedicated profile. It does not automatically share your saved information with other Firefox installations.
lost = <b>You have not lost any personal data or customizations.</b> If youve already saved information to Firefox on this computer, it is still available in another Firefox installation.
options-title = What are my options?
options-do-nothing = If you do nothing, your profile data in { -brand-short-name } will be different from profile data in other installations of Firefox.
options-use-sync = If you would like all of your profile data to be the same on all installations of Firefox, you can use a { -fxaccount-brand-name } to keep them in sync.
resources = Resources:
support-link = Using the Profile Manager - Support Article
sync-header = Sign in or create a { -fxaccount-brand-name }
sync-label = Enter your email
sync-input =
.placeholder = Email
sync-button = Continue
sync-terms = By proceeding, you agree to the <a data-l10n-name="terms">Terms of Service</a> and <a data-l10n-name="privacy">Privacy Notice</a>.
sync-first = First time using { -sync-brand-name }? You'll need to sign in to every installation of Firefox to sync your information.
sync-learn = Learn more

View File

@ -0,0 +1,15 @@
<!-- 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/. -->
<!-- LOCALIZATION NOTE: For this feature, "installation" is used to mean "this
discrete download of Firefox" and "version" is used to mean "the specific
revision number of a given Firefox channel". These terms are not synonymous.
-->
<!ENTITY window.title "Important News">
<!ENTITY window.style "width: 490px">
<!ENTITY sync "To sync information youve already saved to Firefox with this installation of &brandShortName;, sign in with your &syncBrand.fxAccount.label;.">
<!ENTITY continue-button "Continue">
<!ENTITY mainText "This installation of &brandShortName; has a new profile. It does not share bookmarks, passwords, and user preferences with other installations of Firefox (including Firefox, Firefox ESR, Firefox Beta, Firefox Developer Edition, and Firefox Nightly) on this computer.">

View File

@ -60,6 +60,7 @@
% locale pdf.js @AB_CD@ %locale/pdfviewer/
locale/pdfviewer/viewer.properties (%pdfviewer/viewer.properties)
locale/pdfviewer/chrome.properties (%pdfviewer/chrome.properties)
locale/browser/newInstall.dtd (%chrome/browser/newInstall.dtd)
#ifdef XPI_NAME
# Bug 1240628, restructure how l10n repacks work with feature addons

View File

@ -276,3 +276,7 @@
#cfr-notification-footer-spacer {
flex-grow: 1;
}
#content-mask {
background: rgba(0, 0, 0, 0.5);
}

View File

@ -0,0 +1,4 @@
<!-- 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="16" height="16" viewBox="0 0 16 16"><path fill="context-fill" d="M8 16a8 8 0 1 1 8-8 8.009 8.009 0 0 1-8 8zM8 2a6 6 0 1 0 6 6 6.006 6.006 0 0 0-6-6z"></path><path fill="context-fill" d="M8 7a1 1 0 0 0-1 1v3a1 1 0 0 0 2 0V8a1 1 0 0 0-1-1z"></path><circle cx="8" cy="5" r="1.188"></circle></svg>

After

Width:  |  Height:  |  Size: 552 B

View File

@ -56,6 +56,9 @@
skin/classic/browser/identity-icon.svg (../shared/identity-block/identity-icon.svg)
skin/classic/browser/identity-icon-notice.svg (../shared/identity-block/identity-icon-notice.svg)
skin/classic/browser/info.svg (../shared/info.svg)
skin/classic/browser/information.svg (../shared/information.svg)
skin/classic/browser/newInstall.css (../shared/newInstall.css)
skin/classic/browser/newInstallPage.css (../shared/newInstallPage.css)
skin/classic/browser/illustrations/error-session-restore.svg (../shared/illustrations/error-session-restore.svg)

View File

@ -0,0 +1,24 @@
/* 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/. */
window {
padding: 20px;
}
#alert {
width: 32px;
height: 32px;
margin-inline-end: 8px;
list-style-image: url("chrome://browser/skin/information.svg");
}
description {
margin: 0 0 20px 0;
padding: 0;
}
.main-text {
font-size: 133%;
font-weight: bold;
}

View File

@ -0,0 +1,102 @@
/* 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/. */
h1 {
margin: 0 0 40px 0;
}
h3 {
font-size: inherit;
margin: 0;
}
p {
margin: 0 0 20px 0;
}
#main {
max-width: 830px;
margin: 40px auto 0 auto;
padding: 0 5px;
}
#header {
margin-bottom: 40px;
}
#header > img {
height: 52px;
}
#content {
display: flex;
flex-direction: row;
justify-content: space-between;
}
#info {
flex: 1;
max-width: 420px;
}
#sync {
width: 250px;
text-align: center;
}
#sync-header {
font-size: 1.9em;
}
#sync-label {
font-size: 113%;
font-weight: bolder;
margin-bottom: 10px;
}
#sync-input-container {
margin-bottom: 20px;
}
#sync-input {
box-sizing: border-box;
width: 100%;
height: 40px;
padding-inline-start: 20px;
}
#sync-terms {
font-size: 87%;
margin-bottom: 20px;
color: var(--grey-50);
}
#sync-terms a,
#sync-terms a:hover,
#sync-terms a:visited {
color: inherit;
}
#sync-button-container {
margin-bottom: 20px;
}
#sync-button {
box-sizing: border-box;
width: 100%;
height: 42px;
cursor: pointer;
padding: 8px 0;
margin: 0;
color: #FFF !important;
background-color: var(--blue-50);
border-radius: 4px;
}
#sync-first, #sync-learn {
font-size: 87%;
color: var(--grey-50);
margin-bottom: 0;
text-align: start;
}

View File

@ -60,6 +60,7 @@
--blue-80: #002275;
--grey-20: #ededf0;
--grey-30: #d7d7db;
--grey-50: #737373;
--grey-60: #4a4a4f;
--grey-90: #0c0c0d;
--grey-90-a10: rgba(12, 12, 13, 0.1);