summaryrefslogtreecommitdiffstats
path: root/browser/components/aboutlogins/content/components/input-field/login-password-field.mjs
blob: 6d903beb0a6e8f20e429bff6b9ee84fbde6f5c67 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/* 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/. */

import { html, classMap } from "chrome://global/content/vendor/lit.all.mjs";
import { MozLitElement } from "chrome://global/content/lit-utils.mjs";
import { editableFieldTemplate, stylesTemplate } from "./input-field.mjs";

class LoginPasswordField extends MozLitElement {
  static CONCEALED_PASSWORD_TEXT = " ".repeat(8);

  static properties = {
    _value: { type: String, state: true },
    readonly: { type: Boolean, reflect: true },
    visible: { type: Boolean, reflect: true },
  };

  static queries = {
    input: "input",
    button: "button",
  };

  set value(newValue) {
    this._value = newValue;
  }

  get #type() {
    return this.visible ? "text" : "password";
  }

  get #password() {
    return this.readonly && !this.visible
      ? LoginPasswordField.CONCEALED_PASSWORD_TEXT
      : this._value;
  }

  render() {
    return html`
      ${stylesTemplate()}
      <label
        class="field-label"
        data-l10n-id="login-item-password-label"
      ></label>
      ${editableFieldTemplate({
        type: this.#type,
        value: this.#password,
        labelId: "login-item-password-label",
        disabled: this.readonly,
        onFocus: this.handleFocus,
        onBlur: this.handleBlur,
      })}
      <button
        class=${classMap({
          revealed: this.visible,
          "reveal-password-button": true,
        })}
        data-l10n-id="login-item-password-reveal-checkbox"
        @click=${this.toggleVisibility}
      ></button>
    `;
  }

  handleFocus(ev) {
    if (ev.relatedTarget !== this.button) {
      this.visible = true;
    }
  }

  handleBlur(ev) {
    if (ev.relatedTarget !== this.button) {
      this.visible = false;
    }
  }

  toggleVisibility() {
    this.visible = !this.visible;
    if (this.visible) {
      this.onPasswordVisible?.();
    }
    this.input.focus();
  }
}

customElements.define("login-password-field", LoginPasswordField);