Bug 1418886 - Make LoginManagerContent use a WeakSet for login form root elements. r?MattN
MozReview-Commit-ID: HXLrJf2mR4B
--- a/toolkit/components/passwordmgr/LoginManagerContent.jsm
+++ b/toolkit/components/passwordmgr/LoginManagerContent.jsm
@@ -469,34 +469,36 @@ var LoginManagerContent = {
stateForDocument(document) {
let loginFormState = this.loginFormStateByDocument.get(document);
if (!loginFormState) {
loginFormState = {
/**
* Keeps track of filled fields and values.
*/
fillsByRootElement: new WeakMap(),
- loginFormRootElements: new Set(),
+ loginFormRootElements: new WeakSet(),
};
this.loginFormStateByDocument.set(document, loginFormState);
}
return loginFormState;
},
/**
* Compute whether there is an insecure login form on any frame of the current page, and
* notify the parent process. This is used to control whether insecure password UI appears.
*/
_detectInsecureFormLikes(topWindow) {
log("_detectInsecureFormLikes", topWindow.location.href);
// Returns true if this window or any subframes have insecure login forms.
let hasInsecureLoginForms = (thisWindow) => {
let doc = thisWindow.document;
- let hasLoginForm = this.stateForDocument(doc).loginFormRootElements.size > 0;
+ let rootElsWeakSet = this.stateForDocument(doc).loginFormRootElements;
+ let hasLoginForm = ChromeUtils.nondeterministicGetWeakSetKeys(rootElsWeakSet)
+ .filter(el => el.isConnected).length > 0;
return (hasLoginForm && !thisWindow.isSecureContext) ||
Array.some(thisWindow.frames,
frame => hasInsecureLoginForms(frame));
};
let messageManager = messageManagerFromWindow(topWindow);
messageManager.sendAsyncMessage("RemoteLogins:insecureLoginFormPresent", {
hasInsecureLoginForms: hasInsecureLoginForms(topWindow),
@@ -875,21 +877,27 @@ var LoginManagerContent = {
* To avoid multiple notifications for the same FormLike, this currently
* avoids capturing when dealing with a real <form> which are ideally already
* using a submit event.
*
* @param {Document} document being navigated
*/
_onNavigation(aDocument) {
let state = this.stateForDocument(aDocument);
- let loginFormRootElements = state.loginFormRootElements;
- log("_onNavigation: state:", state, "loginFormRootElements size:", loginFormRootElements.size,
+ let rootElsWeakSet = state.loginFormRootElements;
+ let weakLoginFormRootElements = ChromeUtils.nondeterministicGetWeakSetKeys(rootElsWeakSet);
+
+ log("_onNavigation: state:", state, "loginFormRootElements approx size:", weakLoginFormRootElements.length,
"document:", aDocument);
- for (let formRoot of state.loginFormRootElements) {
+ for (let formRoot of weakLoginFormRootElements) {
+ if (!formRoot.isConnected) {
+ continue;
+ }
+
if (formRoot instanceof Ci.nsIDOMHTMLFormElement) {
// For now only perform capture upon navigation for FormLike's without
// a <form> to avoid capture from both an earlyformsubmit and
// navigation for the same "form".
log("Ignoring navigation for the form root to avoid multiple prompts " +
"since it was for a real <form>");
continue;
}