/* 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 "../vendor/lit.all.mjs"; import { MozLitElement } from "../lit-utils.mjs"; window.MozXULElement?.insertFTLIfNeeded( "toolkit/global/mozBreadcrumbGroup.ftl" ); /** * @tagname moz-breadcrumb * @property {string} href * @property {string} label */ export class MozBreadcrumb extends MozLitElement { static properties = { href: { type: String }, label: { type: String, fluent: true }, heading: { type: String, fluent: true }, ariaCurrent: { attribute: "aria-current", type: String }, }; constructor() { super(); this.label = ""; this.heading = ""; this.href = ""; } render() { const labelTemplate = this.label || this.heading || html``; return html` ${this.ariaCurrent ? labelTemplate : html`${labelTemplate}`} `; } } customElements.define("moz-breadcrumb", MozBreadcrumb); /** * @tagname moz-breadcrumb-group */ export class MozBreadcrumbGroup extends MozLitElement { /** * @type {MutationObserver | void} */ #observer; /** * Fired when a breadcrumb is either * added or removed from the DOM, at which * an update is requested to re-render breadcrumbs. * * @type {MutationCallback} */ #onBreadcrumbMutation(mutations) { for (const mutation of mutations) { if (mutation.type === "childList") { this.requestUpdate(); } } } /** * @type {Array} */ get breadcrumbs() { /** * @type {NodeListOf} */ const breadcrumbElements = this.querySelectorAll("moz-breadcrumb"); return Array.from(breadcrumbElements); } setupBreadcrumbs() { const { breadcrumbs } = this; return breadcrumbs.map((breadcrumb, i) => { breadcrumb.setAttribute("slot", i + ""); if (i === breadcrumbs.length - 1) { breadcrumb.setAttribute("aria-current", "page"); } return breadcrumb; }); } update() { super.update(); this.setupBreadcrumbs(); } firstUpdated() { if (!this.#observer) { this.#observer = new MutationObserver((mutations, observer) => this.#onBreadcrumbMutation(mutations, observer) ); this.#observer.observe(this, { childList: true, }); } } disconnectedCallback() { if (this.#observer) { this.#observer.disconnect(); this.#observer = undefined; } super.disconnectedCallback(); } render() { return html` `; } } customElements.define("moz-breadcrumb-group", MozBreadcrumbGroup);