Bug 1472278 - Localize the required form asterisk on the address-form, basic-card-form, and CVV entry field. r?mattn draft
authorJared Wein <jwein@mozilla.com>
Mon, 30 Jul 2018 21:13:36 -0400
changeset 826027 bfeebe1b8b8309c0c73bc67b480c59784d3824b6
parent 826007 01944756583efe10b5d43e015f4ba0dc0f52b3f9
child 826176 67d414cc00b11f5b16ebb3a303efa7e799a21fa2
child 826406 92eafccc68b89f7f0ff3a4dffbb3a151ceac81aa
push id118233
push userbmo:jaws@mozilla.com
push dateThu, 02 Aug 2018 20:37:06 +0000
reviewersmattn
bugs1472278
milestone63.0a1
Bug 1472278 - Localize the required form asterisk on the address-form, basic-card-form, and CVV entry field. r?mattn MozReview-Commit-ID: 7VN1VY7QziT
browser/components/payments/res/containers/address-form.js
browser/components/payments/res/containers/basic-card-form.js
browser/components/payments/res/containers/form.css
browser/components/payments/res/containers/payment-method-picker.js
browser/components/payments/res/paymentRequest.xhtml
browser/components/payments/test/mochitest/test_address_form.html
--- a/browser/components/payments/res/containers/address-form.js
+++ b/browser/components/payments/res/containers/address-form.js
@@ -237,16 +237,18 @@ export default class AddressForm extends
   }
 
   updateRequiredState() {
     for (let formElement of this.form.elements) {
       let container = formElement.closest(`#${formElement.id}-container`);
       if (formElement.localName == "button" || !container) {
         continue;
       }
+      let span = container.querySelector("span");
+      span.setAttribute("fieldRequiredSymbol", this.dataset.fieldRequiredSymbol);
       let required = formElement.required && !formElement.disabled;
       if (required) {
         container.setAttribute("required", "true");
       } else {
         container.removeAttribute("required");
       }
     }
   }
--- a/browser/components/payments/res/containers/basic-card-form.js
+++ b/browser/components/payments/res/containers/basic-card-form.js
@@ -298,16 +298,18 @@ export default class BasicCardForm exten
 
   updateSaveButtonState() {
     this.saveButton.disabled = !this.form.checkValidity();
   }
 
   updateRequiredState() {
     for (let formElement of this.form.elements) {
       let container = formElement.closest("label") || formElement.closest("div");
+      let span = container.querySelector("span");
+      span.setAttribute("fieldRequiredSymbol", this.dataset.fieldRequiredSymbol);
       let required = formElement.required && !formElement.disabled;
       if (required) {
         container.setAttribute("required", "true");
       } else {
         container.removeAttribute("required");
       }
     }
   }
--- a/browser/components/payments/res/containers/form.css
+++ b/browser/components/payments/res/containers/form.css
@@ -1,8 +1,7 @@
 /* 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/. */
 
 :-moz-any(label, div)[required] > span:first-of-type::after {
-  /* The asterisk should be localized, bug 1472278 */
-  content: "*";
+  content: attr(fieldRequiredSymbol);
 }
--- a/browser/components/payments/res/containers/payment-method-picker.js
+++ b/browser/components/payments/res/containers/payment-method-picker.js
@@ -13,17 +13,17 @@ import paymentRequest from "../paymentRe
  */
 
 export default class PaymentMethodPicker extends RichPicker {
   constructor() {
     super();
     this.dropdown.setAttribute("option-type", "basic-card-option");
     this.securityCodeInput = document.createElement("input");
     this.securityCodeInput.autocomplete = "off";
-    this.securityCodeInput.placeholder = "CVV*"; /* XXX Bug 1473772 */
+    this.securityCodeInput.placeholder = this.dataset.cvvPlaceholder;
     this.securityCodeInput.size = 3;
     this.securityCodeInput.classList.add("security-code");
     this.securityCodeInput.addEventListener("change", this);
   }
 
   connectedCallback() {
     super.connectedCallback();
     this.dropdown.after(this.securityCodeInput);
--- a/browser/components/payments/res/paymentRequest.xhtml
+++ b/browser/components/payments/res/paymentRequest.xhtml
@@ -6,16 +6,17 @@
   <!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
   %globalDTD;
   <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
   %brandDTD;
 
   <!ENTITY viewAllItems               "View All Items">
   <!ENTITY paymentSummaryTitle        "Your Payment">
   <!ENTITY header.payTo               "Pay to">
+  <!ENTITY fieldRequiredSymbol        "*">
 
   <!ENTITY shippingAddressLabel       "Shipping Address">
   <!ENTITY deliveryAddressLabel       "Delivery Address">
   <!ENTITY pickupAddressLabel         "Pickup Address">
   <!ENTITY shippingOptionsLabel       "Shipping Options">
   <!ENTITY paymentMethodsLabel        "Payment Method">
   <!ENTITY address.addLink.label      "Add">
   <!ENTITY address.editLink.label     "Edit">
@@ -28,16 +29,17 @@
   <!ENTITY deliveryAddress.addPage.title  "Add Delivery Address">
   <!ENTITY deliveryAddress.editPage.title "Edit Delivery Address">
   <!ENTITY pickupAddress.addPage.title    "Add Pickup Address">
   <!ENTITY pickupAddress.editPage.title   "Edit Pickup Address">
   <!ENTITY billingAddress.addPage.title   "Add Billing Address">
   <!ENTITY billingAddress.editPage.title  "Edit Billing Address">
   <!ENTITY basicCard.addPage.title    "Add Credit Card">
   <!ENTITY basicCard.editPage.title   "Edit Credit Card">
+  <!ENTITY basicCard.cvv.placeholder  "CVV&fieldRequiredSymbol;">
   <!ENTITY payer.addPage.title        "Add Payer Contact">
   <!ENTITY payer.editPage.title       "Edit Payer Contact">
   <!ENTITY payerLabel                 "Contact Information">
   <!ENTITY cancelPaymentButton.label   "Cancel">
   <!ENTITY approvePaymentButton.label  "Pay">
   <!ENTITY processingPaymentButton.label "Processing">
   <!ENTITY successPaymentButton.label    "Done">
   <!ENTITY unknownPaymentButton.label    "Unknown">
@@ -120,16 +122,17 @@
                           selected-state-key="selectedShippingAddress"></address-picker>
 
           <shipping-option-picker class="shipping-related"
                                   label="&shippingOptionsLabel;"></shipping-option-picker>
 
           <payment-method-picker selected-state-key="selectedPaymentCard"
                                  data-add-link-label="&basicCard.addLink.label;"
                                  data-edit-link-label="&basicCard.editLink.label;"
+                                 data-cvv-placeholder="&basicCard.cvv.placeholder;"
                                  label="&paymentMethodsLabel;">
           </payment-method-picker>
           <address-picker class="payer-related"
                           label="&payerLabel;"
                           data-add-link-label="&payer.addLink.label;"
                           data-edit-link-label="&payer.editLink.label;"
                           selected-state-key="selectedPayerAddress"></address-picker>
         </div>
@@ -158,25 +161,27 @@
                        data-address-edit-link-label="&basicCardPage.addressEditLink.label;"
                        data-billing-address-title-add="&billingAddress.addPage.title;"
                        data-billing-address-title-edit="&billingAddress.editPage.title;"
                        data-back-button-label="&basicCardPage.backButton.label;"
                        data-add-button-label="&basicCardPage.addButton.label;"
                        data-update-button-label="&basicCardPage.updateButton.label;"
                        data-cancel-button-label="&cancelPaymentButton.label;"
                        data-persist-checkbox-label="&basicCardPage.persistCheckbox.label;"
+                       data-field-required-symbol="&fieldRequiredSymbol;"
                        hidden="hidden"></basic-card-form>
 
       <address-form id="address-page"
                     data-error-generic-save="&addressPage.error.genericSave;"
                     data-cancel-button-label="&addressPage.cancelButton.label;"
                     data-back-button-label="&addressPage.backButton.label;"
                     data-add-button-label="&addressPage.addButton.label;"
                     data-update-button-label="&addressPage.updateButton.label;"
                     data-persist-checkbox-label="&addressPage.persistCheckbox.label;"
+                    data-field-required-symbol="&fieldRequiredSymbol;"
                     hidden="hidden"></address-form>
 
       <completion-error-page id="completion-timeout-error" class="illustrated"
                   data-page-title="&timeoutErrorPage.title;"
                   data-suggestion-1="&timeoutErrorPage.suggestion1;"
                   data-suggestion-2="&timeoutErrorPage.suggestion2;"
                   data-suggestion-3="&timeoutErrorPage.suggestion3;"
                   data-done-button-label="&timeoutErrorPage.doneButton.label;"
--- a/browser/components/payments/test/mochitest/test_address_form.html
+++ b/browser/components/payments/test/mochitest/test_address_form.html
@@ -271,16 +271,17 @@ add_task(async function test_restricted_
   ok(!isHidden(form.form.querySelector("#tel")),
      "tel should be visible");
 
   form.remove();
 });
 
 add_task(async function test_field_validation() {
   let form = new AddressForm();
+  form.dataset.fieldRequiredSymbol = "*";
   await form.promiseReady;
   display.appendChild(form);
   await asyncElementRendered();
 
   let postalCodeInput = form.form.querySelector("#postal-code");
   let addressLevel1Input = form.form.querySelector("#address-level1");
   ok(!postalCodeInput.value, "postal-code should be empty by default");
   ok(!addressLevel1Input.value, "address-level1 should be empty by default");
@@ -295,17 +296,20 @@ add_task(async function test_field_valid
     postalCodeInput,
     addressLevel1Input,
     countrySelect,
   ];
   for (let field of requiredFields) {
     let container = field.closest("label");
     ok(container.hasAttribute("required"), "Container should have required attribute");
     let span = container.querySelector("span");
-    is(getComputedStyle(span, "::after").content, "\"*\"", "Asterisk should be on " + field.id);
+    is(span.getAttribute("fieldRequiredSymbol"), "*",
+       "span should have asterisk as fieldRequiredSymbol");
+    is(getComputedStyle(span, "::after").content, "attr(fieldRequiredSymbol)",
+       "Asterisk should be on " + field.id);
   }
 
   countrySelect.selectedIndex = [...countrySelect.options].findIndex(o => o.value == "US");
   countrySelect.dispatchEvent(new Event("change"));
 
   sendStringAndCheckValidity(addressLevel1Input, "MI", true);
   sendStringAndCheckValidity(addressLevel1Input, "", false);
   sendStringAndCheckValidity(postalCodeInput, "B4N4N4", false);