Skip to content

Commit 7869d64

Browse files
committed
fix: restore compatibility with Safari 18
1 parent 3fecc20 commit 7869d64

File tree

5 files changed

+87
-30
lines changed

5 files changed

+87
-30
lines changed

src/background/main.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ import {
2121
isContextMenuSupported,
2222
checkSearchEngineAccess,
2323
getEngineMenuIcon,
24-
getAppTheme
24+
getAppTheme,
25+
addTabRevision
2526
} from 'utils/app';
2627
import {
2728
getText,
@@ -1047,6 +1048,10 @@ async function onStartup() {
10471048
await setup({event: 'startup'});
10481049
}
10491050

1051+
async function onTabReplaced(addedTabId, removedTabId) {
1052+
await addTabRevision({addedTabId, removedTabId});
1053+
}
1054+
10501055
function addContextMenuListener() {
10511056
if (browser.contextMenus) {
10521057
browser.contextMenus.onClicked.addListener(onContextMenuItemClick);
@@ -1081,6 +1086,14 @@ function addStartupListener() {
10811086
browser.runtime.onStartup.addListener(onStartup);
10821087
}
10831088

1089+
function addTabReplacedListener() {
1090+
// Safari 18: tab.id changes when an extension page is redirected
1091+
// to a website, changes are saved to assign tasks to the correct tab.
1092+
if (['safari'].includes(targetEnv)) {
1093+
browser.tabs.onReplaced.addListener(onTabReplaced);
1094+
}
1095+
}
1096+
10841097
async function setupUI() {
10851098
const items = [setBrowserAction];
10861099

@@ -1140,6 +1153,7 @@ function init() {
11401153
addAlarmListener();
11411154
addInstallListener();
11421155
addStartupListener();
1156+
addTabReplacedListener();
11431157

11441158
setup();
11451159
}

src/storage/revisions/session/20240514122825_initial_version.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ async function upgrade() {
66
const changes = {
77
platformInfo: null,
88
menuChangeEvent: 0,
9-
privateMenuChangeEvent: 0
9+
privateMenuChangeEvent: 0,
10+
tabRevisions: []
1011
};
1112

1213
changes.storageVersion = revision;

src/utils/app.js

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ import {
1212
getDayPrecisionEpoch,
1313
getDarkColorSchemeQuery,
1414
getExtensionDomain,
15-
getRandomInt
15+
getRandomInt,
16+
requestLock
1617
} from 'utils/common';
1718
import {
1819
targetEnv,
@@ -677,6 +678,43 @@ function normalizeUrl(url) {
677678
return parsedUrl.toString();
678679
}
679680

681+
async function addTabRevision({addedTabId, removedTabId} = {}) {
682+
return requestLock('tab_revisions', async () => {
683+
const {tabRevisions} = await storage.get('tabRevisions', {area: 'session'});
684+
685+
let entryFound = false;
686+
687+
for (const tabIds of tabRevisions) {
688+
if (tabIds.includes(removedTabId)) {
689+
tabIds.push(addedTabId);
690+
691+
entryFound = true;
692+
break;
693+
}
694+
}
695+
696+
if (!entryFound) {
697+
tabRevisions.push([removedTabId, addedTabId]);
698+
}
699+
700+
await storage.set({tabRevisions}, {area: 'session'});
701+
});
702+
}
703+
704+
async function getTabRevisions(tabId) {
705+
return requestLock('tab_revisions', async () => {
706+
const {tabRevisions} = await storage.get('tabRevisions', {area: 'session'});
707+
708+
for (const tabIds of tabRevisions) {
709+
if (tabIds.includes(tabId)) {
710+
return tabIds;
711+
}
712+
}
713+
714+
return null;
715+
});
716+
}
717+
680718
export {
681719
getEnabledEngines,
682720
getSearches,
@@ -711,5 +749,7 @@ export {
711749
checkSearchEngineAccess,
712750
isMatchingUrlHost,
713751
validateUrl,
714-
normalizeUrl
752+
normalizeUrl,
753+
addTabRevision,
754+
getTabRevisions
715755
};

src/utils/common.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,15 @@ function runOnce(name, func) {
536536
}
537537
}
538538

539+
async function requestLock(name, func, {timeout = 60000} = {}) {
540+
const params = [name];
541+
if (timeout) {
542+
params.push({signal: AbortSignal.timeout(timeout)});
543+
}
544+
545+
return navigator.locks.request(...params, func);
546+
}
547+
539548
function sleep(ms) {
540549
return new Promise(resolve => self.setTimeout(resolve, ms));
541550
}
@@ -568,5 +577,6 @@ export {
568577
makeDocumentVisible,
569578
getStore,
570579
runOnce,
580+
requestLock,
571581
sleep
572582
};

src/utils/registry.js

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import {
88
import Queue from 'p-queue';
99

1010
import storage from 'storage/storage';
11+
import {getTabRevisions} from 'utils/app';
12+
import {targetEnv} from 'utils/config';
1113

1214
const storageQueue = new Queue({concurrency: 1});
1315
const registryQueue = new Queue({concurrency: 1});
@@ -240,29 +242,6 @@ async function saveStorageItemReceipt({storageId} = {}) {
240242
});
241243
}
242244

243-
async function aquireLock({name, expiryTime = 1.0} = {}) {
244-
name = await storageQueue.add(async function () {
245-
if (!name) {
246-
name = uuidv4();
247-
}
248-
249-
const token = `lock_${name}`;
250-
251-
const {metadata} = await _getStorageItem({
252-
storageId: token,
253-
metadata: true
254-
});
255-
256-
if (!metadata) {
257-
await addStorageItem('', {token, expiryTime});
258-
259-
return name;
260-
}
261-
});
262-
263-
return name;
264-
}
265-
266245
async function addStorageRegistryItem({storageId, addTime} = {}) {
267246
await registryQueue.add(async function () {
268247
const {storageRegistry} = await storage.get('storageRegistry');
@@ -298,7 +277,21 @@ async function getTaskRegistryItem({taskId, tabId} = {}) {
298277
const {taskRegistry} = await storage.get('taskRegistry');
299278

300279
if (tabId) {
301-
const tab = taskRegistry.tabs[tabId];
280+
let tab = taskRegistry.tabs[tabId];
281+
282+
if (!tab && ['safari'].includes(targetEnv)) {
283+
const tabRevisions = await getTabRevisions(tabId);
284+
285+
if (tabRevisions) {
286+
for (const revision of tabRevisions) {
287+
tab = taskRegistry.tabs[revision];
288+
289+
if (tab) {
290+
break;
291+
}
292+
}
293+
}
294+
}
302295

303296
if (tab) {
304297
return {
@@ -377,6 +370,5 @@ export default {
377370
saveStorageItemReceipt,
378371
addTaskRegistryItem,
379372
getTaskRegistryItem,
380-
cleanupRegistry,
381-
aquireLock
373+
cleanupRegistry
382374
};

0 commit comments

Comments
 (0)