Bug 1551696 - Change reveal-button to a checkbox. r=MattN,Pike draft
authorpulselistener
Sat, 18 May 2019 06:48:47 +0000
changeset 2008564 2a3841e6b9fc481b0f0a9f1314a8b62737f71027
parent 2008563 fc83a5c34b8c4638268e2875c23960f78c05ce5a
child 2008565 1c31be9b186f4d7e6d165a55a95e01a9570b2a94
push id363923
push userreviewbot
push dateSat, 18 May 2019 06:49:52 +0000
treeherdertry@6eb4ec2cb49f [default view] [failures only]
reviewersMattN, Pike
bugs1551696
milestone68.0a1
Bug 1551696 - Change reveal-button to a checkbox. r=MattN,Pike Differential Revision: https://phabricator.services.mozilla.com/D31289 Differential Diff: PHID-DIFF-q6qsz3oilnhdi5zql477
browser/components/aboutlogins/content/aboutLogins.ftl
browser/components/aboutlogins/content/aboutLogins.html
browser/components/aboutlogins/content/components/login-item.js
browser/components/aboutlogins/content/components/modal-input.css
browser/components/aboutlogins/content/components/modal-input.js
--- a/browser/components/aboutlogins/content/aboutLogins.ftl
+++ b/browser/components/aboutlogins/content/aboutLogins.ftl
@@ -22,16 +22,17 @@ login-list =
        *[other] { $count } entries
     }
 
 login-item =
   .cancel-button = Cancel
   .delete-button = Delete
   .edit-button = Edit
   .hostname-label = Website Address
-  .modal-input-reveal-button = Toggle password visibility
+  .modal-input-reveal-checkbox-hide = Hide password
+  .modal-input-reveal-checkbox-show = Show password
   .open-site-button = Launch
   .password-label = Password
   .save-changes-button = Save Changes
   .time-created = Created: { DATETIME($timeCreated, day: "numeric", month: "long", year: "numeric") }
   .time-changed = Last changed: { DATETIME($timeChanged, day: "numeric", month: "long", year: "numeric") }
   .time-used = Last used: { DATETIME($timeUsed, day: "numeric", month: "long", year: "numeric") }
   .username-label = Username
--- a/browser/components/aboutlogins/content/aboutLogins.html
+++ b/browser/components/aboutlogins/content/aboutLogins.html
@@ -29,17 +29,18 @@
                 data-l10n-attrs="count"
                 data-l10n-args='{"count": 0}'></login-list>
     <login-item data-l10n-id="login-item"
                 data-l10n-args='{"timeCreated": 0, "timeChanged": 0, "timeUsed": 0}'
                 data-l10n-attrs="cancel-button,
                                  delete-button,
                                  edit-button,
                                  hostname-label,
-                                 modal-input-reveal-button,
+                                 modal-input-reveal-checkbox-hide,
+                                 modal-input-reveal-checkbox-show,
                                  open-site-button,
                                  password-label,
                                  save-changes-button,
                                  time-created,
                                  time-changed,
                                  time-used,
                                  username-label"></login-item>
 
@@ -100,12 +101,12 @@
       <input type="text"/>
     </template>
 
     <template id="modal-input-template">
       <link rel="stylesheet" href="chrome://global/skin/in-content/common.css">
       <link rel="stylesheet" href="chrome://browser/content/aboutlogins/components/modal-input.css">
       <span class="locked-value"></span>
       <input type="text" class="unlocked-value"/>
-      <button class="reveal-button"/>
+      <input type="checkbox" class="reveal-checkbox"/>
     </template>
   </body>
 </html>
--- a/browser/components/aboutlogins/content/components/login-item.js
+++ b/browser/components/aboutlogins/content/components/login-item.js
@@ -39,38 +39,47 @@ class LoginItem extends ReflectedFluentE
   }
 
   static get reflectedFluentIDs() {
     return [
       "cancel-button",
       "delete-button",
       "edit-button",
       "hostname-label",
-      "modal-input-reveal-button",
+      "modal-input-reveal-checkbox-hide",
+      "modal-input-reveal-checkbox-show",
       "open-site-button",
       "password-label",
       "save-changes-button",
       "time-created",
       "time-changed",
       "time-used",
       "username-label",
     ];
   }
 
   static get observedAttributes() {
     return this.reflectedFluentIDs;
   }
 
   handleSpecialCaseFluentString(attrName) {
-    if (attrName != "modal-input-reveal-button") {
-      return false;
+    switch (attrName) {
+      case "modal-input-reveal-checkbox-hide": {
+        this.shadowRoot.querySelector("modal-input[name='password']")
+                       .setAttribute("reveal-checkbox-hide", this.getAttribute(attrName));
+        break;
+      }
+      case "modal-input-reveal-checkbox-show": {
+        this.shadowRoot.querySelector("modal-input[name='password']")
+                       .setAttribute("reveal-checkbox-show", this.getAttribute(attrName));
+        break;
+      }
+      default:
+        return false;
     }
-
-    this.shadowRoot.querySelector("modal-input[name='password']")
-                   .setAttribute("reveal-button", this.getAttribute(attrName));
     return true;
   }
 
   render() {
     let l10nArgs = {
       timeCreated: this._login.timeCreated || "",
       timeChanged: this._login.timePasswordChanged || "",
       timeUsed: this._login.timeLastUsed || "",
--- a/browser/components/aboutlogins/content/components/modal-input.css
+++ b/browser/components/aboutlogins/content/components/modal-input.css
@@ -2,11 +2,11 @@
  * 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/. */
 
 :host([editing]) .locked-value,
 :host(:not([editing])) .unlocked-value {
   display: none;
 }
 
-:host(:not([type="password"])) .reveal-button {
+:host(:not([type="password"])) .reveal-checkbox {
   display: none;
 }
--- a/browser/components/aboutlogins/content/components/modal-input.js
+++ b/browser/components/aboutlogins/content/components/modal-input.js
@@ -22,27 +22,37 @@ class ModalInput extends ReflectedFluent
       this.value = this.getAttribute("value");
     }
 
     if (this.getAttribute("type") == "password") {
       let unlockedValue = this.shadowRoot.querySelector(".unlocked-value");
       unlockedValue.setAttribute("type", "password");
     }
 
-    this.shadowRoot.querySelector(".reveal-button").addEventListener("click", this);
+    this.shadowRoot.querySelector(".reveal-checkbox").addEventListener("click", this);
   }
 
   static get reflectedFluentIDs() {
-    return ["reveal-button"];
+    return ["reveal-checkbox-hide", "reveal-checkbox-show"];
   }
 
   static get observedAttributes() {
     return ["editing", "type", "value"].concat(ModalInput.reflectedFluentIDs);
   }
 
+  handleSpecialCaseFluentString(attrName) {
+    if (attrName != "reveal-checkbox-hide" &&
+        attrName != "reveal-checkbox-show") {
+      return false;
+    }
+
+    this.updateRevealCheckboxTitle();
+    return true;
+  }
+
   attributeChangedCallback(attr, oldValue, newValue) {
     super.attributeChangedCallback(attr, oldValue, newValue);
 
     if (!this.shadowRoot) {
       return;
     }
 
     let lockedValue = this.shadowRoot.querySelector(".locked-value");
@@ -69,34 +79,32 @@ class ModalInput extends ReflectedFluent
       case "value": {
         this.value = newValue;
         break;
       }
     }
   }
 
   handleEvent(event) {
-    switch (event.type) {
-      case "click": {
-        if (event.target.classList.contains("reveal-button")) {
-          let lockedValue = this.shadowRoot.querySelector(".locked-value");
-          let unlockedValue = this.shadowRoot.querySelector(".unlocked-value");
-          let editing = this.hasAttribute("editing");
-          if ((editing && unlockedValue.getAttribute("type") == "password") ||
-              (!editing && lockedValue.textContent == this.constructor.LOCKED_PASSWORD_DISPLAY)) {
-            lockedValue.textContent = this.value;
-            unlockedValue.setAttribute("type", "text");
-          } else {
-            lockedValue.textContent = this.constructor.LOCKED_PASSWORD_DISPLAY;
-            unlockedValue.setAttribute("type", "password");
-          }
-        }
-        break;
-      }
+    if (event.type != "click" ||
+        !event.target.classList.contains("reveal-checkbox")) {
+      return;
     }
+
+    let revealCheckbox = event.target;
+    let lockedValue = this.shadowRoot.querySelector(".locked-value");
+    let unlockedValue = this.shadowRoot.querySelector(".unlocked-value");
+    if (revealCheckbox.checked) {
+      lockedValue.textContent = this.value;
+      unlockedValue.setAttribute("type", "text");
+    } else {
+      lockedValue.textContent = this.constructor.LOCKED_PASSWORD_DISPLAY;
+      unlockedValue.setAttribute("type", "password");
+    }
+    this.updateRevealCheckboxTitle();
   }
 
   get value() {
     return this.hasAttribute("editing") ? this.shadowRoot.querySelector(".unlocked-value").value.trim()
                                         : this.getAttribute("value") || "";
   }
 
   set value(val) {
@@ -107,10 +115,18 @@ class ModalInput extends ReflectedFluent
     this.shadowRoot.querySelector(".unlocked-value").value = val;
     let lockedValue = this.shadowRoot.querySelector(".locked-value");
     if (this.getAttribute("type") == "password" && val && val.length) {
       lockedValue.textContent = this.constructor.LOCKED_PASSWORD_DISPLAY;
     } else {
       lockedValue.textContent = val;
     }
   }
+
+  updateRevealCheckboxTitle() {
+    let revealCheckbox = this.shadowRoot.querySelector(".reveal-checkbox");
+    let labelAttr = revealCheckbox.checked ? "reveal-checkbox-hide"
+                                           : "reveal-checkbox-show";
+    revealCheckbox.setAttribute("aria-label", this.getAttribute(labelAttr));
+    revealCheckbox.setAttribute("title", this.getAttribute(labelAttr));
+  }
 }
 customElements.define("modal-input", ModalInput);