From 086c044dc34dfc0f74fbe41f4ecb402b2cd34884 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 03:13:33 +0200 Subject: Merging upstream version 125.0.1. Signed-off-by: Daniel Baumann --- .../content/widgets/moz-page-nav/moz-page-nav.mjs | 170 +++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 toolkit/content/widgets/moz-page-nav/moz-page-nav.mjs (limited to 'toolkit/content/widgets/moz-page-nav/moz-page-nav.mjs') diff --git a/toolkit/content/widgets/moz-page-nav/moz-page-nav.mjs b/toolkit/content/widgets/moz-page-nav/moz-page-nav.mjs new file mode 100644 index 0000000000..f998ee735f --- /dev/null +++ b/toolkit/content/widgets/moz-page-nav/moz-page-nav.mjs @@ -0,0 +1,170 @@ +/* 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 } from "chrome://global/content/vendor/lit.all.mjs"; +import { MozLitElement } from "chrome://global/content/lit-utils.mjs"; + +/** + * A grouping of navigation buttons that is displayed at the page level, + * intended to change the selected view, provide a heading, and have links + * to external resources. + * + * @tagname moz-page-nav + * @property {string} currentView - The currently selected view. + * @property {string} heading - A heading to be displayed at the top of the navigation. + * @slot [default] - Used to append moz-page-nav-button elements to the navigation. + */ +export default class MozPageNav extends MozLitElement { + static properties = { + currentView: { type: String }, + heading: { type: String }, + }; + + static queries = { + headingEl: "#page-nav-header", + primaryNavGroupSlot: ".primary-nav-group slot", + secondaryNavGroupSlot: "#secondary-nav-group slot", + }; + + get pageNavButtons() { + return this.primaryNavGroupSlot + .assignedNodes() + .filter( + node => node?.localName === "moz-page-nav-button" && !node.hidden + ); + } + + onChangeView(e) { + this.currentView = e.target.view; + } + + handleFocus(e) { + if (e.key == "ArrowDown" || e.key == "ArrowRight") { + e.preventDefault(); + this.focusNextView(); + } else if (e.key == "ArrowUp" || e.key == "ArrowLeft") { + e.preventDefault(); + this.focusPreviousView(); + } + } + + focusPreviousView() { + let pageNavButtons = this.pageNavButtons; + let currentIndex = pageNavButtons.findIndex(b => b.selected); + let prev = pageNavButtons[currentIndex - 1]; + if (prev) { + prev.activate(); + prev.buttonEl.focus(); + } + } + + focusNextView() { + let pageNavButtons = this.pageNavButtons; + let currentIndex = pageNavButtons.findIndex(b => b.selected); + let next = pageNavButtons[currentIndex + 1]; + if (next) { + next.activate(); + next.buttonEl.focus(); + } + } + + render() { + return html` + + + `; + } + + updated() { + let isViewSelected = false; + let assignedPageNavButtons = this.pageNavButtons; + for (let button of assignedPageNavButtons) { + button.selected = button.view == this.currentView; + isViewSelected = isViewSelected || button.selected; + } + if (!isViewSelected && assignedPageNavButtons.length) { + // Current page nav has no matching view, reset to the first view. + assignedPageNavButtons[0].activate(); + } + } +} +customElements.define("moz-page-nav", MozPageNav); + +/** + * A navigation button intended to change the selected view within a page. + * + * @tagname moz-page-nav-button + * @property {string} iconSrc - The chrome:// url for the icon used for the button. + * @property {string} l10nId - The fluent ID for the button's text + * @property {boolean} selected - Whether or not the button is currently selected. + * @slot [default] - Used to append the l10n string to the button. + */ +export class MozPageNavButton extends MozLitElement { + static properties = { + iconSrc: { type: String }, + l10nId: { type: String }, + selected: { type: Boolean }, + }; + + connectedCallback() { + super.connectedCallback(); + this.setAttribute("role", "none"); + } + + static queries = { + buttonEl: "button", + }; + + get view() { + return this.getAttribute("view"); + } + + activate() { + this.dispatchEvent( + new CustomEvent("change-view", { + bubbles: true, + composed: true, + }) + ); + } + + render() { + return html` + + + `; + } +} +customElements.define("moz-page-nav-button", MozPageNavButton); -- cgit v1.2.3