Bug 1300996 - Part 3: Handle the highlight style if the filled fields being changed by user. r=MattN, lchang
☠☠ backed out by a7bf7405ed8a ☠ ☠
authorRay Lin <ralin@mozilla.com>
Thu, 18 May 2017 10:11:22 +0800
changeset 413140 71ef10fe925e44b0b3e3ad10efeab9931d7bf39e
parent 413139 da12ceebe125788134a169e5fac186685423dd2b
child 413141 221b17bc902aa06c1f2800ce2c3ef7d7d24cba1f
push id1490
push usermtabara@mozilla.com
push dateMon, 31 Jul 2017 14:08:16 +0000
treeherdermozilla-release@70e32e6bf15e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMattN, lchang
bugs1300996
milestone55.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 1300996 - Part 3: Handle the highlight style if the filled fields being changed by user. r=MattN, lchang MozReview-Commit-ID: ITzE1GJ8Yu2
browser/extensions/formautofill/FormAutofillHandler.jsm
--- a/browser/extensions/formautofill/FormAutofillHandler.jsm
+++ b/browser/extensions/formautofill/FormAutofillHandler.jsm
@@ -129,18 +129,67 @@ FormAutofillHandler.prototype = {
             option.selected = true;
             element.dispatchEvent(new Event("input", {"bubbles": true}));
             element.dispatchEvent(new Event("change", {"bubbles": true}));
             this.changeFieldState(fieldDetail, "AUTO_FILLED");
             break;
           }
         }
       }
+
+      // Unlike using setUserInput directly, FormFillController dispatches an
+      // asynchronous "DOMAutoComplete" event with an "input" event follows right
+      // after. So, we need to suppress the first "input" event fired off from
+      // focused input to make sure the latter change handler won't be affected
+      // by auto filling.
+      if (element === focusedInput) {
+        const suppressFirstInputHandler = e => {
+          if (e.isTrusted) {
+            e.stopPropagation();
+            element.removeEventListener("input", suppressFirstInputHandler);
+          }
+        };
+
+        element.addEventListener("input", suppressFirstInputHandler);
+      }
       element.previewValue = "";
     }
+
+    // Handle the highlight style resetting caused by user's correction afterward.
+    log.debug("register change handler for filled form:", this.form);
+    const onChangeHandler = e => {
+      let hasFilledFields;
+
+      if (!e.isTrusted) {
+        return;
+      }
+
+      for (let fieldDetail of this.fieldDetails) {
+        let element = fieldDetail.elementWeakRef.get();
+
+        if (!element) {
+          return;
+        }
+
+        if (e.target == element || (e.target == element.form && e.type == "reset")) {
+          this.changeFieldState(fieldDetail, "NORMAL");
+        }
+
+        hasFilledFields |= (fieldDetail.state == "AUTO_FILLED");
+      }
+
+      // Unregister listeners once no field is in AUTO_FILLED state.
+      if (!hasFilledFields) {
+        this.form.rootElement.removeEventListener("input", onChangeHandler);
+        this.form.rootElement.removeEventListener("reset", onChangeHandler);
+      }
+    };
+
+    this.form.rootElement.addEventListener("input", onChangeHandler);
+    this.form.rootElement.addEventListener("reset", onChangeHandler);
   },
 
   /**
    * Populates result to the preview layers with given profile.
    *
    * @param {Object} profile
    *        A profile to be previewed with
    */