Skip to content

Commit 643189e

Browse files
committed
fix: tabs: incorrect handling of unloaded tabs opened from another addon
- Correctly handle unloaded tabs opened from the outside: wait for the session restore detection and continue a new tab handling if it's not a session restore. - Rename 'Session Restore' to more generic 'Processing tabs...' because we don't know in advance if it's actually a session restore. (resolves #2249)
1 parent 41f9005 commit 643189e

File tree

8 files changed

+77
-67
lines changed

8 files changed

+77
-67
lines changed

src/_locales/dict.sidebar.ts

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -484,28 +484,17 @@ export const sidebarTranslations: Translations = {
484484
zh_TW: '不再顯示',
485485
ja: '再表示しない',
486486
},
487-
// - Session restore
488-
'popup.ses_res.title': {
489-
en: 'Session Restore',
490-
de: 'Sitzung wiederherstellen',
491-
fr: 'Restauration de session',
492-
hu: 'Munkamenet visszaállítása',
493-
pl: 'Przywrócenie sesji',
494-
ru: 'Восстановление сеанса',
495-
zh_CN: '会话恢复',
496-
zh_TW: '回復瀏覽階段',
497-
ja: 'セッション復元',
498-
},
499-
'popup.ses_res.desc': {
500-
en: 'Sidebery is reinitializing tabs for restored session, please wait...',
501-
de: 'Sidebery initialisiert die Registerkarten für die wiederhergestellte Sitzung neu. Bitte warten Sie...',
502-
fr: 'Sidebery réinitialise les onglets pour la session restaurée, veuillez patienter...',
503-
hu: 'Sidebery újraindítja a visszaállított munkamenet lapjait, kérjük, várjon...',
504-
pl: 'Sidebery ponownie inicjuje karty dla przywróconej sesji, proszę czekać...',
505-
ru: 'Sidebery инициализирует вкладки для восстановленной сессии, пожалуйста, подождите...',
506-
zh_CN: 'Sidebery 正在为恢复的会话重新初始化标签页,请稍候...',
507-
zh_TW: 'Sidebery 正為回復的瀏覽階段重新初始化分頁,請稍候...',
508-
ja: 'Sideberyは復元されたセッションのタブを再初期化中です。お待ちください...',
487+
// - Processing tabs
488+
'popup.proc_tabs.title': {
489+
en: 'Processing tabs...',
490+
de: 'Verarbeitung der Tabs...',
491+
fr: 'Traitement des onglets...',
492+
hu: 'Feldolgozás lapok...',
493+
pl: 'Przetwarzanie karty...',
494+
ru: 'Обработка вкладок...',
495+
zh_CN: '正在处理标签页...',
496+
zh_TW: '處理標籤中...',
497+
ja: 'タブを処理しています...',
509498
},
510499

511500
// ---

src/services/popups.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export interface PopupsReactiveState {
1414
siteConfigPopup: SiteConfigPopup | null
1515
tabMoveRulesPopup: TabMoveRulesPopup | null
1616
tabReopenRulesPopup: TabReopenRulesPopup | null
17-
sessionRestorePopup: SessionRestorePopup | null
17+
processingTabsPopup: ProcessingTabsPopup | null
1818
confirm: ConfirmDialog | null
1919
dialog: Dialog | null
2020
}
@@ -57,7 +57,7 @@ export interface SiteConfigPopup {
5757
url: string
5858
}
5959

60-
export interface SessionRestorePopup {}
60+
export interface ProcessingTabsPopup {}
6161

6262
export let reactive: PopupsReactiveState = {
6363
panelConfigPopup: null,
@@ -67,7 +67,7 @@ export let reactive: PopupsReactiveState = {
6767
siteConfigPopup: null,
6868
tabMoveRulesPopup: null,
6969
tabReopenRulesPopup: null,
70-
sessionRestorePopup: null,
70+
processingTabsPopup: null,
7171
confirm: null,
7272
dialog: null,
7373
}
@@ -225,11 +225,11 @@ export function closeTabReopenRulesPopup(): void {
225225
reactive.tabReopenRulesPopup = null
226226
}
227227

228-
export function openSessionRestorePopup() {
229-
reactive.sessionRestorePopup = {}
228+
export function openProcessingTabsPopup() {
229+
reactive.processingTabsPopup = {}
230230
}
231231

232-
export function closeSessionRestorePopup() {
233-
if (!reactive.sessionRestorePopup) return
234-
reactive.sessionRestorePopup = null
232+
export function closeProcessingTabsPopup() {
233+
if (!reactive.processingTabsPopup) return
234+
reactive.processingTabsPopup = null
235235
}

src/services/tabs.fg.handlers.ts

Lines changed: 46 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,7 @@ function checkIfSessionIsRestoring(newTab: Tab) {
122122
maybeRestoredTabs &&
123123
maybeRestoredTabs.length >= SESSION_RESTORE_MIN_TABS_COUNT
124124
) {
125-
// TODO: well, at this moment sidebery doesn't know yet if
126-
// this is a session restore or just multiple new tabs (low probability though)
127-
// so maybe I should show popup with the title like "Processing new tabs..."
128-
// instead?
129-
Popups.openSessionRestorePopup()
125+
Popups.openProcessingTabsPopup()
130126

131127
cancelDeferredMovingOfNewTabs()
132128

@@ -146,6 +142,13 @@ function checkIfSessionIsRestoring(newTab: Tab) {
146142
maybeRestoredTabsDataQuerying.push(dataQuerying.catch(() => undefined))
147143
}
148144

145+
// Set the promise for awaiting a session restore detection
146+
if (maybeRestoredTabsDataQuerying) {
147+
newTab.checkingSessionRestore = new Promise(ok => {
148+
newTab.resolveSessionRestoreDetection = ok
149+
})
150+
}
151+
149152
clearTimeout(checkingIfSessionRestoringTimeout)
150153
checkingIfSessionRestoringTimeout = setTimeout(async () => {
151154
if (
@@ -163,13 +166,8 @@ function checkIfSessionIsRestoring(newTab: Tab) {
163166

164167
tryToRestoreTabsStateFromSessionData(maybeRestoredTabs, tabsSessionData)
165168
} else {
166-
cancelDeferredMovingOfNewTabs()
167-
168-
// Reinit tabs
169-
Tabs.unload()
170-
Tabs.load(LoadSrc.SessionOnly)
171-
172-
Popups.closeSessionRestorePopup()
169+
// It's not a session restore, resolve the promises
170+
maybeRestoredTabs?.forEach(t => t.resolveSessionRestoreDetection?.(false))
173171
}
174172

175173
maybeRestoredTabs = null
@@ -189,18 +187,23 @@ async function tryToRestoreTabsStateFromSessionData(
189187
if (tabsWithSessionDataLen < SESSION_RESTORE_MIN_TABS_COUNT) {
190188
Logs.warn('Tabs.tryToRestoreTabsStateFromSessionData: Not enough session data')
191189

192-
cancelDeferredMovingOfNewTabs()
190+
// Restart deferred tabs moving to sort all new tabs, not just
191+
// the last one in case of two opened tabs b/c the first deferred
192+
// moving was canceled in checkIfSessionIsRestoring fn.
193+
handleNewTabMove()
193194

194-
// Reinit tabs
195-
Tabs.unload()
196-
Tabs.load(LoadSrc.SessionOnly)
195+
// It's not a session restore, resolve the promises
196+
tabs?.forEach(t => t.resolveSessionRestoreDetection?.(false))
197197

198-
Popups.closeSessionRestorePopup()
198+
Popups.closeProcessingTabsPopup()
199199
return
200200
}
201201

202+
// It's a session restore, resolve the session restore detection promises
203+
tabs.forEach(t => t.resolveSessionRestoreDetection?.(true))
204+
202205
// Show popup about restoring the tabs
203-
Popups.openSessionRestorePopup()
206+
Popups.openProcessingTabsPopup()
204207

205208
// Unload tabs
206209
Tabs.unload()
@@ -226,10 +229,10 @@ async function tryToRestoreTabsStateFromSessionData(
226229
await Utils.sleep(100)
227230

228231
// Close popup
229-
Popups.closeSessionRestorePopup()
232+
Popups.closeProcessingTabsPopup()
230233
}
231234

232-
function onTabCreated(nativeTab: NativeTab, attached?: boolean): void {
235+
async function onTabCreated(nativeTab: NativeTab, attached?: boolean) {
233236
if (nativeTab.windowId !== Windows.id) return
234237
if (!Tabs.ready || Tabs.sorting) {
235238
Tabs.deferredEventHandling.push(() => onTabCreated(nativeTab))
@@ -248,9 +251,16 @@ function onTabCreated(nativeTab: NativeTab, attached?: boolean): void {
248251
const tab = Tabs.mutateNativeTabToSideberyTab(nativeTab)
249252

250253
// Stop if multiple tabs were open and data querying is started
254+
let notSessionRestore
251255
if (maybeRestoredTabsDataQuerying) {
252256
checkIfSessionIsRestoring(tab)
253-
return
257+
if (tab.checkingSessionRestore) {
258+
const sessionRestoreIsDetected = await tab.checkingSessionRestore
259+
delete tab.checkingSessionRestore
260+
delete tab.resolveSessionRestoreDetection
261+
if (sessionRestoreIsDetected) return
262+
notSessionRestore = true
263+
}
254264
}
255265

256266
// Check if opener tab is pinned
@@ -381,11 +391,9 @@ function onTabCreated(nativeTab: NativeTab, attached?: boolean): void {
381391

382392
// Find appropriate position using the current settings
383393
else {
384-
panel = Tabs.getPanelForNewTab(tab)
385-
if (!panel) return Logs.err('Cannot handle new tab: Cannot find target panel')
386-
387394
// Check if this is event is part of session restore
388395
if (
396+
!notSessionRestore &&
389397
!attached &&
390398
// Tab is unloaded and has set url
391399
((tab.discarded && tab.url !== 'about:blank') ||
@@ -395,17 +403,28 @@ function onTabCreated(nativeTab: NativeTab, attached?: boolean): void {
395403
tab.pinned)
396404
) {
397405
checkIfSessionIsRestoring(tab)
398-
if (maybeRestoredTabsDataQuerying) return
406+
if (maybeRestoredTabsDataQuerying && tab.checkingSessionRestore) {
407+
const sessionRestoreIsDetected = await tab.checkingSessionRestore
408+
delete tab.checkingSessionRestore
409+
delete tab.resolveSessionRestoreDetection
410+
if (sessionRestoreIsDetected) return
411+
}
399412
}
400413

401-
// Get parent tab
414+
// Get panel
415+
panel = Tabs.getPanelForNewTab(tab)
416+
if (!panel) return Logs.err('Cannot handle new tab: Cannot find target panel')
417+
418+
// Outdent if opener tab is folded (if configured)
402419
const parent = Tabs.byId[tab.openerTabId ?? NOID]
403420
if (!attached && parent?.folded && Settings.state.ignoreFoldedParent) {
404421
tab.openerTabId = parent.parentId
405422
}
406423

407-
// Get index
424+
// Get target index
408425
index = Tabs.getIndexForNewTab(panel, tab)
426+
427+
// Update opener
409428
if (!autoGroupTab) {
410429
tab.openerTabId = Tabs.getParentForNewTab(panel, tab)
411430
}

src/sidebar/components/popup.session-restore.vue renamed to src/sidebar/components/popup.processing-tabs.vue

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
<template lang="pug">
2-
.SessionRestore.popup-container
2+
.ProcessingTabs.popup-container
33
.popup(@click.stop)
4-
h2 {{translate('popup.ses_res.title')}}
4+
h2 {{translate('popup.proc_tabs.title')}}
55
LoadingDots.loading-dots
6-
.msg {{translate('popup.ses_res.desc')}}
76
</template>
87

98
<script lang="ts" setup>

src/sidebar/sidebar.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
Transition(name="popup" type="transition"): DialogPopup(v-if="Popups.reactive.dialog" :dialog="Popups.reactive.dialog")
4848
Transition(name="popup" type="transition"): NewTabShortcutsPopup(v-if="Popups.reactive.newTabShortcutsPopup")
4949
Transition(name="popup" type="transition"): SiteConfigPopup(v-if="Popups.reactive.siteConfigPopup")
50-
Transition(name="popup" type="transition"): SessionRestorePopup(v-if="Popups.reactive.sessionRestorePopup")
50+
Transition(name="popup" type="transition"): ProcessingTabsPopup(v-if="Popups.reactive.processingTabsPopup")
5151
CtxMenuPopup
5252
DragAndDropTooltip
5353
NotificationsPopup
@@ -146,7 +146,7 @@ import GroupConfigPopup from './components/popup.group-config.vue'
146146
import DialogPopup from 'src/components/popup.dialog.vue'
147147
import NewTabShortcutsPopup from '../components/popup.new-tab-shortcuts.vue'
148148
import SiteConfigPopup from '../components/popup.site-config.vue'
149-
import SessionRestorePopup from './components/popup.session-restore.vue'
149+
import ProcessingTabsPopup from './components/popup.processing-tabs.vue'
150150
import SubPanel from './components/sub-panel.vue'
151151
import * as Utils from 'src/utils'
152152
import * as Popups from 'src/services/popups'
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
@import '../../../utils'
22

3-
.SessionRestore
3+
.ProcessingTabs
44
background-color: var(--frame-bg)
55

6-
.SessionRestore .popup
6+
.ProcessingTabs .popup
77
box-shadow: none
88
background-color: transparent
99

10-
.SessionRestore .msg
10+
.ProcessingTabs .msg
1111
position: relative
1212
font-size: rem(14)
1313
padding: 0 8px
1414
color: var(--popup-fg)
1515
opacity: .7
1616
text-align: center
1717

18-
.SessionRestore .loading-dots
18+
.ProcessingTabs .loading-dots
1919
position: relative
2020
margin: 8px 0 16px

src/styles/themes/proton/sidebar/sidebar.styl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ vendors = official
2323
@import './popup'
2424
@import './popup.windows'
2525
@import './popup.confirm'
26-
@import './popup.session-restore'
26+
@import './popup.processing-tabs'
2727
@import './popup.context-menu'
2828
@import './popup.notifications'
2929
@import './popup.bookmarks'

src/types/tabs.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ export interface Tab extends NativeTab {
4646
favImgEl?: HTMLImageElement
4747
favSvgUseEl?: SVGElement
4848
flashFxEl?: HTMLElement
49+
50+
checkingSessionRestore?: Promise<boolean>
51+
resolveSessionRestoreDetection?: (isSessionRestore: boolean) => void
4952
}
5053

5154
export const enum TabStatus {

0 commit comments

Comments
 (0)