From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- browser/extensions/formautofill/.eslintrc.js | 82 ++ browser/extensions/formautofill/api.js | 222 ++++ browser/extensions/formautofill/background.js | 15 + .../formautofill/content/autofillEditForms.js | 644 ++++++++++ .../formautofill/content/customElements.js | 410 ++++++ .../formautofill/content/editAddress.xhtml | 134 ++ .../formautofill/content/editCreditCard.xhtml | 122 ++ .../extensions/formautofill/content/editDialog.js | 239 ++++ .../formautofill/content/formautofill.css | 54 + .../formautofill/content/formfill-anchor.svg | 8 + .../formautofill/content/icon-address-save.svg | 6 + .../formautofill/content/icon-address-update.svg | 6 + .../content/icon-credit-card-generic.svg | 8 + .../formautofill/content/icon-credit-card.svg | 8 + .../formautofill/content/manageAddresses.xhtml | 54 + .../formautofill/content/manageCreditCards.xhtml | 55 + .../formautofill/content/manageDialog.css | 125 ++ .../formautofill/content/manageDialog.js | 464 +++++++ .../content/third-party/cc-logo-amex.png | Bin 0 -> 1306 bytes .../content/third-party/cc-logo-amex@2x.png | Bin 0 -> 2311 bytes .../content/third-party/cc-logo-cartebancaire.png | Bin 0 -> 1240 bytes .../third-party/cc-logo-cartebancaire@2x.png | Bin 0 -> 3111 bytes .../content/third-party/cc-logo-diners.svg | 1 + .../content/third-party/cc-logo-discover.png | Bin 0 -> 1117 bytes .../content/third-party/cc-logo-discover@2x.png | Bin 0 -> 2471 bytes .../content/third-party/cc-logo-jcb.svg | 1 + .../content/third-party/cc-logo-mastercard.svg | 1 + .../content/third-party/cc-logo-mir.svg | 1 + .../content/third-party/cc-logo-unionpay.svg | 1 + .../content/third-party/cc-logo-visa.svg | 1 + .../extensions/formautofill/docs/heuristics.rst | 36 + browser/extensions/formautofill/docs/index.rst | 30 + browser/extensions/formautofill/jar.mn | 7 + .../locales/en-US/formautofill.properties | 127 ++ browser/extensions/formautofill/locales/jar.mn | 8 + browser/extensions/formautofill/locales/moz.build | 7 + browser/extensions/formautofill/manifest.json | 26 + browser/extensions/formautofill/moz.build | 58 + browser/extensions/formautofill/schema.json | 1 + .../formautofill/skin/linux/autocomplete-item.css | 10 + .../formautofill/skin/linux/editDialog.css | 8 + .../formautofill/skin/osx/autocomplete-item.css | 18 + .../formautofill/skin/osx/editDialog.css | 5 + .../skin/shared/autocomplete-item-shared.css | 188 +++ .../formautofill/skin/shared/editAddress.css | 134 ++ .../formautofill/skin/shared/editCreditCard.css | 53 + .../formautofill/skin/shared/editDialog-shared.css | 110 ++ .../skin/windows/autocomplete-item.css | 25 + .../formautofill/skin/windows/editDialog.css | 12 + .../formautofill/test/browser/address/browser.ini | 13 + .../address/browser_address_doorhanger_display.js | 240 ++++ .../browser/address/browser_address_telemetry.js | 691 +++++++++++ .../test/browser/address/head_address.js | 1 + .../formautofill/test/browser/browser.ini | 35 + .../test/browser/browser_autocomplete_footer.js | 137 +++ .../browser_autocomplete_marked_back_forward.js | 66 + .../browser_autocomplete_marked_detached_tab.js | 58 + .../browser/browser_autofill_address_select.js | 64 + .../browser/browser_autofill_duplicate_fields.js | 95 ++ .../test/browser/browser_check_installed.js | 12 + .../test/browser/browser_dropdown_layout.js | 53 + .../test/browser/browser_editAddressDialog.js | 951 ++++++++++++++ .../formautofill/test/browser/browser_fathom_cc.js | 204 +++ .../browser/browser_first_time_use_doorhanger.js | 142 +++ .../test/browser/browser_manageAddressesDialog.js | 105 ++ .../test/browser/browser_privacyPreferences.js | 439 +++++++ .../test/browser/browser_remoteiframe.js | 127 ++ .../browser/browser_submission_in_private_mode.js | 37 + .../test/browser/browser_update_doorhanger.js | 189 +++ .../test/browser/creditCard/browser.ini | 51 + .../creditCard/browser_anti_clickjacking.js | 123 ++ .../browser_creditCard_doorhanger_action.js | 170 +++ .../browser_creditCard_doorhanger_display.js | 311 +++++ .../browser_creditCard_doorhanger_fields.js | 198 +++ .../browser_creditCard_doorhanger_iframe.js | 103 ++ .../browser_creditCard_doorhanger_logo.js | 238 ++++ .../browser_creditCard_doorhanger_sync.js | 117 ++ .../browser_creditCard_dropdown_layout.js | 57 + .../browser_creditCard_fill_cancel_login.js | 37 + .../creditCard/browser_creditCard_heuristics.js | 165 +++ .../browser_creditCard_heuristics_cc_type.js | 77 ++ ...rowser_creditCard_submission_autodetect_type.js | 104 ++ .../browser_creditCard_submission_normalized.js | 109 ++ .../creditCard/browser_creditCard_telemetry.js | 872 +++++++++++++ .../creditCard/browser_editCreditCardDialog.js | 422 +++++++ .../browser/creditCard/browser_insecure_form.js | 145 +++ .../creditCard/browser_manageCreditCardsDialog.js | 290 +++++ .../test/browser/creditCard/head_cc.js | 1 + .../formautofill/test/browser/empty.html | 8 + .../formautofill/test/browser/fathom/test-setup.sh | 39 + .../browser/fathom/testing/resources/sample/1.svg | 3 + .../browser/fathom/testing/resources/sample/10.svg | 1 + .../browser/fathom/testing/resources/sample/11.png | Bin 0 -> 4968 bytes .../browser/fathom/testing/resources/sample/12.gif | Bin 0 -> 37 bytes .../browser/fathom/testing/resources/sample/13.svg | 16 + .../browser/fathom/testing/resources/sample/14.svg | 14 + .../browser/fathom/testing/resources/sample/15.svg | 1 + .../browser/fathom/testing/resources/sample/16.svg | 11 + .../browser/fathom/testing/resources/sample/17.bin | Bin 0 -> 9594 bytes .../browser/fathom/testing/resources/sample/18.svg | 1 + .../browser/fathom/testing/resources/sample/2.svg | 8 + .../browser/fathom/testing/resources/sample/3.svg | 1 + .../browser/fathom/testing/resources/sample/4.svg | 6 + .../browser/fathom/testing/resources/sample/5.svg | 6 + .../browser/fathom/testing/resources/sample/6.svg | 8 + .../fathom/testing/resources/sample/7.woff2 | Bin 0 -> 15480 bytes .../fathom/testing/resources/sample/8.woff2 | Bin 0 -> 15784 bytes .../fathom/testing/resources/sample/9.woff2 | Bin 0 -> 15908 bytes .../test/browser/fathom/testing/sample.html | 20 + .../test/browser/focus-leak/browser.ini | 12 + .../browser_iframe_typecontent_input_focus.js | 56 + .../doc_iframe_typecontent_input_focus.xhtml | 7 + .../doc_iframe_typecontent_input_focus_frame.html | 6 + .../extensions/formautofill/test/browser/head.js | 1094 ++++++++++++++++ .../test/browser/heuristics/browser.ini | 17 + .../heuristics/browser_autocomplete_off_on_form.js | 74 ++ .../browser_autocomplete_off_on_inputs.js | 102 ++ .../test/browser/heuristics/browser_basic.js | 69 ++ .../test/browser/heuristics/browser_cc_exp.js | 56 + .../test/browser/heuristics/browser_de_fields.js | 32 + .../test/browser/heuristics/browser_fr_fields.js | 27 + .../heuristics/browser_ignore_invisible_fields.js | 115 ++ .../browser/heuristics/browser_multiple_section.js | 118 ++ .../heuristics/browser_parseAddressFields.js | 138 +++ .../browser_section_validation_address.js | 79 ++ .../browser/heuristics/browser_sections_by_name.js | 318 +++++ .../browser/heuristics/third_party/browser.ini | 22 + .../heuristics/third_party/browser_BestBuy.js | 82 ++ .../browser/heuristics/third_party/browser_CDW.js | 71 ++ .../heuristics/third_party/browser_CostCo.js | 170 +++ .../heuristics/third_party/browser_DirectAsda.js | 25 + .../browser/heuristics/third_party/browser_Ebay.js | 25 + .../third_party/browser_GlobalDirectAsda.js | 24 + .../heuristics/third_party/browser_HomeDepot.js | 77 ++ .../heuristics/third_party/browser_Lufthansa.js | 28 + .../browser/heuristics/third_party/browser_Lush.js | 31 + .../heuristics/third_party/browser_Macys.js | 88 ++ .../heuristics/third_party/browser_NewEgg.js | 109 ++ .../heuristics/third_party/browser_OfficeDepot.js | 83 ++ .../browser/heuristics/third_party/browser_QVC.js | 96 ++ .../heuristics/third_party/browser_Sears.js | 81 ++ .../heuristics/third_party/browser_Staples.js | 78 ++ .../heuristics/third_party/browser_Walmart.js | 93 ++ .../test/fixtures/autocomplete_address_basic.html | 26 + .../test/fixtures/autocomplete_basic.html | 52 + .../fixtures/autocomplete_creditcard_basic.html | 29 + .../autocomplete_creditcard_cc_exp_field.html | 28 + .../fixtures/autocomplete_creditcard_iframe.html | 12 + .../test/fixtures/autocomplete_iframe.html | 13 + .../test/fixtures/autocomplete_off_on_form.html | 52 + .../test/fixtures/autocomplete_off_on_inputs.html | 77 ++ .../test/fixtures/autocomplete_simple_basic.html | 19 + .../test/fixtures/heuristics_cc_exp.html | 73 ++ .../test/fixtures/heuristics_de_fields.html | 122 ++ .../test/fixtures/heuristics_fr_fields.html | 34 + .../test/fixtures/multiple_section.html | 84 ++ .../third_party/BestBuy/Checkout_Payment.html | 283 +++++ .../BestBuy/Checkout_ShippingAddress.html | 326 +++++ .../test/fixtures/third_party/BestBuy/SignIn.html | 21 + .../CDW/Checkout_BillingPaymentInfo.html | 469 +++++++ .../fixtures/third_party/CDW/Checkout_Logon.html | 118 ++ .../third_party/CDW/Checkout_ShippingInfo.html | 376 ++++++ .../test/fixtures/third_party/CostCo/Payment.html | 892 ++++++++++++++ .../third_party/CostCo/ShippingAddress.html | 527 ++++++++ .../test/fixtures/third_party/CostCo/SignIn.html | 374 ++++++ .../fixtures/third_party/DirectAsda/Payment.html | 90 ++ .../third_party/Ebay/Checkout_Payment_FR.html | 135 ++ .../third_party/GlobalDirectAsda/Payment.html | 154 +++ .../HomeDepot/Checkout_ShippingPayment.html | 381 ++++++ .../fixtures/third_party/HomeDepot/SignIn.html | 83 ++ .../third_party/Lufthansa/Checkout_Payment.html | 23 + .../test/fixtures/third_party/Lush/index.html | 421 +++++++ .../third_party/Macys/Checkout_Payment.html | 474 +++++++ .../Macys/Checkout_ShippingAddress.html | 439 +++++++ .../test/fixtures/third_party/Macys/SignIn.html | 208 ++++ .../fixtures/third_party/NewEgg/BillingInfo.html | 1074 ++++++++++++++++ .../test/fixtures/third_party/NewEgg/Login.html | 156 +++ .../fixtures/third_party/NewEgg/ShippingInfo.html | 270 ++++ .../fixtures/third_party/OfficeDepot/Payment.html | 672 ++++++++++ .../third_party/OfficeDepot/ShippingAddress.html | 347 ++++++ .../fixtures/third_party/OfficeDepot/SignIn.html | 44 + .../fixtures/third_party/QVC/PaymentMethod.html | 527 ++++++++ .../test/fixtures/third_party/QVC/SignIn.html | 80 ++ .../fixtures/third_party/QVC/YourInformation.html | 522 ++++++++ .../formautofill/test/fixtures/third_party/README | 4 + .../fixtures/third_party/Sears/PaymentOptions.html | 566 +++++++++ .../third_party/Sears/ShippingAddress.html | 447 +++++++ .../test/fixtures/third_party/Staples/Basic.html | 117 ++ .../fixtures/third_party/Staples/Basic_ac_on.html | 117 ++ .../third_party/Staples/PaymentBilling.html | 99 ++ .../third_party/Staples/PaymentBilling_ac_on.html | 98 ++ .../fixtures/third_party/Walmart/Checkout.html | 243 ++++ .../test/fixtures/third_party/Walmart/Payment.html | 235 ++++ .../fixtures/third_party/Walmart/Shipping.html | 234 ++++ .../without_autocomplete_address_basic.html | 26 + .../without_autocomplete_creditcard_basic.html | 53 + .../test/mochitest/creditCard/mochitest.ini | 26 + .../test_basic_creditcard_autocomplete_form.html | 251 ++++ .../test/mochitest/creditCard/test_clear_form.html | 205 +++ .../test_clear_form_expiry_select_elements.html | 211 ++++ .../test_creditcard_autocomplete_off.html | 96 ++ ...w_highlight_with_multiple_cc_number_fields.html | 174 +++ .../test_preview_highlight_with_site_prefill.html | 110 ++ .../test/mochitest/formautofill_common.js | 478 +++++++ .../test/mochitest/formautofill_parent_utils.js | 304 +++++ .../formautofill/test/mochitest/mochitest.ini | 23 + .../mochitest/test_address_level_1_submission.html | 102 ++ .../mochitest/test_autofill_and_ordinal_forms.html | 116 ++ .../test/mochitest/test_autofocus_form.html | 69 ++ .../mochitest/test_basic_autocomplete_form.html | 220 ++++ .../test/mochitest/test_form_changes.html | 128 ++ .../test_formautofill_preview_highlight.html | 121 ++ .../test_multi_locale_CA_address_form.html | 273 ++++ .../test/mochitest/test_multiple_forms.html | 67 + .../test/mochitest/test_on_address_submission.html | 121 ++ browser/extensions/formautofill/test/unit/head.js | 357 ++++++ .../test/unit/head_addressComponent.js | 69 ++ .../formautofill/test/unit/test_activeStatus.js | 176 +++ .../test/unit/test_addressComponent_city.js | 27 + .../test/unit/test_addressComponent_country.js | 47 + .../test/unit/test_addressComponent_email.js | 74 ++ .../test/unit/test_addressComponent_name.js | 101 ++ .../unit/test_addressComponent_organization.js | 55 + .../test/unit/test_addressComponent_postal_code.js | 57 + .../test/unit/test_addressComponent_state.js | 32 + .../unit/test_addressComponent_street_address.js | 56 + .../test/unit/test_addressComponent_tel.js | 76 ++ .../test/unit/test_addressDataLoader.js | 102 ++ .../formautofill/test/unit/test_addressRecords.js | 858 +++++++++++++ .../test/unit/test_autofillFormFields.js | 1078 ++++++++++++++++ .../test/unit/test_clearPopulatedForm.js | 116 ++ .../test/unit/test_collectFormFields.js | 638 ++++++++++ .../formautofill/test/unit/test_createRecords.js | 525 ++++++++ .../test/unit/test_creditCardRecords.js | 926 ++++++++++++++ .../test/unit/test_extractLabelStrings.js | 77 ++ .../test/unit/test_findLabelElements.js | 100 ++ .../test/unit/test_getAdaptedProfiles.js | 1300 ++++++++++++++++++++ .../test/unit/test_getAdaptedProfiles_locales.js | 272 ++++ .../test/unit/test_getCategoriesFromFieldNames.js | 95 ++ .../test/unit/test_getCreditCardLogo.js | 25 + .../test/unit/test_getFormInputDetails.js | 204 +++ .../formautofill/test/unit/test_getInfo.js | 363 ++++++ .../formautofill/test/unit/test_getRecords.js | 258 ++++ .../test/unit/test_isAddressAutofillAvailable.js | 74 ++ .../formautofill/test/unit/test_isCJKName.js | 80 ++ .../unit/test_isCreditCardAutofillAvailable.js | 84 ++ .../unit/test_isCreditCardOrAddressFieldType.js | 103 ++ .../formautofill/test/unit/test_known_strings.js | 148 +++ .../test/unit/test_markAsAutofillField.js | 201 +++ .../formautofill/test/unit/test_migrateRecords.js | 382 ++++++ .../formautofill/test/unit/test_nameUtils.js | 289 +++++ .../formautofill/test/unit/test_onFormSubmitted.js | 805 ++++++++++++ .../test/unit/test_parseAddressFormat.js | 66 + .../test/unit/test_parseStreetAddress.js | 74 ++ .../formautofill/test/unit/test_phoneNumber.js | 399 ++++++ .../test/unit/test_previewFormFields.js | 199 +++ .../test/unit/test_profileAutocompleteResult.js | 450 +++++++ .../formautofill/test/unit/test_reconcile.js | 1173 ++++++++++++++++++ .../formautofill/test/unit/test_savedFieldNames.js | 106 ++ .../formautofill/test/unit/test_storage_remove.js | 88 ++ .../test/unit/test_storage_syncfields.js | 498 ++++++++ .../test/unit/test_storage_tombstones.js | 190 +++ .../extensions/formautofill/test/unit/test_sync.js | 1017 +++++++++++++++ .../unit/test_sync_deprecate_credit_card_v4.js | 248 ++++ .../test/unit/test_toOneLineAddress.js | 64 + .../formautofill/test/unit/test_transformFields.js | 972 +++++++++++++++ .../extensions/formautofill/test/unit/xpcshell.ini | 100 ++ 267 files changed, 45735 insertions(+) create mode 100644 browser/extensions/formautofill/.eslintrc.js create mode 100644 browser/extensions/formautofill/api.js create mode 100644 browser/extensions/formautofill/background.js create mode 100644 browser/extensions/formautofill/content/autofillEditForms.js create mode 100644 browser/extensions/formautofill/content/customElements.js create mode 100644 browser/extensions/formautofill/content/editAddress.xhtml create mode 100644 browser/extensions/formautofill/content/editCreditCard.xhtml create mode 100644 browser/extensions/formautofill/content/editDialog.js create mode 100644 browser/extensions/formautofill/content/formautofill.css create mode 100644 browser/extensions/formautofill/content/formfill-anchor.svg create mode 100644 browser/extensions/formautofill/content/icon-address-save.svg create mode 100644 browser/extensions/formautofill/content/icon-address-update.svg create mode 100644 browser/extensions/formautofill/content/icon-credit-card-generic.svg create mode 100644 browser/extensions/formautofill/content/icon-credit-card.svg create mode 100644 browser/extensions/formautofill/content/manageAddresses.xhtml create mode 100644 browser/extensions/formautofill/content/manageCreditCards.xhtml create mode 100644 browser/extensions/formautofill/content/manageDialog.css create mode 100644 browser/extensions/formautofill/content/manageDialog.js create mode 100644 browser/extensions/formautofill/content/third-party/cc-logo-amex.png create mode 100644 browser/extensions/formautofill/content/third-party/cc-logo-amex@2x.png create mode 100644 browser/extensions/formautofill/content/third-party/cc-logo-cartebancaire.png create mode 100644 browser/extensions/formautofill/content/third-party/cc-logo-cartebancaire@2x.png create mode 100644 browser/extensions/formautofill/content/third-party/cc-logo-diners.svg create mode 100644 browser/extensions/formautofill/content/third-party/cc-logo-discover.png create mode 100644 browser/extensions/formautofill/content/third-party/cc-logo-discover@2x.png create mode 100644 browser/extensions/formautofill/content/third-party/cc-logo-jcb.svg create mode 100644 browser/extensions/formautofill/content/third-party/cc-logo-mastercard.svg create mode 100644 browser/extensions/formautofill/content/third-party/cc-logo-mir.svg create mode 100644 browser/extensions/formautofill/content/third-party/cc-logo-unionpay.svg create mode 100644 browser/extensions/formautofill/content/third-party/cc-logo-visa.svg create mode 100644 browser/extensions/formautofill/docs/heuristics.rst create mode 100644 browser/extensions/formautofill/docs/index.rst create mode 100644 browser/extensions/formautofill/jar.mn create mode 100644 browser/extensions/formautofill/locales/en-US/formautofill.properties create mode 100644 browser/extensions/formautofill/locales/jar.mn create mode 100644 browser/extensions/formautofill/locales/moz.build create mode 100644 browser/extensions/formautofill/manifest.json create mode 100644 browser/extensions/formautofill/moz.build create mode 100644 browser/extensions/formautofill/schema.json create mode 100644 browser/extensions/formautofill/skin/linux/autocomplete-item.css create mode 100644 browser/extensions/formautofill/skin/linux/editDialog.css create mode 100644 browser/extensions/formautofill/skin/osx/autocomplete-item.css create mode 100644 browser/extensions/formautofill/skin/osx/editDialog.css create mode 100644 browser/extensions/formautofill/skin/shared/autocomplete-item-shared.css create mode 100644 browser/extensions/formautofill/skin/shared/editAddress.css create mode 100644 browser/extensions/formautofill/skin/shared/editCreditCard.css create mode 100644 browser/extensions/formautofill/skin/shared/editDialog-shared.css create mode 100644 browser/extensions/formautofill/skin/windows/autocomplete-item.css create mode 100644 browser/extensions/formautofill/skin/windows/editDialog.css create mode 100644 browser/extensions/formautofill/test/browser/address/browser.ini create mode 100644 browser/extensions/formautofill/test/browser/address/browser_address_doorhanger_display.js create mode 100644 browser/extensions/formautofill/test/browser/address/browser_address_telemetry.js create mode 100644 browser/extensions/formautofill/test/browser/address/head_address.js create mode 100644 browser/extensions/formautofill/test/browser/browser.ini create mode 100644 browser/extensions/formautofill/test/browser/browser_autocomplete_footer.js create mode 100644 browser/extensions/formautofill/test/browser/browser_autocomplete_marked_back_forward.js create mode 100644 browser/extensions/formautofill/test/browser/browser_autocomplete_marked_detached_tab.js create mode 100644 browser/extensions/formautofill/test/browser/browser_autofill_address_select.js create mode 100644 browser/extensions/formautofill/test/browser/browser_autofill_duplicate_fields.js create mode 100644 browser/extensions/formautofill/test/browser/browser_check_installed.js create mode 100644 browser/extensions/formautofill/test/browser/browser_dropdown_layout.js create mode 100644 browser/extensions/formautofill/test/browser/browser_editAddressDialog.js create mode 100644 browser/extensions/formautofill/test/browser/browser_fathom_cc.js create mode 100644 browser/extensions/formautofill/test/browser/browser_first_time_use_doorhanger.js create mode 100644 browser/extensions/formautofill/test/browser/browser_manageAddressesDialog.js create mode 100644 browser/extensions/formautofill/test/browser/browser_privacyPreferences.js create mode 100644 browser/extensions/formautofill/test/browser/browser_remoteiframe.js create mode 100644 browser/extensions/formautofill/test/browser/browser_submission_in_private_mode.js create mode 100644 browser/extensions/formautofill/test/browser/browser_update_doorhanger.js create mode 100644 browser/extensions/formautofill/test/browser/creditCard/browser.ini create mode 100644 browser/extensions/formautofill/test/browser/creditCard/browser_anti_clickjacking.js create mode 100644 browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_doorhanger_action.js create mode 100644 browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_doorhanger_display.js create mode 100644 browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_doorhanger_fields.js create mode 100644 browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_doorhanger_iframe.js create mode 100644 browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_doorhanger_logo.js create mode 100644 browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_doorhanger_sync.js create mode 100644 browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_dropdown_layout.js create mode 100644 browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_fill_cancel_login.js create mode 100644 browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_heuristics.js create mode 100644 browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_heuristics_cc_type.js create mode 100644 browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_submission_autodetect_type.js create mode 100644 browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_submission_normalized.js create mode 100644 browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_telemetry.js create mode 100644 browser/extensions/formautofill/test/browser/creditCard/browser_editCreditCardDialog.js create mode 100644 browser/extensions/formautofill/test/browser/creditCard/browser_insecure_form.js create mode 100644 browser/extensions/formautofill/test/browser/creditCard/browser_manageCreditCardsDialog.js create mode 100644 browser/extensions/formautofill/test/browser/creditCard/head_cc.js create mode 100644 browser/extensions/formautofill/test/browser/empty.html create mode 100755 browser/extensions/formautofill/test/browser/fathom/test-setup.sh create mode 100644 browser/extensions/formautofill/test/browser/fathom/testing/resources/sample/1.svg create mode 100644 browser/extensions/formautofill/test/browser/fathom/testing/resources/sample/10.svg create mode 100644 browser/extensions/formautofill/test/browser/fathom/testing/resources/sample/11.png create mode 100644 browser/extensions/formautofill/test/browser/fathom/testing/resources/sample/12.gif create mode 100644 browser/extensions/formautofill/test/browser/fathom/testing/resources/sample/13.svg create mode 100644 browser/extensions/formautofill/test/browser/fathom/testing/resources/sample/14.svg create mode 100644 browser/extensions/formautofill/test/browser/fathom/testing/resources/sample/15.svg create mode 100644 browser/extensions/formautofill/test/browser/fathom/testing/resources/sample/16.svg create mode 100644 browser/extensions/formautofill/test/browser/fathom/testing/resources/sample/17.bin create mode 100644 browser/extensions/formautofill/test/browser/fathom/testing/resources/sample/18.svg create mode 100644 browser/extensions/formautofill/test/browser/fathom/testing/resources/sample/2.svg create mode 100644 browser/extensions/formautofill/test/browser/fathom/testing/resources/sample/3.svg create mode 100644 browser/extensions/formautofill/test/browser/fathom/testing/resources/sample/4.svg create mode 100644 browser/extensions/formautofill/test/browser/fathom/testing/resources/sample/5.svg create mode 100644 browser/extensions/formautofill/test/browser/fathom/testing/resources/sample/6.svg create mode 100644 browser/extensions/formautofill/test/browser/fathom/testing/resources/sample/7.woff2 create mode 100644 browser/extensions/formautofill/test/browser/fathom/testing/resources/sample/8.woff2 create mode 100644 browser/extensions/formautofill/test/browser/fathom/testing/resources/sample/9.woff2 create mode 100644 browser/extensions/formautofill/test/browser/fathom/testing/sample.html create mode 100644 browser/extensions/formautofill/test/browser/focus-leak/browser.ini create mode 100644 browser/extensions/formautofill/test/browser/focus-leak/browser_iframe_typecontent_input_focus.js create mode 100644 browser/extensions/formautofill/test/browser/focus-leak/doc_iframe_typecontent_input_focus.xhtml create mode 100644 browser/extensions/formautofill/test/browser/focus-leak/doc_iframe_typecontent_input_focus_frame.html create mode 100644 browser/extensions/formautofill/test/browser/head.js create mode 100644 browser/extensions/formautofill/test/browser/heuristics/browser.ini create mode 100644 browser/extensions/formautofill/test/browser/heuristics/browser_autocomplete_off_on_form.js create mode 100644 browser/extensions/formautofill/test/browser/heuristics/browser_autocomplete_off_on_inputs.js create mode 100644 browser/extensions/formautofill/test/browser/heuristics/browser_basic.js create mode 100644 browser/extensions/formautofill/test/browser/heuristics/browser_cc_exp.js create mode 100644 browser/extensions/formautofill/test/browser/heuristics/browser_de_fields.js create mode 100644 browser/extensions/formautofill/test/browser/heuristics/browser_fr_fields.js create mode 100644 browser/extensions/formautofill/test/browser/heuristics/browser_ignore_invisible_fields.js create mode 100644 browser/extensions/formautofill/test/browser/heuristics/browser_multiple_section.js create mode 100644 browser/extensions/formautofill/test/browser/heuristics/browser_parseAddressFields.js create mode 100644 browser/extensions/formautofill/test/browser/heuristics/browser_section_validation_address.js create mode 100644 browser/extensions/formautofill/test/browser/heuristics/browser_sections_by_name.js create mode 100644 browser/extensions/formautofill/test/browser/heuristics/third_party/browser.ini create mode 100644 browser/extensions/formautofill/test/browser/heuristics/third_party/browser_BestBuy.js create mode 100644 browser/extensions/formautofill/test/browser/heuristics/third_party/browser_CDW.js create mode 100644 browser/extensions/formautofill/test/browser/heuristics/third_party/browser_CostCo.js create mode 100644 browser/extensions/formautofill/test/browser/heuristics/third_party/browser_DirectAsda.js create mode 100644 browser/extensions/formautofill/test/browser/heuristics/third_party/browser_Ebay.js create mode 100644 browser/extensions/formautofill/test/browser/heuristics/third_party/browser_GlobalDirectAsda.js create mode 100644 browser/extensions/formautofill/test/browser/heuristics/third_party/browser_HomeDepot.js create mode 100644 browser/extensions/formautofill/test/browser/heuristics/third_party/browser_Lufthansa.js create mode 100644 browser/extensions/formautofill/test/browser/heuristics/third_party/browser_Lush.js create mode 100644 browser/extensions/formautofill/test/browser/heuristics/third_party/browser_Macys.js create mode 100644 browser/extensions/formautofill/test/browser/heuristics/third_party/browser_NewEgg.js create mode 100644 browser/extensions/formautofill/test/browser/heuristics/third_party/browser_OfficeDepot.js create mode 100644 browser/extensions/formautofill/test/browser/heuristics/third_party/browser_QVC.js create mode 100644 browser/extensions/formautofill/test/browser/heuristics/third_party/browser_Sears.js create mode 100644 browser/extensions/formautofill/test/browser/heuristics/third_party/browser_Staples.js create mode 100644 browser/extensions/formautofill/test/browser/heuristics/third_party/browser_Walmart.js create mode 100644 browser/extensions/formautofill/test/fixtures/autocomplete_address_basic.html create mode 100644 browser/extensions/formautofill/test/fixtures/autocomplete_basic.html create mode 100644 browser/extensions/formautofill/test/fixtures/autocomplete_creditcard_basic.html create mode 100644 browser/extensions/formautofill/test/fixtures/autocomplete_creditcard_cc_exp_field.html create mode 100644 browser/extensions/formautofill/test/fixtures/autocomplete_creditcard_iframe.html create mode 100644 browser/extensions/formautofill/test/fixtures/autocomplete_iframe.html create mode 100644 browser/extensions/formautofill/test/fixtures/autocomplete_off_on_form.html create mode 100644 browser/extensions/formautofill/test/fixtures/autocomplete_off_on_inputs.html create mode 100644 browser/extensions/formautofill/test/fixtures/autocomplete_simple_basic.html create mode 100644 browser/extensions/formautofill/test/fixtures/heuristics_cc_exp.html create mode 100644 browser/extensions/formautofill/test/fixtures/heuristics_de_fields.html create mode 100644 browser/extensions/formautofill/test/fixtures/heuristics_fr_fields.html create mode 100644 browser/extensions/formautofill/test/fixtures/multiple_section.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/BestBuy/Checkout_Payment.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/BestBuy/Checkout_ShippingAddress.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/BestBuy/SignIn.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/CDW/Checkout_BillingPaymentInfo.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/CDW/Checkout_Logon.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/CDW/Checkout_ShippingInfo.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/CostCo/Payment.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/CostCo/ShippingAddress.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/CostCo/SignIn.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/DirectAsda/Payment.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/Ebay/Checkout_Payment_FR.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/GlobalDirectAsda/Payment.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/HomeDepot/Checkout_ShippingPayment.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/HomeDepot/SignIn.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/Lufthansa/Checkout_Payment.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/Lush/index.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/Macys/Checkout_Payment.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/Macys/Checkout_ShippingAddress.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/Macys/SignIn.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/NewEgg/BillingInfo.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/NewEgg/Login.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/NewEgg/ShippingInfo.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/OfficeDepot/Payment.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/OfficeDepot/ShippingAddress.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/OfficeDepot/SignIn.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/QVC/PaymentMethod.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/QVC/SignIn.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/QVC/YourInformation.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/README create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/Sears/PaymentOptions.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/Sears/ShippingAddress.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/Staples/Basic.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/Staples/Basic_ac_on.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/Staples/PaymentBilling.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/Staples/PaymentBilling_ac_on.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/Walmart/Checkout.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/Walmart/Payment.html create mode 100644 browser/extensions/formautofill/test/fixtures/third_party/Walmart/Shipping.html create mode 100644 browser/extensions/formautofill/test/fixtures/without_autocomplete_address_basic.html create mode 100644 browser/extensions/formautofill/test/fixtures/without_autocomplete_creditcard_basic.html create mode 100644 browser/extensions/formautofill/test/mochitest/creditCard/mochitest.ini create mode 100644 browser/extensions/formautofill/test/mochitest/creditCard/test_basic_creditcard_autocomplete_form.html create mode 100644 browser/extensions/formautofill/test/mochitest/creditCard/test_clear_form.html create mode 100644 browser/extensions/formautofill/test/mochitest/creditCard/test_clear_form_expiry_select_elements.html create mode 100644 browser/extensions/formautofill/test/mochitest/creditCard/test_creditcard_autocomplete_off.html create mode 100644 browser/extensions/formautofill/test/mochitest/creditCard/test_preview_highlight_with_multiple_cc_number_fields.html create mode 100644 browser/extensions/formautofill/test/mochitest/creditCard/test_preview_highlight_with_site_prefill.html create mode 100644 browser/extensions/formautofill/test/mochitest/formautofill_common.js create mode 100644 browser/extensions/formautofill/test/mochitest/formautofill_parent_utils.js create mode 100644 browser/extensions/formautofill/test/mochitest/mochitest.ini create mode 100644 browser/extensions/formautofill/test/mochitest/test_address_level_1_submission.html create mode 100644 browser/extensions/formautofill/test/mochitest/test_autofill_and_ordinal_forms.html create mode 100644 browser/extensions/formautofill/test/mochitest/test_autofocus_form.html create mode 100644 browser/extensions/formautofill/test/mochitest/test_basic_autocomplete_form.html create mode 100644 browser/extensions/formautofill/test/mochitest/test_form_changes.html create mode 100644 browser/extensions/formautofill/test/mochitest/test_formautofill_preview_highlight.html create mode 100644 browser/extensions/formautofill/test/mochitest/test_multi_locale_CA_address_form.html create mode 100644 browser/extensions/formautofill/test/mochitest/test_multiple_forms.html create mode 100644 browser/extensions/formautofill/test/mochitest/test_on_address_submission.html create mode 100644 browser/extensions/formautofill/test/unit/head.js create mode 100644 browser/extensions/formautofill/test/unit/head_addressComponent.js create mode 100644 browser/extensions/formautofill/test/unit/test_activeStatus.js create mode 100644 browser/extensions/formautofill/test/unit/test_addressComponent_city.js create mode 100644 browser/extensions/formautofill/test/unit/test_addressComponent_country.js create mode 100644 browser/extensions/formautofill/test/unit/test_addressComponent_email.js create mode 100644 browser/extensions/formautofill/test/unit/test_addressComponent_name.js create mode 100644 browser/extensions/formautofill/test/unit/test_addressComponent_organization.js create mode 100644 browser/extensions/formautofill/test/unit/test_addressComponent_postal_code.js create mode 100644 browser/extensions/formautofill/test/unit/test_addressComponent_state.js create mode 100644 browser/extensions/formautofill/test/unit/test_addressComponent_street_address.js create mode 100644 browser/extensions/formautofill/test/unit/test_addressComponent_tel.js create mode 100644 browser/extensions/formautofill/test/unit/test_addressDataLoader.js create mode 100644 browser/extensions/formautofill/test/unit/test_addressRecords.js create mode 100644 browser/extensions/formautofill/test/unit/test_autofillFormFields.js create mode 100644 browser/extensions/formautofill/test/unit/test_clearPopulatedForm.js create mode 100644 browser/extensions/formautofill/test/unit/test_collectFormFields.js create mode 100644 browser/extensions/formautofill/test/unit/test_createRecords.js create mode 100644 browser/extensions/formautofill/test/unit/test_creditCardRecords.js create mode 100644 browser/extensions/formautofill/test/unit/test_extractLabelStrings.js create mode 100644 browser/extensions/formautofill/test/unit/test_findLabelElements.js create mode 100644 browser/extensions/formautofill/test/unit/test_getAdaptedProfiles.js create mode 100644 browser/extensions/formautofill/test/unit/test_getAdaptedProfiles_locales.js create mode 100644 browser/extensions/formautofill/test/unit/test_getCategoriesFromFieldNames.js create mode 100644 browser/extensions/formautofill/test/unit/test_getCreditCardLogo.js create mode 100644 browser/extensions/formautofill/test/unit/test_getFormInputDetails.js create mode 100644 browser/extensions/formautofill/test/unit/test_getInfo.js create mode 100644 browser/extensions/formautofill/test/unit/test_getRecords.js create mode 100644 browser/extensions/formautofill/test/unit/test_isAddressAutofillAvailable.js create mode 100644 browser/extensions/formautofill/test/unit/test_isCJKName.js create mode 100644 browser/extensions/formautofill/test/unit/test_isCreditCardAutofillAvailable.js create mode 100644 browser/extensions/formautofill/test/unit/test_isCreditCardOrAddressFieldType.js create mode 100644 browser/extensions/formautofill/test/unit/test_known_strings.js create mode 100644 browser/extensions/formautofill/test/unit/test_markAsAutofillField.js create mode 100644 browser/extensions/formautofill/test/unit/test_migrateRecords.js create mode 100644 browser/extensions/formautofill/test/unit/test_nameUtils.js create mode 100644 browser/extensions/formautofill/test/unit/test_onFormSubmitted.js create mode 100644 browser/extensions/formautofill/test/unit/test_parseAddressFormat.js create mode 100644 browser/extensions/formautofill/test/unit/test_parseStreetAddress.js create mode 100644 browser/extensions/formautofill/test/unit/test_phoneNumber.js create mode 100644 browser/extensions/formautofill/test/unit/test_previewFormFields.js create mode 100644 browser/extensions/formautofill/test/unit/test_profileAutocompleteResult.js create mode 100644 browser/extensions/formautofill/test/unit/test_reconcile.js create mode 100644 browser/extensions/formautofill/test/unit/test_savedFieldNames.js create mode 100644 browser/extensions/formautofill/test/unit/test_storage_remove.js create mode 100644 browser/extensions/formautofill/test/unit/test_storage_syncfields.js create mode 100644 browser/extensions/formautofill/test/unit/test_storage_tombstones.js create mode 100644 browser/extensions/formautofill/test/unit/test_sync.js create mode 100644 browser/extensions/formautofill/test/unit/test_sync_deprecate_credit_card_v4.js create mode 100644 browser/extensions/formautofill/test/unit/test_toOneLineAddress.js create mode 100644 browser/extensions/formautofill/test/unit/test_transformFields.js create mode 100644 browser/extensions/formautofill/test/unit/xpcshell.ini (limited to 'browser/extensions/formautofill') diff --git a/browser/extensions/formautofill/.eslintrc.js b/browser/extensions/formautofill/.eslintrc.js new file mode 100644 index 0000000000..f290c1b3c1 --- /dev/null +++ b/browser/extensions/formautofill/.eslintrc.js @@ -0,0 +1,82 @@ +/* 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/. */ + +"use strict"; + +module.exports = { + rules: { + // Rules from the mozilla plugin + "mozilla/balanced-listeners": "error", + "mozilla/no-aArgs": "error", + "mozilla/var-only-at-top-level": "error", + + // No expressions where a statement is expected + "no-unused-expressions": "error", + + // No declaring variables that are never used + "no-unused-vars": [ + "error", + { + args: "none", + vars: "all", + }, + ], + + // No using variables before defined + "no-use-before-define": "error", + + // Disallow using variables outside the blocks they are defined (especially + // since only let and const are used, see "no-var"). + "block-scoped-var": "error", + + // Warn about cyclomatic complexity in functions. + complexity: ["error", { max: 26 }], + + // Maximum depth callbacks can be nested. + "max-nested-callbacks": ["error", 4], + + // Disallow using the console API, except for error statments. + "no-console": ["error", { allow: ["error"] }], + + // Disallow fallthrough of case statements, except if there is a comment. + "no-fallthrough": "error", + + // Disallow use of multiline strings (use template strings instead). + "no-multi-str": "error", + + // Disallow usage of __proto__ property. + "no-proto": "error", + + // Disallow use of assignment in return statement. It is preferable for a + // single line of code to have only one easily predictable effect. + "no-return-assign": "error", + + // Require use of the second argument for parseInt(). + radix: "error", + + // Require "use strict" to be defined globally in the script. + strict: ["error", "global"], + + // Disallow Yoda conditions (where literal value comes first). + yoda: "error", + + // Disallow function or variable declarations in nested blocks + "no-inner-declarations": "error", + }, + + overrides: [ + { + files: "**/head.js", + rules: { + "no-unused-vars": [ + "error", + { + args: "none", + vars: "local", + }, + ], + }, + }, + ], +}; diff --git a/browser/extensions/formautofill/api.js b/browser/extensions/formautofill/api.js new file mode 100644 index 0000000000..000c393e8e --- /dev/null +++ b/browser/extensions/formautofill/api.js @@ -0,0 +1,222 @@ +/* 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/. */ + +"use strict"; + +/* globals ExtensionAPI, Services, XPCOMUtils */ + +const CACHED_STYLESHEETS = new WeakMap(); + +ChromeUtils.defineESModuleGetters(this, { + FormAutofill: "resource://autofill/FormAutofill.sys.mjs", + FormAutofillParent: "resource://autofill/FormAutofillParent.sys.mjs", + FormAutofillStatus: "resource://autofill/FormAutofillParent.sys.mjs", + AutoCompleteParent: "resource://gre/actors/AutoCompleteParent.sys.mjs", +}); + +XPCOMUtils.defineLazyServiceGetter( + this, + "resProto", + "@mozilla.org/network/protocol;1?name=resource", + "nsISubstitutingProtocolHandler" +); + +const RESOURCE_HOST = "formautofill"; + +function insertStyleSheet(domWindow, url) { + let doc = domWindow.document; + let styleSheetAttr = `href="${url}" type="text/css"`; + let styleSheet = doc.createProcessingInstruction( + "xml-stylesheet", + styleSheetAttr + ); + + doc.insertBefore(styleSheet, doc.documentElement); + + if (CACHED_STYLESHEETS.has(domWindow)) { + CACHED_STYLESHEETS.get(domWindow).push(styleSheet); + } else { + CACHED_STYLESHEETS.set(domWindow, [styleSheet]); + } +} + +function ensureCssLoaded(domWindow) { + if (CACHED_STYLESHEETS.has(domWindow)) { + // This window already has autofill stylesheets. + return; + } + + insertStyleSheet(domWindow, "chrome://formautofill/content/formautofill.css"); + insertStyleSheet( + domWindow, + "chrome://formautofill/content/skin/autocomplete-item-shared.css" + ); + insertStyleSheet( + domWindow, + "chrome://formautofill/content/skin/autocomplete-item.css" + ); +} + +this.formautofill = class extends ExtensionAPI { + /** + * Adjusts and checks form autofill preferences during startup. + * + * @param {boolean} addressAutofillAvailable + * @param {boolean} creditCardAutofillAvailable + */ + adjustAndCheckFormAutofillPrefs( + addressAutofillAvailable, + creditCardAutofillAvailable + ) { + // Reset the sync prefs in case the features were previously available + // but aren't now. + if (!creditCardAutofillAvailable) { + Services.prefs.clearUserPref( + "services.sync.engine.creditcards.available" + ); + } + if (!addressAutofillAvailable) { + Services.prefs.clearUserPref("services.sync.engine.addresses.available"); + } + + if (!addressAutofillAvailable && !creditCardAutofillAvailable) { + Services.prefs.clearUserPref("dom.forms.autocomplete.formautofill"); + Services.telemetry.scalarSet("formautofill.availability", false); + return; + } + + // This pref is used for web contents to detect the autocomplete feature. + // When it's true, "element.autocomplete" will return tokens we currently + // support -- otherwise it'll return an empty string. + Services.prefs.setBoolPref("dom.forms.autocomplete.formautofill", true); + Services.telemetry.scalarSet("formautofill.availability", true); + + // These "*.available" prefs determines whether the "addresses"/"creditcards" sync engine is + // available (ie, whether it is shown in any UI etc) - it *does not* determine + // whether the engine is actually enabled or not. + if (FormAutofill.isAutofillAddressesAvailable) { + Services.prefs.setBoolPref( + "services.sync.engine.addresses.available", + true + ); + } else { + Services.prefs.clearUserPref("services.sync.engine.addresses.available"); + } + if (FormAutofill.isAutofillCreditCardsAvailable) { + Services.prefs.setBoolPref( + "services.sync.engine.creditcards.available", + true + ); + } else { + Services.prefs.clearUserPref( + "services.sync.engine.creditcards.available" + ); + } + } + onStartup() { + // We have to do this before actually determining if we're enabled, since + // there are scripts inside of the core browser code that depend on the + // FormAutofill JSMs being registered. + let uri = Services.io.newURI("chrome/res/", null, this.extension.rootURI); + resProto.setSubstitution(RESOURCE_HOST, uri); + + let aomStartup = Cc[ + "@mozilla.org/addons/addon-manager-startup;1" + ].getService(Ci.amIAddonManagerStartup); + const manifestURI = Services.io.newURI( + "manifest.json", + null, + this.extension.rootURI + ); + this.chromeHandle = aomStartup.registerChrome(manifestURI, [ + ["content", "formautofill", "chrome/content/"], + ]); + + // Until we move to fluent (bug 1446164), we're stuck with + // chrome.manifest for handling localization since its what the + // build system can handle for localized repacks. + if (this.extension.rootURI instanceof Ci.nsIJARURI) { + this.autofillManifest = this.extension.rootURI.JARFile.QueryInterface( + Ci.nsIFileURL + ).file; + } else if (this.extension.rootURI instanceof Ci.nsIFileURL) { + this.autofillManifest = this.extension.rootURI.file; + } + + if (this.autofillManifest) { + Components.manager.addBootstrappedManifestLocation(this.autofillManifest); + } else { + console.error( + "Cannot find formautofill chrome.manifest for registring translated strings" + ); + } + let addressAutofillAvailable = FormAutofill.isAutofillAddressesAvailable; + let creditCardAutofillAvailable = + FormAutofill.isAutofillCreditCardsAvailable; + this.adjustAndCheckFormAutofillPrefs( + addressAutofillAvailable, + creditCardAutofillAvailable + ); + if (!creditCardAutofillAvailable && !addressAutofillAvailable) { + return; + } + // Listen for the autocomplete popup message + // or the form submitted message (which may trigger a + // doorhanger) to lazily append our stylesheets related + // to the autocomplete feature. + AutoCompleteParent.addPopupStateListener(ensureCssLoaded); + FormAutofillParent.addMessageObserver(this); + this.onFormSubmitted = (data, window) => ensureCssLoaded(window); + + FormAutofillStatus.init(); + + ChromeUtils.registerWindowActor("FormAutofill", { + parent: { + esModuleURI: "resource://autofill/FormAutofillParent.sys.mjs", + }, + child: { + esModuleURI: "resource://autofill/FormAutofillChild.sys.mjs", + events: { + focusin: {}, + DOMFormBeforeSubmit: {}, + }, + }, + allFrames: true, + }); + } + + onShutdown(isAppShutdown) { + if (isAppShutdown) { + return; + } + + resProto.setSubstitution(RESOURCE_HOST, null); + + this.chromeHandle.destruct(); + this.chromeHandle = null; + + if (this.autofillManifest) { + Components.manager.removeBootstrappedManifestLocation( + this.autofillManifest + ); + } + + ChromeUtils.unregisterWindowActor("FormAutofill"); + + AutoCompleteParent.removePopupStateListener(ensureCssLoaded); + FormAutofillParent.removeMessageObserver(this); + + for (let win of Services.wm.getEnumerator("navigator:browser")) { + let cachedStyleSheets = CACHED_STYLESHEETS.get(win); + + if (!cachedStyleSheets) { + continue; + } + + while (cachedStyleSheets.length !== 0) { + cachedStyleSheets.pop().remove(); + } + } + } +}; diff --git a/browser/extensions/formautofill/background.js b/browser/extensions/formautofill/background.js new file mode 100644 index 0000000000..fe6265415f --- /dev/null +++ b/browser/extensions/formautofill/background.js @@ -0,0 +1,15 @@ +/* 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/. */ + +/* eslint-env webextensions */ + +"use strict"; + +browser.runtime.onUpdateAvailable.addListener(details => { + // By listening to but ignoring this event, any updates will + // be delayed until the next browser restart. + // Note that if we ever wanted to change this, we should make + // sure we manually invalidate the startup cache using the + // startupcache-invalidate notification. +}); diff --git a/browser/extensions/formautofill/content/autofillEditForms.js b/browser/extensions/formautofill/content/autofillEditForms.js new file mode 100644 index 0000000000..3ed64a098a --- /dev/null +++ b/browser/extensions/formautofill/content/autofillEditForms.js @@ -0,0 +1,644 @@ +/* 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/. */ + +/* exported EditAddress, EditCreditCard */ +/* eslint-disable mozilla/balanced-listeners */ // Not relevant since the document gets unloaded. + +"use strict"; + +const { FormAutofill } = ChromeUtils.importESModule( + "resource://autofill/FormAutofill.sys.mjs" +); +const { FormAutofillUtils } = ChromeUtils.importESModule( + "resource://gre/modules/shared/FormAutofillUtils.sys.mjs" +); + +class EditAutofillForm { + constructor(elements) { + this._elements = elements; + } + + /** + * Fill the form with a record object. + * + * @param {object} [record = {}] + */ + loadRecord(record = {}) { + for (let field of this._elements.form.elements) { + let value = record[field.id]; + value = typeof value == "undefined" ? "" : value; + + if (record.guid) { + field.value = value; + } else if (field.localName == "select") { + this.setDefaultSelectedOptionByValue(field, value); + } else { + // Use .defaultValue instead of .value to avoid setting the `dirty` flag + // which triggers form validation UI. + field.defaultValue = value; + } + } + if (!record.guid) { + // Reset the dirty value flag and validity state. + this._elements.form.reset(); + } else { + for (let field of this._elements.form.elements) { + this.updatePopulatedState(field); + this.updateCustomValidity(field); + } + } + } + + setDefaultSelectedOptionByValue(select, value) { + for (let option of select.options) { + option.defaultSelected = option.value == value; + } + } + + /** + * Get a record from the form suitable for a save/update in storage. + * + * @returns {object} + */ + buildFormObject() { + let initialObject = {}; + if (this.hasMailingAddressFields) { + // Start with an empty string for each mailing-address field so that any + // fields hidden for the current country are blanked in the return value. + initialObject = { + "street-address": "", + "address-level3": "", + "address-level2": "", + "address-level1": "", + "postal-code": "", + }; + } + + return Array.from(this._elements.form.elements).reduce((obj, input) => { + if (!input.disabled) { + obj[input.id] = input.value; + } + return obj; + }, initialObject); + } + + /** + * Handle events + * + * @param {DOMEvent} event + */ + handleEvent(event) { + switch (event.type) { + case "change": { + this.handleChange(event); + break; + } + case "input": { + this.handleInput(event); + break; + } + } + } + + /** + * Handle change events + * + * @param {DOMEvent} event + */ + handleChange(event) { + this.updatePopulatedState(event.target); + } + + /** + * Handle input events + * + * @param {DOMEvent} event + */ + handleInput(event) {} + + /** + * Attach event listener + */ + attachEventListeners() { + this._elements.form.addEventListener("input", this); + } + + /** + * Set the field-populated attribute if the field has a value. + * + * @param {DOMElement} field The field that will be checked for a value. + */ + updatePopulatedState(field) { + let span = field.parentNode.querySelector(".label-text"); + if (!span) { + return; + } + span.toggleAttribute("field-populated", !!field.value.trim()); + } + + /** + * Run custom validity routines specific to the field and type of form. + * + * @param {DOMElement} field The field that will be validated. + */ + updateCustomValidity(field) {} +} + +class EditAddress extends EditAutofillForm { + /** + * @param {HTMLElement[]} elements + * @param {object} record + * @param {object} config + * @param {boolean} [config.noValidate=undefined] Whether to validate the form + */ + constructor(elements, record, config) { + super(elements); + + Object.assign(this, config); + let { form } = this._elements; + Object.assign(this._elements, { + addressLevel3Label: form.querySelector( + "#address-level3-container > .label-text" + ), + addressLevel2Label: form.querySelector( + "#address-level2-container > .label-text" + ), + addressLevel1Label: form.querySelector( + "#address-level1-container > .label-text" + ), + postalCodeLabel: form.querySelector( + "#postal-code-container > .label-text" + ), + country: form.querySelector("#country"), + }); + + this.populateCountries(); + // Need to populate the countries before trying to set the initial country. + // Also need to use this._record so it has the default country selected. + this.loadRecord(record); + this.attachEventListeners(); + + form.noValidate = !!config.noValidate; + } + + loadRecord(record) { + this._record = record; + if (!record) { + record = { + country: FormAutofill.DEFAULT_REGION, + }; + } + + let { addressLevel1Options } = FormAutofillUtils.getFormFormat( + record.country + ); + this.populateAddressLevel1(addressLevel1Options, record.country); + + super.loadRecord(record); + this.loadAddressLevel1(record["address-level1"], record.country); + this.formatForm(record.country); + } + + get hasMailingAddressFields() { + let { addressFields } = this._elements.form.dataset; + return ( + !addressFields || + addressFields.trim().split(/\s+/).includes("mailing-address") + ); + } + + /** + * `mailing-address` is a special attribute token to indicate mailing fields + country. + * + * @param {object[]} mailingFieldsOrder - `fieldsOrder` from `getFormFormat` + * @param {string} addressFields - white-space-separated string of requested address fields to show + * @returns {object[]} in the same structure as `mailingFieldsOrder` but including non-mail fields + */ + static computeVisibleFields(mailingFieldsOrder, addressFields) { + if (addressFields) { + let requestedFieldClasses = addressFields.trim().split(/\s+/); + let fieldClasses = []; + if (requestedFieldClasses.includes("mailing-address")) { + fieldClasses = fieldClasses.concat(mailingFieldsOrder); + // `country` isn't part of the `mailingFieldsOrder` so add it when filling a mailing-address + requestedFieldClasses.splice( + requestedFieldClasses.indexOf("mailing-address"), + 1, + "country" + ); + } + + for (let fieldClassName of requestedFieldClasses) { + fieldClasses.push({ + fieldId: fieldClassName, + newLine: fieldClassName == "name", + }); + } + return fieldClasses; + } + + // This is the default which is shown in the management interface and includes all fields. + return mailingFieldsOrder.concat([ + { + fieldId: "country", + }, + { + fieldId: "tel", + }, + { + fieldId: "email", + newLine: true, + }, + ]); + } + + /** + * Format the form based on country. The address-level1 and postal-code labels + * should be specific to the given country. + * + * @param {string} country + */ + formatForm(country) { + const { + addressLevel3L10nId, + addressLevel2L10nId, + addressLevel1L10nId, + addressLevel1Options, + postalCodeL10nId, + fieldsOrder: mailingFieldsOrder, + postalCodePattern, + countryRequiredFields, + } = FormAutofillUtils.getFormFormat(country); + + document.l10n.setAttributes( + this._elements.addressLevel3Label, + addressLevel3L10nId + ); + document.l10n.setAttributes( + this._elements.addressLevel2Label, + addressLevel2L10nId + ); + document.l10n.setAttributes( + this._elements.addressLevel1Label, + addressLevel1L10nId + ); + document.l10n.setAttributes( + this._elements.postalCodeLabel, + postalCodeL10nId + ); + let addressFields = this._elements.form.dataset.addressFields; + let extraRequiredFields = this._elements.form.dataset.extraRequiredFields; + let fieldClasses = EditAddress.computeVisibleFields( + mailingFieldsOrder, + addressFields + ); + let requiredFields = new Set(countryRequiredFields); + if (extraRequiredFields) { + for (let extraRequiredField of extraRequiredFields.trim().split(/\s+/)) { + requiredFields.add(extraRequiredField); + } + } + this.arrangeFields(fieldClasses, requiredFields); + this.updatePostalCodeValidation(postalCodePattern); + this.populateAddressLevel1(addressLevel1Options, country); + } + + /** + * Update address field visibility and order based on libaddressinput data. + * + * @param {object[]} fieldsOrder array of objects with `fieldId` and optional `newLine` properties + * @param {Set} requiredFields Set of `fieldId` strings that mark which fields are required + */ + arrangeFields(fieldsOrder, requiredFields) { + /** + * @see FormAutofillStorage.VALID_ADDRESS_FIELDS + */ + let fields = [ + // `name` is a wrapper for the 3 name fields. + "name", + "organization", + "street-address", + "address-level3", + "address-level2", + "address-level1", + "postal-code", + "country", + "tel", + "email", + ]; + let inputs = []; + for (let i = 0; i < fieldsOrder.length; i++) { + let { fieldId, newLine } = fieldsOrder[i]; + + let container = this._elements.form.querySelector( + `#${fieldId}-container` + ); + let containerInputs = [ + ...container.querySelectorAll("input, textarea, select"), + ]; + containerInputs.forEach(function (input) { + input.disabled = false; + // libaddressinput doesn't list 'country' or 'name' as required. + // The additional-name field should never get marked as required. + input.required = + (fieldId == "country" || + fieldId == "name" || + requiredFields.has(fieldId)) && + input.id != "additional-name"; + }); + inputs.push(...containerInputs); + container.style.display = "flex"; + container.style.order = i; + container.style.pageBreakAfter = newLine ? "always" : "auto"; + // Remove the field from the list of fields + fields.splice(fields.indexOf(fieldId), 1); + } + for (let i = 0; i < inputs.length; i++) { + // Assign tabIndex starting from 1 + inputs[i].tabIndex = i + 1; + } + // Hide the remaining fields + for (let field of fields) { + let container = this._elements.form.querySelector(`#${field}-container`); + container.style.display = "none"; + for (let input of [ + ...container.querySelectorAll("input, textarea, select"), + ]) { + input.disabled = true; + } + } + } + + updatePostalCodeValidation(postalCodePattern) { + let postalCodeInput = this._elements.form.querySelector("#postal-code"); + if (postalCodePattern && postalCodeInput.style.display != "none") { + postalCodeInput.setAttribute("pattern", postalCodePattern); + } else { + postalCodeInput.removeAttribute("pattern"); + } + } + + /** + * Set the address-level1 value on the form field (input or select, whichever is present). + * + * @param {string} addressLevel1Value Value of the address-level1 from the autofill record + * @param {string} country The corresponding country + */ + loadAddressLevel1(addressLevel1Value, country) { + let field = this._elements.form.querySelector("#address-level1"); + + if (field.localName == "input") { + field.value = addressLevel1Value || ""; + return; + } + + let matchedSelectOption = FormAutofillUtils.findAddressSelectOption( + field, + { + country, + "address-level1": addressLevel1Value, + }, + "address-level1" + ); + if (matchedSelectOption && !matchedSelectOption.selected) { + field.value = matchedSelectOption.value; + field.dispatchEvent(new Event("input", { bubbles: true })); + field.dispatchEvent(new Event("change", { bubbles: true })); + } else if (addressLevel1Value) { + // If the option wasn't found, insert an option at the beginning of + // the select that matches the stored value. + field.insertBefore( + new Option(addressLevel1Value, addressLevel1Value, true, true), + field.firstChild + ); + } + } + + /** + * Replace the text input for address-level1 with a select dropdown if + * a fixed set of names exists. Otherwise show a text input. + * + * @param {Map?} options Map of options with regionCode -> name mappings + * @param {string} country The corresponding country + */ + populateAddressLevel1(options, country) { + let field = this._elements.form.querySelector("#address-level1"); + + if (field.dataset.country == country) { + return; + } + + if (!options) { + if (field.localName == "input") { + return; + } + + let input = document.createElement("input"); + input.setAttribute("type", "text"); + input.id = "address-level1"; + input.required = field.required; + input.disabled = field.disabled; + input.tabIndex = field.tabIndex; + field.replaceWith(input); + return; + } + + if (field.localName == "input") { + let select = document.createElement("select"); + select.id = "address-level1"; + select.required = field.required; + select.disabled = field.disabled; + select.tabIndex = field.tabIndex; + field.replaceWith(select); + field = select; + } + + field.textContent = ""; + field.dataset.country = country; + let fragment = document.createDocumentFragment(); + fragment.appendChild(new Option(undefined, undefined, true, true)); + for (let [regionCode, regionName] of options) { + let option = new Option(regionName, regionCode); + fragment.appendChild(option); + } + field.appendChild(fragment); + } + + populateCountries() { + let fragment = document.createDocumentFragment(); + // Sort countries by their visible names. + let countries = [...FormAutofill.countries.entries()].sort((e1, e2) => + e1[1].localeCompare(e2[1]) + ); + for (let [country] of countries) { + const countryName = Services.intl.getRegionDisplayNames(undefined, [ + country.toLowerCase(), + ]); + const option = new Option(countryName, country); + fragment.appendChild(option); + } + this._elements.country.appendChild(fragment); + } + + handleChange(event) { + if (event.target == this._elements.country) { + this.formatForm(event.target.value); + } + super.handleChange(event); + } + + attachEventListeners() { + this._elements.form.addEventListener("change", this); + super.attachEventListeners(); + } +} + +class EditCreditCard extends EditAutofillForm { + /** + * @param {HTMLElement[]} elements + * @param {object} record with a decrypted cc-number + * @param {object} addresses in an object with guid keys for the billing address picker. + */ + constructor(elements, record, addresses) { + super(elements); + + this._addresses = addresses; + Object.assign(this._elements, { + ccNumber: this._elements.form.querySelector("#cc-number"), + invalidCardNumberStringElement: this._elements.form.querySelector( + "#invalidCardNumberString" + ), + month: this._elements.form.querySelector("#cc-exp-month"), + year: this._elements.form.querySelector("#cc-exp-year"), + billingAddress: this._elements.form.querySelector("#billingAddressGUID"), + billingAddressRow: + this._elements.form.querySelector(".billingAddressRow"), + }); + + this.attachEventListeners(); + this.loadRecord(record, addresses); + } + + loadRecord(record, addresses, preserveFieldValues) { + // _record must be updated before generateYears and generateBillingAddressOptions are called. + this._record = record; + this._addresses = addresses; + this.generateBillingAddressOptions(preserveFieldValues); + if (!preserveFieldValues) { + // Re-generating the months will reset the selected option. + this.generateMonths(); + // Re-generating the years will reset the selected option. + this.generateYears(); + super.loadRecord(record); + } + } + + generateMonths() { + const count = 12; + + // Clear the list + this._elements.month.textContent = ""; + + // Empty month option + this._elements.month.appendChild(new Option()); + + // Populate month list. Format: "month number - month name" + let dateFormat = new Intl.DateTimeFormat(navigator.language, { + month: "long", + }).format; + for (let i = 0; i < count; i++) { + let monthNumber = (i + 1).toString(); + let monthName = dateFormat(new Date(1970, i)); + let option = new Option(); + option.value = monthNumber; + // XXX: Bug 1446164 - Localize this string. + option.textContent = `${monthNumber.padStart(2, "0")} - ${monthName}`; + this._elements.month.appendChild(option); + } + } + + generateYears() { + const count = 11; + const currentYear = new Date().getFullYear(); + const ccExpYear = this._record && this._record["cc-exp-year"]; + + // Clear the list + this._elements.year.textContent = ""; + + // Provide an empty year option + this._elements.year.appendChild(new Option()); + + if (ccExpYear && ccExpYear < currentYear) { + this._elements.year.appendChild(new Option(ccExpYear)); + } + + for (let i = 0; i < count; i++) { + let year = currentYear + i; + let option = new Option(year); + this._elements.year.appendChild(option); + } + + if (ccExpYear && ccExpYear > currentYear + count) { + this._elements.year.appendChild(new Option(ccExpYear)); + } + } + + generateBillingAddressOptions(preserveFieldValues) { + let billingAddressGUID; + if (preserveFieldValues && this._elements.billingAddress.value) { + billingAddressGUID = this._elements.billingAddress.value; + } else if (this._record) { + billingAddressGUID = this._record.billingAddressGUID; + } + + this._elements.billingAddress.textContent = ""; + + this._elements.billingAddress.appendChild(new Option("", "")); + + let hasAddresses = false; + for (let [guid, address] of Object.entries(this._addresses)) { + hasAddresses = true; + let selected = guid == billingAddressGUID; + let option = new Option( + FormAutofillUtils.getAddressLabel(address), + guid, + selected, + selected + ); + this._elements.billingAddress.appendChild(option); + } + + this._elements.billingAddressRow.hidden = !hasAddresses; + } + + attachEventListeners() { + this._elements.form.addEventListener("change", this); + super.attachEventListeners(); + } + + handleInput(event) { + // Clear the error message if cc-number is valid + if ( + event.target == this._elements.ccNumber && + FormAutofillUtils.isCCNumber(this._elements.ccNumber.value) + ) { + this._elements.ccNumber.setCustomValidity(""); + } + super.handleInput(event); + } + + updateCustomValidity(field) { + super.updateCustomValidity(field); + + // Mark the cc-number field as invalid if the number is empty or invalid. + if ( + field == this._elements.ccNumber && + !FormAutofillUtils.isCCNumber(field.value) + ) { + let invalidCardNumberString = + this._elements.invalidCardNumberStringElement.textContent; + field.setCustomValidity(invalidCardNumberString || " "); + } + } +} diff --git a/browser/extensions/formautofill/content/customElements.js b/browser/extensions/formautofill/content/customElements.js new file mode 100644 index 0000000000..0b3d761817 --- /dev/null +++ b/browser/extensions/formautofill/content/customElements.js @@ -0,0 +1,410 @@ +/* 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/. */ + +// This file is loaded into the browser window scope. +/* eslint-env mozilla/browser-window */ +/* eslint-disable mozilla/balanced-listeners */ // Not relevant since the document gets unloaded. + +"use strict"; + +// Wrap in a block to prevent leaking to window scope. +(() => { + function sendMessageToBrowser(msgName, data) { + let { AutoCompleteParent } = ChromeUtils.importESModule( + "resource://gre/actors/AutoCompleteParent.sys.mjs" + ); + + let actor = AutoCompleteParent.getCurrentActor(); + if (!actor) { + return; + } + + actor.manager.getActor("FormAutofill").sendAsyncMessage(msgName, data); + } + + class MozAutocompleteProfileListitemBase extends MozElements.MozRichlistitem { + constructor() { + super(); + + /** + * For form autofill, we want to unify the selection no matter by + * keyboard navigation or mouseover in order not to confuse user which + * profile preview is being shown. This field is set to true to indicate + * that selectedIndex of popup should be changed while mouseover item + */ + this.selectedByMouseOver = true; + } + + get _stringBundle() { + if (!this.__stringBundle) { + this.__stringBundle = Services.strings.createBundle( + "chrome://formautofill/locale/formautofill.properties" + ); + } + return this.__stringBundle; + } + + _cleanup() { + this.removeAttribute("formautofillattached"); + if (this._itemBox) { + this._itemBox.removeAttribute("size"); + } + } + + _onOverflow() {} + + _onUnderflow() {} + + handleOverUnderflow() {} + + _adjustAutofillItemLayout() { + let outerBoxRect = this.parentNode.getBoundingClientRect(); + + // Make item fit in popup as XUL box could not constrain + // item's width + this._itemBox.style.width = outerBoxRect.width + "px"; + // Use two-lines layout when width is smaller than 150px or + // 185px if an image precedes the label. + let oneLineMinRequiredWidth = this.getAttribute("ac-image") ? 185 : 150; + + if (outerBoxRect.width <= oneLineMinRequiredWidth) { + this._itemBox.setAttribute("size", "small"); + } else { + this._itemBox.removeAttribute("size"); + } + } + } + + MozElements.MozAutocompleteProfileListitem = class MozAutocompleteProfileListitem extends ( + MozAutocompleteProfileListitemBase + ) { + static get markup() { + return ` +
+
+ + +
+
+ +
+
+ `; + } + + connectedCallback() { + if (this.delayConnectedCallback()) { + return; + } + + this.textContent = ""; + + this.appendChild(this.constructor.fragment); + + this._itemBox = this.querySelector(".autofill-item-box"); + this._labelAffix = this.querySelector(".profile-label-affix"); + this._label = this.querySelector(".profile-label"); + this._comment = this.querySelector(".profile-comment"); + + this.initializeAttributeInheritance(); + this._adjustAcItem(); + } + + static get inheritedAttributes() { + return { + ".autofill-item-box": "ac-image", + }; + } + + set selected(val) { + if (val) { + this.setAttribute("selected", "true"); + } else { + this.removeAttribute("selected"); + } + + sendMessageToBrowser("FormAutofill:PreviewProfile"); + } + + get selected() { + return this.getAttribute("selected") == "true"; + } + + _adjustAcItem() { + this._adjustAutofillItemLayout(); + this.setAttribute("formautofillattached", "true"); + this._itemBox.style.setProperty( + "--primary-icon", + `url(${this.getAttribute("ac-image")})` + ); + + let { primaryAffix, primary, secondary, ariaLabel } = JSON.parse( + this.getAttribute("ac-value") + ); + + this._labelAffix.textContent = primaryAffix; + this._label.textContent = primary; + this._comment.textContent = secondary; + if (ariaLabel) { + this.setAttribute("aria-label", ariaLabel); + } + } + }; + + customElements.define( + "autocomplete-profile-listitem", + MozElements.MozAutocompleteProfileListitem, + { extends: "richlistitem" } + ); + + class MozAutocompleteProfileListitemFooter extends MozAutocompleteProfileListitemBase { + static get markup() { + return ` + + `; + } + + constructor() { + super(); + + this.addEventListener("click", event => { + if (event.button != 0) { + return; + } + + if (this._warningTextBox.contains(event.originalTarget)) { + return; + } + + window.openPreferences("privacy-form-autofill"); + }); + } + + connectedCallback() { + if (this.delayConnectedCallback()) { + return; + } + + this.textContent = ""; + this.appendChild(this.constructor.fragment); + + this._itemBox = this.querySelector(".autofill-footer"); + this._optionButton = this.querySelector(".autofill-button"); + this._warningTextBox = this.querySelector(".autofill-warning"); + + /** + * A handler for updating warning message once selectedIndex has been changed. + * + * There're three different states of warning message: + * 1. None of addresses were selected: We show all the categories intersection of fields in the + * form and fields in the results. + * 2. An address was selested: Show the additional categories that will also be filled. + * 3. An address was selected, but the focused category is the same as the only one category: Only show + * the exact category that we're going to fill in. + * + * @private + * @param {object} data + * Message data + * @param {string[]} data.categories + * The categories of all the fields contained in the selected address. + */ + this.updateWarningNote = data => { + let categories = + data && data.categories ? data.categories : this._allFieldCategories; + // If the length of categories is 1, that means all the fillable fields are in the same + // category. We will change the way to inform user according to this flag. When the value + // is true, we show "Also autofills ...", otherwise, show "Autofills ..." only. + let hasExtraCategories = categories.length > 1; + // Show the categories in certain order to conform with the spec. + let orderedCategoryList = [ + { id: "address", l10nId: "category.address" }, + { id: "name", l10nId: "category.name" }, + { id: "organization", l10nId: "category.organization2" }, + { id: "tel", l10nId: "category.tel" }, + { id: "email", l10nId: "category.email" }, + ]; + let showCategories = hasExtraCategories + ? orderedCategoryList.filter( + category => + categories.includes(category.id) && + category.id != this._focusedCategory + ) + : [ + orderedCategoryList.find( + category => category.id == this._focusedCategory + ), + ]; + + let separator = + this._stringBundle.GetStringFromName("fieldNameSeparator"); + let warningTextTmplKey = hasExtraCategories + ? "phishingWarningMessage" + : "phishingWarningMessage2"; + let categoriesText = showCategories + .map(category => + this._stringBundle.GetStringFromName(category.l10nId) + ) + .join(separator); + + this._warningTextBox.textContent = + this._stringBundle.formatStringFromName(warningTextTmplKey, [ + categoriesText, + ]); + this.parentNode.parentNode.adjustHeight(); + }; + + this._adjustAcItem(); + } + + _onCollapse() { + if (this.showWarningText) { + let { FormAutofillParent } = ChromeUtils.importESModule( + "resource://autofill/FormAutofillParent.sys.mjs" + ); + FormAutofillParent.removeMessageObserver(this); + } + this._itemBox.removeAttribute("no-warning"); + } + + _adjustAcItem() { + this._adjustAutofillItemLayout(); + this.setAttribute("formautofillattached", "true"); + + let buttonTextBundleKey; + if (this._itemBox.getAttribute("size") == "small") { + buttonTextBundleKey = + AppConstants.platform == "macosx" + ? "autocompleteFooterOptionOSXShort2" + : "autocompleteFooterOptionShort2"; + } else { + buttonTextBundleKey = + AppConstants.platform == "macosx" + ? "autocompleteFooterOptionOSX2" + : "autocompleteFooterOption2"; + } + + let buttonText = + this._stringBundle.GetStringFromName(buttonTextBundleKey); + this._optionButton.textContent = buttonText; + + let value = JSON.parse(this.getAttribute("ac-value")); + + this._allFieldCategories = value.categories; + this._focusedCategory = value.focusedCategory; + this.showWarningText = this._allFieldCategories && this._focusedCategory; + + if (this.showWarningText) { + let { FormAutofillParent } = ChromeUtils.importESModule( + "resource://autofill/FormAutofillParent.sys.mjs" + ); + FormAutofillParent.addMessageObserver(this); + this.updateWarningNote(); + } else { + this._itemBox.setAttribute("no-warning", "true"); + } + } + } + + customElements.define( + "autocomplete-profile-listitem-footer", + MozAutocompleteProfileListitemFooter, + { extends: "richlistitem" } + ); + + class MozAutocompleteCreditcardInsecureField extends MozAutocompleteProfileListitemBase { + static get markup() { + return ` +
+ `; + } + + connectedCallback() { + if (this.delayConnectedCallback()) { + return; + } + this.textContent = ""; + this.appendChild(this.constructor.fragment); + + this._itemBox = this.querySelector(".autofill-insecure-item"); + + this._adjustAcItem(); + } + + set selected(val) { + // This item is unselectable since we see this item as a pure message. + } + + get selected() { + return this.getAttribute("selected") == "true"; + } + + _adjustAcItem() { + this._adjustAutofillItemLayout(); + this.setAttribute("formautofillattached", "true"); + + let value = this.getAttribute("ac-value"); + this._itemBox.textContent = value; + } + } + + customElements.define( + "autocomplete-creditcard-insecure-field", + MozAutocompleteCreditcardInsecureField, + { extends: "richlistitem" } + ); + + class MozAutocompleteProfileListitemClearButton extends MozAutocompleteProfileListitemBase { + static get markup() { + return ` + + `; + } + + constructor() { + super(); + + this.addEventListener("click", event => { + if (event.button != 0) { + return; + } + + sendMessageToBrowser("FormAutofill:ClearForm"); + }); + } + + connectedCallback() { + if (this.delayConnectedCallback()) { + return; + } + + this.textContent = ""; + this.appendChild(this.constructor.fragment); + + this._itemBox = this.querySelector(".autofill-item-box"); + this._clearBtn = this.querySelector(".autofill-button"); + + this._adjustAcItem(); + } + + _adjustAcItem() { + this._adjustAutofillItemLayout(); + this.setAttribute("formautofillattached", "true"); + + let clearFormBtnLabel = + this._stringBundle.GetStringFromName("clearFormBtnLabel2"); + this._clearBtn.textContent = clearFormBtnLabel; + } + } + + customElements.define( + "autocomplete-profile-listitem-clear-button", + MozAutocompleteProfileListitemClearButton, + { extends: "richlistitem" } + ); +})(); diff --git a/browser/extensions/formautofill/content/editAddress.xhtml b/browser/extensions/formautofill/content/editAddress.xhtml new file mode 100644 index 0000000000..8972e75c47 --- /dev/null +++ b/browser/extensions/formautofill/content/editAddress.xhtml @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + +
+ +
+ + + +
+ +