Bug 1333351 - Use RegExp to detect the autocomplete type. draft
authorSean Lee <selee@mozilla.com>
Fri, 24 Feb 2017 15:39:38 +0800
changeset 489932 6f435dff5baf376ff0ddfa00962a4ec3eea61362
parent 489583 f36062d04d165f6f6e781cf0633ffcbbebe6c273
child 547124 63189312070b757923da05b6d70a952b716071dd
push id46951
push userbmo:selee@mozilla.com
push dateMon, 27 Feb 2017 09:52:09 +0000
bugs1333351
milestone54.0a1
Bug 1333351 - Use RegExp to detect the autocomplete type. MozReview-Commit-ID: LWuIquwVnUA
browser/extensions/formautofill/FormAutofillHeuristics.jsm
--- a/browser/extensions/formautofill/FormAutofillHeuristics.jsm
+++ b/browser/extensions/formautofill/FormAutofillHeuristics.jsm
@@ -22,22 +22,128 @@ this.FormAutofillHeuristics = {
     "address-level2",
     "address-level1",
     "postal-code",
     "country",
     "tel",
     "email",
   ],
 
+  VALID_LABELS: {
+    "organization": new RegExp(
+      "company|busmness|organization|organisation" +
+      "|firma|firmenname" +   // de-DE
+      "|empresa" +            // es
+      "|societe|société" +    // fr-FR
+      "|ragione.?sociale" +   // it-IT
+      "|会社" +               // ja-JP
+      "|название.?компании" + // ru
+      "|單位|公司" +          // zh-TW
+      "|单位" +               // zh-CN
+      "|회사|직장",           // ko-KR
+      "i"
+    ),
+    "street-address": null,
+    "address-level2": null,
+    "address-level1": null,
+    "postal-code": new RegExp(
+      "zip|postal|post.*code|pcode" +
+      "|pin.?code" +               // en-IN
+      "|postleitzahl" +            // de-DE
+      "|\\bcp\\b" +                // es
+      "|\\bcdp\\b" +               // fr-FR
+      "|\\bcap\\b" +               // it-IT
+      "|郵便番号" +                // ja-JP
+      "|codigo|codpos|\\bcep\\b" + // pt-BR, pt-PT
+      "|Почтовый.?Индекс" +        // ru
+      "|邮政编码|邮编" +           // zh-CN
+      "|郵遞區號" +                // zh-TW
+      "|우편.?번호",               // ko-KR
+      "i"
+    ),
+    "country": new RegExp(
+      "country|countries" +
+      "|país|pais" + // es
+      "|国" +        // ja-JP
+      "|國家" +      // zh-TW
+      "|国家" +      // zh-CN
+      "|국가|나라",  // ko-KR
+      "i"
+    ),
+    "tel": new RegExp(
+      "phone|mobile|contact.?number" +
+      "|telefonnummer" +                             // de-DE
+      "|telefono|teléfono" +                         // es
+      "|telfixe" +                                   // fr-FR
+      "|電話" +                                      // ja-JP
+      "|telefone|telemovel" +                        // pt-BR, pt-PT
+      "|телефон" +                                   // ru
+      "|電話" +                                      // zh-TW
+      "|电话" +                                      // zh-CN
+      "|(?:전화|핸드폰|휴대폰|휴대전화)(?:.?번호)?", // ko-KR
+      "i"
+    ),
+    "email": new RegExp(
+      "e.?mail" +
+      "|courriel" +                                 // fr
+      "|メールアドレス" +                           // ja-JP
+      "|Электронной.?Почты" +                       // ru
+      "|邮件|邮箱" +                                // zh-CN
+      "|電郵地址|電子郵件" +                        // zh-TW
+      "|(?:이메일|전자.?우편|[Ee]-?mail)(.?주소)?", // ko-KR
+      "i"
+    ),
+  },
+
+  _findRelativeLabelElement(element) {
+    let label = document.querySelector('label[for="' + element.id + '"]');
+    if (label) {
+      return label;
+    }
+
+    if (!element.parentNode) {
+      return null;
+    }
+
+    let parent = element.parentNode;
+    if (!parent) {
+      return null;
+    }
+
+    do {
+      if (parent.tagName == "LABEL") {
+        return parent;
+      }
+      parent = parent.parentNode;
+    } while (parent);
+
+    return null;
+  },
+
   getInfo(element) {
     if (!(element instanceof Ci.nsIDOMHTMLInputElement)) {
       return null;
     }
 
     let info = element.getAutocompleteInfo();
-    if (!info || !info.fieldName ||
-        !this.VALID_FIELDS.includes(info.fieldName)) {
+    if (info && info.fieldName &&
+        this.VALID_FIELDS.includes(info.fieldName)) {
+      return info;
+    }
+
+    let label = this._findRelativeLabelElement(element);
+    if (!label) {
       return null;
     }
+    for (let fieldName in this.VALID_LABELS) {
+      if (this.VALID_LABELS[fieldName].test(label.textContent)) {
+        return {
+          fieldName,
+          section: null,
+          addressType: null,
+          contactType: null,
+        };
+      }
+    }
 
-    return info;
+    return null;
   },
 };