diff --git a/.gitignore b/.gitignore index 9afe5dc95..c32604fcd 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,6 @@ build/profile-ru/* build/profile-en/* !build/profile-en/__preserve-dir build/profile-beta/* -!build/profile-beta/__preserve-dir \ No newline at end of file +!build/profile-beta/__preserve-dir +build/profile-esr/* +!build/profile-esr/__preserve-dir \ No newline at end of file diff --git a/addon/manifest.json b/addon/manifest.json index 2c1246e0d..0d76f6549 100644 --- a/addon/manifest.json +++ b/addon/manifest.json @@ -8,7 +8,7 @@ }, "author": "mbnuqw", "name": "__MSG_ExtName__", - "version": "2.2.1", + "version": "2.2.2", "default_locale": "en", "description": "__MSG_ExtDesc__", "homepage_url": "https://github.com/mbnuqw/sidebery", diff --git a/build/debug.js b/build/debug.js index 463dae6da..a734f80d2 100644 --- a/build/debug.js +++ b/build/debug.js @@ -2,7 +2,7 @@ /*eslint no-console: off*/ const { spawn, spawnSync } = require('child_process') const { scripts } = require('../package.json') -const LANG = process.argv[process.argv.length - 1] +const VER = process.argv[process.argv.length - 1] const colors = { reset: '\x1b[0m', @@ -36,7 +36,7 @@ const PERM_HIDE = scripts['dev.perm.hide'].split(' ') const PERM_HIDE_CMD = PERM_HIDE[0] const PERM_HIDE_OPT = PERM_HIDE.slice(1) -const EXT = scripts['dev.ext.' + LANG].split(' ') +const EXT = scripts['dev.ext.' + VER].split(' ') const EXT_CMD = EXT[0] const EXT_OPT = EXT.slice(1) diff --git a/build/profile-esr/__preserve-dir b/build/profile-esr/__preserve-dir new file mode 100644 index 000000000..e5418e0ba --- /dev/null +++ b/build/profile-esr/__preserve-dir @@ -0,0 +1 @@ +preserve-dir \ No newline at end of file diff --git a/package.json b/package.json index 0e99425eb..bccd761a4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sidebery", - "version": "2.2.1", + "version": "2.2.2", "description": "Manage your tabs and bookmarks in sidebar", "main": "index.js", "scripts": { @@ -10,8 +10,10 @@ "dev.perm.hide": "parcel watch ./src/permissions/tab-hide.html -d ./addon/permissions/ --public-url ./ --no-autoinstall", "dev.ext.en": "web-ext run --source-dir ./addon -f firefox-beta --keep-profile-changes --firefox-profile ./build/profile-beta", "dev.ext.ru": "web-ext run --source-dir ./addon -f firefox --keep-profile-changes --firefox-profile ./build/profile-ru", + "dev.ext.esr": "web-ext run --source-dir ./addon -f firefox-esr --keep-profile-changes --firefox-profile ./build/profile-esr", "dev": "node ./build/debug.js en", "dev.ru": "node ./build/debug.js ru", + "dev.esr": "node ./build/debug.js esr", "build.sidebar": "parcel build ./src/sidebar/index.html -d ./addon/sidebar/ --public-url ./ --no-autoinstall --no-source-maps", "build.group": "parcel build ./src/group/group.html -d ./addon/group/ --public-url ./ --no-autoinstall --no-source-maps", "build.perm.url": "parcel build ./src/permissions/all-urls.html -d ./addon/permissions/ --public-url ./ --no-autoinstall --no-source-maps", diff --git a/src/permissions/main.js b/src/permissions/main.js index 9e0b5dabb..dad3c7efa 100644 --- a/src/permissions/main.js +++ b/src/permissions/main.js @@ -1,5 +1,5 @@ // Load settings and set theme -void(async function() { +void (async function() { let ans = await browser.storage.local.get('settings') let settings = ans.settings let theme = settings ? settings.theme : 'dark' @@ -36,7 +36,8 @@ void (async function() { reqBtnEl.addEventListener('click', () => { browser.permissions.request({ origins, permissions }).then(() => { - browser.runtime.reload() + browser.runtime.sendMessage({ action: 'reloadOptPermissions' }) + browser.tabs.getCurrent().then(tab => browser.tabs.remove([tab.id])) }) }) })() diff --git a/src/sidebar/actions/panels.js b/src/sidebar/actions/panels.js index 682153858..20cdba311 100644 --- a/src/sidebar/actions/panels.js +++ b/src/sidebar/actions/panels.js @@ -82,19 +82,13 @@ export default { /** * Update containers data */ - async updateContainers({ state }, containers) { + async updateContainers({ state, dispatch }, containers) { if (!containers) return for (let localCtr of state.containers) { const newCtr = containers.find(nc => nc.id === localCtr.id) if (!newCtr) continue - localCtr.colorCode = newCtr.colorCode - localCtr.color = newCtr.color - localCtr.icon = newCtr.icon - localCtr.iconUrl = newCtr.iconUrl - localCtr.name = newCtr.name - localCtr.lockedTabs = newCtr.lockedTabs localCtr.lockedPanel = newCtr.lockedPanel localCtr.proxy = newCtr.proxy @@ -107,6 +101,8 @@ export default { localCtr.excludeHosts = newCtr.excludeHosts localCtr.lastActiveTab = newCtr.lastActiveTab } + + dispatch('updateReqHandlerDebounced') }, /** @@ -273,7 +269,7 @@ export default { rule = new RegExp(rule.slice(1, rule.length - 1)) } - state.includeHostsRules.push({ ctx: ctr.id, host: rule }) + state.includeHostsRules.push({ ctx: ctr.id, value: rule }) } } @@ -316,7 +312,8 @@ export default { /** * Set request handler */ - turnOnReqHandler() { + turnOnReqHandler({ state }) { + if (state.private) return if (!browser.proxy.onRequest.hasListener(ReqHandler)) { browser.proxy.onRequest.addListener(ReqHandler, { urls: [''] }) } @@ -325,7 +322,8 @@ export default { /** * Unset request handler */ - turnOffReqHandler() { + turnOffReqHandler({ state }) { + if (state.private) return if (browser.proxy.onRequest.hasListener(ReqHandler)) { browser.proxy.onRequest.removeListener(ReqHandler) } diff --git a/src/sidebar/actions/styles.js b/src/sidebar/actions/styles.js index 8003eb3f9..eb469d2cf 100644 --- a/src/sidebar/actions/styles.js +++ b/src/sidebar/actions/styles.js @@ -21,8 +21,7 @@ export default { } state.customStyles = loadedStyles - - setTimeout(() => EventBus.$emit('dynVarChange'), 256) + EventBus.$emit('dynVarChange') }, /** @@ -61,6 +60,7 @@ export default { const rootEl = document.getElementById('root') Vue.set(state.customStyles, key, val) rootEl.style.setProperty(Utils.CSSVar(key), val) + setTimeout(() => EventBus.$emit('dynVarChange'), 256) }, /** @@ -70,5 +70,6 @@ export default { const rootEl = document.getElementById('root') Vue.set(state.customStyles, key, null) rootEl.style.removeProperty(Utils.CSSVar(key)) + setTimeout(() => EventBus.$emit('dynVarChange'), 256) }, } \ No newline at end of file diff --git a/src/sidebar/actions/sync.js b/src/sidebar/actions/sync.js index 64693852b..23152c594 100644 --- a/src/sidebar/actions/sync.js +++ b/src/sidebar/actions/sync.js @@ -110,6 +110,7 @@ export default { * ReSync panels from last loaded state. */ resyncPanels({ state, dispatch }) { + if (!state.windowFocused) return if (state.lastSyncPanels) dispatch('updateSyncPanels', state.lastSyncPanels) }, @@ -119,7 +120,6 @@ export default { updateSyncPanels({ state, getters }, synced) { if (!synced) return if (synced.id === state.localID) return - // console.log('[DEBUG] SYNC ACTION updateSyncPanels'); // Check if this data already used if (state.synced[synced.id] && state.synced[synced.id] >= synced.time) return diff --git a/src/sidebar/actions/sync.test.js b/src/sidebar/actions/sync.test.js index e8503b1f5..d919bc16b 100644 --- a/src/sidebar/actions/sync.test.js +++ b/src/sidebar/actions/sync.test.js @@ -204,7 +204,8 @@ describe('loadSyncPanels', () => { describe('resyncPanels', () => { test('resync panels', async () => { const state = { - lastSyncPanels: '123456789' + windowFocused: true, + lastSyncPanels: '123456789', } const dispatch = jest.fn() diff --git a/src/sidebar/actions/tabs.js b/src/sidebar/actions/tabs.js index 4279a9440..ac4824bb6 100644 --- a/src/sidebar/actions/tabs.js +++ b/src/sidebar/actions/tabs.js @@ -41,7 +41,9 @@ export default { t.parentId = -1 t.invisible = false t.lvl = 0 + t.host = t.url.split('/')[2] || '' state.tabsMap[t.id] = t + if (!t.favIconUrl || t.favIconUrl.startsWith('chrome:')) t.favIconUrl = '' }) state.tabs = tabs @@ -58,14 +60,14 @@ export default { let offset = 0 for (let i = 0; i < ans.tabsTreeState.length; i++) { // Saved nodes - const t = ans.tabsTreeState[i] + const savedTab = ans.tabsTreeState[i] // Current tab - let tab = state.tabs[t.index - offset] + let tab = state.tabs[savedTab.index - offset] if (!tab) break - const sameUrl = t.url === tab.url - const isGroup = Utils.IsGroupUrl(t.url) + const sameUrl = savedTab.url === tab.url + const isGroup = Utils.IsGroupUrl(savedTab.url) if (isGroup) { let nextUrlOk = true @@ -79,20 +81,20 @@ export default { // Removed group if (!sameUrl && nextUrlOk) { - const groupId = Utils.GetGroupId(t.url) - const parent = parents[t.parentId] + const groupId = Utils.GetGroupId(savedTab.url) + const parent = parents[savedTab.parentId] const rTab = await browser.tabs.create({ windowId: state.windowId, - index: t.index, + index: savedTab.index, url: browser.runtime.getURL('group/group.html') + `#${groupId}`, - cookieStoreId: t.ctx, + cookieStoreId: savedTab.ctx, active: false, }) tab = state.tabsMap[rTab.id] - tab.isParent = t.isParent - tab.folded = t.folded - if (t.isParent) parents[t.id] = tab + tab.isParent = savedTab.isParent + tab.folded = savedTab.folded + if (savedTab.isParent) parents[savedTab.id] = tab if (parent) { tab.invisible = parent.folded || parent.invisible tab.parentId = parent.id @@ -103,13 +105,13 @@ export default { // Check if this is actual target tab if (!sameUrl && tab.status === 'complete') break - if (tab.cookieStoreId !== t.ctx) break + if (tab.cookieStoreId !== savedTab.ctx) break - tab.isParent = t.isParent - tab.folded = t.folded - if (t.isParent) parents[t.id] = tab - if (parents[t.parentId]) { - const parentTab = parents[t.parentId] + tab.isParent = savedTab.isParent + tab.folded = savedTab.folded + if (savedTab.isParent) parents[savedTab.id] = tab + if (parents[savedTab.parentId]) { + const parentTab = parents[savedTab.parentId] tab.invisible = parentTab.folded || parentTab.invisible tab.parentId = parentTab.id } @@ -145,6 +147,19 @@ export default { }, delay) }, + /** + * Scroll to active tab + */ + scrollToActiveTab({ state, getters }) { + const activePanel = getters.panels[state.panelIndex] + if (activePanel && activePanel.tabs) { + const activeTab = activePanel.tabs.find(t => t.active) + if (activeTab) { + EventBus.$emit('scrollToActiveTab', state.panelIndex, activeTab.id) + } + } + }, + /** * Create new tab in current window */ @@ -448,14 +463,9 @@ export default { * Clear all cookies of tab urls */ async clearTabsCookies({ state }, tabIds) { - try { - const permitted = await browser.permissions.contains({ origins: [''] }) - if (!permitted) { - const url = browser.runtime.getURL('permissions/all-urls.html') - browser.tabs.create({ url }) - return - } - } catch (err) { + if (!state.permAllUrls) { + const url = browser.runtime.getURL('permissions/all-urls.html') + browser.tabs.create({ url }) return } @@ -800,6 +810,9 @@ export default { pinned: pin, }) oldNewMap[node.id] = info.id + if (state.tabsMap[info.id] && opener) { + state.tabsMap[info.id].parentId = opener + } } // Remove source tabs @@ -873,8 +886,7 @@ export default { */ async groupTabs({ state, dispatch }, tabIds) { // Check permissions - const permitted = await browser.permissions.contains({ origins: [''] }) - if (!permitted) { + if (!state.permAllUrls) { const url = browser.runtime.getURL('permissions/all-urls.html') browser.tabs.create({ url }) return diff --git a/src/sidebar/actions/tabs.test.js b/src/sidebar/actions/tabs.test.js index af01a9f3d..138a912dc 100644 --- a/src/sidebar/actions/tabs.test.js +++ b/src/sidebar/actions/tabs.test.js @@ -575,6 +575,7 @@ describe('bookmarkTabs', () => { describe('clearTabsCookies', () => { test('clear cookies', async () => { const state = { + permAllUrls: true, tabs: [ { id: 1 }, { id: 2, title: 'a', url: 'http://some.com' }, diff --git a/src/sidebar/components/dashboards/containered-tabs.vue b/src/sidebar/components/dashboards/containered-tabs.vue index eb53e411d..883231fec 100644 --- a/src/sidebar/components/dashboards/containered-tabs.vue +++ b/src/sidebar/components/dashboards/containered-tabs.vue @@ -161,6 +161,7 @@