From afdedea2b8284a9590a73a7f10f6cd22bd09eddd Mon Sep 17 00:00:00 2001 From: kunoka <163348146+kunokareal@users.noreply.github.com> Date: Thu, 18 Apr 2024 16:22:34 +0300 Subject: [PATCH 1/4] chore: manifest v3 --- src/bg/background.ts | 2 +- src/manifest.json | 8 +++++--- src/services/menu.actions.ts | 16 ++++++++++++---- src/services/search.actions.ts | 6 +++--- src/styles/themes/proton/sidebar/sidebar.styl | 1 + src/types/web-ext.d.ts | 12 ++++++++++-- 6 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/bg/background.ts b/src/bg/background.ts index 411e62c6f..2429c4cf2 100644 --- a/src/bg/background.ts +++ b/src/bg/background.ts @@ -122,7 +122,7 @@ void (async function main() { function initToolbarButton(): void { Menu.createSettingsMenu() - browser.browserAction.onClicked.addListener((_, info): void => { + browser.action.onClicked.addListener((_, info): void => { if (info && info.button === 1) browser.runtime.openOptionsPage() else browser.sidebarAction.toggle() }) diff --git a/src/manifest.json b/src/manifest.json index af51b1d02..07a76cc22 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -1,5 +1,5 @@ { - "manifest_version": 2, + "manifest_version": 3, "browser_specific_settings": { "gecko": { "id": "{3c078156-979c-498b-8990-85f7987dd929}", @@ -35,7 +35,6 @@ "identity" ], "optional_permissions": [ - "", "proxy", "webRequest", "webRequestBlocking", @@ -46,6 +45,9 @@ "history", "downloads" ], + "host_permissions": [ + "" + ], "sidebar_action": { "default_icon": "./assets/logo-native.svg", "default_title": "Sidebery", @@ -465,7 +467,7 @@ "description": "__MSG_KbOpenSyncPopup__" } }, - "browser_action": { + "action": { "default_icon": "./assets/logo-native.svg", "default_title": "__MSG_ActionTitle__", "default_area": "navbar", diff --git a/src/services/menu.actions.ts b/src/services/menu.actions.ts index 5036cfc6e..70a5377e7 100644 --- a/src/services/menu.actions.ts +++ b/src/services/menu.actions.ts @@ -96,15 +96,23 @@ export function createSettingsMenu(): void { id: 'open_settings', title: translate('menu.browserAction.open_settings'), icons: { '16': 'assets/logo-native.svg' }, - onclick: () => browser.runtime.openOptionsPage(), - contexts: ['browser_action'], + contexts: ['action'], }) browser.menus.create({ id: 'create_snapshot', title: translate('menu.browserAction.create_snapshot'), icons: { '16': 'assets/snapshot-native.svg' }, - onclick: () => Snapshots.createSnapshot(), - contexts: ['browser_action'], + contexts: ['action'], + }) + browser.menus.onClicked.addListener((info, tab) => { + switch (info.menuItemId) { + case 'open_settings': + browser.runtime.openOptionsPage() + break + case 'create_snapshot': + Snapshots.createSnapshot() + break + } }) } diff --git a/src/services/search.actions.ts b/src/services/search.actions.ts index 31ea8830f..f2ea43383 100644 --- a/src/services/search.actions.ts +++ b/src/services/search.actions.ts @@ -434,12 +434,12 @@ export function start(): void { const hasFocus = document.hasFocus() if (!hasFocus) { - browser.browserAction.setPopup({ popup: SEARCH_URL }) - browser.browserAction.openPopup() + browser.action.setPopup({ popup: SEARCH_URL }) + browser.action.openPopup() Search.reactive.barIsActive = true // Reset browser action - setTimeout(() => browser.browserAction.setPopup({ popup: null }), 500) + setTimeout(() => browser.action.setPopup({ popup: null }), 500) } showBar() diff --git a/src/styles/themes/proton/sidebar/sidebar.styl b/src/styles/themes/proton/sidebar/sidebar.styl index e34b805c3..994b57cf0 100644 --- a/src/styles/themes/proton/sidebar/sidebar.styl +++ b/src/styles/themes/proton/sidebar/sidebar.styl @@ -53,6 +53,7 @@ body height: 100% -webkit-font-smoothing: antialiased -moz-osx-font-smoothing: grayscale + font-family: sans-serif padding: 0 margin: 0 font-family: var(--general-font-family) diff --git a/src/types/web-ext.d.ts b/src/types/web-ext.d.ts index 7553e676a..8c34151c3 100644 --- a/src/types/web-ext.d.ts +++ b/src/types/web-ext.d.ts @@ -524,7 +524,7 @@ declare namespace browser { /** * Browser action button */ - namespace browserAction { + namespace action { type BrowserActionButton = 0 | 1 interface PopupDetails { @@ -589,7 +589,7 @@ declare namespace browser { */ namespace menus { // prettier-ignore - type ContextType = 'all' | 'audio' | 'bookmark' | 'browser_action' + type ContextType = 'all' | 'audio' | 'bookmark' | 'action' | 'editable' | 'frame' | 'image' | 'link' | 'page' | 'page_action' | 'password' | 'selection' | 'tab' | 'tools_menu' | 'video' @@ -633,6 +633,14 @@ declare namespace browser { function overrideContext(contextOptions: ContextOptions): void const onHidden: EventTarget + + interface OnClickData { + button?: number + menuItemId: string + } + type ClickListener = (info: OnClickData, tab: tabs.Tab) => void + + const onClicked: EventTarget } /** From 191a67a0ab79e358af479ab9d36701ba7db581f8 Mon Sep 17 00:00:00 2001 From: kunoka <163348146+kunokareal@users.noreply.github.com> Date: Wed, 24 Apr 2024 19:51:43 +0300 Subject: [PATCH 2/4] chore: use scripting api for executeScript # Conflicts: # src/services/tabs.fg.media.ts # src/types/web-ext.d.ts --- src/manifest.json | 1 + src/services/tabs.bg.actions.ts | 48 +++++++------ src/services/tabs.fg.actions.ts | 24 ++++--- src/services/tabs.fg.media.ts | 116 +++++++++++++++++++++----------- src/services/tabs.preview.ts | 32 +++++---- src/types/web-ext.d.ts | 37 +++++++--- 6 files changed, 169 insertions(+), 89 deletions(-) diff --git a/src/manifest.json b/src/manifest.json index 07a76cc22..50534bc40 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -28,6 +28,7 @@ "storage", "unlimitedStorage", "sessions", + "scripting", "menus", "menus.overrideContext", "search", diff --git a/src/services/tabs.bg.actions.ts b/src/services/tabs.bg.actions.ts index 07eb41a8a..8d3faaa95 100644 --- a/src/services/tabs.bg.actions.ts +++ b/src/services/tabs.bg.actions.ts @@ -507,22 +507,26 @@ export async function initInternalPageScripts(tabs: Tab[]) { export function injectUrlPageScript(winId: ID, tabId: ID) { try { - browser.tabs - .executeScript(tabId, { - file: '/injections/url.js', - runAt: 'document_start', - matchAboutBlank: true, + browser.scripting + .executeScript({ + files: ['/injections/url.js'], + target: { tabId }, + injectImmediately: true, }) .catch(err => { Logs.warn('Tabs.injectUrlPageScript: Cannot inject script, tabId:', tabId, err) }) const initData = getUrlPageInitData(winId, tabId) const initDataJson = JSON.stringify(initData) - browser.tabs - .executeScript(tabId, { - code: `window.sideberyInitData=${initDataJson};window.onSideberyInitDataReady?.()`, - runAt: 'document_start', - matchAboutBlank: true, + browser.scripting + .executeScript<[string], void>({ + args: [initDataJson], + func: (initDataJson: string) => { + window.sideberyInitData = JSON.parse(initDataJson); + window.onSideberyInitDataReady?.() + }, + target: { tabId }, + injectImmediately: true, }) .catch(() => { Logs.warn('Tabs.injectUrlPageScript: Cannot inject init data, reloading tab (if active)...') @@ -569,22 +573,26 @@ export async function injectGroupPageScript(winId: ID, tabId: ID): Promise injectingGroup.add(tabId) try { - browser.tabs - .executeScript(tabId, { - file: '/injections/group.js', - runAt: 'document_start', - matchAboutBlank: true, + browser.scripting + .executeScript({ + files: ['/injections/group.js'], + target: { tabId }, + injectImmediately: true, }) .catch(err => { Logs.warn('Tabs.injectGroupPageScript: Cannot inject script, tabId:', tabId, err) }) const initData = await getGroupPageInitData(winId, tabId) const initDataJson = JSON.stringify(initData) - browser.tabs - .executeScript(tabId, { - code: `window.sideberyInitData=${initDataJson};window.onSideberyInitDataReady?.()`, - runAt: 'document_start', - matchAboutBlank: true, + browser.scripting + .executeScript<[string], void>({ + args: [initDataJson], + func: (initDataJson: string) => { + window.sideberyInitData = JSON.parse(initDataJson); + window.onSideberyInitDataReady?.() + }, + target: { tabId }, + injectImmediately: true, }) .catch(() => { Logs.warn('Tabs.injectGroupPageScript: Cannot inject init data, reloading tab') diff --git a/src/services/tabs.fg.actions.ts b/src/services/tabs.fg.actions.ts index 49bdc1aaf..26320ce8c 100644 --- a/src/services/tabs.fg.actions.ts +++ b/src/services/tabs.fg.actions.ts @@ -1192,15 +1192,23 @@ export async function discardTabs(tabIds: ID[] = []): Promise { // Try to reset closing prevention and discard such tabs if (Settings.state.forceDiscard && Permissions.allUrls && secondTryIds.length) { - const forceDiscardInjection = - 'window.onbeforeunload=null;window.addEventListener("beforeunload", e => {e.returnValue=""})' await Promise.allSettled( - secondTryIds.map(id => { - return browser.tabs.executeScript(id, { - code: forceDiscardInjection, - runAt: 'document_start', - allFrames: true, - }) + secondTryIds.map(async (id) => { + return browser.scripting.executeScript({ + func: () => { + window.onbeforeunload = null; + window.addEventListener("beforeunload", e => { + e.stopPropagation() + e.returnValue = '' + }, { capture: true }) + }, + injectImmediately: true, + target: { + tabId: id, + allFrames: true + }, + world: 'MAIN' + }).then(console.log).catch(console.error) }) ) diff --git a/src/services/tabs.fg.media.ts b/src/services/tabs.fg.media.ts index 0663e8f6b..2838183b7 100644 --- a/src/services/tabs.fg.media.ts +++ b/src/services/tabs.fg.media.ts @@ -98,14 +98,17 @@ export async function pauseTabMedia(id?: ID): Promise { tab.reactive.mediaPaused = tab.mediaPaused = true Sidebar.updateMediaStateOfPanelDebounced(100, tab.panelId, tab) - browser.tabs - .executeScript(tab.id, { - file: '../injections/pause-media.js', - runAt: 'document_start', - allFrames: true, + browser.scripting + .executeScript({ + files: ['../injections/play-media.js'], + injectImmediately: true, + target: { + tabId: tab.id, + allFrames: true + } }) .then(results => { - if (results.every(result => result === false)) { + if (results.every(({ result }) => result === false)) { tab.reactive.mediaPaused = tab.mediaPaused = false Sidebar.updateMediaStateOfPanelDebounced(100, tab.panelId, tab) } @@ -153,11 +156,14 @@ export async function playTabMedia(id?: ID): Promise { tab.reactive.mediaPaused = tab.mediaPaused = false Sidebar.updateMediaStateOfPanelDebounced(100, tab.panelId, tab) - browser.tabs - .executeScript(tab.id, { - file: '../injections/play-media.js', - runAt: 'document_start', - allFrames: true, + browser.scripting + .executeScript({ + files: ['../injections/play-media.js'], + injectImmediately: true, + target: { + tabId: tab.id, + allFrames: true + } }) .catch(err => { Logs.err('Tabs.playTabMedia: Cannot exec script:', err) @@ -185,10 +191,9 @@ export async function pauseTabsMediaOfPanel(panelId: ID): Promise { const panel = Sidebar.panelsById[panelId] if (!Utils.isTabsPanel(panel)) return - const injectionConfig: browser.tabs.ExecuteOpts = { - file: '../injections/pause-media.js', - runAt: 'document_start', - allFrames: true, + const injectionConfig: Omit = { + files: ['../injections/pause-media.js'], + injectImmediately: true, } if (Settings.state.pinnedTabsPosition === 'panel') { @@ -198,10 +203,16 @@ export async function pauseTabsMediaOfPanel(panelId: ID): Promise { if ((tab.audible || tab.mutedInfo?.muted) && tab.panelId === panel.id) { tab.reactive.mediaPaused = tab.mediaPaused = true Sidebar.updateMediaStateOfPanelDebounced(100, tab.panelId, tab) - browser.tabs - .executeScript(tab.id, injectionConfig) + browser.scripting + .executeScript({ + ...injectionConfig, + target: { + tabId: tab.id, + allFrames: true + }, + }) .then(results => { - if (results.every(result => result === false)) { + if (results.every(({ result }) => result === false)) { tab.reactive.mediaPaused = tab.mediaPaused = false Sidebar.updateMediaStateOfPanelDebounced(100, tab.panelId, tab) } @@ -218,10 +229,16 @@ export async function pauseTabsMediaOfPanel(panelId: ID): Promise { if (tab.audible || tab.mutedInfo?.muted) { tab.reactive.mediaPaused = tab.mediaPaused = true Sidebar.updateMediaStateOfPanelDebounced(100, tab.panelId, tab) - browser.tabs - .executeScript(tab.id, injectionConfig) + browser.scripting + .executeScript({ + ...injectionConfig, + target: { + tabId: tab.id, + allFrames: true + }, + }) .then(results => { - if (results.every(result => result === false)) { + if (results.every(({ result }) => result === false)) { tab.reactive.mediaPaused = tab.mediaPaused = false Sidebar.updateMediaStateOfPanelDebounced(100, tab.panelId, tab) } @@ -244,10 +261,9 @@ export async function playTabsMediaOfPanel(panelId: ID): Promise { const panel = Sidebar.panelsById[panelId] if (!Utils.isTabsPanel(panel)) return - const injectionConfig: browser.tabs.ExecuteOpts = { - file: '../injections/play-media.js', - runAt: 'document_start', - allFrames: true, + const injectionConfig: Omit = { + files: ['../injections/play-media.js'], + injectImmediately: true, } if (Settings.state.pinnedTabsPosition === 'panel') { @@ -256,7 +272,13 @@ export async function playTabsMediaOfPanel(panelId: ID): Promise { if (tab.mediaPaused && tab.panelId === panel.id) { tab.reactive.mediaPaused = tab.mediaPaused = false Sidebar.updateMediaStateOfPanelDebounced(100, tab.panelId, tab) - browser.tabs.executeScript(tab.id, injectionConfig).catch(err => { + browser.scripting.executeScript({ + ...injectionConfig, + target: { + tabId: tab.id, + allFrames: true + }, + }).catch(err => { Logs.err('Tabs.playTabsMediaOfPanel: Cannot exec script (pinned):', err) }) } @@ -267,7 +289,13 @@ export async function playTabsMediaOfPanel(panelId: ID): Promise { if (tab.mediaPaused) { tab.reactive.mediaPaused = tab.mediaPaused = false Sidebar.updateMediaStateOfPanelDebounced(100, tab.panelId, tab) - browser.tabs.executeScript(tab.id, injectionConfig).catch(err => { + browser.scripting.executeScript({ + ...injectionConfig, + target: { + tabId: tab.id, + allFrames: true + }, + }).catch(err => { Logs.err('Tabs.playTabsMediaOfPanel: Cannot exec script:', err) }) } @@ -293,20 +321,25 @@ export async function pauseAllAudibleTabsMedia(): Promise { if (!result) return } - const injectionConfig: browser.tabs.ExecuteOpts = { - file: '../injections/pause-media.js', - runAt: 'document_start', - allFrames: true, + const injectionConfig: Omit = { + files: ['../injections/pause-media.js'], + injectImmediately: true, } for (const tab of Tabs.list) { if (tab.audible) { tab.reactive.mediaPaused = tab.mediaPaused = true Sidebar.updateMediaStateOfPanelDebounced(100, tab.panelId, tab) - browser.tabs - .executeScript(tab.id, injectionConfig) + browser.scripting + .executeScript({ + ...injectionConfig, + target: { + tabId: tab.id, + allFrames: true + }, + }) .then(results => { - if (results.every(result => result === false)) { + if (results.every(({ result }) => result === false)) { tab.reactive.mediaPaused = tab.mediaPaused = false Sidebar.updateMediaStateOfPanelDebounced(100, tab.panelId, tab) } @@ -326,17 +359,22 @@ export async function playAllPausedTabsMedia(): Promise { if (!result) return } - const injectionConfig: browser.tabs.ExecuteOpts = { - file: '../injections/play-media.js', - runAt: 'document_start', - allFrames: true, + const injectionConfig: Omit = { + files: ['../injections/play-media.js'], + injectImmediately: true, } for (const tab of Tabs.list) { if (tab.mediaPaused) { tab.reactive.mediaPaused = tab.mediaPaused = false Sidebar.updateMediaStateOfPanelDebounced(100, tab.panelId, tab) - browser.tabs.executeScript(tab.id, injectionConfig).catch(err => { + browser.scripting.executeScript({ + ...injectionConfig, + target: { + tabId: tab.id, + allFrames: true + }, + }).catch(err => { Logs.err('Tabs.playAllPausedTabsMedia: Cannot exec script:', err) }) } diff --git a/src/services/tabs.preview.ts b/src/services/tabs.preview.ts index a953b6673..9aea711ba 100644 --- a/src/services/tabs.preview.ts +++ b/src/services/tabs.preview.ts @@ -147,22 +147,30 @@ async function injectTabPreview(tabId: ID, y?: number) { const initData = getTabPreviewInitData(tabId, y) const initDataJson = JSON.stringify(initData) - const injectingData = browser.tabs - .executeScript(activeTab.id, { - code: `window.sideberyInitData=${initDataJson};window.onSideberyInitDataReady?.();true;`, - runAt: 'document_start', - allFrames: false, - matchAboutBlank: true, + const injectingData = browser.scripting + .executeScript<[string], void>({ + args: [initDataJson], + func: (initDataJson: string) => { + window.sideberyInitData = JSON.parse(initDataJson); + window.onSideberyInitDataReady?.();true; + }, + injectImmediately: true, + target: { + tabId: activeTab.id, + allFrames: false, + }, }) .catch(() => { // Cannot inject init data }) - const injectingScript = browser.tabs - .executeScript(activeTab.id, { - file: '../injections/tab-preview.js', - runAt: 'document_start', - allFrames: false, - matchAboutBlank: true, + const injectingScript = browser.scripting + .executeScript({ + files: ['../injections/tab-preview.js'], + injectImmediately: true, + target: { + tabId: activeTab.id, + allFrames: false, + } }) .catch(() => { // Cannot exec script diff --git a/src/types/web-ext.d.ts b/src/types/web-ext.d.ts index 8c34151c3..1471f29dd 100644 --- a/src/types/web-ext.d.ts +++ b/src/types/web-ext.d.ts @@ -314,15 +314,6 @@ declare namespace browser { active?: boolean } - interface ExecuteOpts { - allFrames?: boolean - code?: string - file?: string - frameId?: number - matchAboutBlank?: boolean - runAt?: 'document_start' | 'document_end' | 'document_idle' - } - interface GroupOpts { // The tab ID or list of tab IDs to add to the specified group. tabIds: ID | ID[] @@ -354,7 +345,6 @@ declare namespace browser { function getCurrent(): Promise function saveAsPDF(pageSettings: PageSettings): Promise function duplicate(tabId: ID, opts?: DuplOpts): Promise - function executeScript(tabId: ID, opts: ExecuteOpts): Promise function warmup(tabId: ID): Promise /** * Adds one or more tabs to a specified group, or if no group is specified, @@ -1453,4 +1443,31 @@ declare namespace browser { function getRedirectURL(): string function launchWebAuthFlow(details: LaunchWebAuthDetails): Promise } + + namespace scripting { + interface InjectionTarget { + allFrames?: boolean + frameIds?: number[] + tabId: ID + } + + type ExecutionWorld = 'ISOLATED' | 'MAIN' + + interface InjectDetails { + args?: Args + files?: string[] + func?: (...args: Args) => Result + injectImmediately?: boolean + target: InjectionTarget + world?: ExecutionWorld + } + + interface InjectionResult { + frameId: number + result?: T + error?: unknown // unsupported by chrome + } + + function executeScript(details: InjectDetails): Promise[]> + } } From 39f96f55909e1dfce926d18b047387586d335d8e Mon Sep 17 00:00:00 2001 From: kunoka <163348146+kunokareal@users.noreply.github.com> Date: Wed, 24 Apr 2024 19:51:50 +0300 Subject: [PATCH 3/4] fix: sidebar styles --- src/styles/themes/proton/sidebar/sidebar.styl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/styles/themes/proton/sidebar/sidebar.styl b/src/styles/themes/proton/sidebar/sidebar.styl index 994b57cf0..e8dd83381 100644 --- a/src/styles/themes/proton/sidebar/sidebar.styl +++ b/src/styles/themes/proton/sidebar/sidebar.styl @@ -44,6 +44,9 @@ html display: block height: 100% +* + box-sizing: border-box + body --general-font-family: system-ui @@ -56,6 +59,7 @@ body font-family: sans-serif padding: 0 margin: 0 + cursor: default font-family: var(--general-font-family) a From 759d1bb3959ec197b5dfb912c194866573877c4d Mon Sep 17 00:00:00 2001 From: alina sireneva Date: Thu, 4 Sep 2025 11:06:23 +0300 Subject: [PATCH 4/4] chore: moved listeners setup in background script to top-level --- src/bg/background.ts | 183 ++++++++++++++++++++++--------------------- 1 file changed, 92 insertions(+), 91 deletions(-) diff --git a/src/bg/background.ts b/src/bg/background.ts index 2429c4cf2..0201d2d32 100644 --- a/src/bg/background.ts +++ b/src/bg/background.ts @@ -17,44 +17,99 @@ import { Menu } from 'src/services/menu' import { WebReq } from 'src/services/web-req' import { Sync } from 'src/services/_services' -void (async function main() { - Info.setInstanceType(InstanceType.bg) - IPC.setInstanceType(InstanceType.bg) - Logs.setInstanceType(InstanceType.bg) - - const ts = performance.now() - Logs.info('Init start') - - // Register globaly available actions - IPC.registerActions({ - cacheTabsData: Tabs.cacheTabsData, - getGroupPageInitData: Tabs.getGroupPageInitData, - tabsApiProxy: Tabs.tabsApiProxy, - getSidebarTabs: Tabs.getSidebarTabs, - detachSidebarTabs: Tabs.detachSidebarTabs, - openTabs: Tabs.openTabs, - createSnapshot: Snapshots.createSnapshot, - addSnapshot: Snapshots.addSnapshot, - removeSnapshot: Snapshots.removeSnapshot, - openSnapshotWindows: Snapshots.openWindows, - createWindowWithTabs: Windows.createWithTabs, - isWindowTabsLocked: Windows.isWindowTabsLocked, - saveFavicon: Favicons.saveFavicon, - saveInLocalStorage: Store.setFromRemoteFg, - checkIpInfo: WebReq.checkIpInfo, - disableAutoReopening: WebReq.disableAutoReopening, - enableAutoReopening: WebReq.enableAutoReopening, - - saveToSync: Sync.save, - saveTabsToSync: Sync.saveTabs, - removeFromSync: Sync.remove, - getDataFromSync: Sync.getData, - loadSync: Sync.load, - }) +Info.setInstanceType(InstanceType.bg) +IPC.setInstanceType(InstanceType.bg) +Logs.setInstanceType(InstanceType.bg) + +const ts = performance.now() +Logs.info('Init start') + +// Register globaly available actions +IPC.registerActions({ + cacheTabsData: Tabs.cacheTabsData, + getGroupPageInitData: Tabs.getGroupPageInitData, + tabsApiProxy: Tabs.tabsApiProxy, + getSidebarTabs: Tabs.getSidebarTabs, + detachSidebarTabs: Tabs.detachSidebarTabs, + openTabs: Tabs.openTabs, + createSnapshot: Snapshots.createSnapshot, + addSnapshot: Snapshots.addSnapshot, + removeSnapshot: Snapshots.removeSnapshot, + openSnapshotWindows: Snapshots.openWindows, + createWindowWithTabs: Windows.createWithTabs, + isWindowTabsLocked: Windows.isWindowTabsLocked, + saveFavicon: Favicons.saveFavicon, + saveInLocalStorage: Store.setFromRemoteFg, + checkIpInfo: WebReq.checkIpInfo, + disableAutoReopening: WebReq.disableAutoReopening, + enableAutoReopening: WebReq.enableAutoReopening, + + saveToSync: Sync.save, + saveTabsToSync: Sync.saveTabs, + removeFromSync: Sync.remove, + getDataFromSync: Sync.getData, + loadSync: Sync.load, +}) + +// Init first-need stuff +IPC.setupGlobalMessageListener() +IPC.setupConnectionListener() + +Info.saveVersion() +Windows.setupWindowsListeners() +Containers.setupContainersListeners() +Settings.setupSettingsChangeListener() + +Sidebar.setupListeners() + +WebReq.updateReqHandlers() + +Tabs.setupTabsListeners() + +Permissions.loadPermissions() +Permissions.setupListeners() +Favicons.loadFavicons() +Menu.setupListeners() +Snapshots.scheduleSnapshots() + +// Update title preface on sidebar connection/disconnection +IPC.onConnected(InstanceType.sidebar, winId => { + Logs.info('IPC.onConnected sidebar', winId) + + const tabs = Windows.byId[winId]?.tabs + if (tabs) Tabs.initInternalPageScripts(tabs) + + if (Settings.state.markWindow && winId !== NOID) { + IPC.sendToSidebar(winId, 'updWindowPreface') + } +}) +IPC.onDisconnected(InstanceType.sidebar, winId => { + Logs.info('IPC.onDisconnected sidebar', winId) + + if (Settings.state.markWindow && Windows.byId[winId]) { + browser.windows.update(winId, { titlePreface: '' }) + } +}) + +window.getSideberyState = () => { + // prettier-ignore + return { + IPC, Info, Settings, Windows, Tabs, Containers, + Sidebar, Favicons, Snapshots, Menu, Permissions, + } +} - // Init first-need stuff - IPC.setupGlobalMessageListener() - IPC.setupConnectionListener() +initToolbarButton() + +browser.runtime.onUpdateAvailable.addListener(details => { + const currentVersion = versionToInt(browser.runtime.getManifest().version) + const newVersion = versionToInt(details.version) + if (newVersion <= currentVersion) browser.runtime.reload() +}) + +void (async function main() { + await Tabs.loadTabs() + await Sidebar.loadNav() await Promise.all([ Windows.loadWindows(), Containers.load(), @@ -62,60 +117,6 @@ void (async function main() { Info.loadVersionInfo(), ]) - Info.saveVersion() - Windows.setupWindowsListeners() - Containers.setupContainersListeners() - Settings.setupSettingsChangeListener() - - await Sidebar.loadNav() - Sidebar.setupListeners() - - WebReq.updateReqHandlers() - - Tabs.setupTabsListeners() - await Tabs.loadTabs() - - Permissions.loadPermissions() - Permissions.setupListeners() - Favicons.loadFavicons() - Menu.setupListeners() - Snapshots.scheduleSnapshots() - - // Update title preface on sidebar connection/disconnection - IPC.onConnected(InstanceType.sidebar, winId => { - Logs.info('IPC.onConnected sidebar', winId) - - const tabs = Windows.byId[winId]?.tabs - if (tabs) Tabs.initInternalPageScripts(tabs) - - if (Settings.state.markWindow && winId !== NOID) { - IPC.sendToSidebar(winId, 'updWindowPreface') - } - }) - IPC.onDisconnected(InstanceType.sidebar, winId => { - Logs.info('IPC.onDisconnected sidebar', winId) - - if (Settings.state.markWindow && Windows.byId[winId]) { - browser.windows.update(winId, { titlePreface: '' }) - } - }) - - window.getSideberyState = () => { - // prettier-ignore - return { - IPC, Info, Settings, Windows, Tabs, Containers, - Sidebar, Favicons, Snapshots, Menu, Permissions, - } - } - - initToolbarButton() - - browser.runtime.onUpdateAvailable.addListener(details => { - const currentVersion = versionToInt(browser.runtime.getManifest().version) - const newVersion = versionToInt(details.version) - if (newVersion <= currentVersion) browser.runtime.reload() - }) - Logs.info(`Init end: ${performance.now() - ts}ms`) })()