Bug 1425261 - Improve the address line parser to detect address-line* more correctly. r=lchang draft
authorSean Lee <selee@mozilla.com>
Sun, 07 Jan 2018 15:42:41 +0800
changeset 716946 969b56ee8d1e6b8e8bf1fd178aa7526874a77cc7
parent 716014 3acb14b949150529ec761f845f9a3d61ee341dac
child 745112 fe6991b213204cf98a20b716b9e1da3561b5dc7b
push id94519
push userbmo:selee@mozilla.com
push dateSun, 07 Jan 2018 07:44:58 +0000
reviewerslchang
bugs1425261
milestone59.0a1
Bug 1425261 - Improve the address line parser to detect address-line* more correctly. r=lchang MozReview-Commit-ID: JHqKSnBZsVV
browser/extensions/formautofill/FormAutofillHeuristics.jsm
browser/extensions/formautofill/content/heuristicsRegexp.js
browser/extensions/formautofill/test/fixtures/autocomplete_basic.html
browser/extensions/formautofill/test/unit/heuristics/test_basic.js
browser/extensions/formautofill/test/unit/test_getAdaptedProfiles.js
--- a/browser/extensions/formautofill/FormAutofillHeuristics.jsm
+++ b/browser/extensions/formautofill/FormAutofillHeuristics.jsm
@@ -529,27 +529,61 @@ this.FormAutofillHeuristics = {
    * @param {FieldScanner} fieldScanner
    *        The current parsing status for all elements
    * @returns {boolean}
    *          Return true if there is any field can be recognized in the parser,
    *          otherwise false.
    */
   _parseAddressFields(fieldScanner) {
     let parsedFields = false;
-    let addressLines = ["address-line1", "address-line2", "address-line3"];
-    for (let i = 0; !fieldScanner.parsingFinished && i < addressLines.length; i++) {
+    const addressLines = ["address-line1", "address-line2", "address-line3"];
+    const addressLineRegexps = {
+      "address-line1": new RegExp(
+        "address[_-]?line(1|one)|address1|addr1" +
+        "|addrline1|address_1" + // Extra rules by Firefox
+        "|indirizzo1" + // it-IT
+        "|住所1" + // ja-JP
+        "|地址1" + // zh-CN
+        "|주소.?1", // ko-KR
+        "iu"
+      ),
+      "address-line2": new RegExp(
+        "address[_-]?line(2|two)|address2|addr2" +
+        "|addrline2|address_2" + // Extra rules by Firefox
+        "|indirizzo2" + // it-IT
+        "|住所2" + // ja-JP
+        "|地址2" + // zh-CN
+        "|주소.?2", // ko-KR
+        "iu"
+      ),
+      "address-line3": new RegExp(
+        "address[_-]?line(3|three)|address3|addr3" +
+        "|addrline3|address_3" + // Extra rules by Firefox
+        "|indirizzo3" + // it-IT
+        "|住所3" + // ja-JP
+        "|地址3" + // zh-CN
+        "|주소.?3", // ko-KR
+        "iu"
+      ),
+    };
+    while (!fieldScanner.parsingFinished) {
       let detail = fieldScanner.getFieldDetailByIndex(fieldScanner.parsingIndex);
-      if (!detail || !addressLines.includes(detail.fieldName)) {
+      if (!detail || !addressLines.includes(detail.fieldName) || detail._reason == "autocomplete") {
         // When the field is not related to any address-line[1-3] fields, it
         // means the parsing process can be terminated.
         break;
       }
-      fieldScanner.updateFieldName(fieldScanner.parsingIndex, addressLines[i]);
+      const elem = detail.elementWeakRef.get();
+      for (let regexp of Object.keys(addressLineRegexps)) {
+        if (this._matchRegexp(elem, addressLineRegexps[regexp])) {
+          fieldScanner.updateFieldName(fieldScanner.parsingIndex, regexp);
+          parsedFields = true;
+        }
+      }
       fieldScanner.parsingIndex++;
-      parsedFields = true;
     }
 
     return parsedFields;
   },
 
   /**
    * Try to look for expiration date fields and revise the field names if needed.
    *
--- a/browser/extensions/formautofill/content/heuristicsRegexp.js
+++ b/browser/extensions/formautofill/content/heuristicsRegexp.js
@@ -61,44 +61,47 @@ var HeuristicsRegExp = {
       "iu"
     ),
     "street-address": new RegExp(
       "streetaddress|street-address",
       "iu"
     ),
     "address-line1": new RegExp(
       "^address$|address[_-]?line(one)?|address1|addr1|street" +
+      "|addrline1|address_1" + // Extra rules by Firefox
       "|(?:shipping|billing)address$" +
       "|strasse|straße|hausnummer|housenumber" + // de-DE
       "|house.?name" + // en-GB
       "|direccion|dirección" + // es
       "|adresse" + // fr-FR
       "|indirizzo" + // it-IT
       "|^住所$|住所1" + // ja-JP
       "|morada|endereço" + // pt-BR, pt-PT
       "|Адрес" + // ru
       "|地址" + // zh-CN
       "|^주소.?$|주소.?1", // ko-KR
       "iu"
     ),
     "address-line2": new RegExp(
       "address[_-]?line(2|two)|address2|addr2|street|suite|unit" +
+      "|addrline2|address_2" + // Extra rules by Firefox
       "|adresszusatz|ergänzende.?angaben" + // de-DE
       "|direccion2|colonia|adicional" + // es
       "|addresssuppl|complementnom|appartement" + // fr-FR
       "|indirizzo2" + // it-IT
       "|住所2" + // ja-JP
       "|complemento|addrcomplement" + // pt-BR, pt-PT
       "|Улица" + // ru
       "|地址2" + // zh-CN
       "|주소.?2", // ko-KR
       "iu"
     ),
     "address-line3": new RegExp(
       "address[_-]?line(3|three)|address3|addr3|street|suite|unit" +
+      "|addrline3|address_3" + // Extra rules by Firefox
       "|adresszusatz|ergänzende.?angaben" + // de-DE
       "|direccion3|colonia|adicional" + // es
       "|addresssuppl|complementnom|appartement" + // fr-FR
       "|indirizzo3" + // it-IT
       "|住所3" + // ja-JP
       "|complemento|addrcomplement" + // pt-BR, pt-PT
       "|Улица" + // ru
       "|地址3" + // zh-CN
--- a/browser/extensions/formautofill/test/fixtures/autocomplete_basic.html
+++ b/browser/extensions/formautofill/test/fixtures/autocomplete_basic.html
@@ -35,11 +35,19 @@
     <p><label>cc-name <input type="text" id="B_cc-name" autocomplete="cc-name" /></label></p>
     <p><label>cc-exp-month <input type="text" id="B_cc-exp-month" autocomplete="cc-exp-month" /></label></p>
     <p><label>cc-exp-year <input type="text" id="B_cc-exp-year" autocomplete="cc-exp-year" /></label></p>
     <hr>
     <p><input type="submit" /></p>
     <p><button type="reset">Reset</button></p>
   </form>
 
+  <form id="formC">
+    <p><label><input type="text" name="someprefixAddrLine1" /></label></p>
+    <p><label>City: <input type="text" name="address-level2" /></label></p>
+    <p><label><input type="text" name="someprefixAddrLine2" /></label></p>
+    <p><label>Organization: <input type="text" name="organization" /></label></p>
+    <p><label><input type="text" name="someprefixAddrLine3" /></label></p>
+  </form>
+
 </body>
 </html>
 
--- a/browser/extensions/formautofill/test/unit/heuristics/test_basic.js
+++ b/browser/extensions/formautofill/test/unit/heuristics/test_basic.js
@@ -27,12 +27,19 @@ runHeuristicsTest([
         {"section": "", "addressType": "", "contactType": "", "fieldName": "country"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "tel"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "email"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-number"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-name"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-month"},
         {"section": "", "addressType": "", "contactType": "", "fieldName": "cc-exp-year"},
       ]],
+      [[
+        {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line1"},
+        {"section": "", "addressType": "", "contactType": "", "fieldName": "address-level2"},
+        {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line2"},
+        {"section": "", "addressType": "", "contactType": "", "fieldName": "organization"},
+        {"section": "", "addressType": "", "contactType": "", "fieldName": "address-line3"},
+      ]],
     ],
   },
 ], "../../fixtures/");
 
--- a/browser/extensions/formautofill/test/unit/test_getAdaptedProfiles.js
+++ b/browser/extensions/formautofill/test/unit/test_getAdaptedProfiles.js
@@ -126,18 +126,18 @@ const TESTCASES = [
                <input id="line1" autocomplete="address-line1">
                <input id="line3" autocomplete="address-line3">
                </form>`,
     profileData: [Object.assign({}, DEFAULT_ADDRESS_RECORD)],
     expectedResult: [{
       "guid": "123",
       "street-address": "2 Harrison St line2 line3",
       "-moz-street-address-one-line": "2 Harrison St line2 line3",
-      "address-line1": "2 Harrison St",
-      "address-line2": "line2 line3",
+      "address-line1": "2 Harrison St line2",
+      "address-line2": "line2",
       "address-line3": "line3",
       "address-level1": "CA",
       "country": "US",
       "tel": "+19876543210",
       "tel-national": "9876543210",
     }],
   },
   {