/* 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 https://mozilla.org/MPL/2.0/. */
import { MozLitElement } from "chrome://global/content/lit-utils.mjs";
import {
html,
classMap,
styleMap,
} from "chrome://global/content/vendor/lit.all.mjs";
import {
connectionTimer,
defaultTimeValue,
} from "chrome://browser/content/ipprotection/ipprotection-timer.mjs";
// eslint-disable-next-line import/no-unassigned-import
import "chrome://global/content/elements/moz-toggle.mjs";
// eslint-disable-next-line import/no-unassigned-import
import "chrome://browser/content/ipprotection/ipprotection-site-settings-control.mjs";
/**
* Custom element that implements a status card for IP protection.
*/
export default class IPProtectionStatusCard extends MozLitElement {
TOGGLE_ON_EVENT = "ipprotection-status-card:user-toggled-on";
TOGGLE_OFF_EVENT = "ipprotection-status-card:user-toggled-off";
static queries = {
statusGroupEl: "#status-card",
connectionToggleEl: "#connection-toggle",
locationEl: "#location-wrapper",
siteSettingsEl: "ipprotection-site-settings-control",
};
static shadowRootOptions = {
...MozLitElement.shadowRootOptions,
delegatesFocus: true,
};
static properties = {
protectionEnabled: { type: Boolean },
canShowTime: { type: Boolean },
enabledSince: { type: Object },
location: { type: Object },
siteData: { type: Object },
// Track toggle state separately so that we can tell when the toggle
// is enabled because of the existing protection state or because of user action.
_toggleEnabled: { type: Boolean, state: true },
};
constructor() {
super();
this.keyListener = this.#keyListener.bind(this);
}
connectedCallback() {
super.connectedCallback();
this.dispatchEvent(new CustomEvent("IPProtection:Init", { bubbles: true }));
this.addEventListener("keydown", this.keyListener, { capture: true });
}
disconnectedCallback() {
super.disconnectedCallback();
this.removeEventListener("keydown", this.keyListener, { capture: true });
}
handleToggleConnect(event) {
let isEnabled = event.target.pressed;
if (isEnabled) {
this.dispatchEvent(
new CustomEvent(this.TOGGLE_ON_EVENT, {
bubbles: true,
composed: true,
})
);
} else {
this.dispatchEvent(
new CustomEvent(this.TOGGLE_OFF_EVENT, {
bubbles: true,
composed: true,
})
);
}
this._toggleEnabled = isEnabled;
}
focus() {
this.connectionToggleEl?.focus();
}
#keyListener(event) {
let keyCode = event.code;
switch (keyCode) {
case "ArrowUp":
// Intentional fall-through
case "ArrowDown": {
event.stopPropagation();
event.preventDefault();
let direction =
keyCode == "ArrowDown"
? Services.focus.MOVEFOCUS_FORWARD
: Services.focus.MOVEFOCUS_BACKWARD;
Services.focus.moveFocus(
window,
null,
direction,
Services.focus.FLAG_BYKEY
);
break;
}
}
}
updated(changedProperties) {
super.updated(changedProperties);
// If the toggle state isn't set, do so now and let it
// match the protection state.
if (!changedProperties.has("_toggleEnabled")) {
this._toggleEnabled = this.protectionEnabled;
}
if (!this.protectionEnabled && this._toggleEnabled) {
// After pressing the toggle, if somehow protection was turned off
// (eg. error thrown), unset the toggle.
this._toggleEnabled = false;
}
}
cardContentTemplate() {
const statusCardL10nId = this.protectionEnabled
? "ipprotection-connection-status-on"
: "ipprotection-connection-status-off";
const toggleL10nId = this.protectionEnabled
? "ipprotection-toggle-active"
: "ipprotection-toggle-inactive";
const siteSettingsTemplate = this.protectionEnabled
? this.siteSettingsTemplate()
: null;
return html`