Merge mozilla-central to autoland. a=merge CLOSED TREE

This commit is contained in:
Oana Pop Rus 2019-01-31 12:00:53 +02:00
Родитель 8707bfb5f2 6e3cc15356
Коммит 707db23fae
148 изменённых файлов: 3599 добавлений и 744 удалений

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

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

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

@ -85,12 +85,20 @@ var TrackingProtection = {
this.categoryLabel.textContent = label ? gNavigatorBundle.getString(label) : "";
},
// FIXME This must change! Fingerprinting and cryptomining must have theirs
// own sections. See bug 1522566.
isBlocking(state) {
return (state & Ci.nsIWebProgressListener.STATE_BLOCKED_TRACKING_CONTENT) != 0;
return (state & Ci.nsIWebProgressListener.STATE_BLOCKED_TRACKING_CONTENT) != 0 ||
(state & Ci.nsIWebProgressListener.STATE_BLOCKED_FINGERPRINTING_CONTENT) != 0 ||
(state & Ci.nsIWebProgressListener.STATE_BLOCKED_CRYPTOMINING_CONTENT) != 0;
},
// FIXME This must change! Fingerprinting and cryptomining must have theirs
// own sections. See bug 1522566.
isAllowing(state) {
return (state & Ci.nsIWebProgressListener.STATE_LOADED_TRACKING_CONTENT) != 0;
return (state & Ci.nsIWebProgressListener.STATE_LOADED_TRACKING_CONTENT) != 0 ||
(state & Ci.nsIWebProgressListener.STATE_LOADED_FINGERPRINTING_CONTENT) != 0 ||
(state & Ci.nsIWebProgressListener.STATE_LOADED_CRYPTOMINING_CONTENT) != 0;
},
isDetected(state) {

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

@ -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 {
@ -4914,7 +4936,8 @@ var XULBrowserWindow = {
// 3. Called directly during this object's initializations.
// 4. Due to the nsIWebProgressListener.onLocationChange notification.
// aRequest will be null always in case 2 and 3, and sometimes in case 1 (for
// instance, there won't be a request when STATE_BLOCKED_TRACKING_CONTENT is observed).
// instance, there won't be a request when STATE_BLOCKED_TRACKING_CONTENT or
// other blocking events are observed).
onContentBlockingEvent(aWebProgress, aRequest, aEvent, aIsSimulated) {
// Don't need to do anything if the data we use to update the UI hasn't
// changed

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

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

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

@ -72,7 +72,7 @@ FirefoxProfileMigrator.prototype.getResources = function(aProfile) {
let sourceProfileDir = aProfile ? this._getAllProfiles().get(aProfile.id) :
Cc["@mozilla.org/toolkit/profile-service;1"]
.getService(Ci.nsIToolkitProfileService)
.selectedProfile.rootDir;
.currentProfile.rootDir;
if (!sourceProfileDir || !sourceProfileDir.exists() ||
!sourceProfileDir.isReadable())
return null;

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

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

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

@ -410,26 +410,6 @@ var gMainPane = {
// of the pane hiding/showing code potentially interfering:
document.getElementById("drmGroup").setAttribute("style", "display: none !important");
}
if (AppConstants.MOZ_DEV_EDITION) {
let uAppData = OS.Constants.Path.userApplicationDataDir;
let ignoreSeparateProfile = OS.Path.join(uAppData, "ignore-dev-edition-profile");
setEventListener("separateProfileMode", "command", gMainPane.separateProfileModeChange);
let separateProfileModeCheckbox = document.getElementById("separateProfileMode");
setEventListener("getStarted", "click", gMainPane.onGetStarted);
OS.File.stat(ignoreSeparateProfile).then(() => separateProfileModeCheckbox.checked = false,
() => separateProfileModeCheckbox.checked = true);
if (Services.prefs.getBoolPref("identity.fxaccounts.enabled")) {
document.getElementById("sync-dev-edition-root").hidden = false;
fxAccounts.getSignedInUser().then(data => {
document.getElementById("getStarted").selectedIndex = data ? 1 : 0;
}).catch(Cu.reportError);
}
}
// Initialize the Firefox Updates section.
let version = AppConstants.MOZ_APP_VERSION_DISPLAY;

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

@ -30,20 +30,6 @@
hidden="true">
<label><html:h2 data-l10n-id="startup-header"/></label>
#ifdef MOZ_DEV_EDITION
<vbox id="separateProfileBox">
<checkbox id="separateProfileMode"
data-l10n-id="separate-profile-mode"/>
<hbox id="sync-dev-edition-root" align="center" class="indent" hidden="true">
<label id="useFirefoxSync" data-l10n-id="use-firefox-sync"/>
<deck id="getStarted">
<label class="text-link" data-l10n-id="get-started-not-logged-in"/>
<label class="text-link" data-l10n-id="get-started-configured"/>
</deck>
</hbox>
</vbox>
#endif
<vbox id="startupPageBox">
<checkbox id="browserRestoreSession"
data-l10n-id="startup-restore-previous-session"/>

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

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

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

@ -56,6 +56,8 @@
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/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://mozapps/skin/profile/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;
}

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

@ -6,8 +6,9 @@
"use strict";
const AutocompletePopup = require("devtools/client/shared/autocomplete-popup");
const CSSCompleter = require("devtools/client/sourceeditor/css-autocompleter");
const {KeyCodes} = require("devtools/client/shared/keycodes");
loader.lazyRequireGetter(this, "KeyCodes", "devtools/client/shared/keycodes", true);
loader.lazyRequireGetter(this, "CSSCompleter", "devtools/client/sourceeditor/css-autocompleter");
const CM_TERN_SCRIPTS = [
"chrome://devtools/content/sourceeditor/codemirror/addon/tern/tern.js",

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

@ -180,13 +180,14 @@ function getDeviceName() {
function getProfileLocation() {
// In child processes, we cannot access the profile location.
try {
// For some reason this line must come first or in xpcshell tests
// nsXREDirProvider never gets initialised and so the profile service
// crashes on initialisation.
const profd = Services.dirsvc.get("ProfD", Ci.nsIFile);
const profservice = Cc["@mozilla.org/toolkit/profile-service;1"]
.getService(Ci.nsIToolkitProfileService);
for (const profile of profservice.profiles) {
if (profile.rootDir.path == profd.path) {
return profile.name;
}
if (profservice.currentProfile) {
return profservice.currentProfile.name;
}
return profd.leafName;

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

@ -62,6 +62,7 @@
#include "mozilla/dom/LoadURIOptionsBinding.h"
#include "mozilla/net/ReferrerPolicy.h"
#include "mozilla/net/UrlClassifierFeatureFactory.h"
#include "nsIApplicationCacheChannel.h"
#include "nsIApplicationCacheContainer.h"
@ -6699,7 +6700,8 @@ nsresult nsDocShell::EndPageLoad(nsIWebProgress* aProgress,
// a tracking URL. We make a note of this iframe node by including
// it in a dedicated array of blocked tracking nodes under its parent
// document. (document of parent window of blocked document)
if (isTopFrame == false && aStatus == NS_ERROR_TRACKING_URI) {
if (!isTopFrame &&
UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aStatus)) {
// frameElement is our nsIContent to be annotated
RefPtr<Element> frameElement;
nsPIDOMWindowOuter* thisWindow = GetWindow();
@ -6725,7 +6727,7 @@ nsresult nsDocShell::EndPageLoad(nsIWebProgress* aProgress,
return NS_OK;
}
parentDoc->AddBlockedTrackingNode(frameElement);
parentDoc->AddBlockedNodeByClassifier(frameElement);
return NS_OK;
}

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

@ -25,6 +25,7 @@
#include "mozilla/dom/ReportingHeader.h"
#include "mozilla/dom/UnionTypes.h"
#include "mozilla/dom/WindowBinding.h" // For IdleRequestCallback/Options
#include "mozilla/net/UrlClassifierFeatureFactory.h"
#include "IOActivityMonitor.h"
#include "nsThreadUtils.h"
#include "mozJSComponentLoader.h"
@ -833,5 +834,11 @@ constexpr auto kSkipSelfHosted = JS::SavedFrameSelfHosted::Exclude;
service->RegisterWindowActor(aName, aOptions, aRv);
}
/* static */ bool ChromeUtils::IsClassifierBlockingErrorCode(
GlobalObject& aGlobal, uint32_t aError) {
return net::UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(
static_cast<nsresult>(aError));
}
} // namespace dom
} // namespace mozilla

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

@ -179,6 +179,9 @@ class ChromeUtils {
const nsAString& aName,
const WindowActorOptions& aOptions,
ErrorResult& aRv);
static bool IsClassifierBlockingErrorCode(GlobalObject& aGlobal,
uint32_t aError);
};
} // namespace dom

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

@ -5396,14 +5396,15 @@ void Document::ResolveScheduledSVGPresAttrs() {
mLazySVGPresElements.Clear();
}
already_AddRefed<nsSimpleContentList> Document::BlockedTrackingNodes() const {
already_AddRefed<nsSimpleContentList> Document::BlockedNodesByClassifier()
const {
RefPtr<nsSimpleContentList> list = new nsSimpleContentList(nullptr);
nsTArray<nsWeakPtr> blockedTrackingNodes;
blockedTrackingNodes = mBlockedTrackingNodes;
nsTArray<nsWeakPtr> blockedNodes;
blockedNodes = mBlockedNodesByClassifier;
for (unsigned long i = 0; i < blockedTrackingNodes.Length(); i++) {
nsWeakPtr weakNode = blockedTrackingNodes[i];
for (unsigned long i = 0; i < blockedNodes.Length(); i++) {
nsWeakPtr weakNode = blockedNodes[i];
nsCOMPtr<nsIContent> node = do_QueryReferent(weakNode);
// Consider only nodes to which we have managed to get strong references.
// Coping with nullptrs since it's expected for nodes to disappear when

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

@ -1002,6 +1002,22 @@ class Document : public nsINode,
nsIWebProgressListener::STATE_BLOCKED_TRACKING_CONTENT);
}
/**
* Get fingerprinting content blocked flag for this document.
*/
bool GetHasFingerprintingContentBlocked() {
return mContentBlockingLog.HasBlockedAnyOfType(
nsIWebProgressListener::STATE_BLOCKED_FINGERPRINTING_CONTENT);
}
/**
* Get cryptomining content blocked flag for this document.
*/
bool GetHasCryptominingContentBlocked() {
return mContentBlockingLog.HasBlockedAnyOfType(
nsIWebProgressListener::STATE_BLOCKED_CRYPTOMINING_CONTENT);
}
/**
* Get all cookies blocked flag for this document.
*/
@ -1044,6 +1060,28 @@ class Document : public nsINode,
aHasTrackingContentBlocked);
}
/**
* Set the fingerprinting content blocked flag for this document.
*/
void SetHasFingerprintingContentBlocked(bool aHasFingerprintingContentBlocked,
const nsACString& aOriginBlocked) {
RecordContentBlockingLog(
aOriginBlocked,
nsIWebProgressListener::STATE_BLOCKED_FINGERPRINTING_CONTENT,
aHasFingerprintingContentBlocked);
}
/**
* Set the cryptomining content blocked flag for this document.
*/
void SetHasCryptominingContentBlocked(bool aHasCryptominingContentBlocked,
const nsACString& aOriginBlocked) {
RecordContentBlockingLog(
aOriginBlocked,
nsIWebProgressListener::STATE_BLOCKED_CRYPTOMINING_CONTENT,
aHasCryptominingContentBlocked);
}
/**
* Set the all cookies blocked flag for this document.
*/
@ -1121,6 +1159,44 @@ class Document : public nsINode,
aHasTrackingContentLoaded);
}
/**
* Get fingerprinting content loaded flag for this document.
*/
bool GetHasFingerprintingContentLoaded() {
return mContentBlockingLog.HasBlockedAnyOfType(
nsIWebProgressListener::STATE_LOADED_FINGERPRINTING_CONTENT);
}
/**
* Set the fingerprinting content loaded flag for this document.
*/
void SetHasFingerprintingContentLoaded(bool aHasFingerprintingContentLoaded,
const nsACString& aOriginBlocked) {
RecordContentBlockingLog(
aOriginBlocked,
nsIWebProgressListener::STATE_LOADED_FINGERPRINTING_CONTENT,
aHasFingerprintingContentLoaded);
}
/**
* Get cryptomining content loaded flag for this document.
*/
bool GetHasCryptominingContentLoaded() {
return mContentBlockingLog.HasBlockedAnyOfType(
nsIWebProgressListener::STATE_LOADED_CRYPTOMINING_CONTENT);
}
/**
* Set the cryptomining content loaded flag for this document.
*/
void SetHasCryptominingContentLoaded(bool aHasCryptominingContentLoaded,
const nsACString& aOriginBlocked) {
RecordContentBlockingLog(
aOriginBlocked,
nsIWebProgressListener::STATE_LOADED_CRYPTOMINING_CONTENT,
aHasCryptominingContentLoaded);
}
/**
* Get the sandbox flags for this document.
* @see nsSandboxFlags.h for the possible flags
@ -1370,33 +1446,33 @@ class Document : public nsINode,
mozilla::Maybe<mozilla::dom::ClientState> GetClientState() const;
mozilla::Maybe<mozilla::dom::ServiceWorkerDescriptor> GetController() const;
// Returns the size of the mBlockedTrackingNodes array.
// Returns the size of the mBlockedNodesByClassifier array.
//
// This array contains nodes that have been blocked to prevent
// user tracking. They most likely have had their nsIChannel
// canceled by the URL classifier (Safebrowsing).
// This array contains nodes that have been blocked to prevent user tracking,
// fingerprinting, cryptomining, etc. They most likely have had their
// nsIChannel canceled by the URL classifier (Safebrowsing).
//
// A script can subsequently use GetBlockedTrackingNodes()
// A script can subsequently use GetBlockedNodesByClassifier()
// to get a list of references to these nodes.
//
// Note:
// This expresses how many tracking nodes have been blocked for this
// document since its beginning, not how many of them are still around
// in the DOM tree. Weak references to blocked nodes are added in the
// mBlockedTrackingNodesArray but they are not removed when those nodes
// are removed from the tree or even garbage collected.
long BlockedTrackingNodeCount() const {
return mBlockedTrackingNodes.Length();
// This expresses how many tracking nodes have been blocked for this document
// since its beginning, not how many of them are still around in the DOM tree.
// Weak references to blocked nodes are added in the mBlockedNodesByClassifier
// array but they are not removed when those nodes are removed from the tree
// or even garbage collected.
long BlockedNodeByClassifierCount() const {
return mBlockedNodesByClassifier.Length();
}
//
// Returns strong references to mBlockedTrackingNodes. (Document.h)
// Returns strong references to mBlockedNodesByClassifier. (Document.h)
//
// This array contains nodes that have been blocked to prevent
// user tracking. They most likely have had their nsIChannel
// canceled by the URL classifier (Safebrowsing).
//
already_AddRefed<nsSimpleContentList> BlockedTrackingNodes() const;
already_AddRefed<nsSimpleContentList> BlockedNodesByClassifier() const;
// Helper method that returns true if the document has storage-access sandbox
// flag.
@ -3248,10 +3324,10 @@ class Document : public nsINode,
/*
* Given a node, get a weak reference to it and append that reference to
* mBlockedTrackingNodes. Can be used later on to look up a node in it.
* mBlockedNodesByClassifier. Can be used later on to look up a node in it.
* (e.g., by the UI)
*/
void AddBlockedTrackingNode(nsINode* node) {
void AddBlockedNodeByClassifier(nsINode* node) {
if (!node) {
return;
}
@ -3259,7 +3335,7 @@ class Document : public nsINode,
nsWeakPtr weakNode = do_GetWeakReference(node);
if (weakNode) {
mBlockedTrackingNodes.AppendElement(weakNode);
mBlockedNodesByClassifier.AppendElement(weakNode);
}
}
@ -4248,7 +4324,7 @@ class Document : public nsINode,
// classifier. (Safebrowsing)
//
// Weak nsINode pointers are used to allow nodes to disappear.
nsTArray<nsWeakPtr> mBlockedTrackingNodes;
nsTArray<nsWeakPtr> mBlockedNodesByClassifier;
// Weak reference to mScriptGlobalObject QI:d to nsPIDOMWindow,
// updated on every set of mScriptGlobalObject.

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

@ -5407,6 +5407,30 @@ void nsGlobalWindowOuter::NotifyContentBlockingEvent(unsigned aEvent,
if (!aBlocked) {
unblocked = !doc->GetHasTrackingContentLoaded();
}
} else if (aEvent == nsIWebProgressListener::
STATE_BLOCKED_FINGERPRINTING_CONTENT) {
doc->SetHasFingerprintingContentBlocked(aBlocked, origin);
if (!aBlocked) {
unblocked = !doc->GetHasFingerprintingContentBlocked();
}
} else if (aEvent == nsIWebProgressListener::
STATE_LOADED_FINGERPRINTING_CONTENT) {
doc->SetHasFingerprintingContentLoaded(aBlocked, origin);
if (!aBlocked) {
unblocked = !doc->GetHasFingerprintingContentLoaded();
}
} else if (aEvent ==
nsIWebProgressListener::STATE_BLOCKED_CRYPTOMINING_CONTENT) {
doc->SetHasCryptominingContentBlocked(aBlocked, origin);
if (!aBlocked) {
unblocked = !doc->GetHasCryptominingContentBlocked();
}
} else if (aEvent ==
nsIWebProgressListener::STATE_LOADED_CRYPTOMINING_CONTENT) {
doc->SetHasCryptominingContentLoaded(aBlocked, origin);
if (!aBlocked) {
unblocked = !doc->GetHasCryptominingContentLoaded();
}
} else if (aEvent == nsIWebProgressListener::
STATE_COOKIES_BLOCKED_BY_PERMISSION) {
doc->SetHasCookiesBlockedByPermission(aBlocked, origin);

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

@ -51,6 +51,7 @@
#include "mozilla/dom/Element.h"
#include "mozilla/dom/ImageTracker.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/net/UrlClassifierFeatureFactory.h"
#include "mozilla/Preferences.h"
#ifdef LoadImage
@ -184,16 +185,18 @@ nsImageLoadingContent::Notify(imgIRequest* aRequest, int32_t aType,
nsresult errorCode = NS_OK;
aRequest->GetImageErrorCode(&errorCode);
/* Handle image not loading error because source was a tracking URL.
/* Handle image not loading error because source was a tracking URL (or
* fingerprinting, cryptomining, etc).
* We make a note of this image node by including it in a dedicated
* array of blocked tracking nodes under its parent document.
*/
if (errorCode == NS_ERROR_TRACKING_URI) {
if (net::UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(
errorCode)) {
nsCOMPtr<nsIContent> thisNode =
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
Document* doc = GetOurOwnerDoc();
doc->AddBlockedTrackingNode(thisNode);
doc->AddBlockedNodeByClassifier(thisNode);
}
}
nsresult status =

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

@ -90,6 +90,7 @@
#include "mozilla/dom/HTMLObjectElementBinding.h"
#include "mozilla/dom/HTMLEmbedElement.h"
#include "mozilla/dom/HTMLObjectElement.h"
#include "mozilla/net/UrlClassifierFeatureFactory.h"
#include "mozilla/LoadInfo.h"
#include "nsChannelClassifier.h"
#include "nsFocusManager.h"
@ -993,7 +994,7 @@ nsObjectLoadingContent::OnStartRequest(nsIRequest* aRequest,
return NS_ERROR_FAILURE;
}
if (status == NS_ERROR_TRACKING_URI) {
if (UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(status)) {
mContentBlockingEnabled = true;
return NS_ERROR_FAILURE;
}
@ -1017,14 +1018,15 @@ nsObjectLoadingContent::OnStopRequest(nsIRequest* aRequest,
nsresult aStatusCode) {
AUTO_PROFILER_LABEL("nsObjectLoadingContent::OnStopRequest", NETWORK);
// Handle object not loading error because source was a tracking URL.
// Handle object not loading error because source was a tracking URL (or
// fingerprinting, cryptomining, etc.).
// We make a note of this object node by including it in a dedicated
// array of blocked tracking nodes under its parent document.
if (aStatusCode == NS_ERROR_TRACKING_URI) {
if (UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aStatusCode)) {
nsCOMPtr<nsIContent> thisNode =
do_QueryInterface(static_cast<nsIObjectLoadingContent*>(this));
if (thisNode && thisNode->IsInComposedDoc()) {
thisNode->GetComposedDoc()->AddBlockedTrackingNode(thisNode);
thisNode->GetComposedDoc()->AddBlockedNodeByClassifier(thisNode);
}
}

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

@ -391,6 +391,10 @@ partial namespace ChromeUtils {
[ChromeOnly, Throws]
void registerWindowActor(DOMString aName, WindowActorOptions aOptions);
[ChromeOnly]
// aError should a nsresult.
boolean isClassifierBlockingErrorCode(unsigned long aError);
};
/**

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

@ -79,6 +79,7 @@
#include "mozilla/dom/VideoTrackList.h"
#include "mozilla/dom/WakeLock.h"
#include "mozilla/dom/power/PowerManagerService.h"
#include "mozilla/net/UrlClassifierFeatureFactory.h"
#include "nsAttrValueInlines.h"
#include "nsContentPolicyUtils.h"
#include "nsContentUtils.h"
@ -639,13 +640,15 @@ HTMLMediaElement::MediaLoadListener::OnStartRequest(nsIRequest* aRequest,
NS_ENSURE_SUCCESS(rv, rv);
if (NS_FAILED(status)) {
if (element) {
// Handle media not loading error because source was a tracking URL.
// Handle media not loading error because source was a tracking URL (or
// fingerprinting, cryptomining, etc).
// We make a note of this media node by including it in a dedicated
// array of blocked tracking nodes under its parent document.
if (status == NS_ERROR_TRACKING_URI) {
if (net::UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(
status)) {
Document* ownerDoc = element->OwnerDoc();
if (ownerDoc) {
ownerDoc->AddBlockedTrackingNode(element);
ownerDoc->AddBlockedNodeByClassifier(element);
}
}
element->NotifyLoadError(

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

@ -28,6 +28,7 @@
#include "mozilla/dom/Element.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/SRILogHelper.h"
#include "mozilla/net/UrlClassifierFeatureFactory.h"
#include "nsGkAtoms.h"
#include "nsNetUtil.h"
#include "nsGlobalWindowInner.h"
@ -3249,8 +3250,9 @@ void ScriptLoader::ReportErrorToConsole(ScriptLoadRequest* aRequest,
message = isScript ? "ScriptSourceMalformed" : "ModuleSourceMalformed";
} else if (aResult == NS_ERROR_DOM_BAD_URI) {
message = isScript ? "ScriptSourceNotAllowed" : "ModuleSourceNotAllowed";
} else if (aResult == NS_ERROR_TRACKING_URI) {
// Tracking protection errors already show their own console messages.
} else if (net::UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(
aResult)) {
// Blocking classifier error codes already show their own console messages.
return;
} else {
message = isScript ? "ScriptSourceLoadFailed" : "ModuleSourceLoadFailed";
@ -3285,13 +3287,15 @@ void ScriptLoader::ReportPreloadErrorsToConsole(ScriptLoadRequest* aRequest) {
void ScriptLoader::HandleLoadError(ScriptLoadRequest* aRequest,
nsresult aResult) {
/*
* Handle script not loading error because source was a tracking URL.
* Handle script not loading error because source was an tracking URL (or
* fingerprinting, cryptoming, etc).
* We make a note of this script node by including it in a dedicated
* array of blocked tracking nodes under its parent document.
*/
if (aResult == NS_ERROR_TRACKING_URI) {
if (net::UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(
aResult)) {
nsCOMPtr<nsIContent> cont = do_QueryInterface(aRequest->Element());
mDocument->AddBlockedTrackingNode(cont);
mDocument->AddBlockedNodeByClassifier(cont);
}
if (aRequest->IsModuleRequest() && !aRequest->mIsInline) {

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

@ -61,18 +61,19 @@ interface HTMLDocument : Document {
partial interface HTMLDocument {
/*
* Number of nodes that have been blocked by
* the Safebrowsing API to prevent tracking.
* Number of nodes that have been blocked by the Safebrowsing API to prevent
* tracking, cryptomining and so on. This method is for testing only.
*/
[ChromeOnly, Pure]
readonly attribute long blockedTrackingNodeCount;
readonly attribute long blockedNodeByClassifierCount;
/*
* List of nodes that have been blocked by
* the Safebrowsing API to prevent tracking.
* List of nodes that have been blocked by the Safebrowsing API to prevent
* tracking, fingerprinting, cryptomining and so on. This method is for
* testing only.
*/
[ChromeOnly, Pure]
readonly attribute NodeList blockedTrackingNodes;
readonly attribute NodeList blockedNodesByClassifier;
[ChromeOnly]
void userInteractionForTesting();

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

@ -16,11 +16,9 @@
#include "nsStyleStructInlines.h"
#include "UnitTransforms.h"
#define CLIP_LOG(...)
//#define CLIP_LOG(...) printf_stderr("CLIP: " __VA_ARGS__)
// clang-format off
#define CLIP_LOG(...)
//#define CLIP_LOG(...) printf_stderr("CLIP: " __VA_ARGS__)
//#define CLIP_LOG(...) if (XRE_IsContentProcess()) printf_stderr("CLIP: " __VA_ARGS__)
// clang-format on

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

@ -16,12 +16,11 @@
#include "mozilla/layers/SynchronousTask.h"
#include "TextDrawTarget.h"
// clang-format off
#define WRDL_LOG(...)
//#define WRDL_LOG(...) printf_stderr("WRDL(%p): " __VA_ARGS__)
//#define WRDL_LOG(...) if (XRE_IsContentProcess()) printf_stderr("WRDL(%p): "
//__VA_ARGS__)
//#define WRDL_LOG(...) if (XRE_IsContentProcess()) printf_stderr("WRDL(%p): " __VA_ARGS__)
// clang-format on
namespace mozilla {
namespace wr {

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

@ -238,3 +238,5 @@ XPC_MSG_DEF(NS_ERROR_TRACKING_URI , "The URI is tracking")
XPC_MSG_DEF(NS_ERROR_UNWANTED_URI , "The URI is unwanted")
XPC_MSG_DEF(NS_ERROR_BLOCKED_URI , "The URI is blocked")
XPC_MSG_DEF(NS_ERROR_HARMFUL_URI , "The URI is harmful")
XPC_MSG_DEF(NS_ERROR_FINGERPRINTING_URI , "The URI is fingerprinting")
XPC_MSG_DEF(NS_ERROR_CRYPTOMINING_URI , "The URI is cryptomining")

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

@ -7880,8 +7880,7 @@ bool nsDisplayTransform::CreateWebRenderCommands(
// If it looks like we're animated, we should rasterize in local space
// (disabling subpixel-aa and global pixel snapping)
bool animated =
ActiveLayerTracker::IsStyleMaybeAnimated(Frame(), eCSSProperty_transform);
bool animated = Frame()->HasAnimationOfTransform();
wr::StackingContextParams params;
params.mBoundTransform = &newTransformMatrix;

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

@ -88,7 +88,7 @@ fuzzy-if(gtkWidget||OSX,0-1,0-20) == mouse-click-overflow-auto-details.html over
== mouse-click-fixed-summary.html open-fixed-summary.html
== mouse-click-twice-fixed-summary.html fixed-summary.html
== mouse-click-float-details.html open-float-details.html
fuzzy(0-1,0-1) == mouse-click-twice-float-details.html float-details.html # Bug 1316430
fuzzy(0-4,0-1) == mouse-click-twice-float-details.html float-details.html # Bug 1316430
# Dispatch keyboard event to summary
== key-enter-single-summary.html open-single-summary.html

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

@ -46,6 +46,7 @@
#include "mozilla/dom/MediaList.h"
#include "mozilla/dom/ShadowRoot.h"
#include "mozilla/dom/URL.h"
#include "mozilla/net/UrlClassifierFeatureFactory.h"
#include "mozilla/AsyncEventDispatcher.h"
#include "mozilla/ServoBindings.h"
#include "mozilla/StyleSheet.h"
@ -595,20 +596,22 @@ nsresult SheetLoadData::VerifySheetReadyToParse(nsresult aStatus,
if (NS_FAILED(aStatus)) {
LOG_WARN(
(" Load failed: status 0x%" PRIx32, static_cast<uint32_t>(aStatus)));
// Handle sheet not loading error because source was a tracking URL.
// Handle sheet not loading error because source was a tracking URL (or
// fingerprinting, cryptomining, etc).
// We make a note of this sheet node by including it in a dedicated
// array of blocked tracking nodes under its parent document.
//
// Multiple sheet load instances might be tied to this request,
// we annotate each one linked to a valid owning element (node).
if (aStatus == NS_ERROR_TRACKING_URI) {
if (net::UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(
aStatus)) {
Document* doc = mLoader->GetDocument();
if (doc) {
for (SheetLoadData* data = this; data; data = data->mNext) {
// mOwningElement may be null but AddBlockTrackingNode can cope
nsCOMPtr<nsIContent> content =
do_QueryInterface(data->mOwningElement);
doc->AddBlockedTrackingNode(content);
doc->AddBlockedNodeByClassifier(content);
}
}
}

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

@ -380,6 +380,7 @@ opaque-types = [
# don't align properly on Linux 32-bit
"mozilla::SchedulerGroup", # Non-standard-layout packing of field into superclass
"mozilla::detail::GkAtoms", # https://bugzilla.mozilla.org/show_bug.cgi?id=1517685
"mozilla::detail::ThreadLocal.*",
]
# All cbindgen-types are in mod "structs::root::mozilla".

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

@ -213,15 +213,15 @@ inline void ThreadLocal<T, Storage>::set(const T aValue) {
#if (defined(XP_WIN) || defined(MACOSX_HAS_THREAD_LOCAL)) && \
!defined(__MINGW32__)
# define MOZ_THREAD_LOCAL(TYPE) \
thread_local mozilla::detail::ThreadLocal< \
TYPE, mozilla::detail::ThreadLocalNativeStorage>
thread_local ::mozilla::detail::ThreadLocal< \
TYPE, ::mozilla::detail::ThreadLocalNativeStorage>
#elif defined(HAVE_THREAD_TLS_KEYWORD)
# define MOZ_THREAD_LOCAL(TYPE) \
__thread mozilla::detail::ThreadLocal< \
TYPE, mozilla::detail::ThreadLocalNativeStorage>
__thread ::mozilla::detail::ThreadLocal< \
TYPE, ::mozilla::detail::ThreadLocalNativeStorage>
#else
# define MOZ_THREAD_LOCAL(TYPE) \
mozilla::detail::ThreadLocal<TYPE, mozilla::detail::ThreadLocalKeyStorage>
::mozilla::detail::ThreadLocal<TYPE, ::mozilla::detail::ThreadLocalKeyStorage>
#endif
} // namespace detail

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

@ -29,7 +29,8 @@ SimpleChannelParent::SetParentListener(HttpChannelParentListener* aListener) {
}
NS_IMETHODIMP
SimpleChannelParent::NotifyTrackingProtectionDisabled() {
SimpleChannelParent::NotifyChannelClassifierProtectionDisabled(
uint32_t aAcceptedReason) {
// Nothing to do.
return NS_OK;
}
@ -41,7 +42,7 @@ SimpleChannelParent::NotifyCookieAllowed() {
}
NS_IMETHODIMP
SimpleChannelParent::NotifyTrackingCookieBlocked(uint32_t aRejectedReason) {
SimpleChannelParent::NotifyCookieBlocked(uint32_t aRejectedReason) {
// Nothing to do.
return NS_OK;
}

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

@ -30,10 +30,10 @@ interface nsIParentChannel : nsIStreamListener
[noscript] void setParentListener(in HttpChannelParentListener listener);
/**
* Called to notify the HttpChannelChild that tracking protection was
* disabled for this load.
* Called to notify the HttpChannelChild that channel classifier protection
* was disabled for this load.
*/
[noscript] void notifyTrackingProtectionDisabled();
[noscript] void notifyChannelClassifierProtectionDisabled(in uint32_t aAcceptedReason);
/**
* Called to notify the HttpChannelChild that cookie has been allowed for
@ -45,7 +45,7 @@ interface nsIParentChannel : nsIStreamListener
* Called to notify the HttpChannelChild that cookie has been blocked for
* this load.
*/
[noscript] void notifyTrackingCookieBlocked(in uint32_t aRejectedReason);
[noscript] void notifyCookieBlocked(in uint32_t aRejectedReason);
/**
* Called to notify the HttpChannelChild that flash plugin state has changed.

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

@ -29,7 +29,8 @@ DataChannelParent::SetParentListener(HttpChannelParentListener *aListener) {
}
NS_IMETHODIMP
DataChannelParent::NotifyTrackingProtectionDisabled() {
DataChannelParent::NotifyChannelClassifierProtectionDisabled(
uint32_t aAcceptedReason) {
// Nothing to do.
return NS_OK;
}
@ -41,7 +42,7 @@ DataChannelParent::NotifyCookieAllowed() {
}
NS_IMETHODIMP
DataChannelParent::NotifyTrackingCookieBlocked(uint32_t aRejectedReason) {
DataChannelParent::NotifyCookieBlocked(uint32_t aRejectedReason) {
// Nothing to do.
return NS_OK;
}

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

@ -29,7 +29,8 @@ FileChannelParent::SetParentListener(HttpChannelParentListener *aListener) {
}
NS_IMETHODIMP
FileChannelParent::NotifyTrackingProtectionDisabled() {
FileChannelParent::NotifyChannelClassifierProtectionDisabled(
uint32_t aAcceptedReason) {
// Nothing to do.
return NS_OK;
}
@ -41,7 +42,7 @@ FileChannelParent::NotifyCookieAllowed() {
}
NS_IMETHODIMP
FileChannelParent::NotifyTrackingCookieBlocked(uint32_t aRejectedReason) {
FileChannelParent::NotifyCookieBlocked(uint32_t aRejectedReason) {
// Nothing to do.
return NS_OK;
}

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

@ -500,7 +500,8 @@ FTPChannelParent::SetParentListener(HttpChannelParentListener* aListener) {
}
NS_IMETHODIMP
FTPChannelParent::NotifyTrackingProtectionDisabled() {
FTPChannelParent::NotifyChannelClassifierProtectionDisabled(
uint32_t aAcceptedReason) {
// One day, this should probably be filled in.
return NS_OK;
}
@ -512,7 +513,7 @@ FTPChannelParent::NotifyCookieAllowed() {
}
NS_IMETHODIMP
FTPChannelParent::NotifyTrackingCookieBlocked(uint32_t aRejectedReason) {
FTPChannelParent::NotifyCookieBlocked(uint32_t aRejectedReason) {
// One day, this should probably be filled in.
return NS_OK;
}

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

@ -291,20 +291,24 @@ IPCResult HttpBackgroundChannelChild::RecvDivertMessages() {
return IPC_OK();
}
IPCResult HttpBackgroundChannelChild::RecvNotifyTrackingProtectionDisabled() {
IPCResult
HttpBackgroundChannelChild::RecvNotifyChannelClassifierProtectionDisabled(
const uint32_t& aAcceptedReason) {
LOG(
("HttpBackgroundChannelChild::RecvNotifyTrackingProtectionDisabled "
"[this=%p]\n",
this));
("HttpBackgroundChannelChild::"
"RecvNotifyChannelClassifierProtectionDisabled [this=%p "
"aAcceptedReason=%" PRIu32 "]\n",
this, aAcceptedReason));
MOZ_ASSERT(OnSocketThread());
if (NS_WARN_IF(!mChannelChild)) {
return IPC_OK();
}
// NotifyTrackingProtectionDisabled has no order dependency to OnStartRequest.
// It this be handled as soon as possible
mChannelChild->ProcessNotifyTrackingProtectionDisabled();
// NotifyChannelClassifierProtectionDisabled has no order dependency to
// OnStartRequest. It this be handled as soon as possible
mChannelChild->ProcessNotifyChannelClassifierProtectionDisabled(
aAcceptedReason);
return IPC_OK();
}
@ -323,18 +327,19 @@ IPCResult HttpBackgroundChannelChild::RecvNotifyCookieAllowed() {
return IPC_OK();
}
IPCResult HttpBackgroundChannelChild::RecvNotifyTrackingCookieBlocked(
IPCResult HttpBackgroundChannelChild::RecvNotifyCookieBlocked(
const uint32_t& aRejectedReason) {
LOG((
"HttpBackgroundChannelChild::RecvNotifyTrackingCookieBlocked [this=%p]\n",
this));
LOG(
("HttpBackgroundChannelChild::RecvNotifyCookieBlocked [this=%p "
"aRejectedReason=%" PRIu32 "]\n",
this, aRejectedReason));
MOZ_ASSERT(OnSocketThread());
if (NS_WARN_IF(!mChannelChild)) {
return IPC_OK();
}
mChannelChild->ProcessNotifyTrackingCookieBlocked(aRejectedReason);
mChannelChild->ProcessNotifyCookieBlocked(aRejectedReason);
return IPC_OK();
}

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

@ -63,12 +63,12 @@ class HttpBackgroundChannelChild final : public PHttpBackgroundChannelChild {
IPCResult RecvOnStartRequestSent() override;
IPCResult RecvNotifyTrackingProtectionDisabled() override;
IPCResult RecvNotifyChannelClassifierProtectionDisabled(
const uint32_t& aAcceptedReason) override;
IPCResult RecvNotifyCookieAllowed() override;
IPCResult RecvNotifyTrackingCookieBlocked(
const uint32_t& aRejectedReason) override;
IPCResult RecvNotifyCookieBlocked(const uint32_t& aRejectedReason) override;
IPCResult RecvNotifyTrackingResource(const bool& aIsThirdParty) override;

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

@ -315,11 +315,13 @@ bool HttpBackgroundChannelParent::OnDiversion() {
return true;
}
bool HttpBackgroundChannelParent::OnNotifyTrackingProtectionDisabled() {
bool HttpBackgroundChannelParent::OnNotifyChannelClassifierProtectionDisabled(
uint32_t aAcceptedReason) {
LOG(
("HttpBackgroundChannelParent::OnNotifyTrackingProtectionDisabled "
"[this=%p]\n",
this));
("HttpBackgroundChannelParent::"
"OnNotifyChannelClassifierProtectionDisabled [this=%p - "
"aAcceptedReason=%" PRIu32 "]\n",
this, aAcceptedReason));
AssertIsInMainProcess();
if (NS_WARN_IF(!mIPCOpened)) {
@ -328,12 +330,15 @@ bool HttpBackgroundChannelParent::OnNotifyTrackingProtectionDisabled() {
if (!IsOnBackgroundThread()) {
MutexAutoLock lock(mBgThreadMutex);
RefPtr<HttpBackgroundChannelParent> self = this;
nsresult rv = mBackgroundThread->Dispatch(
NewRunnableMethod(
NS_NewRunnableFunction(
"net::HttpBackgroundChannelParent::"
"OnNotifyTrackingProtectionDisabled",
this,
&HttpBackgroundChannelParent::OnNotifyTrackingProtectionDisabled),
"OnNotifyChannelClassifierProtectionDisabled",
[self, aAcceptedReason]() {
self->OnNotifyChannelClassifierProtectionDisabled(
aAcceptedReason);
}),
NS_DISPATCH_NORMAL);
MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
@ -341,7 +346,7 @@ bool HttpBackgroundChannelParent::OnNotifyTrackingProtectionDisabled() {
return NS_SUCCEEDED(rv);
}
return SendNotifyTrackingProtectionDisabled();
return SendNotifyChannelClassifierProtectionDisabled(aAcceptedReason);
}
bool HttpBackgroundChannelParent::OnNotifyCookieAllowed() {
@ -369,10 +374,12 @@ bool HttpBackgroundChannelParent::OnNotifyCookieAllowed() {
return SendNotifyCookieAllowed();
}
bool HttpBackgroundChannelParent::OnNotifyTrackingCookieBlocked(
bool HttpBackgroundChannelParent::OnNotifyCookieBlocked(
uint32_t aRejectedReason) {
LOG(("HttpBackgroundChannelParent::OnNotifyTrackingCookieBlocked [this=%p]\n",
this));
LOG(
("HttpBackgroundChannelParent::OnNotifyCookieBlocked [this=%p "
"aRejectedReason=%" PRIu32 "]\n",
this, aRejectedReason));
AssertIsInMainProcess();
if (NS_WARN_IF(!mIPCOpened)) {
@ -384,9 +391,9 @@ bool HttpBackgroundChannelParent::OnNotifyTrackingCookieBlocked(
RefPtr<HttpBackgroundChannelParent> self = this;
nsresult rv = mBackgroundThread->Dispatch(
NS_NewRunnableFunction(
"net::HttpBackgroundChannelParent::OnNotifyTrackingCookieBlocked",
"net::HttpBackgroundChannelParent::OnNotifyCookieBlocked",
[self, aRejectedReason]() {
self->OnNotifyTrackingCookieBlocked(aRejectedReason);
self->OnNotifyCookieBlocked(aRejectedReason);
}),
NS_DISPATCH_NORMAL);
@ -395,7 +402,7 @@ bool HttpBackgroundChannelParent::OnNotifyTrackingCookieBlocked(
return NS_SUCCEEDED(rv);
}
return SendNotifyTrackingCookieBlocked(aRejectedReason);
return SendNotifyCookieBlocked(aRejectedReason);
}
bool HttpBackgroundChannelParent::OnNotifyTrackingResource(bool aIsThirdParty) {

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

@ -63,14 +63,15 @@ class HttpBackgroundChannelParent final : public PHttpBackgroundChannelParent {
// over background channel.
bool OnDiversion();
// To send NotifyTrackingProtectionDisabled message over background channel.
bool OnNotifyTrackingProtectionDisabled();
// To send NotifyChannelClassifierProtectionDisabled message over background
// channel.
bool OnNotifyChannelClassifierProtectionDisabled(uint32_t aAcceptedReason);
// To send NotifyCookieAllowed message over background channel.
bool OnNotifyCookieAllowed();
// To send NotifyTrackingCookieBlocked message over background channel.
bool OnNotifyTrackingCookieBlocked(uint32_t aRejectedReason);
// To send NotifyCookieBlocked message over background channel.
bool OnNotifyCookieBlocked(uint32_t aRejectedReason);
// To send NotifyTrackingResource message over background channel.
bool OnNotifyTrackingResource(bool aIsThirdParty);

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

@ -45,6 +45,7 @@
#include "mozilla/AntiTrackingCommon.h"
#include "mozilla/dom/Performance.h"
#include "mozilla/dom/PerformanceStorage.h"
#include "mozilla/net/UrlClassifierFeatureFactory.h"
#include "mozilla/NullPrincipal.h"
#include "mozilla/Services.h"
#include "mozIThirdPartyUtil.h"
@ -4542,8 +4543,10 @@ HttpBaseChannel::GetNativeServerTiming(
}
NS_IMETHODIMP
HttpBaseChannel::CancelForTrackingProtection() {
return Cancel(NS_ERROR_TRACKING_URI);
HttpBaseChannel::CancelByChannelClassifier(nsresult aErrorCode) {
MOZ_ASSERT(
UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode));
return Cancel(aErrorCode);
}
void HttpBaseChannel::SetIPv4Disabled() { mCaps |= NS_HTTP_DISABLE_IPV4; }

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

@ -307,7 +307,7 @@ class HttpBaseChannel : public nsHashPropertyBag,
NS_IMETHOD SetLastRedirectFlags(uint32_t aValue) override;
NS_IMETHOD GetNavigationStartTimeStamp(TimeStamp *aTimeStamp) override;
NS_IMETHOD SetNavigationStartTimeStamp(TimeStamp aTimeStamp) override;
NS_IMETHOD CancelForTrackingProtection() override;
NS_IMETHOD CancelByChannelClassifier(nsresult aErrorCode) override;
virtual void SetIPv4Disabled(void) override;
virtual void SetIPv6Disabled(void) override;

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

@ -23,6 +23,7 @@
#include "mozilla/net/NeckoChild.h"
#include "mozilla/net/HttpChannelChild.h"
#include "mozilla/net/UrlClassifierCommon.h"
#include "mozilla/net/UrlClassifierFeatureFactory.h"
#include "AltDataOutputStreamChild.h"
#include "CookieServiceChild.h"
@ -1190,7 +1191,8 @@ void HttpChannelChild::DoOnStopRequest(nsIRequest* aRequest,
// NB: We use aChannelStatus here instead of mStatus because if there was an
// nsCORSListenerProxy on this request, it will override the tracking
// protection's return value.
if (aChannelStatus == NS_ERROR_TRACKING_URI ||
if (UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(
aChannelStatus) ||
aChannelStatus == NS_ERROR_MALWARE_URI ||
aChannelStatus == NS_ERROR_UNWANTED_URI ||
aChannelStatus == NS_ERROR_BLOCKED_URI ||
@ -1805,18 +1807,22 @@ void HttpChannelChild::ProcessFlushedForDiversion() {
mEventQ->RunOrEnqueue(new HttpFlushedForDiversionEvent(this), true);
}
void HttpChannelChild::ProcessNotifyTrackingProtectionDisabled() {
LOG(("HttpChannelChild::ProcessNotifyTrackingProtectionDisabled [this=%p]\n",
this));
void HttpChannelChild::ProcessNotifyChannelClassifierProtectionDisabled(
uint32_t aAcceptedReason) {
LOG(
("HttpChannelChild::ProcessNotifyChannelClassifierProtectionDisabled "
"[this=%p aAcceptedReason=%" PRIu32 "]\n",
this, aAcceptedReason));
MOZ_ASSERT(OnSocketThread());
RefPtr<HttpChannelChild> self = this;
nsCOMPtr<nsIEventTarget> neckoTarget = GetNeckoTarget();
neckoTarget->Dispatch(
NS_NewRunnableFunction(
"UrlClassifierCommon::NotifyTrackingProtectionDisabled",
[self]() {
UrlClassifierCommon::NotifyTrackingProtectionDisabled(self);
"AntiTrackingCommon::NotifyChannelClassifierProtectionDisabled",
[self, aAcceptedReason]() {
UrlClassifierCommon::NotifyChannelClassifierProtectionDisabled(
self, aAcceptedReason);
}),
NS_DISPATCH_NORMAL);
}
@ -1837,10 +1843,8 @@ void HttpChannelChild::ProcessNotifyCookieAllowed() {
NS_DISPATCH_NORMAL);
}
void HttpChannelChild::ProcessNotifyTrackingCookieBlocked(
uint32_t aRejectedReason) {
LOG(("HttpChannelChild::ProcessNotifyTrackingCookieBlocked [this=%p]\n",
this));
void HttpChannelChild::ProcessNotifyCookieBlocked(uint32_t aRejectedReason) {
LOG(("HttpChannelChild::ProcessNotifyCookieBlocked [this=%p]\n", this));
MOZ_ASSERT(OnSocketThread());
RefPtr<HttpChannelChild> self = this;

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

@ -261,9 +261,10 @@ class HttpChannelChild final : public PHttpChannelChild,
void ProcessOnStatus(const nsresult& aStatus);
void ProcessFlushedForDiversion();
void ProcessDivertMessages();
void ProcessNotifyTrackingProtectionDisabled();
void ProcessNotifyChannelClassifierProtectionDisabled(
uint32_t aAcceptedReason);
void ProcessNotifyCookieAllowed();
void ProcessNotifyTrackingCookieBlocked(uint32_t aRejectedReason);
void ProcessNotifyCookieBlocked(uint32_t aRejectedReason);
void ProcessNotifyTrackingResource(bool aIsThirdParty);
void ProcessNotifyFlashPluginStateChanged(
nsIHttpChannel::FlashPluginState aState);

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

@ -1786,12 +1786,17 @@ HttpChannelParent::SetParentListener(HttpChannelParentListener* aListener) {
}
NS_IMETHODIMP
HttpChannelParent::NotifyTrackingProtectionDisabled() {
LOG(("HttpChannelParent::NotifyTrackingProtectionDisabled [this=%p]\n",
this));
HttpChannelParent::NotifyChannelClassifierProtectionDisabled(
uint32_t aAcceptedReason) {
LOG(
("HttpChannelParent::NotifyChannelClassifierProtectionDisabled [this=%p "
"aAcceptedReason=%" PRIu32 "]\n",
this, aAcceptedReason));
if (!mIPCClosed) {
MOZ_ASSERT(mBgParent);
Unused << NS_WARN_IF(!mBgParent->OnNotifyTrackingProtectionDisabled());
Unused << NS_WARN_IF(
!mBgParent->OnNotifyChannelClassifierProtectionDisabled(
aAcceptedReason));
}
return NS_OK;
}
@ -1807,12 +1812,11 @@ HttpChannelParent::NotifyCookieAllowed() {
}
NS_IMETHODIMP
HttpChannelParent::NotifyTrackingCookieBlocked(uint32_t aRejectedReason) {
LOG(("HttpChannelParent::NotifyTrackingCookieBlocked [this=%p]\n", this));
HttpChannelParent::NotifyCookieBlocked(uint32_t aRejectedReason) {
LOG(("HttpChannelParent::NotifyCookieBlocked [this=%p]\n", this));
if (!mIPCClosed) {
MOZ_ASSERT(mBgParent);
Unused << NS_WARN_IF(
!mBgParent->OnNotifyTrackingCookieBlocked(aRejectedReason));
Unused << NS_WARN_IF(!mBgParent->OnNotifyCookieBlocked(aRejectedReason));
}
return NS_OK;
}

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

@ -54,14 +54,15 @@ child:
// OnDataAvailable and OnStopRequest messages in the queue back to the parent.
async DivertMessages();
// Tell the child that tracking protection was disabled for this load.
async NotifyTrackingProtectionDisabled();
// Tell the child that channel classifier protection was disabled for this
// load.
async NotifyChannelClassifierProtectionDisabled(uint32_t aAcceptedReason);
// Tell the child that cookies are allowed for this load.
async NotifyCookieAllowed();
// Tell the child that tracking cookies are blocked for this load.
async NotifyTrackingCookieBlocked(uint32_t aRejectedReason);
async NotifyCookieBlocked(uint32_t aRejectedReason);
// Tell the child that the resource being loaded is on the tracking
// protection list.

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

@ -610,7 +610,7 @@ TrackingDummyChannel::SetNavigationStartTimeStamp(
}
NS_IMETHODIMP
TrackingDummyChannel::CancelForTrackingProtection() {
TrackingDummyChannel::CancelByChannelClassifier(nsresult aErrorCode) {
return NS_ERROR_NOT_IMPLEMENTED;
}

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

@ -122,6 +122,7 @@
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/ServiceWorkerUtils.h"
#include "mozilla/net/AsyncUrlChannelClassifier.h"
#include "mozilla/net/UrlClassifierFeatureFactory.h"
#ifdef MOZ_TASK_TRACER
# include "GeckoTaskTracer.h"
@ -327,7 +328,7 @@ nsHttpChannel::nsHttpChannel()
mStronglyFramed(false),
mUsedNetwork(0),
mAuthConnectionRestartable(0),
mTrackingProtectionCancellationPending(0),
mChannelClassifierCancellationPending(0),
mAsyncResumePending(0),
mPushedStream(nullptr),
mLocalBlocklist(false),
@ -448,24 +449,27 @@ nsresult nsHttpChannel::PrepareToConnect() {
return OnBeforeConnect();
}
void nsHttpChannel::HandleContinueCancelledByTrackingProtection() {
void nsHttpChannel::HandleContinueCancellingByChannelClassifier(
nsresult aErrorCode) {
MOZ_ASSERT(
UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode));
MOZ_ASSERT(!mCallOnResume, "How did that happen?");
if (mSuspendCount) {
LOG(
("Waiting until resume HandleContinueCancelledByTrackingProtection "
("Waiting until resume HandleContinueCancellingByChannelClassifier "
"[this=%p]\n",
this));
mCallOnResume = [](nsHttpChannel *self) {
self->HandleContinueCancelledByTrackingProtection();
mCallOnResume = [aErrorCode](nsHttpChannel *self) {
self->HandleContinueCancellingByChannelClassifier(aErrorCode);
return NS_OK;
};
return;
}
LOG(("nsHttpChannel::HandleContinueCancelledByTrackingProtection [this=%p]\n",
LOG(("nsHttpChannel::HandleContinueCancellingByChannelClassifier [this=%p]\n",
this));
ContinueCancelledByTrackingProtection();
ContinueCancellingByChannelClassifier(aErrorCode);
}
void nsHttpChannel::HandleOnBeforeConnect() {
@ -5990,9 +5994,14 @@ nsHttpChannel::Cancel(nsresult status) {
MOZ_ASSERT(NS_IsMainThread());
// We should never have a pump open while a CORS preflight is in progress.
MOZ_ASSERT_IF(mPreflightChannel, !mCachePump);
MOZ_ASSERT(status != NS_ERROR_TRACKING_URI,
"NS_ERROR_TRACKING_URI needs to be handled by "
"CancelForTrackingProtection()");
#ifdef DEBUG
if (UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(status)) {
MOZ_CRASH_UNSAFE_PRINTF(
"Blocking classifier error %" PRIx32
" need to be handled by CancelByChannelClassifier()",
static_cast<uint32_t>(status));
}
#endif
LOG(("nsHttpChannel::Cancel [this=%p status=%" PRIx32 "]\n", this,
static_cast<uint32_t>(status)));
@ -6009,12 +6018,14 @@ nsHttpChannel::Cancel(nsresult status) {
}
NS_IMETHODIMP
nsHttpChannel::CancelForTrackingProtection() {
nsHttpChannel::CancelByChannelClassifier(nsresult aErrorCode) {
MOZ_ASSERT(
UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode));
MOZ_ASSERT(NS_IsMainThread());
// We should never have a pump open while a CORS preflight is in progress.
MOZ_ASSERT_IF(mPreflightChannel, !mCachePump);
LOG(("nsHttpChannel::CancelForTrackingProtection [this=%p]\n", this));
LOG(("nsHttpChannel::CancelByChannelClassifier [this=%p]\n", this));
if (mCanceled) {
LOG((" ignoring; already canceled\n"));
@ -6045,9 +6056,9 @@ nsHttpChannel::CancelForTrackingProtection() {
if (mSuspendCount) {
LOG(("Waiting until resume in Cancel [this=%p]\n", this));
MOZ_ASSERT(!mCallOnResume);
mTrackingProtectionCancellationPending = 1;
mCallOnResume = [](nsHttpChannel *self) {
self->HandleContinueCancelledByTrackingProtection();
mChannelClassifierCancellationPending = 1;
mCallOnResume = [aErrorCode](nsHttpChannel *self) {
self->HandleContinueCancellingByChannelClassifier(aErrorCode);
return NS_OK;
};
return NS_OK;
@ -6056,19 +6067,21 @@ nsHttpChannel::CancelForTrackingProtection() {
// Check to see if we should redirect this channel elsewhere by
// nsIHttpChannel.redirectTo API request
if (mAPIRedirectToURI) {
mTrackingProtectionCancellationPending = 1;
mChannelClassifierCancellationPending = 1;
return AsyncCall(&nsHttpChannel::HandleAsyncAPIRedirect);
}
return CancelInternal(NS_ERROR_TRACKING_URI);
return CancelInternal(aErrorCode);
}
void nsHttpChannel::ContinueCancelledByTrackingProtection() {
void nsHttpChannel::ContinueCancellingByChannelClassifier(nsresult aErrorCode) {
MOZ_ASSERT(
UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode));
MOZ_ASSERT(NS_IsMainThread());
// We should never have a pump open while a CORS preflight is in progress.
MOZ_ASSERT_IF(mPreflightChannel, !mCachePump);
LOG(("nsHttpChannel::ContinueCancelledByTrackingProtection [this=%p]\n",
LOG(("nsHttpChannel::ContinueCancellingByChannelClassifier [this=%p]\n",
this));
if (mCanceled) {
LOG((" ignoring; already canceled\n"));
@ -6082,14 +6095,14 @@ void nsHttpChannel::ContinueCancelledByTrackingProtection() {
return;
}
Unused << CancelInternal(NS_ERROR_TRACKING_URI);
Unused << CancelInternal(aErrorCode);
}
nsresult nsHttpChannel::CancelInternal(nsresult status) {
bool trackingProtectionCancellationPending =
!!mTrackingProtectionCancellationPending;
if (status == NS_ERROR_TRACKING_URI) {
mTrackingProtectionCancellationPending = 0;
bool channelClassifierCancellationPending =
!!mChannelClassifierCancellationPending;
if (UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(status)) {
mChannelClassifierCancellationPending = 0;
}
mCanceled = true;
@ -6105,9 +6118,9 @@ nsresult nsHttpChannel::CancelInternal(nsresult status) {
mRequestContext->CancelTailedRequest(this);
CloseCacheEntry(false);
Unused << AsyncAbort(status);
} else if (trackingProtectionCancellationPending) {
} else if (channelClassifierCancellationPending) {
// If we're coming from an asynchronous path when canceling a channel due
// to tracking protection, we need to AsyncAbort the channel now.
// to safe-browsing protection, we need to AsyncAbort the channel now.
Unused << AsyncAbort(status);
}
return NS_OK;
@ -6629,10 +6642,10 @@ nsresult nsHttpChannel::BeginConnectActual() {
AUTO_PROFILER_LABEL("nsHttpChannel::BeginConnectActual", NETWORK);
if (mTrackingProtectionCancellationPending) {
if (mChannelClassifierCancellationPending) {
LOG(
("Waiting for tracking protection cancellation in BeginConnectActual "
"[this=%p]\n",
("Waiting for safe-browsing protection cancellation in "
"BeginConnectActual [this=%p]\n",
this));
return NS_OK;
}

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

@ -169,7 +169,7 @@ class nsHttpChannel final : public HttpBaseChannel,
NS_IMETHOD SetChannelIsForDownload(bool aChannelIsForDownload) override;
NS_IMETHOD GetNavigationStartTimeStamp(TimeStamp *aTimeStamp) override;
NS_IMETHOD SetNavigationStartTimeStamp(TimeStamp aTimeStamp) override;
NS_IMETHOD CancelForTrackingProtection() override;
NS_IMETHOD CancelByChannelClassifier(nsresult aErrorCode) override;
// nsISupportsPriority
NS_IMETHOD SetPriority(int32_t value) override;
// nsIClassOfService
@ -310,9 +310,9 @@ class nsHttpChannel final : public HttpBaseChannel,
const std::function<nsresult(nsHttpChannel *)> &aFunc);
bool RequestIsConditional();
void HandleContinueCancelledByTrackingProtection();
void HandleContinueCancellingByChannelClassifier(nsresult aErrorCode);
nsresult CancelInternal(nsresult status);
void ContinueCancelledByTrackingProtection();
void ContinueCancellingByChannelClassifier(nsresult aErrorCode);
// Connections will only be established in this function.
// (including DNS prefetch and speculative connection.)
@ -679,10 +679,10 @@ class nsHttpChannel final : public HttpBaseChannel,
// the next authentication request can be sent on a whole new connection
uint32_t mAuthConnectionRestartable : 1;
// True if the channel classifier has marked the channel to be cancelled
// due to the tracking protection rules, but the asynchronous cancellation
// True if the channel classifier has marked the channel to be cancelled due
// to the safe-browsing classifier rules, but the asynchronous cancellation
// process hasn't finished yet.
uint32_t mTrackingProtectionCancellationPending : 1;
uint32_t mChannelClassifierCancellationPending : 1;
// True only when we are between Resume and async fire of mCallOnResume.
// Used to suspend any newly created pumps in mCallOnResume handler.

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

@ -352,11 +352,11 @@ interface nsIHttpChannelInternal : nsISupports
/**
* Cancel a channel because we have determined that it needs to be blocked
* for tracking protection. This is an internal API that is meant to be
* called by the channel classifier. Please DO NOT use this API if you don't
* know whether you should be using it.
* for safe-browsing protection. This is an internal API that is meant to
* be called by the channel classifier. Please DO NOT use this API if you
* don't know whether you should be using it.
*/
[noscript] void cancelForTrackingProtection();
[noscript] void cancelByChannelClassifier(in nsresult aErrorCode);
/**
* The channel will be loaded over IPv6, disabling IPv4.

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

@ -8,6 +8,7 @@
#include "mozilla/AntiTrackingCommon.h"
#include "mozilla/BasePrincipal.h"
#include "mozilla/net/UrlClassifierFeatureFactory.h"
#include "mozilla/StaticPrefs.h"
#include "mozIThirdPartyUtil.h"
#include "nsContentUtils.h"
@ -48,22 +49,22 @@ LazyLogModule UrlClassifierCommon::sLog("nsChannelClassifier");
return BasePrincipal::Cast(loadingPrincipal)->AddonAllowsLoad(aURI, true);
}
/* static */ void UrlClassifierCommon::NotifyTrackingProtectionDisabled(
nsIChannel* aChannel) {
/* static */ void
UrlClassifierCommon::NotifyChannelClassifierProtectionDisabled(
nsIChannel* aChannel, uint32_t aEvent) {
// Can be called in EITHER the parent or child process.
nsCOMPtr<nsIParentChannel> parentChannel;
NS_QueryNotificationCallbacks(aChannel, parentChannel);
if (parentChannel) {
// This channel is a parent-process proxy for a child process request.
// Tell the child process channel to do this instead.
parentChannel->NotifyTrackingProtectionDisabled();
parentChannel->NotifyChannelClassifierProtectionDisabled(aEvent);
return;
}
nsCOMPtr<nsIURI> uriBeingLoaded =
AntiTrackingCommon::MaybeGetDocumentURIBeingLoaded(aChannel);
NotifyChannelBlocked(aChannel, uriBeingLoaded,
nsIWebProgressListener::STATE_LOADED_TRACKING_CONTENT);
NotifyChannelBlocked(aChannel, uriBeingLoaded, aEvent);
}
/* static */ void UrlClassifierCommon::NotifyChannelBlocked(
@ -152,11 +153,33 @@ LazyLogModule UrlClassifierCommon::sLog("nsChannelClassifier");
aChannel, chanSpec.get()));
}
// Tracking protection will be disabled so update the security state
// of the document and fire a secure change event. If we can't get the
// window for the channel, then the shield won't show up so we can't send
// an event to the securityUI anyway.
UrlClassifierCommon::NotifyTrackingProtectionDisabled(aChannel);
// Channel classifier protection will be disabled so update the security
// state of the document and fire a secure change event. If we can't get the
// window for the channel, then the shield won't show up so we can't send an
// event to the securityUI anyway.
uint32_t event = 0;
switch (aBlockingPurpose) {
case AntiTrackingCommon::eTrackingProtection:
MOZ_FALLTHROUGH;
case AntiTrackingCommon::eTrackingAnnotations:
event = nsIWebProgressListener::STATE_LOADED_TRACKING_CONTENT;
break;
case AntiTrackingCommon::eFingerprinting:
event = nsIWebProgressListener::STATE_LOADED_FINGERPRINTING_CONTENT;
break;
case AntiTrackingCommon::eCryptomining:
event = nsIWebProgressListener::STATE_LOADED_CRYPTOMINING_CONTENT;
break;
default:
MOZ_CRASH("Invalidate blocking purpose.");
}
UrlClassifierCommon::NotifyChannelClassifierProtectionDisabled(aChannel,
event);
return false;
}
@ -223,10 +246,9 @@ LazyLogModule UrlClassifierCommon::sLog("nsChannelClassifier");
RefPtr<dom::Document> doc = docShell->GetDocument();
NS_ENSURE_TRUE(doc, NS_OK);
unsigned state;
if (aErrorCode == NS_ERROR_TRACKING_URI) {
state = nsIWebProgressListener::STATE_BLOCKED_TRACKING_CONTENT;
} else {
unsigned state =
UrlClassifierFeatureFactory::GetClassifierBlockingEventCode(aErrorCode);
if (!state) {
state = nsIWebProgressListener::STATE_BLOCKED_UNSAFE_CONTENT;
}
@ -237,12 +259,16 @@ LazyLogModule UrlClassifierCommon::sLog("nsChannelClassifier");
channel->GetURI(getter_AddRefs(uri));
NS_ConvertUTF8toUTF16 spec(uri->GetSpecOrDefault());
const char16_t* params[] = {spec.get()};
const char* message = (aErrorCode == NS_ERROR_TRACKING_URI)
? "TrackerUriBlocked"
: "UnsafeUriBlocked";
nsCString category = (aErrorCode == NS_ERROR_TRACKING_URI)
? NS_LITERAL_CSTRING("Tracking Protection")
: NS_LITERAL_CSTRING("Safe Browsing");
const char* message;
nsCString category;
if (UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode)) {
message = UrlClassifierFeatureFactory::
ClassifierBlockingErrorCodeToConsoleMessage(aErrorCode, category);
} else {
message = "UnsafeUriBlocked";
category = NS_LITERAL_CSTRING("Safe Browsing");
}
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, category, doc,
nsContentUtils::eNECKO_PROPERTIES, message,

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

@ -27,7 +27,8 @@ class UrlClassifierCommon final {
static bool AddonMayLoad(nsIChannel* aChannel, nsIURI* aURI);
static void NotifyTrackingProtectionDisabled(nsIChannel* aChannel);
static void NotifyChannelClassifierProtectionDisabled(
nsIChannel* aChannel, uint32_t aAcceptedReason);
static bool ShouldEnableClassifier(
nsIChannel* aChannel,

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

@ -136,8 +136,8 @@ UrlClassifierFeatureCryptomining::ProcessChannel(nsIChannel* aChannel,
// This is a blocking feature.
*aShouldContinue = false;
UrlClassifierCommon::SetBlockedContent(aChannel, NS_ERROR_TRACKING_URI, aList,
EmptyCString(), EmptyCString());
UrlClassifierCommon::SetBlockedContent(aChannel, NS_ERROR_CRYPTOMINING_URI,
aList, EmptyCString(), EmptyCString());
UC_LOG(
("UrlClassifierFeatureCryptomining::ProcessChannel, cancelling "
@ -145,12 +145,10 @@ UrlClassifierFeatureCryptomining::ProcessChannel(nsIChannel* aChannel,
aChannel));
nsCOMPtr<nsIHttpChannelInternal> httpChannel = do_QueryInterface(aChannel);
// FIXME: the way we cancel the channel depends on what the UI wants to show.
// This needs to change, at some point.
if (httpChannel) {
Unused << httpChannel->CancelForTrackingProtection();
Unused << httpChannel->CancelByChannelClassifier(NS_ERROR_CRYPTOMINING_URI);
} else {
Unused << aChannel->Cancel(NS_ERROR_TRACKING_URI);
Unused << aChannel->Cancel(NS_ERROR_CRYPTOMINING_URI);
}
return NS_OK;

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

@ -205,5 +205,75 @@ UrlClassifierFeatureFactory::CreateFeatureWithTables(
return feature.forget();
}
namespace {
struct BlockingErrorCode {
nsresult mErrorCode;
uint32_t mBlockingEventCode;
const char* mConsoleMessage;
nsCString mConsoleCategory;
};
static const BlockingErrorCode sBlockingErrorCodes[] = {
{NS_ERROR_TRACKING_URI,
nsIWebProgressListener::STATE_BLOCKED_TRACKING_CONTENT,
"TrackerUriBlocked", NS_LITERAL_CSTRING("Tracking Protection")},
{NS_ERROR_FINGERPRINTING_URI,
nsIWebProgressListener::STATE_BLOCKED_FINGERPRINTING_CONTENT,
"TrackerUriBlocked", NS_LITERAL_CSTRING("Tracking Protection")},
{NS_ERROR_CRYPTOMINING_URI,
nsIWebProgressListener::STATE_BLOCKED_CRYPTOMINING_CONTENT,
"TrackerUriBlocked", NS_LITERAL_CSTRING("Tracking Protection")},
};
} // namespace
/* static */ bool UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(
nsresult aError) {
// In theory we can iterate through the features, but at the moment, we can
// just have a simple check here.
for (const auto& blockingErrorCode : sBlockingErrorCodes) {
if (aError == blockingErrorCode.mErrorCode) {
return true;
}
}
return false;
}
/* static */ bool UrlClassifierFeatureFactory::IsClassifierBlockingEventCode(
uint32_t aEventCode) {
for (const auto& blockingErrorCode : sBlockingErrorCodes) {
if (aEventCode == blockingErrorCode.mBlockingEventCode) {
return true;
}
}
return false;
}
/* static */ uint32_t
UrlClassifierFeatureFactory::GetClassifierBlockingEventCode(
nsresult aErrorCode) {
for (const auto& blockingErrorCode : sBlockingErrorCodes) {
if (aErrorCode == blockingErrorCode.mErrorCode) {
return blockingErrorCode.mBlockingEventCode;
}
}
return 0;
}
/* static */ const char*
UrlClassifierFeatureFactory::ClassifierBlockingErrorCodeToConsoleMessage(
nsresult aError, nsACString& aCategory) {
for (const auto& blockingErrorCode : sBlockingErrorCodes) {
if (aError == blockingErrorCode.mErrorCode) {
aCategory = blockingErrorCode.mConsoleCategory;
return blockingErrorCode.mConsoleMessage;
}
}
return nullptr;
}
} // namespace net
} // namespace mozilla

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

@ -37,6 +37,20 @@ class UrlClassifierFeatureFactory final {
static already_AddRefed<nsIUrlClassifierFeature> CreateFeatureWithTables(
const nsACString& aName, const nsTArray<nsCString>& aBlacklistTables,
const nsTArray<nsCString>& aWhitelistTables);
// Returns true if this error is known as one of the blocking error codes.
static bool IsClassifierBlockingErrorCode(nsresult aError);
// Returns true if this event is a known blocking state from
// nsIWebProgressListener.
static bool IsClassifierBlockingEventCode(uint32_t aEventCode);
static uint32_t GetClassifierBlockingEventCode(nsresult aErrorCode);
// This can be called only if IsClassifierBlockingErrorCode(aError) returns
// true.
static const char* ClassifierBlockingErrorCodeToConsoleMessage(
nsresult aError, nsACString& aCategory);
};
} // namespace net

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

@ -138,8 +138,8 @@ UrlClassifierFeatureFingerprinting::ProcessChannel(nsIChannel* aChannel,
// This is a blocking feature.
*aShouldContinue = false;
UrlClassifierCommon::SetBlockedContent(aChannel, NS_ERROR_TRACKING_URI, aList,
EmptyCString(), EmptyCString());
UrlClassifierCommon::SetBlockedContent(aChannel, NS_ERROR_FINGERPRINTING_URI,
aList, EmptyCString(), EmptyCString());
UC_LOG(
("UrlClassifierFeatureFingerprinting::ProcessChannel, cancelling "
@ -147,12 +147,11 @@ UrlClassifierFeatureFingerprinting::ProcessChannel(nsIChannel* aChannel,
aChannel));
nsCOMPtr<nsIHttpChannelInternal> httpChannel = do_QueryInterface(aChannel);
// FIXME: the way we cancel the channel depends on what the UI wants to show.
// This needs to change, at some point.
if (httpChannel) {
Unused << httpChannel->CancelForTrackingProtection();
Unused << httpChannel->CancelByChannelClassifier(
NS_ERROR_FINGERPRINTING_URI);
} else {
Unused << aChannel->Cancel(NS_ERROR_TRACKING_URI);
Unused << aChannel->Cancel(NS_ERROR_FINGERPRINTING_URI);
}
return NS_OK;

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

@ -217,7 +217,8 @@ UrlClassifierFeatureTrackingAnnotation::ProcessChannel(nsIChannel* aChannel,
// are unblocked trackers on the site, so notify the UI that we loaded
// tracking content. UI code can treat this notification differently
// depending on whether TP is enabled or disabled.
UrlClassifierCommon::NotifyTrackingProtectionDisabled(aChannel);
UrlClassifierCommon::NotifyChannelClassifierProtectionDisabled(
aChannel, nsIWebProgressListener::STATE_LOADED_TRACKING_CONTENT);
if (StaticPrefs::privacy_trackingprotection_lower_network_priority()) {
LowerPriorityHelper(aChannel);

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

@ -148,7 +148,7 @@ UrlClassifierFeatureTrackingProtection::ProcessChannel(nsIChannel* aChannel,
aChannel));
nsCOMPtr<nsIHttpChannelInternal> httpChannel = do_QueryInterface(aChannel);
if (httpChannel) {
Unused << httpChannel->CancelForTrackingProtection();
Unused << httpChannel->CancelByChannelClassifier(NS_ERROR_TRACKING_URI);
} else {
Unused << aChannel->Cancel(NS_ERROR_TRACKING_URI);
}

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

@ -29,6 +29,7 @@
#include "mozilla/Logging.h"
#include "mozilla/Preferences.h"
#include "mozilla/net/UrlClassifierCommon.h"
#include "mozilla/net/UrlClassifierFeatureFactory.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/Services.h"
@ -284,7 +285,8 @@ void nsChannelClassifier::MarkEntryClassified(nsresult status) {
MOZ_ASSERT(XRE_IsParentProcess());
// Don't cache tracking classifications because we support allowlisting.
if (status == NS_ERROR_TRACKING_URI || mIsAllowListed) {
if (UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(status) ||
mIsAllowListed) {
return;
}
@ -389,7 +391,8 @@ nsChannelClassifier::OnClassifyComplete(nsresult aErrorCode,
const nsACString& aFullHash) {
// Should only be called in the parent process.
MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(aErrorCode != NS_ERROR_TRACKING_URI);
MOZ_ASSERT(
!UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode));
if (mSuspendedChannel) {
nsAutoCString errorName;

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

@ -178,6 +178,25 @@ void nsSecureBrowserUIImpl::CheckForContentBlockingEvents() {
mEvent |= STATE_LOADED_TRACKING_CONTENT;
}
// Has fingerprinting content been blocked or loaded?
if (doc->GetHasFingerprintingContentBlocked()) {
mEvent |= STATE_BLOCKED_FINGERPRINTING_CONTENT;
}
if (doc->GetHasFingerprintingContentLoaded()) {
mEvent |= STATE_LOADED_FINGERPRINTING_CONTENT;
}
// Has cryptomining content been blocked or loaded?
if (doc->GetHasCryptominingContentBlocked()) {
mEvent |= STATE_BLOCKED_CRYPTOMINING_CONTENT;
}
if (doc->GetHasCryptominingContentLoaded()) {
mEvent |= STATE_LOADED_CRYPTOMINING_CONTENT;
}
// Other block types.
if (doc->GetHasCookiesBlockedByPermission()) {
mEvent |= STATE_COOKIES_BLOCKED_BY_PERMISSION;
}

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

@ -1175,7 +1175,6 @@ win64-aarch64-nightly/opt:
extra-config:
stage_platform: win64-aarch64
mozconfig_platform: win64-aarch64
run-on-projects: ['mozilla-central', 'trunk', 'try']
toolchains:
- win64-clang-cl
- win64-aarch64-rust

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

@ -66,7 +66,7 @@ def filter_release_tasks(task, parameters):
if platform in (
'linux', 'linux64',
'macosx64',
'win32', 'win64',
'win32', 'win64', 'win64-aarch64',
):
if task.attributes['kind'] == 'l10n':
# This is on-change l10n

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

@ -257,7 +257,7 @@ var State = {
Cc["@mozilla.org/url-classifier/dbservice;1"].getService(Ci.nsIURIClassifier);
classifier.classify(principal, null, true,
(aErrorCode, aList, aProvider, aFullHash) => {
this._trackingState.set(host, aErrorCode == Cr.NS_ERROR_TRACKING_URI);
this._trackingState.set(host, ChromeUtils.IsClassifierBlockingErrorCode(aErrorCode));
});
}
return this._trackingState.get(host);

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

@ -1502,7 +1502,7 @@ nsresult AntiTrackingCommon::IsOnContentBlockingAllowList(
// This channel is a parent-process proxy for a child process request.
// Tell the child process channel to do this instead.
if (aDecision == BlockingDecision::eBlock) {
parentChannel->NotifyTrackingCookieBlocked(aRejectedReason);
parentChannel->NotifyCookieBlocked(aRejectedReason);
} else {
parentChannel->NotifyCookieAllowed();
}

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

@ -80,7 +80,7 @@ add_task(async function() {
{ expected: 3,
},
async function(obj) {
is(content.document.blockedTrackingNodeCount, obj.expected, "Expected tracking nodes found");
is(content.document.blockedNodeByClassifierCount, obj.expected, "Expected tracking nodes found");
});
info("Removing the tab");

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

@ -75,7 +75,7 @@ add_task(async function() {
{ expected: gExpectedResourcesSeen,
},
async function(obj) {
is(content.document.blockedTrackingNodeCount, obj.expected, "Expected tracking nodes found");
is(content.document.blockedNodeByClassifierCount, obj.expected, "Expected tracking nodes found");
});
info("Removing the tab");

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

@ -2356,6 +2356,46 @@ encoding:
- main
- content
startup:
profile_selection_reason:
bug_numbers:
- 1522934
description: >
How the profile was selected during startup. One of the following reasons:
unknown:
Generally should not happen, set as a default in case no other reason
occured.
profile-manager:
The profile was selected by the profile manager.
profile-reset:
The profile was selected for reset, normally this would mean a restart.
restart:
The user restarted the application, the same profile as previous will
be used.
argument-profile
The profile was selected by the --profile command line argument.
argument-p
The profile was selected by the -p command line argument.
firstrun-claimed-default
A first run of a dedicated profiles build chose the old default
profile to be the default for this install.
firstrun-skipped-default:
A first run of a dedicated profiles build skipped over the old default
profile and created a new profile.
firstrun-created-default:
A first run of the application created a new profile to use.
default:
The default profile was selected as normal.
expires: "72"
keyed: false
kind: string
notification_emails:
- dtownsend@mozilla.com
- rtestard@mozilla.com
release_channel_collection: opt-out
record_in_processes:
- main
# The following section is for probes testing the Telemetry system. They will not be
# submitted in pings and are only used for testing.
telemetry.test:

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

@ -55,8 +55,6 @@ const TOPIC_PROFILE_CHANGE_NET_TEARDOWN = "profile-change-net-teardown";
// Changing this pref requires a restart.
const IS_UNIFIED_TELEMETRY = Services.prefs.getBoolPref(TelemetryUtils.Preferences.Unified, false);
const PING_FORMAT_VERSION = 4;
const MS_IN_A_MINUTE = 60 * 1000;
const PING_TYPE_OPTOUT = "optout";
@ -1046,7 +1044,7 @@ var TelemetrySendImpl = {
},
_buildSubmissionURL(ping) {
const version = isV4PingFormat(ping) ? PING_FORMAT_VERSION : 1;
const version = isV4PingFormat(ping) ? AppConstants.TELEMETRY_PING_FORMAT_VERSION : 1;
return this._server + this._getSubmissionPath(ping) + "?v=" + version;
},

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

@ -0,0 +1,30 @@
"downgrade" ping
================
This ping is captured when attempting to use a profile that was previously used
with a newer version of the application.
This ping is submitted directly through the ```pingsender```. The common ping
data relates to the profile and application that the user attempted to use.
The client ID is submitted with this ping. No environment block is included with
this ping.
Structure:
.. code-block:: js
{
type: "downgrade",
... common ping data
clientId: <UUID>,
payload: {
lastVersion: "", // The last version of the application that ran this profile
hasSync: <bool>, // Whether the profile is signed in to sync
hasBinary: <bool>, // Whether the last version of the application is available to run
button: <int> // The button the user chose to click from the UI:
// 0 - Quit
// 1 - Create new profile
}
}

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

@ -0,0 +1,8 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
DEFINES['TELEMETRY_PING_FORMAT_VERSION'] = 4

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

@ -27,7 +27,7 @@ function checkLoads() {
window.parent.is(mediaItem1, "loaded", "Should not block tracking video");
window.parent.is(xhrItem, "loaded", "Should not block tracking XHR");
window.parent.is(fetchItem, "loaded", "Should not block fetches from tracking domains");
window.parent.is(window.document.blockedTrackingNodeCount, 0,
window.parent.is(window.document.blockedNodeByClassifierCount, 0,
"No elements should be blocked");
// End (parent) test.

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

@ -54,20 +54,20 @@ function checkLoads() {
window.parent.isnot(
style.visibility, "hidden", "Should not load tracking css");
window.parent.is(window.document.blockedTrackingNodeCount, badids.length,
window.parent.is(window.document.blockedNodeByClassifierCount, badids.length,
"Should identify all tracking elements");
var blockedTrackingNodes = window.document.blockedTrackingNodes;
var blockedNodes = window.document.blockedNodesByClassifier;
// Make sure that every node in blockedTrackingNodes exists in the tree
// Make sure that every node in blockedNodes exists in the tree
// (that may not always be the case but do not expect any nodes to disappear
// from the tree here)
var allNodeMatch = true;
for (let i = 0; i < blockedTrackingNodes.length; i++) {
for (let i = 0; i < blockedNodes.length; i++) {
let nodeMatch = false;
for (let j = 0; j < badids.length && !nodeMatch; j++) {
nodeMatch = nodeMatch ||
(blockedTrackingNodes[i] == document.getElementById(badids[j]));
(blockedNodes[i] == document.getElementById(badids[j]));
}
allNodeMatch = allNodeMatch && nodeMatch;
@ -76,18 +76,18 @@ function checkLoads() {
"All annotated nodes are expected in the tree");
// Make sure that every node with a badid (see badids) is found in the
// blockedTrackingNodes. This tells us if we are neglecting to annotate
// blockedNodes. This tells us if we are neglecting to annotate
// some nodes
allNodeMatch = true;
for (let j = 0; j < badids.length; j++) {
let nodeMatch = false;
for (let i = 0; i < blockedTrackingNodes.length && !nodeMatch; i++) {
for (let i = 0; i < blockedNodes.length && !nodeMatch; i++) {
nodeMatch = nodeMatch ||
(blockedTrackingNodes[i] == document.getElementById(badids[j]));
(blockedNodes[i] == document.getElementById(badids[j]));
}
if (!nodeMatch) {
console.log(badids[j] + " was not found in blockedTrackingNodes");
console.log(badids[j] + " was not found in blockedNodes");
}
allNodeMatch = allNodeMatch && nodeMatch;
}

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

@ -72,19 +72,19 @@ function checkLoads(aWindow, aBlocked) {
var style = win.document.defaultView.getComputedStyle(elt);
isnot(style.visibility, aBlocked ? "hidden" : "", "Should not load tracking css");
is(win.document.blockedTrackingNodeCount, aBlocked ? badids.length : 0, "Should identify all tracking elements");
is(win.document.blockedNodeByClassifierCount, aBlocked ? badids.length : 0, "Should identify all tracking elements");
var blockedTrackingNodes = win.document.blockedTrackingNodes;
var blockedNodes = win.document.blockedNodesByClassifier;
// Make sure that every node in blockedTrackingNodes exists in the tree
// Make sure that every node in blockedNodes exists in the tree
// (that may not always be the case but do not expect any nodes to disappear
// from the tree here)
var allNodeMatch = true;
for (let i = 0; i < blockedTrackingNodes.length; i++) {
for (let i = 0; i < blockedNodes.length; i++) {
let nodeMatch = false;
for (let j = 0; j < badids.length && !nodeMatch; j++) {
nodeMatch = nodeMatch ||
(blockedTrackingNodes[i] == win.document.getElementById(badids[j]));
(blockedNodes[i] == win.document.getElementById(badids[j]));
}
allNodeMatch = allNodeMatch && nodeMatch;
@ -92,14 +92,14 @@ function checkLoads(aWindow, aBlocked) {
is(allNodeMatch, true, "All annotated nodes are expected in the tree");
// Make sure that every node with a badid (see badids) is found in the
// blockedTrackingNodes. This tells us if we are neglecting to annotate
// blockedNodes. This tells us if we are neglecting to annotate
// some nodes
allNodeMatch = true;
for (let j = 0; j < badids.length; j++) {
let nodeMatch = false;
for (let i = 0; i < blockedTrackingNodes.length && !nodeMatch; i++) {
for (let i = 0; i < blockedNodes.length && !nodeMatch; i++) {
nodeMatch = nodeMatch ||
(blockedTrackingNodes[i] == win.document.getElementById(badids[j]));
(blockedNodes[i] == win.document.getElementById(badids[j]));
}
allNodeMatch = allNodeMatch && nodeMatch;

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

@ -61,7 +61,7 @@ function checkLoads(aWindow, aWhitelisted, tpEnabled) {
var win = aWindow.content;
if (!tpEnabled) {
is(win.document.getElementById("badscript").dataset.touched, "yes", "Should load tracking javascript");
is(win.document.blockedTrackingNodeCount, 0, "Should not identify any tracking elements");
is(win.document.blockedNodeByClassifierCount, 0, "Should not identify any tracking elements");
return;
}
@ -72,19 +72,19 @@ function checkLoads(aWindow, aWhitelisted, tpEnabled) {
if (!aWhitelisted) {
badids.push("goodscript");
}
is(win.document.blockedTrackingNodeCount, badids.length, "Should identify all tracking elements");
is(win.document.blockedNodeByClassifierCount, badids.length, "Should identify all tracking elements");
var blockedTrackingNodes = win.document.blockedTrackingNodes;
var blockedNodes = win.document.blockedNodesByClassifier;
// Make sure that every node in blockedTrackingNodes exists in the tree
// Make sure that every node in blockedNodes exists in the tree
// (that may not always be the case but do not expect any nodes to disappear
// from the tree here)
var allNodeMatch = true;
for (let i = 0; i < blockedTrackingNodes.length; i++) {
for (let i = 0; i < blockedNodes.length; i++) {
let nodeMatch = false;
for (let j = 0; j < badids.length && !nodeMatch; j++) {
nodeMatch = nodeMatch ||
(blockedTrackingNodes[i] == win.document.getElementById(badids[j]));
(blockedNodes[i] == win.document.getElementById(badids[j]));
}
allNodeMatch = allNodeMatch && nodeMatch;
@ -92,14 +92,14 @@ function checkLoads(aWindow, aWhitelisted, tpEnabled) {
is(allNodeMatch, true, "All annotated nodes are expected in the tree");
// Make sure that every node with a badid (see badids) is found in the
// blockedTrackingNodes. This tells us if we are neglecting to annotate
// blockedNodes. This tells us if we are neglecting to annotate
// some nodes
allNodeMatch = true;
for (let j = 0; j < badids.length; j++) {
let nodeMatch = false;
for (let i = 0; i < blockedTrackingNodes.length && !nodeMatch; i++) {
for (let i = 0; i < blockedNodes.length && !nodeMatch; i++) {
nodeMatch = nodeMatch ||
(blockedTrackingNodes[i] == win.document.getElementById(badids[j]));
(blockedNodes[i] == win.document.getElementById(badids[j]));
}
allNodeMatch = allNodeMatch && nodeMatch;

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

@ -14,33 +14,6 @@ XPCOMUtils.defineLazyServiceGetter(
"nsIToolkitProfileService"
);
// nsIToolkitProfileService.selectProfile can be used only during the selection
// of the profile in the ProfileManager. If we are showing about:profiles in a
// tab, the selectedProfile returns the default profile.
// In this function we use the ProfD to find the current profile.
function findCurrentProfile() {
let cpd;
try {
cpd = Services.dirsvc.get("ProfD", Ci.nsIFile);
} catch (e) {}
if (cpd) {
for (let profile of ProfileService.profiles) {
if (profile.rootDir.path == cpd.path) {
return profile;
}
}
}
// selectedProfile can throw if nothing is selected or if the selected profile
// has been deleted.
try {
return ProfileService.selectedProfile;
} catch (e) {
return null;
}
}
function refreshUI() {
let parent = document.getElementById("profiles");
while (parent.firstChild) {
@ -52,7 +25,7 @@ function refreshUI() {
defaultProfile = ProfileService.defaultProfile;
} catch (e) {}
let currentProfile = findCurrentProfile();
let currentProfile = ProfileService.currentProfile;
for (let profile of ProfileService.profiles) {
let isCurrentProfile = profile == currentProfile;
@ -197,10 +170,10 @@ function display(profileData) {
div.appendChild(sep);
}
// This is called from the createProfileWizard.xul dialog.
function CreateProfile(profile) {
ProfileService.selectedProfile = profile;
ProfileService.flush();
refreshUI();
// The wizard created a profile, just make it the default.
defaultProfile(profile);
}
function createProfileWizard() {
@ -269,30 +242,26 @@ async function removeProfile(profile) {
}
}
// If we are deleting the selected or the default profile we must choose a
// different one.
let isSelected = false;
try {
isSelected = ProfileService.selectedProfile == profile;
} catch (e) {}
// If we are deleting the default profile we must choose a different one.
let isDefault = false;
try {
isDefault = ProfileService.defaultProfile == profile;
} catch (e) {}
if (isSelected || isDefault) {
if (isDefault) {
for (let p of ProfileService.profiles) {
if (profile == p) {
continue;
}
if (isSelected) {
ProfileService.selectedProfile = p;
}
if (isDefault) {
try {
ProfileService.defaultProfile = p;
} catch (e) {
// This can happen on dev-edition if a non-default profile is in use.
// In such a case the next time that dev-edition is started it will
// find no default profile and just create a new one.
}
}
break;
@ -315,10 +284,19 @@ async function removeProfile(profile) {
refreshUI();
}
function defaultProfile(profile) {
async function defaultProfile(profile) {
try {
ProfileService.defaultProfile = profile;
ProfileService.selectedProfile = profile;
ProfileService.flush();
} catch (e) {
// This can happen on dev-edition.
let [title, msg] = await document.l10n.formatValues([
{ id: "profiles-cannot-set-as-default-title" },
{ id: "profiles-cannot-set-as-default-message" },
]);
Services.prompt.alert(window, title, msg);
}
refreshUI();
}

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

@ -12,6 +12,7 @@
<link rel="icon" type="image/png" id="favicon" href="chrome://branding/content/icon32.png" />
<link rel="stylesheet" href="chrome://mozapps/skin/aboutProfiles.css" type="text/css" />
<script type="application/javascript" src="chrome://global/content/aboutProfiles.js" />
<link rel="localization" href="branding/brand.ftl" />
<link rel="localization" href="toolkit/about/aboutProfiles.ftl" />
</head>
<body id="body" class="wide-container">

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

@ -0,0 +1,20 @@
<!-- 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:
This UI can be most easily shown by modifying the version in compatibility.ini
to a newer version and then starting Firefox.
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 "Youve launched an older version of Firefox">
<!ENTITY window.style "width: 490px;">
<!ENTITY window.nosync "Using an older version of Firefox can corrupt bookmarks and browsing history already saved to an existing Firefox profile. To protect your information, create a new profile for this installation of &brandShortName;.">
<!ENTITY window.sync "Using an older version of Firefox can corrupt bookmarks and browsing history already saved to an existing Firefox profile. To protect your information, create a new profile for this installation of &brandShortName;. You can always sign in with a &syncBrand.fxAccount.label; to sync your bookmarks and browsing history between profiles.">
<!ENTITY window.create "Create New Profile">
<!ENTITY window.quit-win "Exit">
<!ENTITY window.quit-nonwin "Quit">

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

@ -31,6 +31,9 @@ profiles-remove = Remove
profiles-set-as-default = Set as default profile
profiles-launch-profile = Launch profile in new browser
profiles-cannot-set-as-default-title = Unable to set default
profiles-cannot-set-as-default-message = The default profile cannot be changed for { -brand-short-name }.
profiles-yes = yes
profiles-no = no

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

@ -83,6 +83,9 @@
locale/@AB_CD@/mozapps/profile/createProfileWizard.dtd (%chrome/mozapps/profile/createProfileWizard.dtd)
locale/@AB_CD@/mozapps/profile/profileSelection.properties (%chrome/mozapps/profile/profileSelection.properties)
locale/@AB_CD@/mozapps/profile/profileSelection.dtd (%chrome/mozapps/profile/profileSelection.dtd)
#ifdef MOZ_BLOCK_PROFILE_DOWNGRADE
locale/@AB_CD@/mozapps/profile/profileDowngrade.dtd (%chrome/mozapps/profile/profileDowngrade.dtd)
#endif
#ifndef MOZ_FENNEC
locale/@AB_CD@/mozapps/update/updates.dtd (%chrome/mozapps/update/updates.dtd)
locale/@AB_CD@/mozapps/update/updates.properties (%chrome/mozapps/update/updates.properties)

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше