From a53025c9d099928b724fefc46e8b51e538bbdcbd Mon Sep 17 00:00:00 2001 From: Maciej Mionskowski Date: Sun, 24 Mar 2024 23:28:58 +0100 Subject: [PATCH] feat: wip: holding control allows highlighting tabs --- src/sidebar/containers/container.js | 27 +++++------------ src/sidebar/containers/contextual.js | 5 ---- src/sidebar/containers/pinned.js | 10 ++----- src/sidebar/containers/vertical.js | 8 ++--- src/sidebar/style.css | 4 ++- src/sidebar/tab/tab.js | 44 +++++++++++++++++++++++++--- 6 files changed, 56 insertions(+), 42 deletions(-) diff --git a/src/sidebar/containers/container.js b/src/sidebar/containers/container.js index b3aa46c..038fa20 100644 --- a/src/sidebar/containers/container.js +++ b/src/sidebar/containers/container.js @@ -25,7 +25,7 @@ export default class AbstractTabContainer { if (removeInfo.isWindowClosing) return if (removeInfo.windowId !== this._window.id) return if (!this.tabs.has(tabId)) return - this.removeTab(tabId) + this.render(true) }) browser.tabs.onMoved.addListener((tabId) => { @@ -34,12 +34,14 @@ export default class AbstractTabContainer { }) browser.tabs.onAttached.addListener((tabId, attachInfo) => { - if (attachInfo.newWindowId !== this._window.id) { - if (!this.tabs.has(tabId)) return - this.removeTab(tabId) - } else { - this.render(true) + if ( + attachInfo.newWindowId !== this._window.id && + !this.tabs.has(tabId) + ) { + // ignore if move happened between different windows + return } + this.render(true) }) browser.tabs.onUpdated.addListener((tabId, change, tab) => { @@ -137,19 +139,6 @@ export default class AbstractTabContainer { ) } - /** - * Removes a tab from DOM, does not remove it from a browser - * @param {integer} tabId - */ - removeTab(tabId) { - if (!this.tabs.has(tabId)) return - const tab = this.tabs.get(tabId) - tab.destroy() - this.tabs.delete(tabId) - tab.element.parentNode.removeChild(tab.element) - this.render(false) - } - async render(updateTabs) { this.element.setAttribute("data-container-id", this.id) this.element.setAttribute("data-tabs-count", this.tabs.size) diff --git a/src/sidebar/containers/contextual.js b/src/sidebar/containers/contextual.js index 7ec6a22..1b9a7b5 100644 --- a/src/sidebar/containers/contextual.js +++ b/src/sidebar/containers/contextual.js @@ -113,11 +113,6 @@ export default class ContextualIdentityContainer extends VerticalContainer { }) } - refresh(contextualIdentity) { - this.contextualIdentity = contextualIdentity - this.render(false) - } - async _queryTabs() { return await browser.tabs.query({ currentWindow: true, diff --git a/src/sidebar/containers/pinned.js b/src/sidebar/containers/pinned.js index 34d1c2c..86832ef 100644 --- a/src/sidebar/containers/pinned.js +++ b/src/sidebar/containers/pinned.js @@ -23,22 +23,18 @@ export default class PinnedTabsContainer extends AbstractTabContainer { } _handleTabPinned(tabId, change, tab) { - if (!tab.pinned) { - this.removeTab(tabId) - } else { - this.render(true) - } + this.render(true) } async render(updateTabs) { - super.render(updateTabs) + await super.render(updateTabs) if (updateTabs) { let tabs = await browser.tabs.query({ currentWindow: true, pinned: true, }) this.renderTabs(this.element, tabs) - this.render(false) + await this.render(false) } } diff --git a/src/sidebar/containers/vertical.js b/src/sidebar/containers/vertical.js index e53b722..044655e 100644 --- a/src/sidebar/containers/vertical.js +++ b/src/sidebar/containers/vertical.js @@ -72,8 +72,8 @@ export default class VerticalContainer extends AbstractTabContainer { if (tab.url !== "about:newtab") { tabInfo.url = tab.url } - await this._actionNewTab(tabInfo) await browser.tabs.remove(tabId) + await this._actionNewTab(tabInfo) } } @@ -99,11 +99,7 @@ export default class VerticalContainer extends AbstractTabContainer { } _handleTabPinned(tabId, change, tab) { - if (tab.pinned) { - this.removeTab(tabId) - } else { - this.render(true) - } + this.render(true) } async _actionNewTab(options) {} diff --git a/src/sidebar/style.css b/src/sidebar/style.css index b98aafa..933581c 100644 --- a/src/sidebar/style.css +++ b/src/sidebar/style.css @@ -170,7 +170,9 @@ body:not(.wrap-titles) .container-tab-title, .container-title { } .tab-active, -.tab-active:hover { +.tab-active:hover, +.tab-highlighted, +.tab-highlighted:hover { background: var(--color-focus) } diff --git a/src/sidebar/tab/tab.js b/src/sidebar/tab/tab.js index c537c04..7f4441c 100644 --- a/src/sidebar/tab/tab.js +++ b/src/sidebar/tab/tab.js @@ -43,6 +43,17 @@ export default class ContainerTab { } ) + browser.tabs.onHighlighted.addListener((event) => { + if (event.windowId !== this._window.id) { + return + } + const newHighlighted = event.tabIds.indexOf(this.id) !== -1 + if (newHighlighted !== this.tab.highlighted) { + this.tab.highlighted = newHighlighted + this.render() + } + }) + this.element.setAttribute("draggable", true) this.element.addEventListener("contextmenu", (e) => browser.menus.overrideContext({ @@ -115,14 +126,34 @@ export default class ContainerTab { this._removeCloseClick.bind(this) ) - this.element.addEventListener("click", (e) => { + this.element.addEventListener("click", async (e) => { // prevent reloading tab e.preventDefault() e.stopPropagation() if (e.button !== 0) return - browser.tabs.update(this.id, { - active: true, - }) + if (!!e.ctrlKey && !this.tab.active) { + const highlighted = await browser.tabs.query({ + windowId: this._window.id, + highlighted: true, + }) + const tabsToSelect = [...highlighted.map((tab) => tab.index)] + const currentIndex = await browser.tabs.get(this.id) + const index = tabsToSelect.indexOf(currentIndex.index) + if (index === -1) { + tabsToSelect.push(currentIndex.index) + } else { + tabsToSelect.splice(index, 1) + } + await browser.tabs.highlight({ + windowId: this._window.id, + populate: false, + tabs: tabsToSelect, + }) + } else { + await browser.tabs.update(this.id, { + active: true, + }) + } }) this.element.addEventListener("auxclick", (e) => { @@ -200,6 +231,11 @@ export default class ContainerTab { } else { link.classList.remove("tab-active") } + if (!!this.tab.highlighted) { + link.classList.add("tab-highlighted") + } else { + link.classList.remove("tab-highlighted") + } if (this.tab.pinned) { link.classList.add("tab-pinned") } else {