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 : 1505cf27f900070debc1f9e1c71ec4bef3bc099d
extra : source : 05200c5388b4f7adc4414268727458515d7b9ed9
This commit is contained in:
Dave Townsend 2019-01-30 11:31:13 -08:00
Родитель 0b0a1e8daa
Коммит 5d41d30a08
28 изменённых файлов: 549 добавлений и 46 удалений

Просмотреть файл

@ -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.

Просмотреть файл

@ -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 {

Просмотреть файл

@ -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;
}
}

Просмотреть файл

@ -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>

Просмотреть файл

@ -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>

Просмотреть файл

@ -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 });

Просмотреть файл

@ -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

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 53 KiB

Просмотреть файл

@ -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

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 19 KiB

Просмотреть файл

@ -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

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

После

Ширина:  |  Высота:  |  Размер: 16 KiB

Просмотреть файл

@ -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

Просмотреть файл

@ -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>

После

Ширина:  |  Высота:  |  Размер: 2.3 KiB

Просмотреть файл

@ -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

Просмотреть файл

@ -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) {

Просмотреть файл

@ -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

Просмотреть файл

@ -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,7 +203,20 @@ 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)) {
} else {
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)) {
@ -219,8 +247,9 @@ function openBrowserWindow(cmdLine, triggeringPrincipal, urlOrUrlList, postData
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,6 +626,7 @@ nsBrowserContentHandler.prototype = {
if (this.mFeatures === null) {
this.mFeatures = "";
if (cmdLine) {
try {
var width = cmdLine.handleFlagWithParam("width", false);
var height = cmdLine.handleFlagWithParam("height", false);
@ -601,6 +637,7 @@ nsBrowserContentHandler.prototype = {
this.mFeatures += ",height=" + height;
} catch (e) {
}
}
// The global PB Service consumes this flag, so only eat it in per-window
// PB builds.

Просмотреть файл

@ -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();
}
},
/**

Просмотреть файл

@ -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

Просмотреть файл

@ -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.">

Просмотреть файл

@ -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

Просмотреть файл

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

Просмотреть файл

@ -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>

После

Ширина:  |  Высота:  |  Размер: 552 B

Просмотреть файл

@ -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)

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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);