Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 51 additions & 38 deletions unclose/bg.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,56 @@
// Serialize all storage writes to prevent counter races on rapid tab events.
var _writeQueue = Promise.resolve();
function enqueueWrite(asyncFn) {
_writeQueue = _writeQueue.then(asyncFn).catch((err) => {
console.error('[unclose] storage write failed:', err);
});
return _writeQueue;
}

chrome.tabs.onUpdated.addListener(async function(tabId, changeInfo, tab) {
await ensureInitialized();
var tabKey = "TabList-" + tabId;
var currentUrl = tab.url || await storageGet(tabKey);
var updates = {};
if (tab.url)
updates[tabKey] = tab.url;
updates["TabIndex-" + tabId] = tab.index;
if (tab.favIconUrl)
updates["TabFavicon-" + tabId] = tab.favIconUrl;
if(tab.title != null && currentUrl)
updates["TabTitle-" + tabId] = tab.title;
else if (currentUrl)
updates["TabTitle-" + tabId] = currentUrl;
await storageSet(updates);
await enqueueWrite(async () => {
await ensureInitialized();
var tabKey = "TabList-" + tabId;
var currentUrl = tab.url || await storageGet(tabKey);
var updates = {};
if (tab.url)
updates[tabKey] = tab.url;
updates["TabIndex-" + tabId] = tab.index;
if (tab.favIconUrl)
updates["TabFavicon-" + tabId] = tab.favIconUrl;
if (tab.title != null)
updates["TabTitle-" + tabId] = tab.title;
else if (currentUrl)
updates["TabTitle-" + tabId] = currentUrl;
await storageSet(updates);
});
});

chrome.tabs.onRemoved.addListener(async function(tabId, info) {
await ensureInitialized();
// Should we record this tab?
var tabKey = "TabList-" + tabId;
var state = await storageGet({
closeCount: 0,
actualCount: 0,
[tabKey]: null
chrome.tabs.onRemoved.addListener(async function(tabId, info) {
await enqueueWrite(async () => {
await ensureInitialized();
// Should we record this tab?
var tabKey = "TabList-" + tabId;
var state = await storageGet({
closeCount: 0,
actualCount: 0,
[tabKey]: null
});
var url = state[tabKey];
var re = /^(http:|https:|ftp:|file:)/;
if (url && re.test(url)) {
var closeCount = parseInt(state.closeCount, 10) || 0;
var actualCount = (parseInt(state.actualCount, 10) || 0) + 1;
var updates = {
closeCount: closeCount + 1,
actualCount: actualCount
};
updates["ClosedTab-" + closeCount] = tabId;
updates["ClosedTabTime-" + closeCount] = new Date().getTime();
await storageSet(updates);
await setBadgeText();
}
else
await clear(tabId);
});
var url = state[tabKey];
var re = /^(http:|https:|ftp:|file:)/;
if (url && re.test(url)) {
var closeCount = parseInt(state.closeCount, 10) || 0;
var actualCount = (parseInt(state.actualCount, 10) || 0) + 1;
var updates = {
closeCount: closeCount + 1,
actualCount: actualCount
};
updates["ClosedTab-" + closeCount] = tabId;
updates["ClosedTabTime-" + closeCount] = new Date().getTime();
await storageSet(updates);
await setBadgeText();
}
else
await clear(tabId);
});
9 changes: 6 additions & 3 deletions unclose/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,13 @@ async function init()
await initialize();
}

chrome.runtime.onInstalled.addListener(async function() {
await init();
chrome.runtime.onInstalled.addListener(async function(details) {
if (details.reason === 'install') await init();
else await ensureInitialized();
});

chrome.runtime.onStartup.addListener(async function() {
await init();
// chrome.storage.session is cleared automatically on browser restart;
// just reset the counters and badge.
await initialize();
});
6 changes: 4 additions & 2 deletions unclose/popup.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@ function prev() {
// Show |url| in a new tab.
async function showUrl(tabId) {
var state = await storageGet({
actualCount: 0,
["TabList-" + tabId]: null,
["TabIndex-" + tabId]: null
});
Expand All @@ -146,8 +145,11 @@ async function showUrl(tabId) {

await chrome.tabs.create(createProperties);
await clear(tabId);
// Re-read actualCount right before decrementing to minimise the race window
// with concurrent onRemoved increments.
var currentCount = parseInt(await storageGet("actualCount"), 10) || 0;
await storageSet({
actualCount: Math.max((parseInt(state.actualCount, 10) || 0) - 1, 0)
actualCount: Math.max(currentCount - 1, 0)
});
await setBadgeText();
await loadContent();
Expand Down