Bug 1375799 - (Part 1) [Form Autofill] Use localized strings instead of hardcoded strings. r=lchang,MattN

MozReview-Commit-ID: DgWLFN2EDc8

--HG--
extra : rebase_source : ab7545bbc09d57d2cb043506738e51cda9b4b33d
This commit is contained in:
Scott Wu 2017-06-29 16:23:44 -07:00
parent 3a859abc10
commit 5b2f66044f
7 changed files with 155 additions and 40 deletions

View File

@ -11,6 +11,7 @@ const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
const ADDRESS_REFERENCES = "chrome://formautofill/content/addressReferences.js";
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
this.FormAutofillUtils = {
get AUTOFILL_FIELDS_THRESHOLD() { return 3; },
@ -201,6 +202,20 @@ this.FormAutofillUtils = {
return sandbox;
},
/**
* Get country address data. Fallback to US if not found.
* @param {string} country
* @returns {object}
*/
getCountryAddressData(country) {
// Load the addressData if needed
if (!this._addressDataLoaded) {
Object.assign(this, this.loadDataFromScript(ADDRESS_REFERENCES));
this._addressDataLoaded = true;
}
return this.addressData[`data/${country}`] || this.addressData["data/US"];
},
/**
* Find the option element from select element.
* 1. Try to find the locale using the country from address.
@ -218,15 +233,7 @@ this.FormAutofillUtils = {
return null;
}
// Load the addressData if needed
if (!this._addressDataLoaded) {
Object.assign(this, this.loadDataFromScript(ADDRESS_REFERENCES));
this._addressDataLoaded = true;
}
// Set dataset to "data/US" as fallback
let dataset = this.addressData[`data/${address.country}`] ||
this.addressData["data/US"];
let dataset = this.getCountryAddressData(address.country);
let collator = new Intl.Collator(dataset.lang, {sensitivity: "base", ignorePunctuation: true});
for (let option of selectEl.options) {
@ -303,6 +310,37 @@ this.FormAutofillUtils = {
strCompare(a = "", b = "", collator) {
return !collator.compare(a, b);
},
/**
* Get formatting information of a given country
* @param {string} country
* @returns {object}
* {
* {string} addressLevel1Label
* {string} postalCodeLabel
* }
*/
getFormFormat(country) {
const dataset = this.getCountryAddressData(country);
return {
"addressLevel1Label": dataset.state_name_type || "province",
"postalCodeLabel": dataset.zip_name_type || "postalCode",
};
},
/**
* Localize elements with "data-localization" attribute
* @param {string} bundleURI
* @param {DOMElement} root
*/
localizeMarkup(bundleURI, root) {
const bundle = Services.strings.createBundle(bundleURI);
let elements = root.querySelectorAll("[data-localization]");
for (let element of elements) {
element.textContent = bundle.GetStringFromName(element.getAttribute("data-localization"));
element.removeAttribute("data-localization");
}
},
};
this.log = null;

View File

@ -5,6 +5,8 @@
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
const AUTOFILL_BUNDLE_URI = "chrome://formautofill/locale/formautofill.properties";
const REGIONS_BUNDLE_URI = "chrome://global/locale/regionNames.properties";
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://formautofill/FormAutofillUtils.jsm");
@ -15,12 +17,27 @@ function EditDialog() {
}
EditDialog.prototype = {
init() {
this._elements = {
get _elements() {
if (this._elementRefs) {
return this._elementRefs;
}
this._elementRefs = {
title: document.querySelector("title"),
addressLevel1Label: document.querySelector("#address-level1-container > span"),
postalCodeLabel: document.querySelector("#postal-code-container > span"),
country: document.getElementById("country"),
controlsContainer: document.getElementById("controls-container"),
cancel: document.getElementById("cancel"),
save: document.getElementById("save"),
};
return this._elementRefs;
},
set _elements(refs) {
this._elementRefs = refs;
},
init() {
this.attachEventListeners();
},
@ -29,6 +46,27 @@ EditDialog.prototype = {
this._elements = null;
},
/**
* Format the form based on country. The address-level1 and postal-code labels
* should be specific to the given country.
* @param {string} country
*/
formatForm(country) {
// TODO: Use fmt to show/hide and order fields (Bug 1383687)
const {addressLevel1Label, postalCodeLabel} = FormAutofillUtils.getFormFormat(country);
this._elements.addressLevel1Label.dataset.localization = addressLevel1Label;
this._elements.postalCodeLabel.dataset.localization = postalCodeLabel;
FormAutofillUtils.localizeMarkup(AUTOFILL_BUNDLE_URI, document);
},
localizeDocument() {
if (this._address) {
this._elements.title.dataset.localization = "editDialogTitle";
}
FormAutofillUtils.localizeMarkup(REGIONS_BUNDLE_URI, this._elements.country);
this.formatForm(this._address && this._address.country);
},
/**
* Asks FormAutofillParent to save or update an address.
* @param {object} data
@ -77,7 +115,6 @@ EditDialog.prototype = {
case "DOMContentLoaded": {
this.init();
if (this._address) {
document.title = "Edit Address";
this.loadInitialValues(this._address);
}
break;
@ -161,4 +198,4 @@ EditDialog.prototype = {
},
};
new EditDialog();
window.dialog = new EditDialog();

View File

@ -5,7 +5,7 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Add New Address</title>
<title data-localization="addNewDialogTitle"/>
<link rel="stylesheet" href="chrome://formautofill-shared/skin/editAddress.css" />
<link rel="stylesheet" href="chrome://formautofill/skin/editAddress.css" />
<script src="chrome://formautofill/content/editAddress.js"></script>
@ -13,56 +13,61 @@
<body>
<form autocomplete="off">
<label id="given-name-container">
<span>First Name</span>
<span data-localization="givenName"/>
<input id="given-name" type="text"/>
</label>
<label id="additional-name-container">
<span>Middle Name</span>
<span data-localization="additionalName"/>
<input id="additional-name" type="text"/>
</label>
<label id="family-name-container">
<span>Last Name</span>
<span data-localization="familyName"/>
<input id="family-name" type="text"/>
</label>
<label id="organization-container">
<span>Company</span>
<span data-localization="organization"/>
<input id="organization" type="text"/>
</label>
<label id="street-address-container">
<span>Street Address</span>
<span data-localization="streetAddress"/>
<textarea id="street-address" rows="3"/>
</label>
<label id="address-level2-container">
<span>City/Town</span>
<span data-localization="city"/>
<input id="address-level2" type="text"/>
</label>
<label id="address-level1-container">
<span>State/Province</span>
<span/>
<input id="address-level1" type="text"/>
</label>
<label id="postal-code-container">
<span>Zip/Postal</span>
<span/>
<input id="postal-code" type="text"/>
</label>
<label id="country-container">
<span>Country</span>
<span data-localization="country"/>
<select id="country">
<option/>
<option value="US">United States</option>
<option value="US" data-localization="us"/>
</select>
</label>
<label id="email-container">
<span>Email</span>
<span data-localization="email"/>
<input id="email" type="email"/>
</label>
<label id="tel-container">
<span>Phone</span>
<span data-localization="tel"/>
<input id="tel" type="tel"/>
</label>
</form>
<div id="controls-container">
<button id="cancel">Cancel</button>
<button id="save" disabled="disabled">Save</button>
<button id="cancel" data-localization="cancel"/>
<button id="save" disabled="disabled" data-localization="save"/>
</div>
<script type="application/javascript"><![CDATA[
"use strict";
// Localize strings before DOMContentLoaded to prevent flash
window.dialog.localizeDocument();
]]></script>
</body>
</html>

View File

@ -179,6 +179,7 @@
* Used to determine if it has the extra categories other than the focued category. If
* the value is true, we show "Also fill ...", otherwise, show "Fill ..." only.
*/
const namespace = "category.";
this._updateText = (categories = this._allFieldCategories, hasExtraCategories = true) => {
let warningTextTmplKey = hasExtraCategories ? "phishingWarningMessage" : "phishingWarningMessage2";
let sep = this._stringBundle.GetStringFromName("fieldNameSeparator");
@ -187,7 +188,7 @@
let showCategories = hasExtraCategories ?
orderedCategoryList.filter(category => categories.includes(category) && category != this._focusedCategory) :
[this._focusedCategory];
let categoriesText = showCategories.map(this._stringBundle.GetStringFromName).join(sep);
let categoriesText = showCategories.map(category => this._stringBundle.GetStringFromName(namespace + category)).join(sep);
this._warningTextBox.textContent = this._stringBundle.formatStringFromName(warningTextTmplKey,
[categoriesText], 1);

View File

@ -6,6 +6,7 @@
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
const EDIT_ADDRESS_URL = "chrome://formautofill/content/editAddress.xhtml";
const AUTOFILL_BUNDLE_URI = "chrome://formautofill/locale/formautofill.properties";
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
@ -57,6 +58,10 @@ ManageAddressDialog.prototype = {
this._elements = null;
},
localizeDocument() {
FormAutofillUtils.localizeMarkup(AUTOFILL_BUNDLE_URI, document);
},
/**
* Load addresses and render them.
*
@ -302,4 +307,4 @@ ManageAddressDialog.prototype = {
},
};
new ManageAddressDialog();
window.dialog = new ManageAddressDialog();

View File

@ -5,7 +5,7 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Saved Addresses</title>
<title data-localization="manageDialogTitle"/>
<link rel="stylesheet" href="chrome://global/skin/in-content/common.css" />
<link rel="stylesheet" href="chrome://formautofill/content/manageAddresses.css" />
<script src="chrome://formautofill/content/manageAddresses.js"></script>
@ -17,13 +17,18 @@
<a href="https://luke-chang.github.io/autofill-demo/basic.html" target="_blank">Demo page</a>
</p>
<fieldset>
<legend>Addresses</legend>
<legend data-localization="addressListHeader"/>
<select id="addresses" size="9" multiple="multiple"/>
</fieldset>
<div id="controls-container">
<button id="remove" disabled="disabled">Remove</button>
<button id="add">Add…</button>
<button id="edit" disabled="disabled">Edit…</button>
<button id="remove" disabled="disabled" data-localization="remove"/>
<button id="add" data-localization="add"/>
<button id="edit" disabled="disabled" data-localization="edit"/>
</div>
<script type="application/javascript">
"use strict";
// Localize strings before DOMContentLoaded to prevent flash
window.dialog.localizeDocument();
</script>
</body>
</html>

View File

@ -18,11 +18,11 @@ autocompleteFooterOption = Form Autofill Options
autocompleteFooterOptionShort = More Options
autocompleteFooterOptionOSX = Form Autofill Preferences
autocompleteFooterOptionOSXShort = Preferences
address = address
name = name
organization = company
tel = phone
email = email
category.address = address
category.name = name
category.organization = company
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
@ -31,3 +31,27 @@ fieldNameSeparator = ,\u0020
# The text would be e.g. Also fill company, phone, email
phishingWarningMessage = Also autofills %S
phishingWarningMessage2 = Autofills %S
manageDialogTitle = Saved Addresses
addressListHeader = Addresses
remove = Remove
add = Add…
edit = Edit…
addNewDialogTitle = Add New Address
editDialogTitle = Edit Address
givenName = First Name
additionalName = Middle Name
familyName = Last Name
organization = Company
streetAddress = Street Address
city = City
province = Province
state = State
postalCode = Postal Code
zip = Zip Code
country = Country
tel = Phone
email = Email
cancel = Cancel
save = Save