diff --git a/src/sidebar/sidebar.html b/src/sidebar/sidebar.html index 0db9e96..6d68032 100644 --- a/src/sidebar/sidebar.html +++ b/src/sidebar/sidebar.html @@ -3,12 +3,16 @@ +
+
+ +
@@ -38,4 +42,4 @@ - \ No newline at end of file + diff --git a/src/sidebar/sidebar.js b/src/sidebar/sidebar.js index 0453dd7..febc3b6 100644 --- a/src/sidebar/sidebar.js +++ b/src/sidebar/sidebar.js @@ -47,6 +47,7 @@ export const ContainerTabsSidebar = { ) this._initContextualIdentities() + this._initSearch() }, _initContextualIdentities() { @@ -92,6 +93,53 @@ export const ContainerTabsSidebar = { }) }, + async _initSearch() { + const searchInput = document.querySelector('.search-input'); + const searchFilterStyle = document.querySelector('style#search-filter-style') + let cidQueryPromise = Promise.resolve(); + let tabQueryPromise = Promise.resolve(); + searchInput.addEventListener('input', async () => { + const searchQuery = searchInput.value.toLowerCase().trim(); + if (searchQuery.length === 0) { + searchFilterStyle.textContent = '' + return + } + cidQueryPromise = cidQueryPromise.then(() => browser.contextualIdentities.query({})) + tabQueryPromise = tabQueryPromise.then(() => browser.tabs.query({})) + const allIdentities = await cidQueryPromise + const allTabs = await tabQueryPromise + const matchingIdentities = allIdentities.filter(cid => { + return cid.name.toLowerCase().indexOf(searchQuery) >= 0 + }) + const matchingTabs = allTabs.filter(tab => { + return (tab.title.toLowerCase().indexOf(searchQuery) >= 0) || + (tab.url.toLowerCase().indexOf(searchQuery) >= 0) + }) + const cookieStoreIds = new Set() + const tabIds = new Set() + matchingIdentities.forEach(cid => { + cookieStoreIds.add(cid.cookieStoreId) + }); + matchingTabs.forEach(tab => { + cookieStoreIds.add(tab.cookieStoreId) + tabIds.add(tab.id) + }); + const containerSelector = [...cookieStoreIds] + .map(id => `#containers .container[data-container-id="${id}"]`) + .join(', ') + const tabSelector = [...tabIds] + .map(id => `#containers .container-tab[data-tab-id="${id}"]`) + .join(', ') + searchFilterStyle.textContent = ` + #containers .container { display: none; } + #containers .container-tab { display: none; } + ${containerSelector} { display: block; } + ${tabSelector} { display: flex; } + ` + }) + searchInput.focus() + }, + /** * Removes a container from DOM, does not remove it from a browser * @param {integer} cookieStoreId - contextual identity id diff --git a/src/sidebar/style.css b/src/sidebar/style.css index b19e922..4dfff75 100644 --- a/src/sidebar/style.css +++ b/src/sidebar/style.css @@ -15,6 +15,18 @@ a, a:link, a:visited { text-decoration: none; } +.search-container { + padding: 5px; +} +.search-input { + display: block; + width: 100%; + padding: 0.5rem; + border: 1px solid var(--color-input-border); + background: var(--color-input-background); + color: var(--color-text); +} + #pinned-tabs { display: flex; flex-wrap: wrap; diff --git a/src/sidebar/theme/dark.css b/src/sidebar/theme/dark.css index 0a6d93f..05a9da4 100644 --- a/src/sidebar/theme/dark.css +++ b/src/sidebar/theme/dark.css @@ -7,6 +7,8 @@ --color-default-container: #fff; --color-container-background: #111; --color-container-border: #222; + --color-input-background: #111; + --color-input-border: #222; --color-tab-background: #222; --color-close: #ccc; --color-icon: #eee; @@ -28,4 +30,5 @@ .container-icon[src$=".png"] { filter: invert(); -} \ No newline at end of file +} + diff --git a/src/sidebar/theme/grey.css b/src/sidebar/theme/grey.css index f1d99fa..3bfd04d 100644 --- a/src/sidebar/theme/grey.css +++ b/src/sidebar/theme/grey.css @@ -9,6 +9,8 @@ --color-container-background: #2B2D30; --color-default-container: #fff; --color-container-border: #222; + --color-input-background: #424242; + --color-input-border: #222; --color-close: #ccc; --color-icon: #eee; } diff --git a/src/sidebar/theme/light.css b/src/sidebar/theme/light.css index 95e6c13..df51684 100644 --- a/src/sidebar/theme/light.css +++ b/src/sidebar/theme/light.css @@ -8,6 +8,8 @@ --color-container-background: #ffffff; --color-container-border: #e3e4e6; --color-tab-background: #ececec; + --color-input-border: #e3e4e6; + --color-input-background: #fff; --color-close: var(--color-icon); --color-icon: rgba(24, 25, 26, 0.35); } @@ -28,4 +30,4 @@ .container-actions .container-action:hover, .container-tab-close:hover, .container-tab-action:hover { background: rgba(0,0,0, 0.1); -} \ No newline at end of file +}