password-rules-tooltip.mjs (3252B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 import { html } from "chrome://global/content/vendor/lit.all.mjs"; 6 import { MozLitElement } from "chrome://global/content/lit-utils.mjs"; 7 8 /** 9 * The widget for enabling password protection if the backup is not yet 10 * encrypted. 11 */ 12 export default class PasswordRulesTooltip extends MozLitElement { 13 static properties = { 14 hasEmail: { type: Boolean }, 15 tooShort: { type: Boolean }, 16 open: { type: Boolean }, 17 }; 18 19 static get queries() { 20 return { 21 passwordRulesEl: "#password-rules-wrapper", 22 }; 23 } 24 25 constructor() { 26 super(); 27 this.hasEmail = false; 28 this.tooShort = false; 29 this._onResize = null; 30 } 31 32 _debounce(fn, delay) { 33 let timeout; 34 return (...args) => { 35 clearTimeout(timeout); 36 timeout = setTimeout(() => fn(...args), delay); 37 }; 38 } 39 40 _handleResize() { 41 if (this.open) { 42 this.positionPopover(); 43 } 44 } 45 46 connectedCallback() { 47 super.connectedCallback(); 48 this._onResize = this._debounce(() => this._handleResize(), 200); 49 window.addEventListener("resize", this._onResize); 50 } 51 52 disconnectedCallback() { 53 super.disconnectedCallback(); 54 if (this._onResize) { 55 window.removeEventListener("resize", this._onResize); 56 } 57 } 58 59 show() { 60 this.passwordRulesEl.showPopover(); 61 this.positionPopover(); 62 } 63 64 hide() { 65 this.passwordRulesEl.hidePopover(); 66 } 67 68 positionPopover() { 69 const anchorRect = this.getBoundingClientRect(); 70 const popover = this.passwordRulesEl; 71 const isWideViewport = window.innerWidth >= 1200; 72 const isRTL = document.dir === "rtl"; 73 74 // Calculate top position 75 const topPos = isWideViewport 76 ? anchorRect.top + anchorRect.height / 2 77 : anchorRect.bottom; 78 79 popover.style.top = `${topPos}px`; 80 popover.style.right = isRTL ? "auto" : "inherit"; 81 popover.style.left = isRTL ? "inherit" : "auto"; 82 } 83 84 _onBeforeToggle(e) { 85 this.open = e.newState == "open"; 86 } 87 88 render() { 89 return html` 90 <link 91 rel="stylesheet" 92 href="chrome://browser/content/backup/password-rules-tooltip.css" 93 /> 94 <div 95 id="password-rules-wrapper" 96 role="tooltip" 97 aria-describedby="password-rules-header" 98 popover="manual" 99 @beforetoggle=${this._onBeforeToggle} 100 > 101 <h2 102 id="password-rules-header" 103 data-l10n-id="password-rules-header" 104 ></h2> 105 <ul> 106 <li class=${this.tooShort && "warning"}> 107 <span 108 data-l10n-id="password-rules-length-description" 109 class="rule-description" 110 aria-labelledby="password-rules-header" 111 ></span> 112 </li> 113 <li class=${this.hasEmail && "warning"}> 114 <span 115 data-l10n-id="password-rules-email-description" 116 class="rule-description" 117 aria-labelledby="password-rules-header" 118 ></span> 119 </li> 120 </ul> 121 </div> 122 `; 123 } 124 } 125 126 customElements.define("password-rules-tooltip", PasswordRulesTooltip);