зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1383687 - Order edit dialog fields based on country selected. r=lchang,steveck
MozReview-Commit-ID: 1qPxvHhNGtK --HG-- extra : rebase_source : 12d892ce9c30f70b3fb5dd48c17744e23f45a604
This commit is contained in:
Родитель
8512de2ea7
Коммит
cefdf5737a
|
@ -657,6 +657,7 @@ this.FormAutofillUtils = {
|
|||
* {
|
||||
* {string} addressLevel1Label
|
||||
* {string} postalCodeLabel
|
||||
* {object} fieldsOrder
|
||||
* }
|
||||
*/
|
||||
getFormFormat(country) {
|
||||
|
@ -664,6 +665,7 @@ this.FormAutofillUtils = {
|
|||
return {
|
||||
"addressLevel1Label": dataset.state_name_type || "province",
|
||||
"postalCodeLabel": dataset.zip_name_type || "postalCode",
|
||||
"fieldsOrder": this.parseAddressFormat(dataset.fmt || "%N%n%O%n%A%n%C, %S %Z"),
|
||||
};
|
||||
},
|
||||
|
||||
|
|
|
@ -13,38 +13,42 @@
|
|||
</head>
|
||||
<body>
|
||||
<form id="form" autocomplete="off">
|
||||
<label id="given-name-container">
|
||||
<span data-localization="givenName"/>
|
||||
<input id="given-name" type="text"/>
|
||||
</label>
|
||||
<label id="additional-name-container">
|
||||
<span data-localization="additionalName"/>
|
||||
<input id="additional-name" type="text"/>
|
||||
</label>
|
||||
<label id="family-name-container">
|
||||
<span data-localization="familyName"/>
|
||||
<input id="family-name" type="text"/>
|
||||
</label>
|
||||
<label id="organization-container">
|
||||
<span data-localization="organization2"/>
|
||||
<input id="organization" type="text"/>
|
||||
</label>
|
||||
<label id="street-address-container">
|
||||
<span data-localization="streetAddress"/>
|
||||
<textarea id="street-address" rows="3"/>
|
||||
</label>
|
||||
<label id="address-level2-container">
|
||||
<span data-localization="city"/>
|
||||
<input id="address-level2" type="text"/>
|
||||
</label>
|
||||
<label id="address-level1-container">
|
||||
<span/>
|
||||
<input id="address-level1" type="text"/>
|
||||
</label>
|
||||
<label id="postal-code-container">
|
||||
<span/>
|
||||
<input id="postal-code" type="text"/>
|
||||
</label>
|
||||
<div>
|
||||
<div id="name-container">
|
||||
<label id="given-name-container">
|
||||
<span data-localization="givenName"/>
|
||||
<input id="given-name" type="text"/>
|
||||
</label>
|
||||
<label id="additional-name-container">
|
||||
<span data-localization="additionalName"/>
|
||||
<input id="additional-name" type="text"/>
|
||||
</label>
|
||||
<label id="family-name-container">
|
||||
<span data-localization="familyName"/>
|
||||
<input id="family-name" type="text"/>
|
||||
</label>
|
||||
</div>
|
||||
<label id="organization-container">
|
||||
<span data-localization="organization2"/>
|
||||
<input id="organization" type="text"/>
|
||||
</label>
|
||||
<label id="street-address-container">
|
||||
<span data-localization="streetAddress"/>
|
||||
<textarea id="street-address" rows="3"/>
|
||||
</label>
|
||||
<label id="address-level2-container">
|
||||
<span data-localization="city"/>
|
||||
<input id="address-level2" type="text"/>
|
||||
</label>
|
||||
<label id="address-level1-container">
|
||||
<span/>
|
||||
<input id="address-level1" type="text"/>
|
||||
</label>
|
||||
<label id="postal-code-container">
|
||||
<span/>
|
||||
<input id="postal-code" type="text"/>
|
||||
</label>
|
||||
</div>
|
||||
<label id="country-container">
|
||||
<span data-localization="country"/>
|
||||
<select id="country">
|
||||
|
|
|
@ -120,6 +120,10 @@ class EditDialog {
|
|||
this.handleKeyPress(event);
|
||||
break;
|
||||
}
|
||||
case "change": {
|
||||
this.handleChange(event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,6 +184,15 @@ class EditDialog {
|
|||
this._elements.controlsContainer.removeEventListener("click", this);
|
||||
document.removeEventListener("input", this);
|
||||
}
|
||||
|
||||
// An interface to be inherited.
|
||||
localizeDocument() {}
|
||||
|
||||
// An interface to be inherited.
|
||||
handleSubmit(event) {}
|
||||
|
||||
// An interface to be inherited.
|
||||
handleChange(event) {}
|
||||
}
|
||||
|
||||
class EditAddress extends EditDialog {
|
||||
|
@ -194,11 +207,42 @@ class EditAddress extends EditDialog {
|
|||
* @param {string} country
|
||||
*/
|
||||
formatForm(country) {
|
||||
// TODO: Use fmt to show/hide and order fields (Bug 1383687)
|
||||
const {addressLevel1Label, postalCodeLabel} = FormAutofillUtils.getFormFormat(country);
|
||||
const {addressLevel1Label, postalCodeLabel, fieldsOrder} = FormAutofillUtils.getFormFormat(country);
|
||||
this._elements.addressLevel1Label.dataset.localization = addressLevel1Label;
|
||||
this._elements.postalCodeLabel.dataset.localization = postalCodeLabel;
|
||||
FormAutofillUtils.localizeMarkup(AUTOFILL_BUNDLE_URI, document);
|
||||
this.arrangeFields(fieldsOrder);
|
||||
}
|
||||
|
||||
arrangeFields(fieldsOrder) {
|
||||
let fields = [
|
||||
"name",
|
||||
"organization",
|
||||
"street-address",
|
||||
"address-level2",
|
||||
"address-level1",
|
||||
"postal-code",
|
||||
];
|
||||
let inputs = [];
|
||||
for (let i = 0; i < fieldsOrder.length; i++) {
|
||||
let {fieldId, newLine} = fieldsOrder[i];
|
||||
let container = document.getElementById(`${fieldId}-container`);
|
||||
inputs.push(...container.querySelectorAll("input, textarea, select"));
|
||||
container.style.display = "flex";
|
||||
container.style.order = i;
|
||||
container.style.pageBreakAfter = newLine ? "always" : "auto";
|
||||
// Remove the field from the list of fields
|
||||
fields.splice(fields.indexOf(fieldId), 1);
|
||||
}
|
||||
for (let i = 0; i < inputs.length; i++) {
|
||||
// Assign tabIndex starting from 1
|
||||
inputs[i].tabIndex = i + 1;
|
||||
}
|
||||
// Hide the remaining fields
|
||||
for (let field of fields) {
|
||||
let container = document.getElementById(`${field}-container`);
|
||||
container.style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
localizeDocument() {
|
||||
|
@ -220,6 +264,20 @@ class EditAddress extends EditDialog {
|
|||
await this.saveRecord(this.buildFormObject(), this._record ? this._record.guid : null);
|
||||
window.close();
|
||||
}
|
||||
|
||||
handleChange(event) {
|
||||
this.formatForm(event.target.value);
|
||||
}
|
||||
|
||||
attachEventListeners() {
|
||||
this._elements.country.addEventListener("change", this);
|
||||
super.attachEventListeners();
|
||||
}
|
||||
|
||||
detachEventListeners() {
|
||||
this._elements.country.removeEventListener("change", this);
|
||||
super.detachEventListeners();
|
||||
}
|
||||
}
|
||||
|
||||
class EditCreditCard extends EditDialog {
|
||||
|
|
|
@ -26,13 +26,11 @@ select {
|
|||
flex: 0 1 50%;
|
||||
}
|
||||
|
||||
#family-name-container,
|
||||
#organization-container,
|
||||
#address-level2-container,
|
||||
#tel-container {
|
||||
padding-inline-end: 50%;
|
||||
}
|
||||
|
||||
#name-container,
|
||||
#street-address-container,
|
||||
#email-container {
|
||||
flex: 0 1 100%;
|
||||
|
|
|
@ -9,13 +9,17 @@ p {
|
|||
display: flex;
|
||||
}
|
||||
|
||||
form {
|
||||
form,
|
||||
div {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
form {
|
||||
/* Add extra space to ensure invalid input box is displayed properly */
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
form > label,
|
||||
form label,
|
||||
form > p {
|
||||
margin: 0 0 0.5em !important;
|
||||
}
|
||||
|
|
|
@ -34,32 +34,41 @@ add_task(async function test_saveAddress() {
|
|||
ok(true, "Edit address dialog is closed");
|
||||
resolve();
|
||||
}, {once: true});
|
||||
EventUtils.synthesizeKey("VK_TAB", {}, win);
|
||||
EventUtils.synthesizeKey(TEST_ADDRESS_1["given-name"], {}, win);
|
||||
EventUtils.synthesizeKey("VK_TAB", {}, win);
|
||||
EventUtils.synthesizeKey(TEST_ADDRESS_1["additional-name"], {}, win);
|
||||
EventUtils.synthesizeKey("VK_TAB", {}, win);
|
||||
EventUtils.synthesizeKey(TEST_ADDRESS_1["family-name"], {}, win);
|
||||
EventUtils.synthesizeKey("VK_TAB", {}, win);
|
||||
EventUtils.synthesizeKey(TEST_ADDRESS_1.organization, {}, win);
|
||||
EventUtils.synthesizeKey("VK_TAB", {}, win);
|
||||
EventUtils.synthesizeKey(TEST_ADDRESS_1["street-address"], {}, win);
|
||||
EventUtils.synthesizeKey("VK_TAB", {}, win);
|
||||
EventUtils.synthesizeKey(TEST_ADDRESS_1["address-level2"], {}, win);
|
||||
EventUtils.synthesizeKey("VK_TAB", {}, win);
|
||||
EventUtils.synthesizeKey(TEST_ADDRESS_1["address-level1"], {}, win);
|
||||
EventUtils.synthesizeKey("VK_TAB", {}, win);
|
||||
EventUtils.synthesizeKey(TEST_ADDRESS_1["postal-code"], {}, win);
|
||||
EventUtils.synthesizeKey("VK_TAB", {}, win);
|
||||
EventUtils.synthesizeKey(TEST_ADDRESS_1.country, {}, win);
|
||||
EventUtils.synthesizeKey("VK_TAB", {}, win);
|
||||
EventUtils.synthesizeKey(TEST_ADDRESS_1.email, {}, win);
|
||||
EventUtils.synthesizeKey("VK_TAB", {}, win);
|
||||
EventUtils.synthesizeKey(TEST_ADDRESS_1.tel, {}, win);
|
||||
EventUtils.synthesizeKey("VK_TAB", {}, win);
|
||||
EventUtils.synthesizeKey("VK_TAB", {}, win);
|
||||
info("saving address");
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, win);
|
||||
let doc = win.document;
|
||||
// Verify labels
|
||||
is(doc.querySelector("#address-level1-container > span").textContent, "State",
|
||||
"US address-level1 label should be 'State'");
|
||||
is(doc.querySelector("#postal-code-container > span").textContent, "Zip Code",
|
||||
"US postal-code label should be 'Zip Code'");
|
||||
// Input address info and verify move through form with tab keys
|
||||
const keyInputs = [
|
||||
"VK_TAB",
|
||||
TEST_ADDRESS_1["given-name"],
|
||||
"VK_TAB",
|
||||
TEST_ADDRESS_1["additional-name"],
|
||||
"VK_TAB",
|
||||
TEST_ADDRESS_1["family-name"],
|
||||
"VK_TAB",
|
||||
TEST_ADDRESS_1.organization,
|
||||
"VK_TAB",
|
||||
TEST_ADDRESS_1["street-address"],
|
||||
"VK_TAB",
|
||||
TEST_ADDRESS_1["address-level2"],
|
||||
"VK_TAB",
|
||||
TEST_ADDRESS_1["address-level1"],
|
||||
"VK_TAB",
|
||||
TEST_ADDRESS_1["postal-code"],
|
||||
"VK_TAB",
|
||||
TEST_ADDRESS_1.country,
|
||||
"VK_TAB",
|
||||
TEST_ADDRESS_1.email,
|
||||
"VK_TAB",
|
||||
TEST_ADDRESS_1.tel,
|
||||
"VK_TAB",
|
||||
"VK_TAB",
|
||||
"VK_RETURN",
|
||||
];
|
||||
keyInputs.forEach(input => EventUtils.synthesizeKey(input, {}, win));
|
||||
}, {once: true});
|
||||
});
|
||||
let addresses = await getAddresses();
|
||||
|
@ -95,3 +104,109 @@ add_task(async function test_editAddress() {
|
|||
addresses = await getAddresses();
|
||||
is(addresses.length, 0, "Address storage is empty");
|
||||
});
|
||||
|
||||
add_task(async function test_saveAddressCA() {
|
||||
await new Promise(resolve => {
|
||||
let win = window.openDialog(EDIT_ADDRESS_DIALOG_URL);
|
||||
win.addEventListener("load", () => {
|
||||
win.addEventListener("unload", () => {
|
||||
ok(true, "Edit address dialog is closed");
|
||||
resolve();
|
||||
}, {once: true});
|
||||
let doc = win.document;
|
||||
// Change country to verify labels
|
||||
doc.querySelector("#country").focus();
|
||||
EventUtils.synthesizeKey("Canada", {}, win);
|
||||
is(doc.querySelector("#address-level1-container > span").textContent, "Province",
|
||||
"CA address-level1 label should be 'Province'");
|
||||
is(doc.querySelector("#postal-code-container > span").textContent, "Postal Code",
|
||||
"CA postal-code label should be 'Postal Code'");
|
||||
// Input address info and verify move through form with tab keys
|
||||
doc.querySelector("#given-name").focus();
|
||||
const keyInputs = [
|
||||
TEST_ADDRESS_CA_1["given-name"],
|
||||
"VK_TAB",
|
||||
TEST_ADDRESS_CA_1["additional-name"],
|
||||
"VK_TAB",
|
||||
TEST_ADDRESS_CA_1["family-name"],
|
||||
"VK_TAB",
|
||||
TEST_ADDRESS_CA_1.organization,
|
||||
"VK_TAB",
|
||||
TEST_ADDRESS_CA_1["street-address"],
|
||||
"VK_TAB",
|
||||
TEST_ADDRESS_CA_1["address-level2"],
|
||||
"VK_TAB",
|
||||
TEST_ADDRESS_CA_1["address-level1"],
|
||||
"VK_TAB",
|
||||
TEST_ADDRESS_CA_1["postal-code"],
|
||||
"VK_TAB",
|
||||
TEST_ADDRESS_CA_1.country,
|
||||
"VK_TAB",
|
||||
TEST_ADDRESS_CA_1.email,
|
||||
"VK_TAB",
|
||||
TEST_ADDRESS_CA_1.tel,
|
||||
"VK_TAB",
|
||||
"VK_TAB",
|
||||
"VK_RETURN",
|
||||
];
|
||||
keyInputs.forEach(input => EventUtils.synthesizeKey(input, {}, win));
|
||||
}, {once: true});
|
||||
});
|
||||
let addresses = await getAddresses();
|
||||
for (let [fieldName, fieldValue] of Object.entries(TEST_ADDRESS_CA_1)) {
|
||||
is(addresses[0][fieldName], fieldValue, "check " + fieldName);
|
||||
}
|
||||
await removeAllRecords();
|
||||
});
|
||||
|
||||
add_task(async function test_saveAddressDE() {
|
||||
await new Promise(resolve => {
|
||||
let win = window.openDialog(EDIT_ADDRESS_DIALOG_URL);
|
||||
win.addEventListener("load", () => {
|
||||
win.addEventListener("unload", () => {
|
||||
ok(true, "Edit address dialog is closed");
|
||||
resolve();
|
||||
}, {once: true});
|
||||
let doc = win.document;
|
||||
// Change country to verify labels
|
||||
doc.querySelector("#country").focus();
|
||||
EventUtils.synthesizeKey("Germany", {}, win);
|
||||
is(doc.querySelector("#postal-code-container > span").textContent, "Postal Code",
|
||||
"DE postal-code label should be 'Postal Code'");
|
||||
is(doc.querySelector("#address-level1-container").style.display, "none",
|
||||
"DE address-level1 should be hidden");
|
||||
// Input address info and verify move through form with tab keys
|
||||
doc.querySelector("#given-name").focus();
|
||||
const keyInputs = [
|
||||
TEST_ADDRESS_DE_1["given-name"],
|
||||
"VK_TAB",
|
||||
TEST_ADDRESS_DE_1["additional-name"],
|
||||
"VK_TAB",
|
||||
TEST_ADDRESS_DE_1["family-name"],
|
||||
"VK_TAB",
|
||||
TEST_ADDRESS_DE_1.organization,
|
||||
"VK_TAB",
|
||||
TEST_ADDRESS_DE_1["street-address"],
|
||||
"VK_TAB",
|
||||
TEST_ADDRESS_DE_1["postal-code"],
|
||||
"VK_TAB",
|
||||
TEST_ADDRESS_DE_1["address-level2"],
|
||||
"VK_TAB",
|
||||
TEST_ADDRESS_DE_1.country,
|
||||
"VK_TAB",
|
||||
TEST_ADDRESS_DE_1.email,
|
||||
"VK_TAB",
|
||||
TEST_ADDRESS_DE_1.tel,
|
||||
"VK_TAB",
|
||||
"VK_TAB",
|
||||
"VK_RETURN",
|
||||
];
|
||||
keyInputs.forEach(input => EventUtils.synthesizeKey(input, {}, win));
|
||||
}, {once: true});
|
||||
});
|
||||
let addresses = await getAddresses();
|
||||
for (let [fieldName, fieldValue] of Object.entries(TEST_ADDRESS_DE_1)) {
|
||||
is(addresses[0][fieldName], fieldValue, "check " + fieldName);
|
||||
}
|
||||
await removeAllRecords();
|
||||
});
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* exported MANAGE_ADDRESSES_DIALOG_URL, MANAGE_CREDIT_CARDS_DIALOG_URL, EDIT_ADDRESS_DIALOG_URL, EDIT_CREDIT_CARD_DIALOG_URL,
|
||||
BASE_URL, TEST_ADDRESS_1, TEST_ADDRESS_2, TEST_ADDRESS_3, TEST_ADDRESS_4, TEST_ADDRESS_5,
|
||||
BASE_URL, TEST_ADDRESS_1, TEST_ADDRESS_2, TEST_ADDRESS_3, TEST_ADDRESS_4, TEST_ADDRESS_5, TEST_ADDRESS_CA_1, TEST_ADDRESS_DE_1,
|
||||
TEST_CREDIT_CARD_1, TEST_CREDIT_CARD_2, TEST_CREDIT_CARD_3, FORM_URL, CREDITCARD_FORM_URL,
|
||||
FTU_PREF, ENABLED_AUTOFILL_ADDRESSES_PREF, AUTOFILL_CREDITCARDS_AVAILABLE_PREF, ENABLED_AUTOFILL_CREDITCARDS_PREF,
|
||||
SYNC_USERNAME_PREF, SYNC_ADDRESSES_PREF, SYNC_CREDITCARDS_PREF, SYNC_CREDITCARDS_AVAILABLE_PREF, CREDITCARDS_USED_STATUS_PREF,
|
||||
|
@ -67,6 +67,33 @@ const TEST_ADDRESS_5 = {
|
|||
tel: "+16172535702",
|
||||
};
|
||||
|
||||
const TEST_ADDRESS_CA_1 = {
|
||||
"given-name": "John",
|
||||
"additional-name": "R.",
|
||||
"family-name": "Smith",
|
||||
organization: "Mozilla",
|
||||
"street-address": "163 W Hastings\nSuite 209",
|
||||
"address-level2": "Vancouver",
|
||||
"address-level1": "BC",
|
||||
"postal-code": "V6B 1H5",
|
||||
country: "CA",
|
||||
tel: "+17787851540",
|
||||
email: "timbl@w3.org",
|
||||
};
|
||||
|
||||
const TEST_ADDRESS_DE_1 = {
|
||||
"given-name": "John",
|
||||
"additional-name": "R.",
|
||||
"family-name": "Smith",
|
||||
organization: "Mozilla",
|
||||
"street-address": "Geb\u00E4ude 3, 4. Obergeschoss\nSchlesische Stra\u00DFe 27",
|
||||
"address-level2": "Berlin",
|
||||
"postal-code": "10997",
|
||||
country: "DE",
|
||||
tel: "+4930983333000",
|
||||
email: "timbl@w3.org",
|
||||
};
|
||||
|
||||
const TEST_CREDIT_CARD_1 = {
|
||||
"cc-name": "John Doe",
|
||||
"cc-number": "1234567812345678",
|
||||
|
|
Загрузка…
Ссылка в новой задаче