diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index b87414286..3e73f39c4 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -1622,6 +1622,8 @@ pref("browser.pocket.oAuthConsumerKey", "40249-e88c401e1b1f2242d9e441c4"); pref("browser.pocket.useLocaleList", true); pref("browser.pocket.enabledLocales", "cs de en-GB en-US en-ZA es-ES es-MX fr hu it ja ja-JP-mac ko nl pl pt-BR pt-PT ru zh-CN zh-TW"); +pref("signon.privateBrowsingCapture.enabled", true); + pref("view_source.tab", true); pref("dom.webnotifications.serviceworker.enabled", true); diff --git a/browser/base/content/tab-content.js b/browser/base/content/tab-content.js index 57407c809..faade1aed 100644 --- a/browser/base/content/tab-content.js +++ b/browser/base/content/tab-content.js @@ -13,6 +13,8 @@ Cu.import("resource://gre/modules/ExtensionContent.jsm"); const g104FxForcePref = "tenfourfox.reader.force-enable"; // TenFourFox issue 583 const g104FxStickyPref = "tenfourfox.reader.sticky"; // TenFourFox issue 620 +const g104FxAutoPref = "tenfourfox.reader.auto."; // TenFourFox issue 636 + Cu.import("resource://gre/modules/Preferences.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "E10SUtils", @@ -262,6 +264,7 @@ var AboutReaderListener = { _articlePromise: null, _alwaysAllowReaderMode: true, // TenFourFox issue 583 _stickyReaderMode: true, // TenFourFox issue 620 + _currentURISpec: null, // TenFourFox issue 636 init: function() { addEventListener("AboutReaderContentLoaded", this, false, true); @@ -273,12 +276,15 @@ var AboutReaderListener = { Services.prefs.addObserver(g104FxForcePref, this, false); Services.prefs.addObserver(g104FxStickyPref, this, false); Services.obs.addObserver(this, "AboutReader:Ready", false); + /* content-document-global-created seems to NS_ASSERT */ + Services.obs.addObserver(this, "document-element-inserted", false); }, - // TenFourFox issue 583 + // TenFourFox issue 583 + 636 uninit: function() { Services.prefs.removeObserver(g104FxForcePref, this, false); Services.obs.removeObserver(this, "AboutReader:Ready"); + Services.obs.removeObserver(this, "document-element-inserted"); }, observe: function(subject, topic, data) { // jshint ignore:line if (topic === "nsPref:changed") { @@ -288,6 +294,54 @@ var AboutReaderListener = { if (topic === "AboutReader:Ready") { this.stickyReaderLinks(); } + if (topic === "document-element-inserted") { // TenFourFox issue 636 + this.doAutoReaderView(); + } + }, + + // TenFourFox issue 636 + doAutoReaderView: function() { + if (!content || this.isAboutReader) + return; + + if (!content.document.documentURI.startsWith("http:") && + !content.document.documentURI.startsWith("https")) { + /* could be another about: page, could be ftp, ... */ + this._currentURISpec = null; + return; + } + + /* if we ended up back here because we explicitly exited Reader View on + the same URL, then honour what the user probably wants. */ + let loc = content.document.location; + if (this._currentURISpec == loc.href) return; + this._currentURISpec = loc.href; + + /* process into an nsIURI. this gives us a reliable host *and* spec w/o ref */ + let uri = Services.io.newURI(loc.href, null, null); + if (uri && uri.host && uri.host.length && uri.host.length > 0) { + let w = null; + try { + w = Services.prefs.getCharPref(g104FxAutoPref + uri.host); + } catch(e) { } + if (w && w.length && w.length > 0) { + if (w == "y") { + this._currentURISpec = uri.specIgnoringRef; // might change + loc.replace("about:reader?url="+encodeURIComponent(uri.specIgnoringRef)); + return; + } + if (w == "s") { + if (uri.path && uri.path.length && uri.path != "" && uri.path != "/" + && !uri.path.startsWith("/?") + && !uri.path.toLowerCase().startsWith("/index.") + ) { + this._currentURISpec = uri.specIgnoringRef; // might change + loc.replace("about:reader?url="+encodeURIComponent(uri.specIgnoringRef)); + return; + } + } + } + } }, receiveMessage: function(message) { diff --git a/browser/components/preferences/in-content/security.js b/browser/components/preferences/in-content/security.js index fea9f5292..914f70a0e 100644 --- a/browser/components/preferences/in-content/security.js +++ b/browser/components/preferences/in-content/security.js @@ -99,23 +99,15 @@ var gSecurityPane = { /** * Enables/disables the Exceptions button used to configure sites where - * passwords are never saved. When browser is set to start in Private - * Browsing mode, the "Remember passwords" UI is useless, so we disable it. + * passwords are never saved. */ readSavePasswords: function () { - var pref = document.getElementById("signon.rememberSignons"); - var excepts = document.getElementById("passwordExceptions"); + var prefValue = document.getElementById("signon.rememberSignons").value; + document.getElementById("passwordExceptions").disabled = !prefValue; - if (PrivateBrowsingUtils.permanentPrivateBrowsing) { - document.getElementById("savePasswords").disabled = true; - excepts.disabled = true; - return false; - } else { - excepts.disabled = !pref.value; - // don't override pref value in UI - return undefined; - } + // don't override pref value in UI + return undefined; }, /** diff --git a/caps/nsScriptSecurityManager.cpp b/caps/nsScriptSecurityManager.cpp index f6f609d83..9c17a3e39 100644 --- a/caps/nsScriptSecurityManager.cpp +++ b/caps/nsScriptSecurityManager.cpp @@ -885,6 +885,7 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal, BLOK("static.yieldmo.com") || BLOK("ads.rubiconproject.com") || + BLOK("eus.rubiconproject.com") || BLOK("fastlane.rubiconproject.com") || BLOK("optimized-by.rubiconproject.com") || @@ -1262,6 +1263,10 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal, BLOK("tag.durationmedia.net") || + BLOK("www.datadoghq-browser-agent.com") || + + BLOK("ext.chtbl.com") || + #include "shavar-blocklist.h" 0) { diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 1b33d14e0..622320e4f 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -4106,6 +4106,7 @@ pref("signon.rememberSignons.visibilityToggle", false); #endif pref("signon.autofillForms", true); pref("signon.autologin.proxy", false); +pref("signon.privateBrowsingCapture.enabled", false); pref("signon.storeWhenAutocompleteOff", true); pref("signon.ui.experimental", false); pref("signon.debug", false); diff --git a/toolkit/components/passwordmgr/LoginHelper.jsm b/toolkit/components/passwordmgr/LoginHelper.jsm index b9ff8b010..3ccc63553 100644 --- a/toolkit/components/passwordmgr/LoginHelper.jsm +++ b/toolkit/components/passwordmgr/LoginHelper.jsm @@ -37,6 +37,8 @@ this.LoginHelper = { * Warning: this only updates if a logger was created. */ debug: Services.prefs.getBoolPref("signon.debug"), + privateBrowsingCaptureEnabled: + Services.prefs.getBoolPref("signon.privateBrowsingCapture.enabled"), createLogger(aLogPrefix) { let getMaxLogLevel = () => { @@ -54,6 +56,8 @@ this.LoginHelper = { // Watch for pref changes and update this.debug and the maxLogLevel for created loggers Services.prefs.addObserver("signon.", () => { this.debug = Services.prefs.getBoolPref("signon.debug"); + this.privateBrowsingCaptureEnabled = + Services.prefs.getBoolPref("signon.privateBrowsingCapture.enabled"); logger.maxLogLevel = getMaxLogLevel(); }, false); diff --git a/toolkit/components/passwordmgr/LoginManagerContent.jsm b/toolkit/components/passwordmgr/LoginManagerContent.jsm index 75fc97cf6..dcd661f75 100644 --- a/toolkit/components/passwordmgr/LoginManagerContent.jsm +++ b/toolkit/components/passwordmgr/LoginManagerContent.jsm @@ -752,7 +752,8 @@ var LoginManagerContent = { var doc = form.ownerDocument; var win = doc.defaultView; - if (PrivateBrowsingUtils.isContentWindowPrivate(win)) { + if (PrivateBrowsingUtils.isContentWindowPrivate(win) && + !LoginHelper.privateBrowsingCaptureEnabled) { // We won't do anything in private browsing mode anyway, // so there's no need to perform further checks. log("(form submission ignored in private browsing mode)"); diff --git a/toolkit/components/passwordmgr/LoginManagerParent.jsm b/toolkit/components/passwordmgr/LoginManagerParent.jsm index c17f3b619..6fe72744c 100644 --- a/toolkit/components/passwordmgr/LoginManagerParent.jsm +++ b/toolkit/components/passwordmgr/LoginManagerParent.jsm @@ -21,6 +21,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "LoginDoorhangers", "resource://gre/modules/LoginDoorhangers.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "LoginHelper", "resource://gre/modules/LoginHelper.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils", + "resource://gre/modules/PrivateBrowsingUtils.jsm"); XPCOMUtils.defineLazyGetter(this, "log", () => { let logger = LoginHelper.createLogger("LoginManagerParent"); @@ -435,6 +437,10 @@ var LoginManagerParent = { } function recordLoginUse(login) { + if (!target || PrivateBrowsingUtils.isBrowserPrivate(target)) { + // don't record non-interactive use in private browsing + return; + } // Update the lastUsed timestamp and increment the use count. let propBag = Cc["@mozilla.org/hash-property-bag;1"]. createInstance(Ci.nsIWritablePropertyBag); diff --git a/toolkit/components/passwordmgr/nsLoginManagerPrompter.js b/toolkit/components/passwordmgr/nsLoginManagerPrompter.js index e5f0b8407..245e18490 100644 --- a/toolkit/components/passwordmgr/nsLoginManagerPrompter.js +++ b/toolkit/components/passwordmgr/nsLoginManagerPrompter.js @@ -326,6 +326,12 @@ LoginManagerPrompter.prototype = { } }, + get _allowRememberLogin() { + if (!this._inPrivateBrowsing) { + return true; + } + return LoginHelper.privateBrowsingCaptureEnabled; + }, @@ -376,10 +382,8 @@ LoginManagerPrompter.prototype = { // If hostname is null, we can't save this login. if (hostname) { - var canRememberLogin; - if (this._inPrivateBrowsing) - canRememberLogin = false; - else + var canRememberLogin = false; + if (this._allowRememberLogin) canRememberLogin = (aSavePassword == Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY) && this._pwmgr.getLoginSavingEnabled(hostname); @@ -614,7 +618,7 @@ LoginManagerPrompter.prototype = { } var canRememberLogin = this._pwmgr.getLoginSavingEnabled(hostname); - if (this._inPrivateBrowsing) + if (!this._allowRememberLogin) canRememberLogin = false; // if checkboxLabel is null, the checkbox won't be shown at all. @@ -828,7 +832,7 @@ LoginManagerPrompter.prototype = { * This is "password-save" or "password-change" depending on the * original notification type. This is used for telemetry and tests. */ - _showLoginCaptureDoorhanger(login, type) { + _showLoginCaptureDoorhanger(login, type, options = {}) { let { browser } = this._getNotifyWindow(); let saveMsgNames = { @@ -1036,7 +1040,7 @@ LoginManagerPrompter.prototype = { "password-notification-icon", mainAction, secondaryActions, - { + Object.assign({ timeout: Date.now() + 10000, displayURI: Services.io.newURI(login.hostname, null, null), persistWhileVisible: true, @@ -1080,7 +1084,7 @@ LoginManagerPrompter.prototype = { } return false; }, - } + }, options) ); }, @@ -1120,7 +1124,9 @@ LoginManagerPrompter.prototype = { // Notification is a PopupNotification if (aNotifyObj == this._getPopupNote()) { - this._showLoginCaptureDoorhanger(aLogin, "password-save"); + this._showLoginCaptureDoorhanger(aLogin, "password-save", { + dismissed: this._inPrivateBrowsing, + }); } else { var notNowButtonText = this._getLocalizedString("notifyBarNotNowButtonText");