Bug 1168707 - Improve logging of FormLike objects with a toJSON method and add/improve some logging. r=dolske
authorMatthew Noorenberghe <mozilla@noorenberghe.ca>
Mon, 29 Jun 2015 00:11:29 -0700
changeset 250407 b2019a8bf74946b583eced862c4e5f83139e5e19
parent 250406 4bb0b566feb9a6b517e99988d1b6a0c2ecf6afa2
child 250408 54e05c26ea80884b9c55e5e7bffc7ff629cf4e40
push id28955
push usercbook@mozilla.com
push dateMon, 29 Jun 2015 12:14:53 +0000
treeherdermozilla-central@2b04d25fd77a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdolske
bugs1168707
milestone41.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1168707 - Improve logging of FormLike objects with a toJSON method and add/improve some logging. r=dolske
toolkit/components/passwordmgr/LoginManagerContent.jsm
--- a/toolkit/components/passwordmgr/LoginManagerContent.jsm
+++ b/toolkit/components/passwordmgr/LoginManagerContent.jsm
@@ -552,25 +552,25 @@ var LoginManagerContent = {
           break;
         }
       }
     }
 
     if (!usernameField)
       log("(form -- no username field found)");
     else
-      log("Username field id/name/value is: ", usernameField.id, " / ",
-          usernameField.name, " / ", usernameField.value);
+      log("Username field ", usernameField, "has name/value:",
+          usernameField.name, "/", usernameField.value);
 
     // If we're not submitting a form (it's a page load), there are no
     // password field values for us to use for identifying fields. So,
     // just assume the first password field is the one to be filled in.
     if (!isSubmission || pwFields.length == 1) {
       var passwordField = pwFields[0].element;
-      log("Password field id/name is: ", passwordField.id, " / ", passwordField.name);
+      log("Password field", passwordField, "has name: ", passwordField.name);
       return [usernameField, passwordField, null];
     }
 
 
     // Try to figure out WTF is in the form based on the password values.
     var oldPasswordField, newPasswordField;
     var pw1 = pwFields[0].element.value;
     var pw2 = pwFields[1].element.value;
@@ -902,16 +902,17 @@ var LoginManagerContent = {
         if (!disabledOrReadOnly && !userEnteredDifferentCase && userNameDiffers) {
           usernameField.setUserInput(selectedLogin.username);
         }
       }
       if (passwordField.value != selectedLogin.password) {
         passwordField.setUserInput(selectedLogin.password);
       }
 
+      log("_fillForm succeeded");
       recordAutofillResult(AUTOFILL_RESULT.FILLED);
       let doc = form.ownerDocument;
       let win = doc.defaultView;
       let messageManager = messageManagerFromWindow(win);
       messageManager.sendAsyncMessage("LoginStats:LoginFillSuccessful");
     } finally {
       Services.obs.notifyObservers(form, "passwordmgr-processed-form", null);
     }
@@ -1083,16 +1084,17 @@ let FormLikeFactory = {
       elements: [...aForm.elements],
       rootElement: aForm,
     };
 
     for (let prop of this._propsFromForm) {
       formLike[prop] = aForm[prop];
     }
 
+    this._addToJSONProperty(formLike);
     return formLike;
   },
 
   /**
    * Create a FormLike object from an <input type=password>.
    *
    * If the <input> is in a <form>, construct the FormLike from the form.
    * Otherwise, create a FormLike with a rootElement (wrapper) according to
@@ -1112,19 +1114,68 @@ let FormLikeFactory = {
     }
 
     if (aPasswordField.form) {
       return this.createFromForm(aPasswordField.form);
     }
 
     let doc = aPasswordField.ownerDocument;
     log("Created non-form FormLike for rootElement:", doc.documentElement);
-    return {
+    let formLike = {
       action: LoginUtils._getPasswordOrigin(doc.baseURI),
       autocomplete: "on",
       // Exclude elements inside the rootElement that are already in a <form> as
       // they will be handled by their own FormLike.
       elements: [for (el of doc.documentElement.querySelectorAll("input")) if (!el.form) el],
       ownerDocument: doc,
       rootElement: doc.documentElement,
     };
+
+    this._addToJSONProperty(formLike);
+    return formLike;
+  },
+
+  /**
+   * Add a `toJSON` property to a FormLike so logging which ends up going
+   * through dump doesn't include usless garbage from DOM objects.
+   */
+  _addToJSONProperty(aFormLike) {
+    function prettyElementOutput(aElement) {
+      let idText = aElement.id ? "#" + aElement.id : "";
+      let classText = [for (className of aElement.classList) "." + className].join("");
+      return `<${aElement.nodeName + idText + classText}>`;
+    }
+
+    Object.defineProperty(aFormLike, "toJSON", {
+      value: () => {
+        let cleansed = {};
+        for (let key of Object.keys(aFormLike)) {
+          let value = aFormLike[key];
+          let cleansedValue = value;
+
+          switch (key) {
+            case "elements": {
+              cleansedValue = [for (element of value) prettyElementOutput(element)];
+              break;
+            }
+
+            case "ownerDocument": {
+              cleansedValue = {
+                location: {
+                  href: value.location.href,
+                },
+              };
+              break;
+            }
+
+            case "rootElement": {
+              cleansedValue = prettyElementOutput(value);
+              break;
+            }
+          }
+
+          cleansed[key] = cleansedValue;
+        }
+        return cleansed;
+      }
+    });
   },
 };