From d8bbc7858622b6d9c278469aab701ca0b609cddf Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 15 May 2024 05:35:49 +0200 Subject: Merging upstream version 126.0. Signed-off-by: Daniel Baumann --- browser/extensions/formautofill/api.js | 8 - .../formautofill/content/customElements.js | 392 --------------------- .../formautofill/content/formautofill.css | 11 +- .../locales/en-US/formautofill.properties | 18 - browser/extensions/formautofill/moz.build | 3 - .../formautofill/skin/linux/autocomplete-item.css | 10 - .../formautofill/skin/osx/autocomplete-item.css | 18 - .../skin/shared/autocomplete-item-shared.css | 182 ---------- .../skin/windows/autocomplete-item.css | 25 -- .../address/browser_address_doorhanger_state.js | 4 + ...rowser_edit_address_doorhanger_display_state.js | 5 + .../test/browser/browser_autocomplete_footer.js | 29 +- .../test/browser/browser_dropdown_layout.js | 30 -- .../browser_creditCard_dropdown_layout.js | 2 +- .../browser/creditCard/browser_insecure_form.js | 14 +- .../extensions/formautofill/test/browser/head.js | 37 +- .../test_basic_creditcard_autocomplete_form.html | 31 +- .../test_creditcard_autocomplete_off.html | 9 +- .../test/mochitest/formautofill_common.js | 21 +- .../mochitest/test_autofill_and_ordinal_forms.html | 20 +- .../test/mochitest/test_autofocus_form.html | 8 +- .../mochitest/test_basic_autocomplete_form.html | 30 +- .../test/mochitest/test_form_changes.html | 21 +- .../test_formautofill_preview_highlight.html | 2 +- .../test/unit/test_addressComponent_state.js | 12 + .../formautofill/test/unit/test_getRecords.js | 28 +- .../formautofill/test/unit/test_phoneNumber.js | 2 +- .../test/unit/test_profileAutocompleteResult.js | 93 +++-- 28 files changed, 219 insertions(+), 846 deletions(-) delete mode 100644 browser/extensions/formautofill/content/customElements.js delete mode 100644 browser/extensions/formautofill/skin/linux/autocomplete-item.css delete mode 100644 browser/extensions/formautofill/skin/osx/autocomplete-item.css delete mode 100644 browser/extensions/formautofill/skin/shared/autocomplete-item-shared.css delete mode 100644 browser/extensions/formautofill/skin/windows/autocomplete-item.css (limited to 'browser/extensions/formautofill') diff --git a/browser/extensions/formautofill/api.js b/browser/extensions/formautofill/api.js index 967b4a8d63..2733e1361f 100644 --- a/browser/extensions/formautofill/api.js +++ b/browser/extensions/formautofill/api.js @@ -48,14 +48,6 @@ function ensureCssLoaded(domWindow) { } 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 { diff --git a/browser/extensions/formautofill/content/customElements.js b/browser/extensions/formautofill/content/customElements.js deleted file mode 100644 index 2f22a8173a..0000000000 --- a/browser/extensions/formautofill/content/customElements.js +++ /dev/null @@ -1,392 +0,0 @@ -/* 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._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 { primary, secondary, ariaLabel } = JSON.parse( - this.getAttribute("ac-value") - ); - - this._label.textContent = primary.toString().replaceAll("*", "•"); - this._comment.textContent = secondary.toString().replaceAll("*", "•"); - 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 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"); - } - - this._optionButton.textContent = value.manageLabel; - } - } - - 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/formautofill.css b/browser/extensions/formautofill/content/formautofill.css index 911b152f8d..8cf13da601 100644 --- a/browser/extensions/formautofill/content/formautofill.css +++ b/browser/extensions/formautofill/content/formautofill.css @@ -3,19 +3,12 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #PopupAutoComplete { - &[resultstyles~="autofill-profile"] { + &[resultstyles~="autofill"] { min-width: 150px !important; } - &[resultstyles~="autofill-insecureWarning"] { - min-width: 200px !important; - } - > richlistbox > richlistitem { - &[originaltype="autofill-profile"], - &[originaltype="autofill-footer"], - &[originaltype="autofill-insecureWarning"], - &[originaltype="autofill-clear-button"] { + &[originaltype="autofill"] { display: block; margin: 0; padding: 0; diff --git a/browser/extensions/formautofill/locales/en-US/formautofill.properties b/browser/extensions/formautofill/locales/en-US/formautofill.properties index d3add192d7..f63dbf8e20 100644 --- a/browser/extensions/formautofill/locales/en-US/formautofill.properties +++ b/browser/extensions/formautofill/locales/en-US/formautofill.properties @@ -2,27 +2,9 @@ # 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/. -# LOCALIZATION NOTE (category.address, category.name, category.organization2, category.tel, category.email): -# Used in autofill drop down suggestion to indicate what other categories Form Autofill will attempt to fill. -category.address = address -category.name = name -category.organization2 = organization -category.tel = phone -category.email = email -# LOCALIZATION NOTE (fieldNameSeparator): This is used as a separator between categories. -fieldNameSeparator = ,\u0020 -# LOCALIZATION NOTE (phishingWarningMessage, phishingWarningMessage2): The warning -# text that is displayed for informing users what categories are about to be filled. -# "%S" will be replaced with a list generated from the pre-defined categories. -# The text would be e.g. Also autofills organization, phone, email. -phishingWarningMessage = Also autofills %S -phishingWarningMessage2 = Autofills %S # LOCALIZATION NOTE (insecureFieldWarningDescription): %S is brandShortName. This string is used in drop down # suggestion when users try to autofill credit card on an insecure website (without https). insecureFieldWarningDescription = %S has detected an insecure site. Form Autofill is temporarily disabled. -# LOCALIZATION NOTE (clearFormBtnLabel2): Label for the button in the dropdown menu that used to clear the populated -# form. -clearFormBtnLabel2 = Clear Autofill Form learnMoreLabel = Learn more # LOCALIZATION NOTE (savedAddressesBtnLabel): Label for the button that opens a dialog that shows the diff --git a/browser/extensions/formautofill/moz.build b/browser/extensions/formautofill/moz.build index 2a94a19341..4dd89dc6ab 100644 --- a/browser/extensions/formautofill/moz.build +++ b/browser/extensions/formautofill/moz.build @@ -18,17 +18,14 @@ FINAL_TARGET_FILES.features["formautofill@mozilla.org"] += [ if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk": FINAL_TARGET_FILES.features["formautofill@mozilla.org"].chrome.content.skin += [ - "skin/linux/autocomplete-item.css", "skin/linux/editDialog.css", ] elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "cocoa": FINAL_TARGET_FILES.features["formautofill@mozilla.org"].chrome.content.skin += [ - "skin/osx/autocomplete-item.css", "skin/osx/editDialog.css", ] elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "windows": FINAL_TARGET_FILES.features["formautofill@mozilla.org"].chrome.content.skin += [ - "skin/windows/autocomplete-item.css", "skin/windows/editDialog.css", ] diff --git a/browser/extensions/formautofill/skin/linux/autocomplete-item.css b/browser/extensions/formautofill/skin/linux/autocomplete-item.css deleted file mode 100644 index 8f782aaa2a..0000000000 --- a/browser/extensions/formautofill/skin/linux/autocomplete-item.css +++ /dev/null @@ -1,10 +0,0 @@ -/* 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/. */ - -@namespace url("http://www.w3.org/1999/xhtml"); - - -.autofill-item-box { - --default-font-size: 14.25; -} diff --git a/browser/extensions/formautofill/skin/osx/autocomplete-item.css b/browser/extensions/formautofill/skin/osx/autocomplete-item.css deleted file mode 100644 index 121c1139da..0000000000 --- a/browser/extensions/formautofill/skin/osx/autocomplete-item.css +++ /dev/null @@ -1,18 +0,0 @@ -/* 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/. */ - -@namespace url("http://www.w3.org/1999/xhtml"); - -/* On Mac, the autocomplete panel changes color in system dark mode. We need - to change the contrast on warning-background-color accordingly. */ -@media (prefers-color-scheme: dark) { - .autofill-item-box { - --warning-background-color: rgba(248,232,28,.6); - } - } - - -.autofill-item-box { - --default-font-size: 11; -} diff --git a/browser/extensions/formautofill/skin/shared/autocomplete-item-shared.css b/browser/extensions/formautofill/skin/shared/autocomplete-item-shared.css deleted file mode 100644 index 876b8d6651..0000000000 --- a/browser/extensions/formautofill/skin/shared/autocomplete-item-shared.css +++ /dev/null @@ -1,182 +0,0 @@ -/* 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/. */ - -@namespace url("http://www.w3.org/1999/xhtml"); -@namespace xul url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"); - - -xul|richlistitem[originaltype="autofill-profile"][selected="true"] > .autofill-item-box { - background-color: SelectedItem; - color: SelectedItemText; -} - -xul|richlistitem[originaltype="autofill-footer"][selected="true"] > .autofill-item-box > .autofill-button, -xul|richlistitem[originaltype="autofill-clear-button"][selected="true"] > .autofill-item-box > .autofill-button { - background-color: ButtonHighlight; -} - -xul|richlistitem[originaltype="autofill-insecureWarning"] { - border-bottom: 1px solid var(--panel-separator-color); - background-color: var(--arrowpanel-dimmed); -} - -.autofill-item-box { - --item-padding-vertical: 7px; - --item-padding-horizontal: 10px; - --col-spacer: 7px; - --item-width: calc(50% - (var(--col-spacer) / 2)); - --comment-text-color: GreyText; - --warning-text-color: GreyText; - --warning-background-color: rgba(248, 232, 28, .2); - - --default-font-size: 12; - --label-font-size: 12; - --comment-font-size: 10; - --warning-font-size: 10; - --btn-font-size: 11; -} - -.autofill-item-box[size="small"] { - --item-padding-vertical: 7px; - --col-spacer: 0px; - --row-spacer: 3px; - --item-width: 100%; -} - -.autofill-item-box:not([ac-image=""]) { - --item-padding-vertical: 6.5px; - --comment-font-size: 11; -} - -.autofill-footer, -.autofill-footer[size="small"] { - --item-width: 100%; - --item-padding-vertical: 0; - --item-padding-horizontal: 0; -} - -.autofill-item-box { - box-sizing: border-box; - margin: 0; - border-bottom: 1px solid rgba(38,38,38,.15); - padding: var(--item-padding-vertical) 0; - padding-inline: var(--item-padding-horizontal); - display: flex; - flex-direction: row; - flex-wrap: wrap; - align-items: center; - background-color: Field; - color: FieldText; -} - -.autofill-item-box:last-child { - border-bottom: 0; -} - -.autofill-item-box > .profile-item-col { - box-sizing: border-box; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - width: var(--item-width); -} - -.autofill-item-box > .profile-label-col { - text-align: start; -} - -.autofill-item-box:not([ac-image=""]) > .profile-label-col::before { - margin-inline-end: 5px; - float: inline-start; - content: ""; - width: 16px; - height: 16px; - background-image: var(--primary-icon); - background-size: contain; - background-repeat: no-repeat; - background-position: center; - -moz-context-properties: fill; - fill: var(--comment-text-color) -} - -.autofill-item-box > .profile-label-col > .profile-label { - font-size: calc(var(--label-font-size) / var(--default-font-size) * 1em); - unicode-bidi: plaintext; -} - -.autofill-item-box > .profile-comment-col { - margin-inline-start: var(--col-spacer); - text-align: end; - color: var(--comment-text-color); -} - -.autofill-item-box > .profile-comment-col > .profile-comment { - font-size: calc(var(--comment-font-size) / var(--default-font-size) * 1em); - unicode-bidi: plaintext; -} - -.autofill-item-box[size="small"] { - flex-direction: column; -} - -.autofill-item-box[size="small"] > .profile-comment-col { - margin-top: var(--row-spacer); - text-align: start; -} - -.autofill-footer { - padding: 0; - flex-direction: column; -} - -.autofill-footer > .autofill-footer-row { - display: flex; - justify-content: center; - align-items: center; - width: var(--item-width); -} - -.autofill-footer > .autofill-warning { - padding: 2.5px 0; - color: var(--warning-text-color); - text-align: center; - background-color: var(--warning-background-color); - border-bottom: 1px solid rgba(38,38,38,.15); - font-size: calc(var(--warning-font-size) / var(--default-font-size) * 1em); -} - -.autofill-footer > .autofill-button { - box-sizing: border-box; - padding: 0 10px; - min-height: 40px; - background-color: ButtonFace; - font-size: calc(var(--btn-font-size) / var(--default-font-size) * 1em); - color: ButtonText; - text-align: center; -} - -.autofill-footer[no-warning="true"] > .autofill-warning { - display: none; -} - -.autofill-insecure-item { - box-sizing: border-box; - padding: 4px 0; - display: flex; - flex-direction: row; - flex-wrap: nowrap; - align-items: center; - color: GrayText; -} - -.autofill-insecure-item::before { - display: block; - margin-inline: 4px 8px; - content: ""; - width: 16px; - height: 16px; - background-image: url(chrome://global/skin/icons/security-broken.svg); - -moz-context-properties: fill; - fill: GrayText; -} diff --git a/browser/extensions/formautofill/skin/windows/autocomplete-item.css b/browser/extensions/formautofill/skin/windows/autocomplete-item.css deleted file mode 100644 index 4f0cb71346..0000000000 --- a/browser/extensions/formautofill/skin/windows/autocomplete-item.css +++ /dev/null @@ -1,25 +0,0 @@ -/* 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/. */ - -@namespace url("http://www.w3.org/1999/xhtml"); -@namespace xul url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"); - -.autofill-item-box { - --default-font-size: 12; -} - -xul|richlistitem[originaltype="autofill-footer"][selected="true"] > .autofill-item-box > .autofill-button, -xul|richlistitem[originaltype="autofill-clear-button"][selected="true"] > .autofill-item-box > .autofill-button { - background-color: color-mix(in srgb, Field 90%, FieldText); -} - -@media (prefers-contrast) { - xul|richlistitem[originaltype="autofill-profile"][selected="true"] > .autofill-item-box { - background-color: SelectedItem; - } - - .autofill-item-box { - --comment-text-color: GrayText; - } -} diff --git a/browser/extensions/formautofill/test/browser/address/browser_address_doorhanger_state.js b/browser/extensions/formautofill/test/browser/address/browser_address_doorhanger_state.js index f3b04d7f9c..003228c1cc 100644 --- a/browser/extensions/formautofill/test/browser/address/browser_address_doorhanger_state.js +++ b/browser/extensions/formautofill/test/browser/address/browser_address_doorhanger_state.js @@ -94,6 +94,10 @@ add_task(async function test_save_doorhanger_state_valid() { filled: { "address-level1": "CA" }, expected: { "address-level1": "CA" }, }, + { + filled: { "address-level1": "CA-BC" }, + expected: { "address-level1": "CA-BC" }, + }, { filled: { "address-level1": "california" }, expected: { "address-level1": "california" }, diff --git a/browser/extensions/formautofill/test/browser/address/browser_edit_address_doorhanger_display_state.js b/browser/extensions/formautofill/test/browser/address/browser_edit_address_doorhanger_display_state.js index 1d8933ad31..ccddbc743d 100644 --- a/browser/extensions/formautofill/test/browser/address/browser_edit_address_doorhanger_display_state.js +++ b/browser/extensions/formautofill/test/browser/address/browser_edit_address_doorhanger_display_state.js @@ -40,6 +40,10 @@ add_task(async function test_edit_doorhanger_display_state() { filled: { "address-level1": "Washington" }, expected: { label: "WA" }, }, + { + filled: { "address-level1": "CA-BC", country: "CA" }, + expected: { label: "BC" }, + }, ]; for (const TEST of TEST_CASES) { @@ -54,6 +58,7 @@ add_task(async function test_edit_doorhanger_display_state() { "#organization": DEFAULT.organization, "#street-address": DEFAULT["street-address"], "#address-level1": TEST.filled["address-level1"], + "#country": TEST.filled.country || DEFAULT.country, }, }); await onSavePopupShown; diff --git a/browser/extensions/formautofill/test/browser/browser_autocomplete_footer.js b/browser/extensions/formautofill/test/browser/browser_autocomplete_footer.js index 1e7ba523e8..1b4c934a38 100644 --- a/browser/extensions/formautofill/test/browser/browser_autocomplete_footer.js +++ b/browser/extensions/formautofill/test/browser/browser_autocomplete_footer.js @@ -14,6 +14,15 @@ add_setup(async function setup_storage() { ); }); +function getFooterLabel(itemsBox) { + let footer = itemsBox.getItemAtIndex(itemsBox.itemCount - 1); + while (footer.collapsed) { + footer = footer.previousSibling; + } + + return footer.querySelector(".line1-label"); +} + add_task(async function test_footer_has_correct_button_text_on_address() { await BrowserTestUtils.withNewTab( { gBrowser, url: URL }, @@ -23,9 +32,7 @@ add_task(async function test_footer_has_correct_button_text_on_address() { } = browser; await openPopupOn(browser, "#organization"); - const footer = itemsBox.querySelector( - ".autofill-footer-row.autofill-button" - ); + let footer = getFooterLabel(itemsBox); Assert.equal( footer.innerText, l10n.formatValueSync("autofill-manage-addresses-label") @@ -44,9 +51,7 @@ add_task(async function test_footer_has_correct_button_text_on_credit_card() { } = browser; await openPopupOn(browser, "#cc-number"); - const footer = itemsBox.querySelector( - ".autofill-footer-row.autofill-button" - ); + let footer = getFooterLabel(itemsBox); Assert.equal( footer.innerText, l10n.formatValueSync("autofill-manage-payment-methods-label") @@ -65,6 +70,7 @@ add_task(async function test_press_enter_on_footer() { } = browser; await openPopupOn(browser, "#organization"); + // Navigate to the footer and press enter. const listItemElems = itemsBox.querySelectorAll( ".autocomplete-richlistitem" @@ -75,7 +81,7 @@ add_task(async function test_press_enter_on_footer() { true ); for (let i = 0; i < listItemElems.length; i++) { - if (!listItemElems[i].collapsed) { + if (!listItemElems[i].disabled) { await BrowserTestUtils.synthesizeKey("VK_DOWN", {}, browser); } } @@ -110,7 +116,6 @@ add_task(async function test_click_on_footer() { while (optionButton.collapsed) { optionButton = optionButton.previousElementSibling; } - optionButton = optionButton._optionButton; const prefTabPromise = BrowserTestUtils.waitForNewTab( gBrowser, @@ -140,15 +145,7 @@ add_task(async function test_phishing_warning_single_category() { await BrowserTestUtils.withNewTab( { gBrowser, url: URL }, async function (browser) { - const { - autoCompletePopup: { richlistbox: itemsBox }, - } = browser; - await openPopupOn(browser, "#tel"); - const warningBox = itemsBox.querySelector( - ".autocomplete-richlistitem:last-child" - )._warningTextBox; - ok(warningBox, "Got phishing warning box"); await expectWarningText(browser, "Also autofills address"); await closePopup(browser); } diff --git a/browser/extensions/formautofill/test/browser/browser_dropdown_layout.js b/browser/extensions/formautofill/test/browser/browser_dropdown_layout.js index bc1d2fccab..41d57c20df 100644 --- a/browser/extensions/formautofill/test/browser/browser_dropdown_layout.js +++ b/browser/extensions/formautofill/test/browser/browser_dropdown_layout.js @@ -7,22 +7,6 @@ add_task(async function setup_storage() { await setStorage(TEST_ADDRESS_1, TEST_ADDRESS_2, TEST_ADDRESS_3); }); -async function reopenPopupWithResizedInput(browser, selector, newSize) { - await closePopup(browser); - /* eslint no-shadow: ["error", { "allow": ["selector", "newSize"] }] */ - await SpecialPowers.spawn( - browser, - [{ selector, newSize }], - async function ({ selector, newSize }) { - const input = content.document.querySelector(selector); - - input.style.boxSizing = "border-box"; - input.style.width = newSize + "px"; - } - ); - await openPopupOn(browser, selector); -} - add_task(async function test_address_dropdown() { await BrowserTestUtils.withNewTab( { gBrowser, url: URL }, @@ -33,20 +17,6 @@ add_task(async function test_address_dropdown() { is(firstItem.getAttribute("ac-image"), "", "Should not show icon"); - // The breakpoint of two-lines layout is 150px - await reopenPopupWithResizedInput(browser, focusInput, 140); - is( - firstItem._itemBox.getAttribute("size"), - "small", - "Show two-lines layout" - ); - await reopenPopupWithResizedInput(browser, focusInput, 160); - is( - firstItem._itemBox.hasAttribute("size"), - false, - "Show one-line layout" - ); - await closePopup(browser); } ); diff --git a/browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_dropdown_layout.js b/browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_dropdown_layout.js index 2b1fb9043c..ad28d857ae 100644 --- a/browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_dropdown_layout.js +++ b/browser/extensions/formautofill/test/browser/creditCard/browser_creditCard_dropdown_layout.js @@ -79,7 +79,7 @@ add_task(async function test_credit_card_dropdown_icon_invalid_types_select() { const creditCardItems = getDisplayedPopupItems( browser, - "[originaltype='autofill-profile']" + "[originaltype='autofill']" ); for (const [index, creditCardItem] of creditCardItems.entries()) { diff --git a/browser/extensions/formautofill/test/browser/creditCard/browser_insecure_form.js b/browser/extensions/formautofill/test/browser/creditCard/browser_insecure_form.js index 5de499b942..09c2f7e195 100644 --- a/browser/extensions/formautofill/test/browser/creditCard/browser_insecure_form.js +++ b/browser/extensions/formautofill/test/browser/creditCard/browser_insecure_form.js @@ -55,28 +55,28 @@ add_task(async function test_insecure_form() { urlPath: TEST_URL_PATH, protocol: "https", focusInput: "#organization", - expectedType: "autofill-profile", - expectedResultLength: 2, + expectedType: "autofill", + expectedResultLength: 3, // add one for the status row }, { urlPath: TEST_URL_PATH, protocol: "http", focusInput: "#organization", - expectedType: "autofill-profile", - expectedResultLength: 2, + expectedType: "autofill", + expectedResultLength: 3, // add one for the status row }, { urlPath: TEST_URL_PATH_CC, protocol: "https", focusInput: "#cc-name", - expectedType: "autofill-profile", - expectedResultLength: 3, + expectedType: "autofill", + expectedResultLength: 3, // no status row here }, { urlPath: TEST_URL_PATH_CC, protocol: "http", focusInput: "#cc-name", - expectedType: "autofill-insecureWarning", // insecure warning field + expectedType: "insecureWarning", // insecure warning field expectedResultLength: 1, }, ]; diff --git a/browser/extensions/formautofill/test/browser/head.js b/browser/extensions/formautofill/test/browser/head.js index 8de8488f1f..3f87f7b5ef 100644 --- a/browser/extensions/formautofill/test/browser/head.js +++ b/browser/extensions/formautofill/test/browser/head.js @@ -535,25 +535,6 @@ async function runAndWaitForAutocompletePopupOpen(browser, taskFn) { await taskFn(); await popupShown; - await BrowserTestUtils.waitForMutationCondition( - browser.autoCompletePopup.richlistbox, - { childList: true, subtree: true, attributes: true }, - () => { - const listItemElems = getDisplayedPopupItems(browser); - return ( - !![...listItemElems].length && - [...listItemElems].every(item => { - return ( - (item.getAttribute("originaltype") == "autofill-profile" || - item.getAttribute("originaltype") == "autofill-insecureWarning" || - item.getAttribute("originaltype") == "autofill-clear-button" || - item.getAttribute("originaltype") == "autofill-footer") && - item.hasAttribute("formautofillattached") - ); - }) - ); - } - ); } async function waitForPopupEnabled(browser) { @@ -595,7 +576,7 @@ function waitPopupStateInChild(bc, messageName) { async function openPopupOn(browser, selector) { let childNotifiedPromise = waitPopupStateInChild( browser, - "FormAutoComplete:PopupOpened" + "AutoComplete:PopupOpened" ); await SimpleTest.promiseFocus(browser); @@ -613,7 +594,7 @@ async function openPopupOn(browser, selector) { async function openPopupOnSubframe(browser, frameBrowsingContext, selector) { let childNotifiedPromise = waitPopupStateInChild( frameBrowsingContext, - "FormAutoComplete:PopupOpened" + "AutoComplete:PopupOpened" ); await SimpleTest.promiseFocus(browser); @@ -637,7 +618,7 @@ async function closePopup(browser) { let childNotifiedPromise = waitPopupStateInChild( browser, - "FormAutoComplete:PopupClosed" + "AutoComplete:PopupClosed" ); let popupClosePromise = BrowserTestUtils.waitForPopupEvent( browser.autoCompletePopup, @@ -655,7 +636,7 @@ async function closePopup(browser) { async function closePopupForSubframe(browser, frameBrowsingContext) { let childNotifiedPromise = waitPopupStateInChild( browser, - "FormAutoComplete:PopupClosed" + "AutoComplete:PopupClosed" ); let popupClosePromise = BrowserTestUtils.waitForPopupEvent( @@ -850,14 +831,8 @@ async function expectWarningText(browser, expectedText) { const { autoCompletePopup: { richlistbox: itemsBox }, } = browser; - let warningBox = itemsBox.querySelector( - ".autocomplete-richlistitem:last-child" - ); - - while (warningBox.collapsed) { - warningBox = warningBox.previousSibling; - } - warningBox = warningBox._warningTextBox; + let warningBox = itemsBox.querySelector(".ac-status"); + ok(warningBox.parentNode.disabled, "Got warning box and is disabled"); await BrowserTestUtils.waitForMutationCondition( warningBox, diff --git a/browser/extensions/formautofill/test/mochitest/creditCard/test_basic_creditcard_autocomplete_form.html b/browser/extensions/formautofill/test/mochitest/creditCard/test_basic_creditcard_autocomplete_form.html index 8d1333b727..717d40946f 100644 --- a/browser/extensions/formautofill/test/mochitest/creditCard/test_basic_creditcard_autocomplete_form.html +++ b/browser/extensions/formautofill/test/mochitest/creditCard/test_basic_creditcard_autocomplete_form.html @@ -59,6 +59,11 @@ async function setupFormHistory() { ]); } +function replaceStars(str) +{ + return str.replaceAll("*", "•") +} + initPopupListener(); // Form with history only. @@ -86,7 +91,7 @@ add_task(async function all_saved_fields_less_than_threshold() { synthesizeKey("KEY_ArrowDown"); checkMenuEntries([reducedMockRecord].map(patchRecordCCNumber).map(({ cc, expected }) => JSON.stringify({ primary: cc["cc-name"], - secondary: cc.ccNumberFmt, + secondary: replaceStars(cc.ccNumberFmt), ariaLabel: `Visa ${cc["cc-name"]} ${cc.ccNumberFmt}`, image: expected.image, }))); @@ -102,8 +107,8 @@ add_task(async function check_menu_when_both_existed() { await expectPopup(); synthesizeKey("KEY_ArrowDown"); checkMenuEntries(MOCK_STORAGE.map(patchRecordCCNumber).map(({ cc, expected }) => JSON.stringify({ - primary: cc.ccNumberFmt, - secondary: cc["cc-name"], + primary: replaceStars(cc.ccNumberFmt), + secondary: cc["cc-name"].toString(), ariaLabel: `${getCCTypeName(cc)} ${cc.ccNumberFmt.replaceAll("*", "")} ${cc["cc-name"]}`, image: expected.image, }))); @@ -112,8 +117,8 @@ add_task(async function check_menu_when_both_existed() { await expectPopup(); synthesizeKey("KEY_ArrowDown"); checkMenuEntries(MOCK_STORAGE.map(patchRecordCCNumber).map(({ cc, expected }) => JSON.stringify({ - primary: cc["cc-name"], - secondary: cc.ccNumberFmt, + primary: cc["cc-name"].toString(), + secondary: replaceStars(cc.ccNumberFmt), ariaLabel: `${getCCTypeName(cc)} ${cc["cc-name"]} ${cc.ccNumberFmt}`, image: expected.image, }))); @@ -122,8 +127,8 @@ add_task(async function check_menu_when_both_existed() { await expectPopup(); synthesizeKey("KEY_ArrowDown"); checkMenuEntries(MOCK_STORAGE.map(patchRecordCCNumber).map(({ cc, expected }) => JSON.stringify({ - primary: cc["cc-exp-year"], - secondary: cc.ccNumberFmt, + primary: cc["cc-exp-year"].toString(), + secondary: replaceStars(cc.ccNumberFmt), ariaLabel: `${getCCTypeName(cc)} ${cc["cc-exp-year"]} ${cc.ccNumberFmt}`, image: expected.image, }))); @@ -132,8 +137,8 @@ add_task(async function check_menu_when_both_existed() { await expectPopup(); synthesizeKey("KEY_ArrowDown"); checkMenuEntries(MOCK_STORAGE.map(patchRecordCCNumber).map(({ cc, expected }) => JSON.stringify({ - primary: cc["cc-exp-month"], - secondary: cc.ccNumberFmt, + primary: cc["cc-exp-month"].toString(), + secondary: replaceStars(cc.ccNumberFmt), ariaLabel: `${getCCTypeName(cc)} ${cc["cc-exp-month"]} ${cc.ccNumberFmt}`, image: expected.image, }))); @@ -185,8 +190,8 @@ add_task(async function check_fields_after_form_autofill() { // The popup doesn't auto-show on focus because the field isn't empty await expectPopup(); checkMenuEntries(MOCK_STORAGE.slice(1).map(patchRecordCCNumber).map(({ cc, expected }) => JSON.stringify({ - primary: cc["cc-exp-year"], - secondary: cc.ccNumberFmt, + primary: cc["cc-exp-year"].toString(), + secondary: replaceStars(cc.ccNumberFmt), ariaLabel: `${getCCTypeName(cc)} ${cc["cc-exp-year"]} ${cc.ccNumberFmt}`, image: expected.image, }))); @@ -220,7 +225,7 @@ add_task(async function check_cc_popup_on_field_blank() { await expectPopup(); checkMenuEntries(MOCK_STORAGE.map(patchRecordCCNumber).map(({ cc, expected }) => JSON.stringify({ primary: cc["cc-name"], - secondary: cc.ccNumberFmt, + secondary: replaceStars(cc.ccNumberFmt), ariaLabel: `${getCCTypeName(cc)} ${cc["cc-name"]} ${cc.ccNumberFmt}`, image: expected.image, }))); @@ -240,7 +245,7 @@ add_task(async function check_form_autofill_resume() { await expectPopup(); checkMenuEntries(MOCK_STORAGE.map(patchRecordCCNumber).map(({ cc, expected }) => JSON.stringify({ primary: cc["cc-name"], - secondary: cc.ccNumberFmt, + secondary: replaceStars(cc.ccNumberFmt), ariaLabel: `${getCCTypeName(cc)} ${cc["cc-name"]} ${cc.ccNumberFmt}`, image: expected.image, }))); diff --git a/browser/extensions/formautofill/test/mochitest/creditCard/test_creditcard_autocomplete_off.html b/browser/extensions/formautofill/test/mochitest/creditCard/test_creditcard_autocomplete_off.html index 04ff6ff85c..c42a1ad2d0 100644 --- a/browser/extensions/formautofill/test/mochitest/creditCard/test_creditcard_autocomplete_off.html +++ b/browser/extensions/formautofill/test/mochitest/creditCard/test_creditcard_autocomplete_off.html @@ -49,6 +49,11 @@ async function setupFormHistory() { ]); } +function replaceStars(str) +{ + return str.replaceAll("*", "•") +} + initPopupListener(); // Show Form History popup for non-autocomplete="off" field only @@ -73,7 +78,7 @@ add_task(async function check_menu_when_both_with_autocomplete_off() { synthesizeKey("KEY_ArrowDown"); await expectPopup(); checkMenuEntries(MOCK_STORAGE.map(patchRecordCCNumber).map(({ cc, expected }) => JSON.stringify({ - primary: cc.ccNumberFmt, + primary: replaceStars(cc.ccNumberFmt), secondary: cc["cc-name"], ariaLabel: `${getCCTypeName(cc)} ${cc.ccNumberFmt.replaceAll("*", "")} ${cc["cc-name"]}`, image: expected.image, @@ -84,7 +89,7 @@ add_task(async function check_menu_when_both_with_autocomplete_off() { await expectPopup(); checkMenuEntries(MOCK_STORAGE.map(patchRecordCCNumber).map(({ cc, expected }) => JSON.stringify({ primary: cc["cc-name"], - secondary: cc.ccNumberFmt, + secondary: replaceStars(cc.ccNumberFmt), ariaLabel: `${getCCTypeName(cc)} ${cc["cc-name"]} ${cc.ccNumberFmt}`, image: expected.image, }))); diff --git a/browser/extensions/formautofill/test/mochitest/formautofill_common.js b/browser/extensions/formautofill/test/mochitest/formautofill_common.js index 6cdf9ca86b..0e371ba3af 100644 --- a/browser/extensions/formautofill/test/mochitest/formautofill_common.js +++ b/browser/extensions/formautofill/test/mochitest/formautofill_common.js @@ -80,8 +80,9 @@ function clickOnElement(selector) { SimpleTest.executeSoon(() => element.click()); } -// The equivalent helper function to getAdaptedProfiles in FormAutofillHandler.jsm that -// transforms the given profile to expected filled profile. +// The equivalent helper function to getAdaptedProfiles in +// FormAutofillSection.sys.mjs that transforms the given profile to expected +// filled profile. function _getAdaptedProfile(profile) { const adaptedProfile = Object.assign({}, profile); @@ -270,12 +271,18 @@ async function onStorageChanged(type) { }); } -function checkMenuEntries(expectedValues, isFormAutofillResult = true) { +function makeAddressLabel({ primary, secondary, status }) { + return JSON.stringify({ + primary, + secondary, + status, + ariaLabel: primary + " " + secondary + " " + status, + }); +} + +function checkMenuEntries(expectedValues, extraRows = 1) { let actualValues = getMenuEntries(); - // Expect one more item would appear at the bottom as the footer if the result is from form autofill. - let expectedLength = isFormAutofillResult - ? expectedValues.length + 1 - : expectedValues.length; + let expectedLength = expectedValues.length + extraRows; is(actualValues.length, expectedLength, " Checking length of expected menu"); for (let i = 0; i < expectedValues.length; i++) { diff --git a/browser/extensions/formautofill/test/mochitest/test_autofill_and_ordinal_forms.html b/browser/extensions/formautofill/test/mochitest/test_autofill_and_ordinal_forms.html index ab3c08e89a..f3213d3708 100644 --- a/browser/extensions/formautofill/test/mochitest/test_autofill_and_ordinal_forms.html +++ b/browser/extensions/formautofill/test/mochitest/test_autofill_and_ordinal_forms.html @@ -31,6 +31,8 @@ let MOCK_STORAGE = [{ initPopupListener(); +let statusText = 'Also autofills address, name, organization'; + add_task(async function setupStorage() { await addAddress(MOCK_STORAGE[0]); @@ -46,9 +48,13 @@ add_task(async function check_switch_autofill_form_popup() { await expectPopup(); checkMenuEntries( [ - `{"primary":"+13453453456","secondary":"123 Sesame Street."}`, + makeAddressLabel({ + primary: "+13453453456", + secondary: "123 Sesame Street.", + status: statusText + }), + `{"primary":"","secondary":"","status":"${statusText}","style":"status"}`, ], - true ); await testMenuEntry(0, "!(el instanceof MozElements.MozAutocompleteRichlistitem)"); @@ -60,7 +66,7 @@ add_task(async function check_switch_oridnal_form_popup() { await setInput("#username", ""); synthesizeKey("KEY_ArrowDown"); await expectPopup(); - checkMenuEntries(["petya"], false); + checkMenuEntries(["petya"], 0); await testMenuEntry(0, "el instanceof MozElements.MozAutocompleteRichlistitem"); }); @@ -73,9 +79,13 @@ add_task(async function check_switch_autofill_form_popup_back() { await expectPopup(); checkMenuEntries( [ - `{"primary":"+13453453456","secondary":"123 Sesame Street."}`, + makeAddressLabel({ + primary: "+13453453456", + secondary: "123 Sesame Street.", + status: statusText + }), + `{"primary":"","secondary":"","status":"${statusText}","style":"status"}`, ], - true ); await testMenuEntry(0, "!(el instanceof MozElements.MozAutocompleteRichlistitem)"); diff --git a/browser/extensions/formautofill/test/mochitest/test_autofocus_form.html b/browser/extensions/formautofill/test/mochitest/test_autofocus_form.html index e2240474c8..2aa34f0c54 100644 --- a/browser/extensions/formautofill/test/mochitest/test_autofocus_form.html +++ b/browser/extensions/formautofill/test/mochitest/test_autofocus_form.html @@ -39,8 +39,12 @@ add_task(async function check_autocomplete_on_autofocus_field() { synthesizeKey("KEY_ArrowDown"); await expectPopup(); checkMenuEntries(MOCK_STORAGE.map(address => - JSON.stringify({primary: address.organization, secondary: address["street-address"]}) - )); + makeAddressLabel({ + primary: address.organization, + secondary: address["street-address"], + status: "Also autofills address, phone" + }) + ), 2); }); diff --git a/browser/extensions/formautofill/test/mochitest/test_basic_autocomplete_form.html b/browser/extensions/formautofill/test/mochitest/test_basic_autocomplete_form.html index a642b2abca..b8a50c7d7c 100644 --- a/browser/extensions/formautofill/test/mochitest/test_basic_autocomplete_form.html +++ b/browser/extensions/formautofill/test/mochitest/test_basic_autocomplete_form.html @@ -81,44 +81,48 @@ add_task(async function check_menu_when_both_existed() { synthesizeKey("KEY_ArrowDown"); await expectPopup(); checkMenuEntries(MOCK_STORAGE.map(address => - JSON.stringify({ + makeAddressLabel({ primary: address.organization, secondary: FormAutofillUtils.toOneLineAddress(address["street-address"]), + status: "Also autofills address, phone" }) - )); + ), 2); await setInput("#street-address", ""); await notExpectPopup(); synthesizeKey("KEY_ArrowDown"); await expectPopup(); checkMenuEntries(MOCK_STORAGE.map(address => - JSON.stringify({ + makeAddressLabel({ primary: FormAutofillUtils.toOneLineAddress(address["street-address"]), secondary: address.organization, + status: "Also autofills organization, phone" }) - )); + ), 2); await setInput("#tel", ""); await notExpectPopup(); synthesizeKey("KEY_ArrowDown"); await expectPopup(); checkMenuEntries(MOCK_STORAGE.map(address => - JSON.stringify({ + makeAddressLabel({ primary: address.tel, secondary: FormAutofillUtils.toOneLineAddress(address["street-address"]), + status: "Also autofills address, organization" }) - )); + ), 2); await setInput("#address-line1", ""); await notExpectPopup(); synthesizeKey("KEY_ArrowDown"); await expectPopup(); checkMenuEntries(MOCK_STORAGE.map(address => - JSON.stringify({ + makeAddressLabel({ primary: FormAutofillUtils.toOneLineAddress(address["street-address"]), secondary: address.organization, + status: "Also autofills organization, phone" }) - )); + ), 2); }); // Display history search result if no matched data in addresses. @@ -152,11 +156,12 @@ add_task(async function check_fields_after_form_autofill() { synthesizeKey("KEY_ArrowDown"); await expectPopup(); checkMenuEntries(MOCK_STORAGE.map(address => - JSON.stringify({ + makeAddressLabel({ primary: address.organization, secondary: FormAutofillUtils.toOneLineAddress(address["street-address"]), + status: "Also autofills address, phone" }) - ).slice(1)); + ).slice(1), 2); synthesizeKey("KEY_ArrowDown"); await triggerAutofillAndCheckProfile(MOCK_STORAGE[1]); synthesizeKey("KEY_Escape"); @@ -180,11 +185,12 @@ add_task(async function check_form_autofill_resume() { await setInput("#tel", ""); await triggerPopupAndHoverItem("#tel", 0); checkMenuEntries(MOCK_STORAGE.map(address => - JSON.stringify({ + makeAddressLabel({ primary: address.tel, secondary: FormAutofillUtils.toOneLineAddress(address["street-address"]), + status: "Also autofills address, organization" }) - )); + ), 2); await triggerAutofillAndCheckProfile(MOCK_STORAGE[0]); }); diff --git a/browser/extensions/formautofill/test/mochitest/test_form_changes.html b/browser/extensions/formautofill/test/mochitest/test_form_changes.html index 1bfc655328..dfe91a63e1 100644 --- a/browser/extensions/formautofill/test/mochitest/test_form_changes.html +++ b/browser/extensions/formautofill/test/mochitest/test_form_changes.html @@ -61,8 +61,12 @@ async function checkFormChangeHappened(formId) { await expectPopup(); synthesizeKey("KEY_ArrowDown"); checkMenuEntries(MOCK_STORAGE.map(address => - JSON.stringify({primary: address.tel, secondary: address.name}) - )); + makeAddressLabel({ + primary: address.tel, + secondary: address.name, + status: "Also autofills name, organization" + }) + ), 2); // Click the first entry of the autocomplete popup and make sure all fields are autofilled synthesizeKey("KEY_Enter"); @@ -76,8 +80,9 @@ async function checkFormChangeHappened(formId) { // Click on an autofilled field would show an autocomplete popup with "clear form" entry checkMenuEntries([ - JSON.stringify({primary: "", secondary: ""}), // Clear Autofill Form - ], true); + "Clear Autofill Form", // Clear Autofill Form + "Manage addresses" // FormAutofill Preferemce + ], 0); // This is for checking the changes of element removed and added then. document.querySelector(`#${formId} input[name=address-level2]`).remove(); @@ -87,8 +92,12 @@ async function checkFormChangeHappened(formId) { synthesizeKey("KEY_ArrowDown"); await expectPopup(); checkMenuEntries(MOCK_STORAGE.map(address => - JSON.stringify({primary: address["address-level2"], secondary: address.name}) - )); + makeAddressLabel({ + primary: address["address-level2"], + secondary: address.name, + status: "Also autofills name, organization, phone" + }) + ), 2); // Make sure everything is autofilled in the end synthesizeKey("KEY_ArrowDown"); diff --git a/browser/extensions/formautofill/test/mochitest/test_formautofill_preview_highlight.html b/browser/extensions/formautofill/test/mochitest/test_formautofill_preview_highlight.html index 3a372ae34e..19c7a82fe4 100644 --- a/browser/extensions/formautofill/test/mochitest/test_formautofill_preview_highlight.html +++ b/browser/extensions/formautofill/test/mochitest/test_formautofill_preview_highlight.html @@ -81,7 +81,7 @@ add_task(async function check_preview() { // Navigate to the footer synthesizeKey("KEY_ArrowDown"); - await notifySelectedIndex(MOCK_STORAGE.length); + await notifySelectedIndex(MOCK_STORAGE.length + 1); // skip over the status row await checkFormFieldsStyle(null); synthesizeKey("KEY_ArrowDown"); diff --git a/browser/extensions/formautofill/test/unit/test_addressComponent_state.js b/browser/extensions/formautofill/test/unit/test_addressComponent_state.js index 41d83e78c9..4e4c390008 100644 --- a/browser/extensions/formautofill/test/unit/test_addressComponent_state.js +++ b/browser/extensions/formautofill/test/unit/test_addressComponent_state.js @@ -7,14 +7,26 @@ const VALID_TESTS = [ ["CA", true], ["CA.", true], ["CC", false], + + // change region to CA + { region: "CA" }, + ["BC", true], + ["British Columbia", true], + ["CA-BC", true], ]; const COMPARE_TESTS = [ ["California", "california", SAME], // case insensitive ["CA", "california", SAME], ["CA", "ca", SAME], + ["CA", "CA.", SAME], ["California", "New Jersey", DIFFERENT], ["New York", "New Jersey", DIFFERENT], + + // change region to CA + { region: "CA" }, + ["British Columbia", "BC", SAME], + ["CA-BC", "BC", SAME], ]; const TEST_FIELD_NAME = "address-level1"; diff --git a/browser/extensions/formautofill/test/unit/test_getRecords.js b/browser/extensions/formautofill/test/unit/test_getRecords.js index 9a7e5e6ac7..1ecbccab22 100644 --- a/browser/extensions/formautofill/test/unit/test_getRecords.js +++ b/browser/extensions/formautofill/test/unit/test_getRecords.js @@ -85,7 +85,7 @@ add_task(async function test_getRecords() { sinon.stub(collection, "getAll"); collection.getAll.returns(Promise.resolve(expectedResult)); } - await FormAutofillParent._getRecords({ collectionName }); + await FormAutofillParent.getRecords({ collectionName }); if (collection) { Assert.equal(collection.getAll.called, true); collection.getAll.restore(); @@ -105,7 +105,7 @@ add_task(async function test_getRecords_addresses() { description: "If the search string could match 1 address", filter: { collectionName: "addresses", - info: { fieldName: "street-address" }, + fieldName: "street-address", searchString: "Some", }, expectedResult: [TEST_ADDRESS_2], @@ -114,7 +114,7 @@ add_task(async function test_getRecords_addresses() { description: "If the search string could match multiple addresses", filter: { collectionName: "addresses", - info: { fieldName: "country" }, + fieldName: "country", searchString: "u", }, expectedResult: [TEST_ADDRESS_1, TEST_ADDRESS_2], @@ -123,7 +123,7 @@ add_task(async function test_getRecords_addresses() { description: "If the search string could not match any address", filter: { collectionName: "addresses", - info: { fieldName: "street-address" }, + fieldName: "street-address", searchString: "test", }, expectedResult: [], @@ -132,7 +132,7 @@ add_task(async function test_getRecords_addresses() { description: "If the search string is empty", filter: { collectionName: "addresses", - info: { fieldName: "street-address" }, + fieldName: "street-address", searchString: "", }, expectedResult: [TEST_ADDRESS_1, TEST_ADDRESS_2], @@ -142,7 +142,7 @@ add_task(async function test_getRecords_addresses() { "Check if the filtering logic is free from searching special chars", filter: { collectionName: "addresses", - info: { fieldName: "street-address" }, + fieldName: "street-address", searchString: ".*", }, expectedResult: [], @@ -152,7 +152,7 @@ add_task(async function test_getRecords_addresses() { "Prevent broken while searching the property that does not exist", filter: { collectionName: "addresses", - info: { fieldName: "tel" }, + fieldName: "tel", searchString: "1", }, expectedResult: [], @@ -161,7 +161,7 @@ add_task(async function test_getRecords_addresses() { for (let testCase of testCases) { info("Starting testcase: " + testCase.description); - let result = await FormAutofillParent._getRecords(testCase.filter); + let result = await FormAutofillParent.getRecords(testCase.filter); Assert.deepEqual(result, testCase.expectedResult); } }); @@ -195,7 +195,7 @@ add_task(async function test_getRecords_creditCards() { description: "If the search string could match multiple creditCards", filter: { collectionName: "creditCards", - info: { fieldName: "cc-name" }, + fieldName: "cc-name", searchString: "John", }, expectedResult: encryptedCCRecords, @@ -204,7 +204,7 @@ add_task(async function test_getRecords_creditCards() { description: "If the search string could not match any creditCard", filter: { collectionName: "creditCards", - info: { fieldName: "cc-name" }, + fieldName: "cc-name", searchString: "T", }, expectedResult: [], @@ -215,7 +215,7 @@ add_task(async function test_getRecords_creditCards() { "if the search string could match multiple creditCards", filter: { collectionName: "creditCards", - info: { fieldName: "cc-number" }, + fieldName: "cc-number", searchString: "4", }, expectedResult: encryptedCCRecords, @@ -224,7 +224,7 @@ add_task(async function test_getRecords_creditCards() { description: "If the search string could match 1 creditCard", filter: { collectionName: "creditCards", - info: { fieldName: "cc-name" }, + fieldName: "cc-name", searchString: "John Doe", }, mpEnabled: true, @@ -234,7 +234,7 @@ add_task(async function test_getRecords_creditCards() { description: "Return all creditCards if focused field is cc number", filter: { collectionName: "creditCards", - info: { fieldName: "cc-number" }, + fieldName: "cc-number", searchString: "411", }, mpEnabled: true, @@ -252,7 +252,7 @@ add_task(async function test_getRecords_creditCards() { token.reset(); token.initPassword("password"); } - let result = await FormAutofillParent._getRecords(testCase.filter); + let result = await FormAutofillParent.getRecords(testCase.filter); Assert.deepEqual(result, testCase.expectedResult); } }); diff --git a/browser/extensions/formautofill/test/unit/test_phoneNumber.js b/browser/extensions/formautofill/test/unit/test_phoneNumber.js index 133e54f6d7..b776bfd8b5 100644 --- a/browser/extensions/formautofill/test/unit/test_phoneNumber.js +++ b/browser/extensions/formautofill/test/unit/test_phoneNumber.js @@ -1,5 +1,5 @@ /** - * Tests PhoneNumber.jsm and PhoneNumberNormalizer.jsm. + * Tests PhoneNumber.sys.mjs and PhoneNumberNormalizer.sys.mjs. */ "use strict"; diff --git a/browser/extensions/formautofill/test/unit/test_profileAutocompleteResult.js b/browser/extensions/formautofill/test/unit/test_profileAutocompleteResult.js index 7200bc8975..30cdae3d8a 100644 --- a/browser/extensions/formautofill/test/unit/test_profileAutocompleteResult.js +++ b/browser/extensions/formautofill/test/unit/test_profileAutocompleteResult.js @@ -51,6 +51,15 @@ let allFieldNames = [ "tel", ]; +function makeAddressLabel({ primary, secondary, status }) { + return JSON.stringify({ + primary, + secondary, + status, + ariaLabel: primary + " " + secondary + " " + status, + }); +} + let addressTestCases = [ { description: "Focus on an `organization` field", @@ -65,21 +74,23 @@ let addressTestCases = [ items: [ { value: "", - style: "autofill-profile", + style: "autofill", comment: JSON.stringify(matchingProfiles[0]), - label: JSON.stringify({ + label: makeAddressLabel({ primary: "Sesame Street", secondary: "123 Sesame Street.", + status: "Also autofills address, name, phone", }), image: "", }, { value: "", - style: "autofill-profile", + style: "autofill", comment: JSON.stringify(matchingProfiles[1]), - label: JSON.stringify({ + label: makeAddressLabel({ primary: "Mozilla", secondary: "331 E. Evelyn Avenue", + status: "Also autofills address, name, phone", }), image: "", }, @@ -99,31 +110,34 @@ let addressTestCases = [ items: [ { value: "", - style: "autofill-profile", + style: "autofill", comment: JSON.stringify(matchingProfiles[0]), - label: JSON.stringify({ + label: makeAddressLabel({ primary: "1-345-345-3456.", secondary: "123 Sesame Street.", + status: "Also autofills address, name, organization", }), image: "", }, { value: "", - style: "autofill-profile", + style: "autofill", comment: JSON.stringify(matchingProfiles[1]), - label: JSON.stringify({ + label: makeAddressLabel({ primary: "1-650-903-0800", secondary: "331 E. Evelyn Avenue", + status: "Also autofills address, name, organization", }), image: "", }, { value: "", - style: "autofill-profile", + style: "autofill", comment: JSON.stringify(matchingProfiles[2]), - label: JSON.stringify({ + label: makeAddressLabel({ primary: "1-000-000-0000", secondary: "321, No Name St. 2nd line 3rd line", + status: "Also autofills address", }), image: "", }, @@ -143,31 +157,34 @@ let addressTestCases = [ items: [ { value: "", - style: "autofill-profile", + style: "autofill", comment: JSON.stringify(matchingProfiles[0]), - label: JSON.stringify({ + label: makeAddressLabel({ primary: "123 Sesame Street.", secondary: "Timothy Berners-Lee", + status: "Also autofills name, organization, phone", }), image: "", }, { value: "", - style: "autofill-profile", + style: "autofill", comment: JSON.stringify(matchingProfiles[1]), - label: JSON.stringify({ + label: makeAddressLabel({ primary: "331 E. Evelyn Avenue", secondary: "John Doe", + status: "Also autofills name, organization, phone", }), image: "", }, { value: "", - style: "autofill-profile", + style: "autofill", comment: JSON.stringify(matchingProfiles[2]), - label: JSON.stringify({ + label: makeAddressLabel({ primary: "321, No Name St. 2nd line 3rd line", secondary: "1-000-000-0000", + status: "Also autofills phone", }), image: "", }, @@ -187,31 +204,34 @@ let addressTestCases = [ items: [ { value: "", - style: "autofill-profile", + style: "autofill", comment: JSON.stringify(matchingProfiles[0]), - label: JSON.stringify({ + label: makeAddressLabel({ primary: "123 Sesame Street.", secondary: "Timothy Berners-Lee", + status: "Also autofills name, organization, phone", }), image: "", }, { value: "", - style: "autofill-profile", + style: "autofill", comment: JSON.stringify(matchingProfiles[1]), - label: JSON.stringify({ + label: makeAddressLabel({ primary: "331 E. Evelyn Avenue", secondary: "John Doe", + status: "Also autofills name, organization, phone", }), image: "", }, { value: "", - style: "autofill-profile", + style: "autofill", comment: JSON.stringify(matchingProfiles[2]), - label: JSON.stringify({ + label: makeAddressLabel({ primary: "321, No Name St.", secondary: "1-000-000-0000", + status: "Also autofills phone", }), image: "", }, @@ -287,11 +307,11 @@ let creditCardTestCases = [ items: [ { value: "", - style: "autofill-profile", + style: "autofill", comment: JSON.stringify(matchingProfiles[0]), label: JSON.stringify({ primary: "Timothy Berners-Lee", - secondary: "****6785", + secondary: "••••6785", ariaLabel: "Visa Timothy Berners-Lee ****6785", image: "chrome://formautofill/content/third-party/cc-logo-visa.svg", }), @@ -299,11 +319,11 @@ let creditCardTestCases = [ }, { value: "", - style: "autofill-profile", + style: "autofill", comment: JSON.stringify(matchingProfiles[1]), label: JSON.stringify({ primary: "John Doe", - secondary: "****1234", + secondary: "••••1234", ariaLabel: "American Express John Doe ****1234", image: "chrome://formautofill/content/third-party/cc-logo-amex.png", }), @@ -325,10 +345,10 @@ let creditCardTestCases = [ items: [ { value: "", - style: "autofill-profile", + style: "autofill", comment: JSON.stringify(matchingProfiles[0]), label: JSON.stringify({ - primary: "****6785", + primary: "••••6785", secondary: "Timothy Berners-Lee", ariaLabel: "Visa 6785 Timothy Berners-Lee", image: "chrome://formautofill/content/third-party/cc-logo-visa.svg", @@ -337,10 +357,10 @@ let creditCardTestCases = [ }, { value: "", - style: "autofill-profile", + style: "autofill", comment: JSON.stringify(matchingProfiles[1]), label: JSON.stringify({ - primary: "****1234", + primary: "••••1234", secondary: "John Doe", ariaLabel: "American Express 1234 John Doe", image: "chrome://formautofill/content/third-party/cc-logo-amex.png", @@ -349,10 +369,10 @@ let creditCardTestCases = [ }, { value: "", - style: "autofill-profile", + style: "autofill", comment: JSON.stringify(matchingProfiles[2]), label: JSON.stringify({ - primary: "****5678", + primary: "••••5678", secondary: "", ariaLabel: "5678", image: "chrome://formautofill/content/icon-credit-card-generic.svg", @@ -416,7 +436,14 @@ add_task(async function test_all_patterns() { let expectedItemLength = expectedValue.items.length; // If the last item shows up as a footer, we expect one more item // than expected. - if (actual.getStyleAt(actual.matchCount - 1) == "autofill-footer") { + if (actual.getStyleAt(actual.matchCount - 1) == "action") { + expectedItemLength++; + } + // Add one row for the status. + if ( + actual.matchCount > 2 && + actual.getStyleAt(actual.matchCount - 2) == "status" + ) { expectedItemLength++; } -- cgit v1.2.3