Bug 1039069 - Provide a popup about English for intl users.
MozReview-Commit-ID: DA3erj7qfsZ
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -550,16 +550,19 @@ pref("privacy.history.custom",
// 6 - Last 24 hours
pref("privacy.sanitize.timeSpan", 1);
pref("privacy.sanitize.sanitizeOnShutdown", false);
pref("privacy.sanitize.migrateFx3Prefs", false);
pref("privacy.panicButton.enabled", true);
+pref("privacy.resistFingerprinting", false);
+pref("privacy.spoof_english", 0);
+
// Time until temporary permissions expire, in ms
pref("privacy.temporary_permission_expire_time_ms", 3600000);
pref("network.proxy.share_proxy_settings", false); // use the same proxy settings for all protocols
// simple gestures support
pref("browser.gesture.swipe.left", "Browser:BackOrBackDuplicate");
pref("browser.gesture.swipe.right", "Browser:ForwardOrForwardDuplicate");
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -33,17 +33,17 @@ XPCOMUtils.defineLazyGetter(this, "exten
PluralForm:false, Preferences:false, PrivateBrowsingUtils:false,
ProcessHangMonitor:false, PromiseUtils:false, ReaderMode:false,
ReaderParent:false, RecentWindow:false, SessionStore:false,
ShortcutUtils:false, SimpleServiceDiscovery:false, SitePermissions:false,
Social:false, TabCrashHandler:false, Task:false, TelemetryStopwatch:false,
Translation:false, UITour:false, UpdateUtils:false, Weave:false,
WebNavigationFrames: false, fxAccounts:false, gDevTools:false,
gDevToolsBrowser:false, webrtcUI:false, FullZoomUI:false,
- Marionette:false,
+ Marionette:false, LanguagePrompt:false
*/
/**
* IF YOU ADD OR REMOVE FROM THIS LIST, PLEASE UPDATE THE LIST ABOVE AS WELL.
* XXX Bug 1325373 is for making eslint detect these automatically.
*/
[
["AboutHome", "resource:///modules/AboutHome.jsm"],
@@ -55,16 +55,17 @@ XPCOMUtils.defineLazyGetter(this, "exten
["Color", "resource://gre/modules/Color.jsm"],
["ContentSearch", "resource:///modules/ContentSearch.jsm"],
["Deprecated", "resource://gre/modules/Deprecated.jsm"],
["E10SUtils", "resource:///modules/E10SUtils.jsm"],
["ExtensionsUI", "resource:///modules/ExtensionsUI.jsm"],
["FormValidationHandler", "resource:///modules/FormValidationHandler.jsm"],
["FullZoomUI", "resource:///modules/FullZoomUI.jsm"],
["GMPInstallManager", "resource://gre/modules/GMPInstallManager.jsm"],
+ ["LanguagePrompt", "resource://gre/modules/LanguagePrompt.jsm"],
["LightweightThemeManager", "resource://gre/modules/LightweightThemeManager.jsm"],
["Log", "resource://gre/modules/Log.jsm"],
["LoginManagerParent", "resource://gre/modules/LoginManagerParent.jsm"],
["NewTabUtils", "resource://gre/modules/NewTabUtils.jsm"],
["PageThumbs", "resource://gre/modules/PageThumbs.jsm"],
["PluralForm", "resource://gre/modules/PluralForm.jsm"],
["Preferences", "resource://gre/modules/Preferences.jsm"],
["PrivateBrowsingUtils", "resource://gre/modules/PrivateBrowsingUtils.jsm"],
@@ -1712,16 +1713,19 @@ var gBrowserInit = {
gBrowser.tabContainer.addEventListener("TabSelect", function() {
for (let panel of document.querySelectorAll("panel[tabspecific='true']")) {
if (panel.state == "open") {
panel.hidePopup();
}
}
});
+
+ LanguagePrompt.init();
+
this.delayedStartupFinished = true;
_resolveDelayedStartup();
Services.obs.notifyObservers(window, "browser-delayed-startup-finished");
TelemetryTimestamps.add("delayedStartupFinished");
},
// Returns the URI(s) to load at startup.
@@ -1802,16 +1806,18 @@ var gBrowserInit = {
TrackingProtection.uninit();
RefreshBlocker.uninit();
CaptivePortalWatcher.uninit();
SidebarUI.uninit();
+ LanguagePrompt.uninit();
+
// Now either cancel delayedStartup, or clean up the services initialized from
// it.
if (this._boundDelayedStartup) {
this._cancelDelayedStartup();
} else {
if (Win7Features)
Win7Features.onCloseWindow();
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -440,16 +440,18 @@ offlineApps.allowStoring.label=Allow Sto
offlineApps.allowStoring.accesskey=A
offlineApps.dontAllow.label=Don’t Allow
offlineApps.dontAllow.accesskey=n
offlineApps.usage=This website (%S) is now storing more than %SMB of data on your computer for offline use.
offlineApps.manageUsage=Show settings
offlineApps.manageUsageAccessKey=S
+privacy.spoof_english = To give you more privacy, %S can request the English language version of web pages. This may cause web pages that you prefer to read in your native language to display in English instead.\n\nWould you like to request English language web pages for better privacy?
+
identity.identified.verifier=Verified by: %S
identity.identified.verified_by_you=You have added a security exception for this site.
identity.identified.state_and_country=%S, %S
identity.icon.tooltip=Show site information
identity.extension.label=Extension (%S)
identity.extension.tooltip=Loaded by extension: %S
identity.showDetails.tooltip=Show connection details
new file mode 100644
--- /dev/null
+++ b/toolkit/components/resistfingerprinting/LanguagePrompt.jsm
@@ -0,0 +1,102 @@
+// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
+/* 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/. */
+"use strict";
+
+this.EXPORTED_SYMBOLS = ["LanguagePrompt"];
+
+const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+const BROWSER_PROPERTIES = "chrome://browser/locale/browser.properties";
+const BRAND_PROPERTIES = "chrome://branding/locale/brand.properties";
+
+var LanguagePrompt = {
+ _prefSpoofEnglish: "privacy.spoof_english",
+ _prefResistFingerprinting: "privacy.resistFingerprinting",
+
+ _initialized: false,
+
+ init() {
+ if (this._initialized) {
+ return;
+ }
+ this._initialized = true;
+ Services.prefs.addObserver("privacy", this);
+ },
+
+ observe(subject, topic, data) {
+ if (topic != "nsPref:changed") {
+ return;
+ }
+ if (data == this._prefResistFingerprinting) {
+ if (Services.prefs.getBoolPref(this._prefResistFingerprinting)) {
+ // Ask the user if they want to make "English requests" if their default
+ // language isn't English and the prompt hasn't been displayed before.
+ if (this._getGeneralUseragentLocale().substring(0, 2) != "en" &&
+ !Services.prefs.getIntPref(this._prefSpoofEnglish)) {
+ this._promptForLanguagePreference();
+ }
+ } else {
+ Services.prefs.setIntPref(this._prefSpoofEnglish, 0);
+ }
+ } else if (data == this._prefSpoofEnglish) {
+ if (Services.prefs.getIntPref(this._prefSpoofEnglish) == 2) {
+ // spoof
+ Services.prefs.setCharPref("intl.accept_languages", "en-us, en");
+ Services.prefs.setBoolPref("javascript.use_us_english_locale", true);
+ } else {
+ // don't spoof
+ if (Services.prefs.prefHasUserValue("intl.accept_languages")) {
+ Services.prefs.clearUserPref("intl.accept_languages");
+ }
+ if (Services.prefs.prefHasUserValue("javascript.use_us_english_locale")) {
+ Services.prefs.clearUserPref("javascript.use_us_english_locale");
+ }
+ }
+ }
+ },
+
+ uninit() {
+ if (!this._initialized) {
+ return;
+ }
+ this._initialized = false;
+ Services.prefs.removeObserver("privacy", this);
+ },
+
+ _getGeneralUseragentLocale() {
+ try {
+ var locale = Services.prefs.getCharPref("general.useragent.locale");
+ if (/chrome:\/\//.test(locale)) {
+ return Services.prefs.getComplexValue("general.useragent.locale",
+ Components.interfaces.nsIPrefLocalizedString).data;
+ }
+ return locale;
+ } catch (err) {
+ dump("Error while getting general.useragent.locale:" + err + "\n");
+ return "en-US";
+ }
+ },
+
+ _promptForLanguagePreference() {
+ var prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"]
+ .getService(Components.interfaces.nsIPromptService);
+
+ // Display two buttons, both with string titles.
+ var flags = prompts.STD_YES_NO_BUTTONS;
+ let brandBundle = Services.strings.createBundle(BRAND_PROPERTIES);
+ let brandShortName = brandBundle.GetStringFromName("brandShortName");
+ let navigatorBundle = Services.strings.createBundle(BROWSER_PROPERTIES);
+ var message = navigatorBundle.formatStringFromName("privacy.spoof_english", [brandShortName], 1);
+
+ var response = prompts.confirmEx(null, "", message, flags, null, null, null, null, {value: false});
+
+ // Update preferences to reflect their response and to prevent the prompt from
+ // being displayed again.
+ Services.prefs.setIntPref(this._prefSpoofEnglish, response == 0 ? 2 : 1);
+ }
+};
--- a/toolkit/components/resistfingerprinting/moz.build
+++ b/toolkit/components/resistfingerprinting/moz.build
@@ -8,8 +8,12 @@ UNIFIED_SOURCES += [
'nsRFPService.cpp',
]
FINAL_LIBRARY = 'xul'
EXPORTS += [
'nsRFPService.h',
]
+
+EXTRA_JS_MODULES += [
+ 'LanguagePrompt.jsm',
+]