Skip to content

Commit

Permalink
fix: restore compatibility with Safari 18
Browse files Browse the repository at this point in the history
  • Loading branch information
dessant committed Sep 28, 2024
1 parent 3fecc20 commit 7869d64
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 30 deletions.
16 changes: 15 additions & 1 deletion src/background/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ import {
isContextMenuSupported,
checkSearchEngineAccess,
getEngineMenuIcon,
getAppTheme
getAppTheme,
addTabRevision
} from 'utils/app';
import {
getText,
Expand Down Expand Up @@ -1047,6 +1048,10 @@ async function onStartup() {
await setup({event: 'startup'});
}

async function onTabReplaced(addedTabId, removedTabId) {
await addTabRevision({addedTabId, removedTabId});
}

function addContextMenuListener() {
if (browser.contextMenus) {
browser.contextMenus.onClicked.addListener(onContextMenuItemClick);
Expand Down Expand Up @@ -1081,6 +1086,14 @@ function addStartupListener() {
browser.runtime.onStartup.addListener(onStartup);
}

function addTabReplacedListener() {
// Safari 18: tab.id changes when an extension page is redirected
// to a website, changes are saved to assign tasks to the correct tab.
if (['safari'].includes(targetEnv)) {
browser.tabs.onReplaced.addListener(onTabReplaced);
}
}

async function setupUI() {
const items = [setBrowserAction];

Expand Down Expand Up @@ -1140,6 +1153,7 @@ function init() {
addAlarmListener();
addInstallListener();
addStartupListener();
addTabReplacedListener();

setup();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ async function upgrade() {
const changes = {
platformInfo: null,
menuChangeEvent: 0,
privateMenuChangeEvent: 0
privateMenuChangeEvent: 0,
tabRevisions: []
};

changes.storageVersion = revision;
Expand Down
44 changes: 42 additions & 2 deletions src/utils/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import {
getDayPrecisionEpoch,
getDarkColorSchemeQuery,
getExtensionDomain,
getRandomInt
getRandomInt,
requestLock
} from 'utils/common';
import {
targetEnv,
Expand Down Expand Up @@ -677,6 +678,43 @@ function normalizeUrl(url) {
return parsedUrl.toString();
}

async function addTabRevision({addedTabId, removedTabId} = {}) {
return requestLock('tab_revisions', async () => {
const {tabRevisions} = await storage.get('tabRevisions', {area: 'session'});

let entryFound = false;

for (const tabIds of tabRevisions) {
if (tabIds.includes(removedTabId)) {
tabIds.push(addedTabId);

entryFound = true;
break;
}
}

if (!entryFound) {
tabRevisions.push([removedTabId, addedTabId]);
}

await storage.set({tabRevisions}, {area: 'session'});
});
}

async function getTabRevisions(tabId) {
return requestLock('tab_revisions', async () => {
const {tabRevisions} = await storage.get('tabRevisions', {area: 'session'});

for (const tabIds of tabRevisions) {
if (tabIds.includes(tabId)) {
return tabIds;
}
}

return null;
});
}

export {
getEnabledEngines,
getSearches,
Expand Down Expand Up @@ -711,5 +749,7 @@ export {
checkSearchEngineAccess,
isMatchingUrlHost,
validateUrl,
normalizeUrl
normalizeUrl,
addTabRevision,
getTabRevisions
};
10 changes: 10 additions & 0 deletions src/utils/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,15 @@ function runOnce(name, func) {
}
}

async function requestLock(name, func, {timeout = 60000} = {}) {
const params = [name];
if (timeout) {
params.push({signal: AbortSignal.timeout(timeout)});
}

return navigator.locks.request(...params, func);
}

function sleep(ms) {
return new Promise(resolve => self.setTimeout(resolve, ms));
}
Expand Down Expand Up @@ -568,5 +577,6 @@ export {
makeDocumentVisible,
getStore,
runOnce,
requestLock,
sleep
};
44 changes: 18 additions & 26 deletions src/utils/registry.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {
import Queue from 'p-queue';

import storage from 'storage/storage';
import {getTabRevisions} from 'utils/app';
import {targetEnv} from 'utils/config';

const storageQueue = new Queue({concurrency: 1});
const registryQueue = new Queue({concurrency: 1});
Expand Down Expand Up @@ -240,29 +242,6 @@ async function saveStorageItemReceipt({storageId} = {}) {
});
}

async function aquireLock({name, expiryTime = 1.0} = {}) {
name = await storageQueue.add(async function () {
if (!name) {
name = uuidv4();
}

const token = `lock_${name}`;

const {metadata} = await _getStorageItem({
storageId: token,
metadata: true
});

if (!metadata) {
await addStorageItem('', {token, expiryTime});

return name;
}
});

return name;
}

async function addStorageRegistryItem({storageId, addTime} = {}) {
await registryQueue.add(async function () {
const {storageRegistry} = await storage.get('storageRegistry');
Expand Down Expand Up @@ -298,7 +277,21 @@ async function getTaskRegistryItem({taskId, tabId} = {}) {
const {taskRegistry} = await storage.get('taskRegistry');

if (tabId) {
const tab = taskRegistry.tabs[tabId];
let tab = taskRegistry.tabs[tabId];

if (!tab && ['safari'].includes(targetEnv)) {
const tabRevisions = await getTabRevisions(tabId);

if (tabRevisions) {
for (const revision of tabRevisions) {
tab = taskRegistry.tabs[revision];

if (tab) {
break;
}
}
}
}

if (tab) {
return {
Expand Down Expand Up @@ -377,6 +370,5 @@ export default {
saveStorageItemReceipt,
addTaskRegistryItem,
getTaskRegistryItem,
cleanupRegistry,
aquireLock
cleanupRegistry
};

0 comments on commit 7869d64

Please sign in to comment.