); return; } // Select the current row. const row = event.target; const { guid, previousElementSibling: prevRow, nextElementSibling: nextRow, } = row; this.selectedGuids.add(guid); // Select the previous or next sibling, depending on which arrow key was used. if (event.code === "ArrowUp" && prevRow) { this.selectedGuids.add(prevRow.guid); } else if (event.code === "ArrowDown" && nextRow) { this.selectedGuids.add(nextRow.guid); } else { this.requestVirtualListUpdate(); } // Notify the host component. this.dispatchEvent( new CustomEvent("update-selection", { bubbles: true, composed: true, }) ); } clearSelection() { this.selectedGuids.clear(); this.requestVirtualListUpdate(); } get selectAllShortcut() { const [l10nMessage] = this.shortcutsLocalization.formatMessagesSync([ "text-action-select-all-shortcut", ]); const shortcutKey = l10nMessage.attributes[0].value; return shortcutKey; } #selectAll() { for (const { guid } of this.tabItems) { this.selectedGuids.add(guid); } this.requestVirtualListUpdate(); this.dispatchEvent( new CustomEvent("update-selection", { bubbles: true, composed: true, }) ); } itemTemplate = (tabItem, i) => { let tabIndex = -1; if ((this.searchQuery || this.sortOption == "lastvisited") && i == 0) { // Make the first row focusable if there is no header. tabIndex = 0; } else if (!this.searchQuery) { tabIndex = 0; } return html` e.currentTarget.primaryActionHandler(e)} > `; }; stylesheets() { return [ super.stylesheets(), html``, ]; } } customElements.define("sidebar-tab-list", SidebarTabList); export class SidebarTabRow extends FxviewTabRowBase { static properties = { containerObj: { type: Object }, guid: { type: String }, selected: { type: Boolean, reflect: true }, indicators: { type: Array }, }; /** * Fallback to the native implementation in sidebar. We want to focus the * entire row instead of delegating it to link or hover buttons. */ focus() { HTMLElement.prototype.focus.call(this); } #getContainerClasses() { let containerClasses = ["fxview-tab-row-container-indicator", "icon"]; if (this.containerObj) { let { icon, color } = this.containerObj; containerClasses.push(`identity-icon-${icon}`); containerClasses.push(`identity-color-${color}`); } return containerClasses; } #containerIndicatorTemplate() { let tabList = this.getRootNode().host; let tabsToCheck = tabList.tabItems; return html`${when( tabsToCheck.some(tab => tab.containerObj), () => html`` )}`; } secondaryButtonTemplate() { return html`${when( this.secondaryL10nId && this.secondaryActionClass, () => html`` )}`; } render() { return html` ${this.stylesheets()} ${when( this.containerObj, () => html` ` )} ${this.faviconTemplate()} ${this.titleTemplate()} ${this.secondaryButtonTemplate()} ${this.#containerIndicatorTemplate()} `; } } customElements.define("sidebar-tab-row", SidebarTabRow); PK