diff --git a/CLOBBER b/CLOBBER
index 6881acdc0fcf..a69337ad6c5e 100644
--- a/CLOBBER
+++ b/CLOBBER
@@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
-Bug 1210154 - Update the clang toolchain
+Bug 1215696 - Update mp4parse to v0.1.1
diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js
index 7acdef9e1527..88e5edac66da 100644
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -257,6 +257,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "ReaderMode",
XPCOMUtils.defineLazyModuleGetter(this, "ReaderParent",
"resource:///modules/ReaderParent.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "LoginManagerParent",
+ "resource://gre/modules/LoginManagerParent.jsm");
+
var gInitialPages = [
"about:blank",
"about:newtab",
@@ -1194,6 +1197,10 @@ var gBrowserInit = {
}
}, false, true);
+ gBrowser.addEventListener("InsecureLoginFormsStateChange", function() {
+ gIdentityHandler.refreshForInsecureLoginForms();
+ });
+
let uriToLoad = this._getUriToLoad();
if (uriToLoad && uriToLoad != "about:blank") {
if (uriToLoad instanceof Ci.nsISupportsArray) {
@@ -7056,9 +7063,7 @@ var gIdentityHandler = {
}
// Then, update the user interface with the available data.
- if (this._identityBox) {
- this.refreshIdentityBlock();
- }
+ this.refreshIdentityBlock();
// Handle a location change while the Control Center is focused
// by closing the popup (bug 1207542)
if (shouldHidePopup) {
@@ -7071,6 +7076,20 @@ var gIdentityHandler = {
// information we don't want to suddenly change the panel contents.
},
+ /**
+ * This is called asynchronously when requested by the Logins module, after
+ * the insecure login forms state for the page has been updated.
+ */
+ refreshForInsecureLoginForms() {
+ // Check this._uri because we don't want to refresh the user interface if
+ // this is called before the first page load in the window for any reason.
+ if (!this._uri) {
+ Cu.reportError("Unexpected early call to refreshForInsecureLoginForms.");
+ return;
+ }
+ this.refreshIdentityBlock();
+ },
+
/**
* Attempt to provide proper IDN treatment for host names
*/
@@ -7107,6 +7126,10 @@ var gIdentityHandler = {
* Updates the identity block user interface with the data from this object.
*/
refreshIdentityBlock() {
+ if (!this._identityBox) {
+ return;
+ }
+
let icon_label = "";
let tooltip = "";
let icon_country_label = "";
@@ -7175,6 +7198,11 @@ var gIdentityHandler = {
this._identityBox.classList.add("weakCipher");
}
}
+ if (LoginManagerParent.hasInsecureLoginForms(gBrowser.selectedBrowser)) {
+ // Insecure login forms can only be present on "unknown identity"
+ // pages, either already insecure or with mixed active content loaded.
+ this._identityBox.classList.add("insecureLoginForms");
+ }
tooltip = gNavigatorBundle.getString("identity.unknown.tooltip");
}
@@ -7212,6 +7240,12 @@ var gIdentityHandler = {
connection = "secure";
}
+ // Determine if there are insecure login forms.
+ let loginforms = "secure";
+ if (LoginManagerParent.hasInsecureLoginForms(gBrowser.selectedBrowser)) {
+ loginforms = "insecure";
+ }
+
// Determine the mixed content state.
let mixedcontent = [];
if (this._isMixedPassiveContentLoaded) {
@@ -7249,6 +7283,7 @@ var gIdentityHandler = {
for (let id of elementIDs) {
let element = document.getElementById(id);
updateAttribute(element, "connection", connection);
+ updateAttribute(element, "loginforms", loginforms);
updateAttribute(element, "ciphers", ciphers);
updateAttribute(element, "mixedcontent", mixedcontent);
updateAttribute(element, "isbroken", this._isBroken);
diff --git a/browser/base/content/test/general/browser.ini b/browser/base/content/test/general/browser.ini
index 0af044441ef3..c50ddb821f15 100644
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -268,7 +268,7 @@ tags = mcb
tags = mcb
[browser_bug906190.js]
tags = mcb
-skip-if = buildapp == "mulet" || e10s # Bug 1093642 - test manipulates content and relies on content focus
+skip-if = buildapp == "mulet" || e10s || os == "linux" # Bug 1093642 - test manipulates content and relies on content focus, Bug 1212520 - Re-enable on Linux
[browser_mixedContentFromOnunload.js]
tags = mcb
[browser_mixedContentFramesOnHttp.js]
@@ -322,6 +322,7 @@ skip-if = e10s # Bug 863514 - no gesture support.
[browser_homeDrop.js]
skip-if = buildapp == 'mulet'
[browser_identity_UI.js]
+[browser_insecureLoginForms.js]
[browser_keywordBookmarklets.js]
skip-if = e10s # Bug 1102025 - different principals for the bookmarklet only in e10s mode (unclear if test or 'real' issue)
[browser_keywordSearch.js]
diff --git a/browser/base/content/test/general/browser_insecureLoginForms.js b/browser/base/content/test/general/browser_insecureLoginForms.js
new file mode 100644
index 000000000000..fabb66cbfb91
--- /dev/null
+++ b/browser/base/content/test/general/browser_insecureLoginForms.js
@@ -0,0 +1,92 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// Load directly from the browser-chrome support files of login tests.
+const testUrlPath =
+ "://example.com/browser/toolkit/components/passwordmgr/test/browser/";
+
+/**
+ * Waits for the given number of occurrences of InsecureLoginFormsStateChange
+ * on the given browser element.
+ */
+function waitForInsecureLoginFormsStateChange(browser, count) {
+ return BrowserTestUtils.waitForEvent(browser, "InsecureLoginFormsStateChange",
+ false, () => --count == 0);
+}
+
+/**
+ * Checks the insecure login forms logic for the identity block.
+ */
+add_task(function* test_simple() {
+ for (let scheme of ["http", "https"]) {
+ let tab = gBrowser.addTab(scheme + testUrlPath + "form_basic.html");
+ let browser = tab.linkedBrowser;
+ yield Promise.all([
+ BrowserTestUtils.switchTab(gBrowser, tab),
+ BrowserTestUtils.browserLoaded(browser),
+ // One event is triggered by pageshow and one by DOMFormHasPassword.
+ waitForInsecureLoginFormsStateChange(browser, 2),
+ ]);
+
+ let { gIdentityHandler } = gBrowser.ownerGlobal;
+ gIdentityHandler._identityBox.click();
+ document.getElementById("identity-popup-security-expander").click();
+
+ if (scheme == "http") {
+ let identityBoxImage = gBrowser.ownerGlobal
+ .getComputedStyle(document.getElementById("page-proxy-favicon"), "")
+ .getPropertyValue("list-style-image");
+ let securityViewBG = gBrowser.ownerGlobal
+ .getComputedStyle(document.getElementById("identity-popup-securityView"), "")
+ .getPropertyValue("background-image");
+ let securityContentBG = gBrowser.ownerGlobal
+ .getComputedStyle(document.getElementById("identity-popup-security-content"), "")
+ .getPropertyValue("background-image");
+ is(identityBoxImage,
+ "url(\"chrome://browser/skin/identity-mixed-active-loaded.svg\")",
+ "Using expected icon image in the identity block");
+ is(securityViewBG,
+ "url(\"chrome://browser/skin/controlcenter/mcb-disabled.svg\")",
+ "Using expected icon image in the Control Center main view");
+ is(securityContentBG,
+ "url(\"chrome://browser/skin/controlcenter/mcb-disabled.svg\")",
+ "Using expected icon image in the Control Center subview");
+ }
+
+ // Messages should be visible when the scheme is HTTP, and invisible when
+ // the scheme is HTTPS.
+ is(Array.every(document.querySelectorAll("[when-loginforms=insecure]"),
+ element => !is_hidden(element)),
+ scheme == "http",
+ "The relevant messages should visible or hidden.");
+
+ gIdentityHandler._identityPopup.hidden = true;
+ gBrowser.removeTab(tab);
+ }
+});
+
+/**
+ * Checks that the insecure login forms logic does not regress mixed content
+ * blocking messages when mixed active content is loaded.
+ */
+add_task(function* test_mixedcontent() {
+ yield new Promise(resolve => SpecialPowers.pushPrefEnv({
+ "set": [["security.mixed_content.block_active_content", false]],
+ }, resolve));
+
+ // Load the page with the subframe in a new tab.
+ let tab = gBrowser.addTab("https" + testUrlPath + "insecure_test.html");
+ let browser = tab.linkedBrowser;
+ yield Promise.all([
+ BrowserTestUtils.switchTab(gBrowser, tab),
+ BrowserTestUtils.browserLoaded(browser),
+ // Two events are triggered by pageshow and one by DOMFormHasPassword.
+ waitForInsecureLoginFormsStateChange(browser, 3),
+ ]);
+
+ assertMixedContentBlockingState(browser, { activeLoaded: true,
+ activeBlocked: false,
+ passiveLoaded: false });
+
+ gBrowser.removeTab(tab);
+});
diff --git a/browser/base/content/test/general/head.js b/browser/base/content/test/general/head.js
index 86adcb9e53fc..c202c592a9e9 100644
--- a/browser/base/content/test/general/head.js
+++ b/browser/base/content/test/general/head.js
@@ -890,6 +890,13 @@ function assertMixedContentBlockingState(tabbrowser, states = {}) {
}
}
+ if (activeLoaded || activeBlocked || passiveLoaded) {
+ doc.getElementById("identity-popup-security-expander").click();
+ is(Array.filter(doc.querySelectorAll("[observes=identity-popup-mcb-learn-more]"),
+ element => !is_hidden(element)).length, 1,
+ "The 'Learn more' link should be visible once.");
+ }
+
gIdentityHandler._identityPopup.hidden = true;
}
diff --git a/browser/components/controlcenter/content/panel.inc.xul b/browser/components/controlcenter/content/panel.inc.xul
index 2648b93d8640..205a7df6ca83 100644
--- a/browser/components/controlcenter/content/panel.inc.xul
+++ b/browser/components/controlcenter/content/panel.inc.xul
@@ -41,6 +41,7 @@
&identity.activeLoaded;&identity.weakEncryption;
+ &identity.insecureLoginForms;
- &identity.description.insecure;
+ &identity.description.insecure;
+
+
+ &identity.description.insecureLoginForms;&identity.description.weakCipher;
@@ -138,8 +143,14 @@
class="identity-popup-warning-yellow">&identity.description.passiveLoaded3;
- &identity.description.activeLoaded;
- &identity.description.activeLoaded2;
+ &identity.description.activeLoaded;
+ &identity.description.activeLoaded2;
+
+ &identity.description.activeLoaded;