/* 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/. */ const lazy = {}; ChromeUtils.defineESModuleGetters(lazy, { SyncedTabsController: "resource:///modules/SyncedTabsController.sys.mjs", }); import { html, ifDefined, when, } from "chrome://global/content/vendor/lit.all.mjs"; import { escapeHtmlEntities, navigateToLink, } from "chrome://browser/content/firefoxview/helpers.mjs"; import { SidebarPage } from "./sidebar-page.mjs"; class SyncedTabsInSidebar extends SidebarPage { controller = new lazy.SyncedTabsController(this); static queries = { cards: { all: "moz-card" }, searchTextbox: "fxview-search-textbox", }; constructor() { super(); this.onSearchQuery = this.onSearchQuery.bind(this); } connectedCallback() { super.connectedCallback(); this.controller.addSyncObservers(); this.controller.updateStates(); this.addContextMenuListeners(); this.addSidebarFocusedListeners(); } disconnectedCallback() { super.disconnectedCallback(); this.controller.removeSyncObservers(); this.removeContextMenuListeners(); this.removeSidebarFocusedListeners(); } handleContextMenuEvent(e) { this.triggerNode = this.findTriggerNode(e, "fxview-tab-row"); if (!this.triggerNode) { e.preventDefault(); } } handleCommandEvent(e) { switch (e.target.id) { case "sidebar-synced-tabs-context-bookmark-tab": this.topWindow.PlacesCommandHook.bookmarkLink( this.triggerNode.url, this.triggerNode.title ); break; default: super.handleCommandEvent(e); break; } } handleSidebarFocusedEvent() { this.searchTextbox?.focus(); } /** * The template shown when the list of synced devices is currently * unavailable. * * @param {object} options * @param {string} options.action * @param {string} options.buttonLabel * @param {string[]} options.descriptionArray * @param {string} options.descriptionLink * @param {boolean} options.error * @param {string} options.header * @param {string} options.headerIconUrl * @param {string} options.mainImageUrl * @returns {TemplateResult} */ messageCardTemplate({ action, buttonLabel, descriptionArray, descriptionLink, error, header, headerIconUrl, mainImageUrl, }) { return html` `; } /** * The template shown for a device that has tabs. * * @param {string} deviceName * @param {string} deviceType * @param {Array} tabItems * @returns {TemplateResult} */ deviceTemplate(deviceName, deviceType, tabItems) { return html` `; } /** * The template shown for a device that has no tabs. * * @param {string} deviceName * @param {string} deviceType * @returns {TemplateResult} */ noDeviceTabsTemplate(deviceName, deviceType) { return html` `; } /** * The template shown for a device that has tabs, but no tabs that match the * current search query. * * @param {string} deviceName * @param {string} deviceType * @returns {TemplateResult} */ noSearchResultsTemplate(deviceName, deviceType) { return html` `; } /** * The template shown for the list of synced devices. * * @returns {TemplateResult[]} */ deviceListTemplate() { return Object.values(this.controller.getRenderInfo()).map( ({ name: deviceName, deviceType, tabItems, tabs }) => { if (tabItems.length) { return this.deviceTemplate(deviceName, deviceType, tabItems); } else if (tabs.length) { return this.noSearchResultsTemplate(deviceName, deviceType); } return this.noDeviceTabsTemplate(deviceName, deviceType); } ); } render() { const messageCard = this.controller.getMessageCard(); return html` ${this.stylesheet()} `; } onSearchQuery(e) { this.controller.searchQuery = e.detail.query; this.requestUpdate(); } } customElements.define("sidebar-syncedtabs", SyncedTabsInSidebar);