/* eslint-disable prettier/prettier */ /* eslint-disable no-useless-concat */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * Form Autofill field Heuristics RegExp. */ /* exported HeuristicsRegExp */ "use strict"; var HeuristicsRegExp = { RULES: { email: undefined, tel: undefined, organization: undefined, "street-address": undefined, "address-line1": undefined, "address-line2": undefined, "address-line3": undefined, "address-level2": undefined, "address-level1": undefined, "postal-code": undefined, country: undefined, // Note: We place the `cc-name` field for Credit Card first, because // it is more specific than the `name` field below and we want to check // for it before we catch the more generic one. "cc-name": undefined, name: undefined, "given-name": undefined, "additional-name": undefined, "family-name": undefined, "cc-number": undefined, "cc-exp-month": undefined, "cc-exp-year": undefined, "cc-exp": undefined, "cc-type": undefined, }, RULE_SETS: [ //========================================================================= // Firefox-specific rules { "address-line1": "addrline1|address_1", "address-line2": "addrline2|address_2", "address-line3": "addrline3|address_3", "address-level1": "land", // de-DE "additional-name": "apellido.?materno|lastlastname", "cc-name": "accountholdername" + "|titulaire", // fr-FR "cc-number": "(cc|kk)nr", // de-DE "cc-exp-month": "month" + "|(cc|kk)month", // de-DE "cc-exp-year": "year" + "|(cc|kk)year", // de-DE "cc-type": "type" + "|kartenmarke", // de-DE }, //========================================================================= // These are the rules used by Bitwarden [0], converted into RegExp form. // [0] https://github.com/bitwarden/browser/blob/c2b8802201fac5e292d55d5caf3f1f78088d823c/src/services/autofill.service.ts#L436 { email: "(^e-?mail$)|(^email-?address$)", tel: "(^phone$)" + "|(^mobile$)" + "|(^mobile-?phone$)" + "|(^tel$)" + "|(^telephone$)" + "|(^phone-?number$)", organization: "(^company$)" + "|(^company-?name$)" + "|(^organization$)" + "|(^organization-?name$)", "street-address": "(^address$)" + "|(^street-?address$)" + "|(^addr$)" + "|(^street$)" + "|(^mailing-?addr(ess)?$)" + // Modified to not grab lines, below "|(^billing-?addr(ess)?$)" + // Modified to not grab lines, below "|(^mail-?addr(ess)?$)" + // Modified to not grab lines, below "|(^bill-?addr(ess)?$)", // Modified to not grab lines, below "address-line1": "(^address-?1$)" + "|(^address-?line-?1$)" + "|(^addr-?1$)" + "|(^street-?1$)", "address-line2": "(^address-?2$)" + "|(^address-?line-?2$)" + "|(^addr-?2$)" + "|(^street-?2$)", "address-line3": "(^address-?3$)" + "|(^address-?line-?3$)" + "|(^addr-?3$)" + "|(^street-?3$)", "address-level2": "(^city$)" + "|(^town$)" + "|(^address-?level-?2$)" + "|(^address-?city$)" + "|(^address-?town$)", "address-level1": "(^state$)" + "|(^province$)" + "|(^provence$)" + "|(^address-?level-?1$)" + "|(^address-?state$)" + "|(^address-?province$)", "postal-code": "(^postal$)" + "|(^zip$)" + "|(^zip2$)" + "|(^zip-?code$)" + "|(^postal-?code$)" + "|(^post-?code$)" + "|(^address-?zip$)" + "|(^address-?postal$)" + "|(^address-?code$)" + "|(^address-?postal-?code$)" + "|(^address-?zip-?code$)", country: "(^country$)" + "|(^country-?code$)" + "|(^country-?name$)" + "|(^address-?country$)" + "|(^address-?country-?name$)" + "|(^address-?country-?code$)", name: "(^name$)|full-?name|your-?name", "given-name": "(^f-?name$)" + "|(^first-?name$)" + "|(^given-?name$)" + "|(^first-?n$)", "additional-name": "(^m-?name$)" + "|(^middle-?name$)" + "|(^additional-?name$)" + "|(^middle-?initial$)" + "|(^middle-?n$)" + "|(^middle-?i$)", "family-name": "(^l-?name$)" + "|(^last-?name$)" + "|(^s-?name$)" + "|(^surname$)" + "|(^family-?name$)" + "|(^family-?n$)" + "|(^last-?n$)", "cc-name": "cc-?name" + "|card-?name" + "|cardholder-?name" + "|cardholder" + // "|(^name$)" + // Removed to avoid overwriting "name", above. "|(^nom$)", "cc-number": "cc-?number" + "|cc-?num" + "|card-?number" + "|card-?num" + "|(^number$)" + "|(^cc$)" + "|cc-?no" + "|card-?no" + "|(^credit-?card$)" + "|numero-?carte" + "|(^carte$)" + "|(^carte-?credit$)" + "|num-?carte" + "|cb-?num", "cc-exp": "(^cc-?exp$)" + "|(^card-?exp$)" + "|(^cc-?expiration$)" + "|(^card-?expiration$)" + "|(^cc-?ex$)" + "|(^card-?ex$)" + "|(^card-?expire$)" + "|(^card-?expiry$)" + "|(^validite$)" + "|(^expiration$)" + "|(^expiry$)" + "|mm-?yy" + "|mm-?yyyy" + "|yy-?mm" + "|yyyy-?mm" + "|expiration-?date" + "|payment-?card-?expiration" + "|(^payment-?cc-?date$)", "cc-exp-month": "(^exp-?month$)" + "|(^cc-?exp-?month$)" + "|(^cc-?month$)" + "|(^card-?month$)" + "|(^cc-?mo$)" + "|(^card-?mo$)" + "|(^exp-?mo$)" + "|(^card-?exp-?mo$)" + "|(^cc-?exp-?mo$)" + "|(^card-?expiration-?month$)" + "|(^expiration-?month$)" + "|(^cc-?mm$)" + "|(^cc-?m$)" + "|(^card-?mm$)" + "|(^card-?m$)" + "|(^card-?exp-?mm$)" + "|(^cc-?exp-?mm$)" + "|(^exp-?mm$)" + "|(^exp-?m$)" + "|(^expire-?month$)" + "|(^expire-?mo$)" + "|(^expiry-?month$)" + "|(^expiry-?mo$)" + "|(^card-?expire-?month$)" + "|(^card-?expire-?mo$)" + "|(^card-?expiry-?month$)" + "|(^card-?expiry-?mo$)" + "|(^mois-?validite$)" + "|(^mois-?expiration$)" + "|(^m-?validite$)" + "|(^m-?expiration$)" + "|(^expiry-?date-?field-?month$)" + "|(^expiration-?date-?month$)" + "|(^expiration-?date-?mm$)" + "|(^exp-?mon$)" + "|(^validity-?mo$)" + "|(^exp-?date-?mo$)" + "|(^cb-?date-?mois$)" + "|(^date-?m$)", "cc-exp-year": "(^exp-?year$)" + "|(^cc-?exp-?year$)" + "|(^cc-?year$)" + "|(^card-?year$)" + "|(^cc-?yr$)" + "|(^card-?yr$)" + "|(^exp-?yr$)" + "|(^card-?exp-?yr$)" + "|(^cc-?exp-?yr$)" + "|(^card-?expiration-?year$)" + "|(^expiration-?year$)" + "|(^cc-?yy$)" + "|(^cc-?y$)" + "|(^card-?yy$)" + "|(^card-?y$)" + "|(^card-?exp-?yy$)" + "|(^cc-?exp-?yy$)" + "|(^exp-?yy$)" + "|(^exp-?y$)" + "|(^cc-?yyyy$)" + "|(^card-?yyyy$)" + "|(^card-?exp-?yyyy$)" + "|(^cc-?exp-?yyyy$)" + "|(^expire-?year$)" + "|(^expire-?yr$)" + "|(^expiry-?year$)" + "|(^expiry-?yr$)" + "|(^card-?expire-?year$)" + "|(^card-?expire-?yr$)" + "|(^card-?expiry-?year$)" + "|(^card-?expiry-?yr$)" + "|(^an-?validite$)" + "|(^an-?expiration$)" + "|(^annee-?validite$)" + "|(^annee-?expiration$)" + "|(^expiry-?date-?field-?year$)" + "|(^expiration-?date-?year$)" + "|(^cb-?date-?ann$)" + "|(^expiration-?date-?yy$)" + "|(^expiration-?date-?yyyy$)" + "|(^validity-?year$)" + "|(^exp-?date-?year$)" + "|(^date-?y$)", "cc-type": "(^cc-?type$)" + "|(^card-?type$)" + "|(^card-?brand$)" + "|(^cc-?brand$)" + "|(^cb-?type$)", }, //========================================================================= // These rules are from Chromium source codes [1]. Most of them // converted to JS format have the same meaning with the original ones except // the first line of "address-level1". // [1] https://source.chromium.org/chromium/chromium/src/+/master:components/autofill/core/common/autofill_regex_constants.cc { // ==== Email ==== email: "e.?mail" + "|courriel" + // fr "|correo.*electr(o|ó)nico" + // es-ES "|メールアドレス" + // ja-JP "|Электронной.?Почты" + // ru "|邮件|邮箱" + // zh-CN "|電郵地址" + // zh-TW "|ഇ-മെയില്‍|ഇലക്ട്രോണിക്.?" + "മെയിൽ" + // ml "|ایمیل|پست.*الکترونیک" + // fa "|ईमेल|इलॅक्ट्रॉनिक.?मेल" + // hi "|(\\b|_)eposta(\\b|_)" + // tr "|(?:이메일|전자.?우편|[Ee]-?mail)(.?주소)?", // ko-KR // ==== Telephone ==== tel: "phone|mobile|contact.?number" + "|telefonnummer" + // de-DE "|telefono|teléfono" + // es "|telfixe" + // fr-FR "|電話" + // ja-JP "|telefone|telemovel" + // pt-BR, pt-PT "|телефон" + // ru "|मोबाइल" + // hi for mobile "|(\\b|_|\\*)telefon(\\b|_|\\*)" + // tr "|电话" + // zh-CN "|മൊബൈല്‍" + // ml for mobile "|(?:전화|핸드폰|휴대폰|휴대전화)(?:.?번호)?", // ko-KR // ==== Address Fields ==== organization: "company|business|organization|organisation" + "|(? { if (set[name]) { // Add the rule. // We make the regex lower case so that we can match it against the // lower-cased field name and get a rough equivalent of a case-insensitive // match. This avoids a performance cliff with the "iu" flag on regular // expressions. rules.push(`(${set[name].toLowerCase()})`.normalize("NFKC")); } }); const value = new RegExp(rules.join("|"), "u"); Object.defineProperty(this.RULES, name, { get: undefined }); Object.defineProperty(this.RULES, name, { value }); return value; }, init() { Object.keys(this.RULES).forEach(field => Object.defineProperty(this.RULES, field, { get() { return HeuristicsRegExp._getRule(field); }, }) ); }, }; HeuristicsRegExp.init();