Bug 1446164 - Migrate formautofill edit dialogs to Fluent. r=sgalich,fluent-reviewers,flod

Migrating the strings used by the edit dialogs also allows/requires for their migration elsewhere.

Some streamlining is applied to how autofillEditForms.js gets access to e.g. FormFillUtils methods, so that they are no longer routed via the XHTML files' script tags. The prior independence of this file from internal dependencies appears to have been in place to support its use as a part of the Payments API's UI, but that was dropped in bug 1721229.

The Fluent migration script included in this patch also covers changes from the immediately preceding patch.

The intl documentation change is a typo correction that was noticed while working on this patch.

Depends on D155478

Differential Revision: https://phabricator.services.mozilla.com/D155705
This commit is contained in:
Eemeli Aro 2022-09-01 08:26:47 +00:00
Родитель 107c5bf2d9
Коммит 5475c4b139
15 изменённых файлов: 569 добавлений и 439 удалений

Просмотреть файл

@ -7,6 +7,13 @@
"use strict";
const { FormAutofill } = ChromeUtils.import(
"resource://autofill/FormAutofill.jsm"
);
const { FormAutofillUtils } = ChromeUtils.import(
"resource://autofill/FormAutofillUtils.jsm"
);
class EditAutofillForm {
constructor(elements) {
this._elements = elements;
@ -141,11 +148,6 @@ class EditAddress extends EditAutofillForm {
* @param {HTMLElement[]} elements
* @param {object} record
* @param {object} config
* @param {string[]} config.DEFAULT_REGION
* @param {function} config.getFormFormat Function to return form layout info for a given country.
* @param {function} config.findAddressSelectOption Finds the matching select option for a given
select element, address, and fieldName.
* @param {string[]} config.countries
* @param {boolean} [config.noValidate=undefined] Whether to validate the form
*/
constructor(elements, record, config) {
@ -182,11 +184,13 @@ class EditAddress extends EditAutofillForm {
this._record = record;
if (!record) {
record = {
country: this.DEFAULT_REGION,
country: FormAutofill.DEFAULT_REGION,
};
}
let { addressLevel1Options } = this.getFormFormat(record.country);
let { addressLevel1Options } = FormAutofillUtils.getFormFormat(
record.country
);
this.populateAddressLevel1(addressLevel1Options, record.country);
super.loadRecord(record);
@ -257,19 +261,32 @@ class EditAddress extends EditAutofillForm {
*/
formatForm(country) {
const {
addressLevel3Label,
addressLevel2Label,
addressLevel1Label,
addressLevel3L10nId,
addressLevel2L10nId,
addressLevel1L10nId,
addressLevel1Options,
postalCodeLabel,
postalCodeL10nId,
fieldsOrder: mailingFieldsOrder,
postalCodePattern,
countryRequiredFields,
} = this.getFormFormat(country);
this._elements.addressLevel3Label.dataset.localization = addressLevel3Label;
this._elements.addressLevel2Label.dataset.localization = addressLevel2Label;
this._elements.addressLevel1Label.dataset.localization = addressLevel1Label;
this._elements.postalCodeLabel.dataset.localization = postalCodeLabel;
} = 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(
@ -376,7 +393,7 @@ class EditAddress extends EditAutofillForm {
return;
}
let matchedSelectOption = this.findAddressSelectOption(
let matchedSelectOption = FormAutofillUtils.findAddressSelectOption(
field,
{
country,
@ -451,13 +468,14 @@ class EditAddress extends EditAutofillForm {
populateCountries() {
let fragment = document.createDocumentFragment();
// Sort countries by their visible names.
let countries = [...this.countries.entries()].sort((e1, e2) =>
let countries = [...FormAutofill.countries.entries()].sort((e1, e2) =>
e1[1].localeCompare(e2[1])
);
for (let country of countries) {
let option = new Option();
option.value = country[0];
option.dataset.localizationRegion = country[0].toLowerCase();
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);
@ -481,15 +499,11 @@ 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.
* @param {object} config
* @param {function} config.isCCNumber Function to determine if a string is a valid CC number.
* @param {function} config.getSupportedNetworks Function to get the list of card networks
*/
constructor(elements, record, addresses, config) {
constructor(elements, record, addresses) {
super(elements);
this._addresses = addresses;
Object.assign(this, config);
Object.assign(this._elements, {
ccNumber: this._elements.form.querySelector("#cc-number"),
invalidCardNumberStringElement: this._elements.form.querySelector(
@ -581,11 +595,11 @@ class EditCreditCard extends EditAutofillForm {
// include an empty first option
frag.appendChild(new Option("", ""));
let supportedNetworks = this.getSupportedNetworks();
let supportedNetworks = FormAutofillUtils.getCreditCardNetworks();
for (let id of supportedNetworks) {
let option = new Option();
option.value = id;
option.dataset.localization = "cardNetwork." + id;
const option = new Option(undefined, id);
// autofill-card-network-amex, ..., autofill-card-network-visa
option.dataset.l10nId = `autofill-card-network-${id}`;
frag.appendChild(option);
}
this._elements.ccType.appendChild(frag);
@ -608,7 +622,7 @@ class EditCreditCard extends EditAutofillForm {
hasAddresses = true;
let selected = guid == billingAddressGUID;
let option = new Option(
this.getAddressLabel(address),
FormAutofillUtils.getAddressLabel(address),
guid,
selected,
selected
@ -628,7 +642,7 @@ class EditCreditCard extends EditAutofillForm {
// Clear the error message if cc-number is valid
if (
event.target == this._elements.ccNumber &&
this.isCCNumber(this._elements.ccNumber.value)
FormAutofillUtils.isCCNumber(this._elements.ccNumber.value)
) {
this._elements.ccNumber.setCustomValidity("");
}
@ -639,7 +653,10 @@ class EditCreditCard extends EditAutofillForm {
super.updateCustomValidity(field);
// Mark the cc-number field as invalid if the number is empty or invalid.
if (field == this._elements.ccNumber && !this.isCCNumber(field.value)) {
if (
field == this._elements.ccNumber &&
!FormAutofillUtils.isCCNumber(field.value)
) {
let invalidCardNumberString = this._elements
.invalidCardNumberStringElement.textContent;
field.setCustomValidity(invalidCardNumberString || " ");

Просмотреть файл

@ -2,21 +2,18 @@
<!-- 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/. -->
<!DOCTYPE html [
<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
%globalDTD;
]>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title data-localization="addNewAddressTitle"/>
<title data-l10n-id="autofill-add-new-address-title"></title>
<link rel="localization" href="browser/preferences/formAutofill.ftl"/>
<link rel="stylesheet" href="chrome://formautofill/content/skin/editDialog-shared.css"/>
<link rel="stylesheet" href="chrome://formautofill/content/skin/editAddress.css"/>
<link rel="stylesheet" href="chrome://formautofill/content/skin/editDialog.css"/>
<script src="chrome://formautofill/content/l10n.js"></script>
<script src="chrome://formautofill/content/editDialog.js"></script>
<script src="chrome://formautofill/content/autofillEditForms.js"></script>
</head>
<body dir="&locale.dir;">
<body>
<form id="form" class="editAddressForm" autocomplete="off">
<!--
The <span class="label-text" /> needs to be after the form field in the same element in
@ -25,24 +22,24 @@
<div id="name-container" class="container">
<label id="given-name-container">
<input id="given-name" type="text" required="required"/>
<span data-localization="givenName" class="label-text"/>
<span data-l10n-id="autofill-address-given-name" class="label-text"/>
</label>
<label id="additional-name-container">
<input id="additional-name" type="text"/>
<span data-localization="additionalName" class="label-text"/>
<span data-l10n-id="autofill-address-additional-name" class="label-text"/>
</label>
<label id="family-name-container">
<input id="family-name" type="text" required="required"/>
<span data-localization="familyName" class="label-text"/>
<span data-l10n-id="autofill-address-family-name" class="label-text"/>
</label>
</div>
<label id="organization-container" class="container">
<input id="organization" type="text"/>
<span data-localization="organization2" class="label-text"/>
<span data-l10n-id="autofill-address-organization" class="label-text"/>
</label>
<label id="street-address-container" class="container">
<textarea id="street-address" rows="3"/>
<span data-localization="streetAddress" class="label-text"/>
<span data-l10n-id="autofill-address-street" class="label-text"/>
</label>
<label id="address-level3-container" class="container">
<input id="address-level3" type="text"/>
@ -67,49 +64,34 @@
<select id="country" required="required">
<option/>
</select>
<span data-localization="country" class="label-text"/>
<span data-l10n-id="autofill-address-country" class="label-text"/>
</label>
<label id="tel-container" class="container">
<input id="tel" type="tel" dir="auto"/>
<span data-localization="tel" class="label-text"/>
<span data-l10n-id="autofill-address-tel" class="label-text"/>
</label>
<label id="email-container" class="container">
<input id="email" type="email" required="required"/>
<span data-localization="email" class="label-text"/>
<span data-l10n-id="autofill-address-email" class="label-text"/>
</label>
</form>
<div id="controls-container">
<span id="country-warning-message" data-localization="countryWarningMessage2"/>
<button id="cancel" data-localization="cancelBtnLabel"/>
<button id="save" class="primary" data-localization="saveBtnLabel"/>
<span id="country-warning-message" data-l10n-id="autofill-country-warning-message"/>
<button id="cancel" data-l10n-id="autofill-cancel-button"/>
<button id="save" class="primary" data-l10n-id="autofill-save-button"/>
</div>
<script><![CDATA[
"use strict";
/* import-globals-from l10n.js */
let {
DEFAULT_REGION,
countries,
} = FormAutofill;
let {
getFormFormat,
findAddressSelectOption,
} = FormAutofillUtils;
let args = window.arguments || [];
let {
const {
record,
noValidate,
} = args[0] || {};
} = window.arguments?.[0] ?? {};
/* import-globals-from autofillEditForms.js */
var fieldContainer = new EditAddress({
const fieldContainer = new EditAddress({
form: document.getElementById("form"),
}, record, {
DEFAULT_REGION,
getFormFormat: getFormFormat.bind(FormAutofillUtils),
findAddressSelectOption: findAddressSelectOption.bind(FormAutofillUtils),
countries,
noValidate,
});

Просмотреть файл

@ -2,55 +2,52 @@
<!-- 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/. -->
<!DOCTYPE html [
<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
%globalDTD;
]>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title data-localization="addNewCreditCardTitle"/>
<title data-l10n-id="autofill-add-new-card-title"></title>
<link rel="localization" href="browser/preferences/formAutofill.ftl"/>
<link rel="stylesheet" href="chrome://formautofill/content/skin/editDialog-shared.css"/>
<link rel="stylesheet" href="chrome://formautofill/content/skin/editCreditCard.css"/>
<link rel="stylesheet" href="chrome://formautofill/content/skin/editDialog.css"/>
<script src="chrome://formautofill/content/l10n.js"></script>
<script src="chrome://formautofill/content/editDialog.js"></script>
<script src="chrome://formautofill/content/autofillEditForms.js"></script>
</head>
<body dir="&locale.dir;">
<body>
<form id="form" class="editCreditCardForm contentPane" autocomplete="off">
<!--
The <span class="label-text" /> needs to be after the form field in the same element in
order to get proper label styling with :focus and :moz-ui-invalid.
-->
<label id="cc-number-container" class="container" role="none">
<span id="invalidCardNumberString" hidden="hidden" data-localization="invalidCardNumber"></span>
<span id="invalidCardNumberString" hidden="hidden" data-l10n-id="autofill-card-invalid-number"></span>
<!-- Because there is text both before and after the input, a11y will
include the value of the input in the label. Therefore, we override
with aria-labelledby.
-->
<input id="cc-number" type="text" required="required" minlength="14" pattern="[- 0-9]+" aria-labelledby="cc-number-label"/>
<span id="cc-number-label" data-localization="cardNumber" class="label-text"/>
<span id="cc-number-label" data-l10n-id="autofill-card-number" class="label-text"/>
</label>
<label id="cc-exp-month-container" class="container">
<select id="cc-exp-month" required="required">
<option/>
</select>
<span data-localization="cardExpiresMonth" class="label-text"/>
<span data-l10n-id="autofill-card-expires-month" class="label-text"/>
</label>
<label id="cc-exp-year-container" class="container">
<select id="cc-exp-year" required="required">
<option/>
</select>
<span data-localization="cardExpiresYear" class="label-text"/>
<span data-l10n-id="autofill-card-expires-year" class="label-text"/>
</label>
<label id="cc-name-container" class="container">
<input id="cc-name" type="text" required="required"/>
<span data-localization="nameOnCard" class="label-text"/>
<span data-l10n-id="autofill-card-name-on-card" class="label-text"/>
</label>
<label id="cc-type-container" class="container">
<select id="cc-type" required="required">
</select>
<span data-localization="cardNetwork" class="label-text"/>
<span data-l10n-id="autofill-card-network" class="label-text"/>
</label>
<label id="cc-csc-container" class="container" hidden="hidden">
<!-- The CSC container will get filled in by forms that need a CSC (using csc-input.js) -->
@ -58,45 +55,33 @@
<div id="billingAddressGUID-container" class="billingAddressRow container rich-picker">
<select id="billingAddressGUID" required="required">
</select>
<label for="billingAddressGUID" data-localization="billingAddress" class="label-text"/>
<label for="billingAddressGUID" data-l10n-id="autofill-card-billing-address" class="label-text"/>
</div>
</form>
<div id="controls-container">
<button id="cancel" data-localization="cancelBtnLabel"/>
<button id="save" class="primary" data-localization="saveBtnLabel"/>
<button id="cancel" data-l10n-id="autofill-cancel-button"/>
<button id="save" class="primary" data-l10n-id="autofill-save-button"/>
</div>
<script><![CDATA[
"use strict";
/* import-globals-from l10n.js */
/* import-globals-from editDialog.js */
(async () => {
let {
getAddressLabel,
isCCNumber,
getCreditCardNetworks,
} = FormAutofillUtils;
let args = window.arguments || [];
let {
const {
record,
} = args[0] || {};
} = window.arguments?.[0] ?? {};
let addresses = {};
const addresses = {};
for (let address of await formAutofillStorage.addresses.getAll()) {
addresses[address.guid] = address;
}
/* import-globals-from autofillEditForms.js */
let fieldContainer = new EditCreditCard({
const fieldContainer = new EditCreditCard({
form: document.getElementById("form"),
}, record, addresses,
{
getAddressLabel: getAddressLabel.bind(FormAutofillUtils),
isCCNumber: isCCNumber.bind(FormAutofillUtils),
getSupportedNetworks: getCreditCardNetworks.bind(FormAutofillUtils),
});
}, record, addresses);
/* import-globals-from editDialog.js */
new EditCreditCardDialog({
title: document.querySelector("title"),
fieldContainer,

Просмотреть файл

@ -7,11 +7,6 @@
"use strict";
// eslint-disable-next-line no-unused-vars
const { FormAutofill } = ChromeUtils.import(
"resource://autofill/FormAutofill.jsm"
);
ChromeUtils.defineModuleGetter(
this,
"formAutofillStorage",
@ -160,7 +155,10 @@ class EditAddressDialog extends AutofillEditDialog {
localizeDocument() {
if (this._record?.guid) {
this._elements.title.dataset.localization = "editAddressTitle";
document.l10n.setAttributes(
this._elements.title,
"autofill-edit-address-title"
);
}
}
@ -193,7 +191,10 @@ class EditCreditCardDialog extends AutofillEditDialog {
localizeDocument() {
if (this._record?.guid) {
this._elements.title.dataset.localization = "editCreditCardTitle";
document.l10n.setAttributes(
this._elements.title,
"autofill-edit-card-title"
);
}
}

Просмотреть файл

@ -1,64 +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/. */
"use strict";
/**
* This file will be replaced by Fluent but it's a middle ground so we can share
* the edit dialog code with the unprivileged PaymentRequest dialog before the
* Fluent conversion
*/
const { FormAutofillUtils } = ChromeUtils.import(
"resource://autofill/FormAutofillUtils.jsm"
);
const CONTENT_WIN = typeof window != "undefined" ? window : this;
const L10N_ATTRIBUTES = ["data-localization", "data-localization-region"];
// eslint-disable-next-line mozilla/balanced-listeners
CONTENT_WIN.addEventListener("DOMContentLoaded", function onDCL(evt) {
let doc = evt.target;
FormAutofillUtils.localizeMarkup(doc);
let mutationObserver = new doc.ownerGlobal.MutationObserver(
function onMutation(mutations) {
for (let mutation of mutations) {
switch (mutation.type) {
case "attributes": {
if (!mutation.target.hasAttribute(mutation.attributeName)) {
// The attribute was removed in the meantime.
continue;
}
FormAutofillUtils.localizeAttributeForElement(
mutation.target,
mutation.attributeName
);
break;
}
case "childList": {
// We really only care about elements appending inside pages.
let parent = HTMLDocument.isInstance(mutation.target)
? mutation.target.documentElement
: mutation.target;
if (!mutation.addedNodes || !parent.closest(".page")) {
break;
}
FormAutofillUtils.localizeMarkup(mutation.target);
break;
}
}
}
}
);
mutationObserver.observe(doc, {
attributes: true,
attributeFilter: L10N_ATTRIBUTES,
childList: true,
subtree: true,
});
});

Просмотреть файл

@ -150,7 +150,7 @@ class ManageRecords {
let selectedGuids = this._selectedOptions.map(option => option.value);
this.clearRecordElements();
for (let record of records) {
let { id, args, raw } = this.getLabelInfo(record);
let { id, args, raw } = await this.getLabelInfo(record);
let option = new Option(
raw ?? "",
record.guid,
@ -323,10 +323,8 @@ class ManageAddresses extends ManageRecords {
constructor(elements) {
super("addresses", elements);
elements.add.setAttribute(
"searchkeywords",
FormAutofillUtils.EDIT_ADDRESS_KEYWORDS.map(key =>
FormAutofillUtils.stringBundle.GetStringFromName(key)
).join("\n")
"search-l10n-ids",
FormAutofillUtils.EDIT_ADDRESS_L10N_IDS.join(",")
);
}
@ -353,10 +351,8 @@ class ManageCreditCards extends ManageRecords {
constructor(elements) {
super("creditCards", elements);
elements.add.setAttribute(
"searchkeywords",
FormAutofillUtils.EDIT_CREDITCARD_KEYWORDS.map(key =>
FormAutofillUtils.stringBundle.GetStringFromName(key)
).join("\n")
"search-l10n-ids",
FormAutofillUtils.EDIT_CREDITCARD_L10N_IDS.join(",")
);
Services.telemetry.recordEvent("creditcard", "show", "manage");
@ -417,22 +413,17 @@ class ManageCreditCards extends ManageRecords {
* cardholder's name, separated by a comma.
*
* @param {object} creditCard
* @returns {string}
* @returns {Promise<string>}
*/
getLabelInfo(creditCard) {
async getLabelInfo(creditCard) {
// The card type is displayed visually using an image. For a11y, we need
// to expose it as text. We do this using aria-label. However,
// aria-label overrides the text content, so we must include that also.
// Since the text content is generated by Fluent, aria-label must be
// generated by Fluent also.
let type;
try {
type = FormAutofillUtils.stringBundle.GetStringFromName(
`cardNetwork.${creditCard["cc-type"]}`
);
} catch (e) {
type = ""; // Unknown.
}
const type = await document.l10n.formatValue(
`autofill-card-network-${creditCard["cc-type"]}`
);
return CreditCard.getLabelInfo({
name: creditCard["cc-name"],
number: creditCard["cc-number"],

Просмотреть файл

@ -111,117 +111,6 @@ autofillReauthOSDialogMac = change the authentication settings
autofillReauthOSDialogWin = To change the authentication settings, enter your Windows login credentials.
autofillReauthOSDialogLin = To change the authentication settings, enter your Linux login credentials.
# LOCALIZATION NOTE (manageAddressesTitle, manageCreditCardsTitle): The dialog title for the list of addresses or
# credit cards in browser preferences.
manageAddressesTitle = Saved Addresses
manageCreditCardsTitle = Saved Credit Cards
# LOCALIZATION NOTE (addressesListHeader, creditCardsListHeader): The header for the list of addresses or credit cards
# in browser preferences.
addressesListHeader = Addresses
creditCardsListHeader = Credit Cards
removeBtnLabel = Remove
addBtnLabel = Add…
editBtnLabel = Edit…
# LOCALIZATION NOTE (manageDialogsWidth): This strings sets the default width for windows used to manage addresses and
# credit cards.
manageDialogsWidth = 560px
# LOCALIZATION NOTE (addNewAddressTitle, editAddressTitle): The dialog title for creating or editing addresses
# in browser preferences.
addNewAddressTitle = Add New Address
editAddressTitle = Edit Address
givenName = First Name
additionalName = Middle Name
familyName = Last Name
organization2 = Organization
streetAddress = Street Address
## address-level-3 (Sublocality) names
# LOCALIZATION NOTE (neighborhood): Used in IR, MX
neighborhood = Neighborhood
# LOCALIZATION NOTE (village_township): Used in MY
village_township = Village or Township
island = Island
# LOCALIZATION NOTE (townland): Used in IE
townland = Townland
## address-level-2 names
city = City
# LOCALIZATION NOTE (district): Used in HK, SD, SY, TR as Address Level-2
# and used in KR as Sublocality.
district = District
# LOCALIZATION NOTE (post_town): Used in GB, NO, SE
post_town = Post town
# LOCALIZATION NOTE (suburb): Used in AU as Address Level-2
# and used in ZZ as Sublocality.
suburb = Suburb
# address-level-1 names
province = Province
state = State
county = County
# LOCALIZATION NOTE (parish): Used in BB, JM
parish = Parish
# LOCALIZATION NOTE (prefecture): Used in JP
prefecture = Prefecture
# LOCALIZATION NOTE (area): Used in HK
area = Area
# LOCALIZATION NOTE (do_si): Used in KR
do_si = Do/Si
# LOCALIZATION NOTE (department): Used in NI, CO
department = Department
# LOCALIZATION NOTE (emirate): Used in AE
emirate = Emirate
# LOCALIZATION NOTE (oblast): Used in RU and UA
oblast = Oblast
# LOCALIZATION NOTE (pin, postalCode, zip, eircode): Postal code name types
# LOCALIZATION NOTE (pin): Used in IN
pin = Pin
postalCode = Postal Code
zip = ZIP Code
# LOCALIZATION NOTE (eircode): Used in IE
eircode = Eircode
country = Country or Region
tel = Phone
email = Email
cancelBtnLabel = Cancel
saveBtnLabel = Save
countryWarningMessage2 = Form Autofill is currently available only for certain countries.
# LOCALIZATION NOTE (addNewCreditCardTitle, editCreditCardTitle): The dialog title for creating or editing
# credit cards in browser preferences.
addNewCreditCardTitle = Add New Credit Card
editCreditCardTitle = Edit Credit Card
cardNumber = Card Number
invalidCardNumber = Please enter a valid card number
nameOnCard = Name on Card
cardExpiresMonth = Exp. Month
cardExpiresYear = Exp. Year
billingAddress = Billing Address
cardNetwork = Card Type
# LOCALIZATION NOTE (cardCVV): Credit card security code https://en.wikipedia.org/wiki/Card_security_code
cardCVV = CVV
# LOCALIZATION NOTE: (cardNetwork.*): These are brand names and should only be translated when a locale-specific name for that brand is in common use
cardNetwork.amex = American Express
cardNetwork.cartebancaire = Carte Bancaire
cardNetwork.diners = Diners Club
cardNetwork.discover = Discover
cardNetwork.jcb = JCB
cardNetwork.mastercard = MasterCard
cardNetwork.mir = MIR
cardNetwork.unionpay = Union Pay
cardNetwork.visa = Visa
# LOCALIZATION NOTE (editCreditCardPasswordPrompt.*, useCreditCardPasswordPrompt.*): %S is brandShortName.
editCreditCardPasswordPrompt.win = %S is trying to show credit card information. Confirm access to this Windows account below.
# LOCALIZATION NOTE (editCreditCardPasswordPrompt.macos): This string is
# preceded by the operating system (macOS) with "Firefox is trying to ", and
# has a period added to its end. Make sure to test in your locale.
editCreditCardPasswordPrompt.macos = show credit card information
editCreditCardPasswordPrompt.linux = %S is trying to show credit card information.
useCreditCardPasswordPrompt.win = %S is trying to use stored credit card information. Confirm access to this Windows account below.
# LOCALIZATION NOTE (useCreditCardPasswordPrompt.macos): This string is
# preceded by the operating system (macOS) with "Firefox is trying to ", and

Просмотреть файл

@ -528,39 +528,35 @@ add_task(async function test_countryAndStateFieldLabels() {
continue;
}
// Clear L10N attributes and textContent to not leave leftovers between country tests
// Clear L10N textContent to not leave leftovers between country tests
for (let labelEl of mutableLabels) {
doc.l10n.setAttributes(labelEl, "");
labelEl.textContent = "";
delete labelEl.dataset.localization;
}
info(`Selecting '${countryOption.label}' (${countryOption.value})`);
EventUtils.synthesizeKey(countryOption.label, {}, win);
let l10nResolve;
let l10nReady = new Promise(resolve => {
l10nResolve = resolve;
});
let verifyL10n = () => {
if (mutableLabels.every(labelEl => labelEl.textContent)) {
win.removeEventListener("MozAfterPaint", verifyL10n);
l10nResolve();
}
};
win.addEventListener("MozAfterPaint", verifyL10n);
await l10nReady;
// Check that the labels were filled
for (let labelEl of mutableLabels) {
if (!labelEl.textContent) {
// This test used to rely on the implied initial timer of
// TestUtils.waitForCondition. See bug 1700685.
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
await new Promise(resolve => setTimeout(resolve, 10));
await TestUtils.waitForCondition(
() => labelEl.textContent,
"Wait for label to be populated by the mutation observer",
10
);
}
isnot(
labelEl.textContent,
"",
"Ensure textContent is non-empty for: " + countryOption.value
);
is(
labelEl.dataset.localization,
undefined,
"Ensure data-localization was removed: " + countryOption.value
);
}
let stateOptions = doc.querySelector("#address-level1").options;

Просмотреть файл

@ -16,6 +16,83 @@ autofill-manage-remove-button = Remove
autofill-manage-add-button = Add…
autofill-manage-edit-button = Edit…
##
# The dialog title for creating addresses in browser preferences.
autofill-add-new-address-title = Add New Address
# The dialog title for editing addresses in browser preferences.
autofill-edit-address-title = Edit Address
autofill-address-given-name = First Name
autofill-address-additional-name = Middle Name
autofill-address-family-name = Last Name
autofill-address-organization = Organization
autofill-address-street = Street Address
## address-level-3 (Sublocality) names
# Used in IR, MX
autofill-address-neighborhood = Neighborhood
# Used in MY
autofill-address-village-township = Village or Township
autofill-address-island = Island
# Used in IE
autofill-address-townland = Townland
## address-level-2 names
autofill-address-city = City
# Used in HK, SD, SY, TR as Address Level-2 and used in KR as Sublocality.
autofill-address-district = District
# Used in GB, NO, SE
autofill-address-post-town = Post town
# Used in AU as Address Level-2 and used in ZZ as Sublocality.
autofill-address-suburb = Suburb
## address-level-1 names
autofill-address-province = Province
autofill-address-state = State
autofill-address-county = County
# Used in BB, JM
autofill-address-parish = Parish
# Used in JP
autofill-address-prefecture = Prefecture
# Used in HK
autofill-address-area = Area
# Used in KR
autofill-address-do-si = Do/Si
# Used in NI, CO
autofill-address-department = Department
# Used in AE
autofill-address-emirate = Emirate
# Used in RU and UA
autofill-address-oblast = Oblast
## Postal code name types
# Used in IN
autofill-address-pin = Pin
autofill-address-postal-code = Postal Code
autofill-address-zip = ZIP Code
# Used in IE
autofill-address-eircode = Eircode
##
autofill-address-country = Country or Region
autofill-address-tel = Phone
autofill-address-email = Email
autofill-cancel-button = Cancel
autofill-save-button = Save
autofill-country-warning-message = Form Autofill is currently available only for certain countries.
# The dialog title for creating credit cards in browser preferences.
autofill-add-new-card-title = Add New Credit Card
# The dialog title for editing credit cards in browser preferences.
autofill-edit-card-title = Edit Credit Card
# In macOS, this string is preceded by the operating system with "Firefox is trying to ",
# and has a period added to its end. Make sure to test in your locale.
autofill-edit-card-password-prompt = { PLATFORM() ->
@ -23,3 +100,23 @@ autofill-edit-card-password-prompt = { PLATFORM() ->
[windows] { -brand-short-name } is trying to show credit card information. Confirm access to this Windows account below.
*[other] { -brand-short-name } is trying to show credit card information.
}
autofill-card-number = Card Number
autofill-card-invalid-number = Please enter a valid card number
autofill-card-name-on-card = Name on Card
autofill-card-expires-month = Exp. Month
autofill-card-expires-year = Exp. Year
autofill-card-billing-address = Billing Address
autofill-card-network = Card Type
## These are brand names and should only be translated when a locale-specific name for that brand is in common use
autofill-card-network-amex = American Express
autofill-card-network-cartebancaire = Carte Bancaire
autofill-card-network-diners = Diners Club
autofill-card-network-discover = Discover
autofill-card-network-jcb = JCB
autofill-card-network-mastercard = MasterCard
autofill-card-network-mir = MIR
autofill-card-network-unionpay = Union Pay
autofill-card-network-visa = Visa

Просмотреть файл

@ -274,7 +274,7 @@ Example:
.. code-block:: javascript
let regs = getLanguageDisplayNames(["pl"], ["US", "CA", "MX"]);
let regs = getRegionDisplayNames(["pl"], ["US", "CA", "MX"]);
regs === ["Stany Zjednoczone", "Kanada", "Meksyk"];
mozIntl.getLocaleDisplayNames(locales, localeCodes)
@ -286,7 +286,7 @@ Example:
.. code-block:: javascript
let locs = getLanguageDisplayNames(["pl"], ["sr-RU", "es-MX", "fr-CA"]);
let locs = getLocaleDisplayNames(["pl"], ["sr-RU", "es-MX", "fr-CA"]);
locs === ["Serbski (Rosja)", "Hiszpański (Meksyk)", "Francuski (Kanada)"];
mozIntl.getAvailableLocaleDisplayNames(type)

Просмотреть файл

@ -0,0 +1,282 @@
# Any copyright is dedicated to the Public Domain.
# http://creativecommons.org/publicdomain/zero/1.0/
import fluent.syntax.ast as FTL
from fluent.migrate.helpers import TERM_REFERENCE, transforms_from
from fluent.migrate.transforms import COPY, REPLACE, Transform
def migrate(ctx):
"""Bugs 1446164 & 1786708 - Migrate formautofill dialogs to Fluent, part {index}."""
source = "browser/extensions/formautofill/formautofill.properties"
target = "browser/browser/preferences/formAutofill.ftl"
ctx.add_transforms(
target,
target,
# Bug 1786708
transforms_from(
"""
autofill-manage-addresses-title = { COPY(source, "manageAddressesTitle") }
autofill-manage-credit-cards-title = { COPY(source, "manageCreditCardsTitle") }
autofill-manage-addresses-list-header = { COPY(source, "addressesListHeader") }
autofill-manage-credit-cards-list-header = { COPY(source, "creditCardsListHeader") }
autofill-manage-remove-button = { COPY(source, "removeBtnLabel") }
autofill-manage-add-button = { COPY(source, "addBtnLabel") }
autofill-manage-edit-button = { COPY(source, "editBtnLabel") }
autofill-manage-dialog =
.style = min-width: { COPY(source, "manageDialogsWidth") }
""",
source=source,
)
+ [
FTL.Message(
FTL.Identifier("autofill-edit-card-password-prompt"),
value=Transform.pattern_of(
FTL.SelectExpression(
selector=FTL.FunctionReference(
id=FTL.Identifier("PLATFORM"), arguments=FTL.CallArguments()
),
variants=[
FTL.Variant(
key=FTL.Identifier("macos"),
value=COPY(
source, "editCreditCardPasswordPrompt.macos"
),
),
FTL.Variant(
key=FTL.Identifier("windows"),
value=REPLACE(
source,
"editCreditCardPasswordPrompt.win",
{
"%1$S": TERM_REFERENCE("brand-short-name"),
},
),
),
FTL.Variant(
key=FTL.Identifier("other"),
value=REPLACE(
source,
"editCreditCardPasswordPrompt.linux",
{
"%1$S": TERM_REFERENCE("brand-short-name"),
},
),
default=True,
),
],
)
),
)
]
+
# Bug 1446164
[
FTL.Message(
id=FTL.Identifier("autofill-add-new-address-title"),
value=COPY(source, "addNewAddressTitle"),
),
FTL.Message(
id=FTL.Identifier("autofill-edit-address-title"),
value=COPY(source, "editAddressTitle"),
),
FTL.Message(
id=FTL.Identifier("autofill-address-given-name"),
value=COPY(source, "givenName"),
),
FTL.Message(
id=FTL.Identifier("autofill-address-additional-name"),
value=COPY(source, "additionalName"),
),
FTL.Message(
id=FTL.Identifier("autofill-address-family-name"),
value=COPY(source, "familyName"),
),
FTL.Message(
id=FTL.Identifier("autofill-address-organization"),
value=COPY(source, "organization2"),
),
FTL.Message(
id=FTL.Identifier("autofill-address-street"),
value=COPY(source, "streetAddress"),
),
FTL.Message(
id=FTL.Identifier("autofill-address-neighborhood"),
value=COPY(source, "neighborhood"),
),
FTL.Message(
id=FTL.Identifier("autofill-address-village-township"),
value=COPY(source, "village_township"),
),
FTL.Message(
id=FTL.Identifier("autofill-address-island"),
value=COPY(source, "island"),
),
FTL.Message(
id=FTL.Identifier("autofill-address-townland"),
value=COPY(source, "townland"),
),
FTL.Message(
id=FTL.Identifier("autofill-address-city"), value=COPY(source, "city")
),
FTL.Message(
id=FTL.Identifier("autofill-address-district"),
value=COPY(source, "district"),
),
FTL.Message(
id=FTL.Identifier("autofill-address-post-town"),
value=COPY(source, "post_town"),
),
FTL.Message(
id=FTL.Identifier("autofill-address-suburb"),
value=COPY(source, "suburb"),
),
FTL.Message(
id=FTL.Identifier("autofill-address-province"),
value=COPY(source, "province"),
),
FTL.Message(
id=FTL.Identifier("autofill-address-state"), value=COPY(source, "state")
),
FTL.Message(
id=FTL.Identifier("autofill-address-county"),
value=COPY(source, "county"),
),
FTL.Message(
id=FTL.Identifier("autofill-address-parish"),
value=COPY(source, "parish"),
),
FTL.Message(
id=FTL.Identifier("autofill-address-prefecture"),
value=COPY(source, "prefecture"),
),
FTL.Message(
id=FTL.Identifier("autofill-address-area"), value=COPY(source, "area")
),
FTL.Message(
id=FTL.Identifier("autofill-address-do-si"), value=COPY(source, "do_si")
),
FTL.Message(
id=FTL.Identifier("autofill-address-department"),
value=COPY(source, "department"),
),
FTL.Message(
id=FTL.Identifier("autofill-address-emirate"),
value=COPY(source, "emirate"),
),
FTL.Message(
id=FTL.Identifier("autofill-address-oblast"),
value=COPY(source, "oblast"),
),
FTL.Message(
id=FTL.Identifier("autofill-address-pin"), value=COPY(source, "pin")
),
FTL.Message(
id=FTL.Identifier("autofill-address-postal-code"),
value=COPY(source, "postalCode"),
),
FTL.Message(
id=FTL.Identifier("autofill-address-zip"), value=COPY(source, "zip")
),
FTL.Message(
id=FTL.Identifier("autofill-address-eircode"),
value=COPY(source, "eircode"),
),
FTL.Message(
id=FTL.Identifier("autofill-address-country"),
value=COPY(source, "country"),
),
FTL.Message(
id=FTL.Identifier("autofill-address-tel"), value=COPY(source, "tel")
),
FTL.Message(
id=FTL.Identifier("autofill-address-email"), value=COPY(source, "email")
),
FTL.Message(
id=FTL.Identifier("autofill-cancel-button"),
value=COPY(source, "cancelBtnLabel"),
),
FTL.Message(
id=FTL.Identifier("autofill-save-button"),
value=COPY(source, "saveBtnLabel"),
),
FTL.Message(
id=FTL.Identifier("autofill-country-warning-message"),
value=COPY(source, "countryWarningMessage2"),
),
FTL.Message(
id=FTL.Identifier("autofill-add-new-card-title"),
value=COPY(source, "addNewCreditCardTitle"),
),
FTL.Message(
id=FTL.Identifier("autofill-edit-card-title"),
value=COPY(source, "editCreditCardTitle"),
),
FTL.Message(
id=FTL.Identifier("autofill-card-number"),
value=COPY(source, "cardNumber"),
),
FTL.Message(
id=FTL.Identifier("autofill-card-invalid-number"),
value=COPY(source, "invalidCardNumber"),
),
FTL.Message(
id=FTL.Identifier("autofill-card-name-on-card"),
value=COPY(source, "nameOnCard"),
),
FTL.Message(
id=FTL.Identifier("autofill-card-expires-month"),
value=COPY(source, "cardExpiresMonth"),
),
FTL.Message(
id=FTL.Identifier("autofill-card-expires-year"),
value=COPY(source, "cardExpiresYear"),
),
FTL.Message(
id=FTL.Identifier("autofill-card-billing-address"),
value=COPY(source, "billingAddress"),
),
FTL.Message(
id=FTL.Identifier("autofill-card-network"),
value=COPY(source, "cardNetwork"),
),
FTL.Message(
id=FTL.Identifier("autofill-card-network-amex"),
value=COPY(source, "cardNetwork.amex"),
),
FTL.Message(
id=FTL.Identifier("autofill-card-network-cartebancaire"),
value=COPY(source, "cardNetwork.cartebancaire"),
),
FTL.Message(
id=FTL.Identifier("autofill-card-network-diners"),
value=COPY(source, "cardNetwork.diners"),
),
FTL.Message(
id=FTL.Identifier("autofill-card-network-discover"),
value=COPY(source, "cardNetwork.discover"),
),
FTL.Message(
id=FTL.Identifier("autofill-card-network-jcb"),
value=COPY(source, "cardNetwork.jcb"),
),
FTL.Message(
id=FTL.Identifier("autofill-card-network-mastercard"),
value=COPY(source, "cardNetwork.mastercard"),
),
FTL.Message(
id=FTL.Identifier("autofill-card-network-mir"),
value=COPY(source, "cardNetwork.mir"),
),
FTL.Message(
id=FTL.Identifier("autofill-card-network-unionpay"),
value=COPY(source, "cardNetwork.unionpay"),
),
FTL.Message(
id=FTL.Identifier("autofill-card-network-visa"),
value=COPY(source, "cardNetwork.visa"),
),
],
)

Просмотреть файл

@ -40,10 +40,10 @@ const {
ENABLED_AUTOFILL_CREDITCARDS_REAUTH_PREF,
} = FormAutofill;
const {
MANAGE_ADDRESSES_KEYWORDS,
EDIT_ADDRESS_KEYWORDS,
MANAGE_CREDITCARDS_KEYWORDS,
EDIT_CREDITCARD_KEYWORDS,
MANAGE_ADDRESSES_L10N_IDS,
EDIT_ADDRESS_L10N_IDS,
MANAGE_CREDITCARDS_L10N_IDS,
EDIT_CREDITCARD_L10N_IDS,
} = FormAutofillUtils;
// Add credit card enabled flag in telemetry environment for recording the number of
// users who disable/enable the credit card autofill feature.
@ -149,13 +149,7 @@ FormAutofillPreferences.prototype = {
// Add preferences search support
savedAddressesBtn.setAttribute(
"search-l10n-ids",
"autofill-manage-addresses-title"
);
savedAddressesBtn.setAttribute(
"searchkeywords",
MANAGE_ADDRESSES_KEYWORDS.concat(EDIT_ADDRESS_KEYWORDS)
.map(key => this.bundle.GetStringFromName(key))
.join("\n")
MANAGE_ADDRESSES_L10N_IDS.concat(EDIT_ADDRESS_L10N_IDS).join(",")
);
// Manually set the checked state
@ -223,13 +217,7 @@ FormAutofillPreferences.prototype = {
// Add preferences search support
savedCreditCardsBtn.setAttribute(
"search-l10n-ids",
"autofill-manage-credit-cards-title"
);
savedCreditCardsBtn.setAttribute(
"searchkeywords",
MANAGE_CREDITCARDS_KEYWORDS.concat(EDIT_CREDITCARD_KEYWORDS)
.map(key => this.bundle.GetStringFromName(key))
.join("\n")
MANAGE_CREDITCARDS_L10N_IDS.concat(EDIT_CREDITCARD_L10N_IDS).join(",")
);
// Manually set the checked state

Просмотреть файл

@ -17,29 +17,35 @@ const ADDRESS_REFERENCES_EXT = "addressReferencesExt.js";
const ADDRESSES_COLLECTION_NAME = "addresses";
const CREDITCARDS_COLLECTION_NAME = "creditCards";
const MANAGE_ADDRESSES_KEYWORDS = ["addNewAddressTitle"];
const EDIT_ADDRESS_KEYWORDS = [
"givenName",
"additionalName",
"familyName",
"organization2",
"streetAddress",
"state",
"province",
"city",
"country",
"zip",
"postalCode",
"email",
"tel",
const MANAGE_ADDRESSES_L10N_IDS = [
"autofill-add-new-address-title",
"autofill-manage-addresses-title",
];
const MANAGE_CREDITCARDS_KEYWORDS = ["addNewCreditCardTitle"];
const EDIT_CREDITCARD_KEYWORDS = [
"cardNumber",
"nameOnCard",
"cardExpiresMonth",
"cardExpiresYear",
"cardNetwork",
const EDIT_ADDRESS_L10N_IDS = [
"autofill-address-given-name",
"autofill-address-additional-name",
"autofill-address-family-name",
"autofill-address-organization",
"autofill-address-street",
"autofill-address-state",
"autofill-address-province",
"autofill-address-city",
"autofill-address-country",
"autofill-address-zip",
"autofill-address-postal-code",
"autofill-address-email",
"autofill-address-tel",
];
const MANAGE_CREDITCARDS_L10N_IDS = [
"autofill-add-new-card-title",
"autofill-manage-credit-cards-title",
];
const EDIT_CREDITCARD_L10N_IDS = [
"autofill-card-number",
"autofill-card-name-on-card",
"autofill-card-expires-month",
"autofill-card-expires-year",
"autofill-card-network",
];
const FIELD_STATES = {
NORMAL: "NORMAL",
@ -215,10 +221,10 @@ FormAutofillUtils = {
ADDRESSES_COLLECTION_NAME,
CREDITCARDS_COLLECTION_NAME,
MANAGE_ADDRESSES_KEYWORDS,
EDIT_ADDRESS_KEYWORDS,
MANAGE_CREDITCARDS_KEYWORDS,
EDIT_CREDITCARD_KEYWORDS,
MANAGE_ADDRESSES_L10N_IDS,
EDIT_ADDRESS_L10N_IDS,
MANAGE_CREDITCARDS_L10N_IDS,
EDIT_CREDITCARD_L10N_IDS,
MAX_FIELD_VALUE_LENGTH,
FIELD_STATES,
SECTION_TYPES,
@ -1061,10 +1067,10 @@ FormAutofillUtils = {
* @param {string} country
* @returns {object}
* {
* {string} addressLevel3Label
* {string} addressLevel2Label
* {string} addressLevel1Label
* {string} postalCodeLabel
* {string} addressLevel3L10nId
* {string} addressLevel2L10nId
* {string} addressLevel1L10nId
* {string} postalCodeL10nId
* {object} fieldsOrder
* {string} postalCodePattern
* }
@ -1088,9 +1094,15 @@ FormAutofillUtils = {
// When particular values are missing for a country, the
// data/ZZ value should be used instead:
// https://chromium-i18n.appspot.com/ssl-aggregate-address/data/ZZ
addressLevel3Label: dataset.sublocality_name_type || "suburb",
addressLevel2Label: dataset.locality_name_type || "city",
addressLevel1Label: dataset.state_name_type || "province",
addressLevel3L10nId: this.getAddressFieldL10nId(
dataset.sublocality_name_type || "suburb"
),
addressLevel2L10nId: this.getAddressFieldL10nId(
dataset.locality_name_type || "city"
),
addressLevel1L10nId: this.getAddressFieldL10nId(
dataset.state_name_type || "province"
),
addressLevel1Options: this.buildRegionMapIfAvailable(
dataset.sub_keys,
dataset.sub_isoids,
@ -1099,52 +1111,15 @@ FormAutofillUtils = {
),
countryRequiredFields: this.parseRequireString(dataset.require || "AC"),
fieldsOrder: this.parseAddressFormat(dataset.fmt || "%N%n%O%n%A%n%C"),
postalCodeLabel: dataset.zip_name_type || "postalCode",
postalCodeL10nId: this.getAddressFieldL10nId(
dataset.zip_name_type || "postal-code"
),
postalCodePattern: dataset.zip,
};
},
/**
* Localize "data-localization" or "data-localization-region" attributes.
* @param {Element} element
* @param {string} attributeName
*/
localizeAttributeForElement(element, attributeName) {
switch (attributeName) {
case "data-localization": {
element.textContent = this.stringBundle.GetStringFromName(
element.getAttribute(attributeName)
);
element.removeAttribute(attributeName);
break;
}
case "data-localization-region": {
let regionCode = element.getAttribute(attributeName);
element.textContent = Services.intl.getRegionDisplayNames(undefined, [
regionCode,
]);
element.removeAttribute(attributeName);
return;
}
default:
throw new Error("Unexpected attributeName");
}
},
/**
* Localize elements with "data-localization" or "data-localization-region" attributes.
* @param {Element} root
*/
localizeMarkup(root) {
let elements = root.querySelectorAll("[data-localization]");
for (let element of elements) {
this.localizeAttributeForElement(element, "data-localization");
}
elements = root.querySelectorAll("[data-localization-region]");
for (let element of elements) {
this.localizeAttributeForElement(element, "data-localization-region");
}
getAddressFieldL10nId(type) {
return "autofill-address-" + type.replace(/_/g, "-");
},
CC_FATHOM_NONE: 0,

Просмотреть файл

@ -15,6 +15,12 @@ XPCOMUtils.defineLazyModuleGetters(lazy, {
FormAutofillUtils: "resource://autofill/FormAutofillUtils.jsm",
});
XPCOMUtils.defineLazyGetter(
lazy,
"l10n",
() => new Localization(["browser/preferences/formAutofill.ftl"], true)
);
class ProfileAutoCompleteResult {
constructor(
searchString,
@ -416,14 +422,9 @@ class CreditCardResult extends ProfileAutoCompleteResult {
// The card type is displayed visually using an image. For a11y, we need
// to expose it as text. We do this using aria-label. However,
// aria-label overrides the text content, so we must include that also.
let ccTypeName;
try {
ccTypeName = lazy.FormAutofillUtils.stringBundle.GetStringFromName(
`cardNetwork.${profile["cc-type"]}`
);
} catch (e) {
ccTypeName = null; // Unknown.
}
let ccTypeName = lazy.l10n.formatValueSync(
`autofill-card-network-${profile["cc-type"]}`
);
const ariaLabel = [ccTypeName, primaryAffix, primary, secondary]
.filter(chunk => !!chunk) // Exclude empty chunks.
.join(" ");

Просмотреть файл

@ -383,19 +383,9 @@ let FormAutofillPrompter = {
creditCard.record["cc-number"] ||
creditCard.record["cc-number-decrypted"];
let name = creditCard.record["cc-name"];
let month = creditCard.record["cc-exp-month"];
let year = creditCard.record["cc-exp-year"];
let type = lazy.CreditCard.getType(number);
let ccLabelInfo = lazy.CreditCard.getLabelInfo({
number,
name,
month,
year,
type,
});
let description = [ccLabelInfo.args.number, ccLabelInfo.args.name].join(
", "
);
let maskedNumber = lazy.CreditCard.getMaskedNumber(number);
let description = `${maskedNumber}, ${name}`;
const telemetryObject = creditCard.guid
? "update_doorhanger"
: "capture_doorhanger";