diff --git a/src/js/background.js b/src/js/background.js index 5e2c0477..722ae51b 100644 --- a/src/js/background.js +++ b/src/js/background.js @@ -6,7 +6,7 @@ * http://github.com/greatsuspender/thegreatsuspender * ༼ つ ◕_◕ ༽つ */ -var tgs = (function() { +var tgs = (function () { // eslint-disable-line no-unused-vars 'use strict'; @@ -85,19 +85,19 @@ var tgs = (function() { retries = retries || 0; if (retries > 300) { // allow 30 seconds :scream: - chrome.tabs.create({ url: chrome.extension.getURL('broken.html') }); + chrome.tabs.create({url: chrome.extension.getURL('broken.html')}); return Promise.reject('Failed to initialise background scripts'); } - return new Promise(function(resolve) { + return new Promise(function (resolve) { const isReady = getExtensionGlobals() !== null; resolve(isReady); - }).then(function(isReady) { + }).then(function (isReady) { if (isReady) { return Promise.resolve(); } - return new Promise(function(resolve) { + return new Promise(function (resolve) { window.setTimeout(resolve, 100); - }).then(function() { + }).then(function () { retries += 1; return backgroundScriptsReadyAsPromised(retries); }); @@ -105,7 +105,7 @@ var tgs = (function() { } function initAsPromised() { - return new Promise(async function(resolve) { + return new Promise(async function (resolve) { gsUtils.log('background', 'PERFORMING BACKGROUND INIT...'); addCommandListeners(); addMessageListeners(); @@ -124,7 +124,7 @@ var tgs = (function() { } //initialise currentStationary and currentFocused vars - const activeTabs = await gsChrome.tabsQuery({ active: true }); + const activeTabs = await gsChrome.tabsQuery({active: true}); const currentWindow = await gsChrome.windowsGetLastFocused(); for (let activeTab of activeTabs) { _currentStationaryTabIdByWindowId[activeTab.windowId] = activeTab.id; @@ -139,27 +139,24 @@ var tgs = (function() { }); } - function startTimers() { - startSessionMetricsJob(); - } function getInternalViewByTabId(tabId) { - const internalViews = chrome.extension.getViews({ tabId: tabId }); + const internalViews = chrome.extension.getViews({tabId: tabId}); if (internalViews.length === 1) { return internalViews[0]; } return null; } + function getInternalViewsByViewName(viewName) { - const internalViews = chrome.extension - .getViews() - .filter(o => o.location.pathname.indexOf(viewName) >= 0); - return internalViews; + return chrome.extension + .getViews() + .filter(o => o.location.pathname.indexOf(viewName) >= 0); } function getCurrentlyActiveTab(callback) { // wrap this in an anonymous async function so we can use await - (async function() { + (async function () { const currentWindowActiveTabs = await gsChrome.tabsQuery({ active: true, currentWindow: true, @@ -195,10 +192,10 @@ var tgs = (function() { // Fallback on currentStationaryTabId const currentStationaryTabId = - _currentStationaryTabIdByWindowId[_currentStationaryWindowId]; + _currentStationaryTabIdByWindowId[_currentStationaryWindowId]; if (currentStationaryTabId) { const currentStationaryTab = await gsChrome.tabsGet( - currentStationaryTabId + currentStationaryTabId ); if (currentStationaryTab !== null) { callback(currentStationaryTab); @@ -217,7 +214,7 @@ var tgs = (function() { return false; } var lastStationaryTabIdForWindow = - _currentStationaryTabIdByWindowId[tab.windowId]; + _currentStationaryTabIdByWindowId[tab.windowId]; if (lastStationaryTabIdForWindow) { return tab.id === lastStationaryTabIdForWindow; } else { @@ -231,7 +228,7 @@ var tgs = (function() { return false; } var currentFocusedTabIdForWindow = - _currentFocusedTabIdByWindowId[tab.windowId]; + _currentFocusedTabIdByWindowId[tab.windowId]; if (currentFocusedTabIdForWindow) { return tab.id === currentFocusedTabIdForWindow; } else { @@ -252,20 +249,20 @@ var tgs = (function() { function whitelistHighlightedTab(includePath) { includePath = includePath || false; - getCurrentlyActiveTab(function(activeTab) { + getCurrentlyActiveTab(function (activeTab) { if (activeTab) { if (gsUtils.isSuspendedTab(activeTab)) { let url = gsUtils.getRootUrl( - gsUtils.getOriginalUrl(activeTab.url), - includePath, - false + gsUtils.getOriginalUrl(activeTab.url), + includePath, + false ); gsUtils.saveToWhitelist(url); unsuspendTab(activeTab); } else if (gsUtils.isNormalTab(activeTab)) { let url = gsUtils.getRootUrl(activeTab.url, includePath, false); gsUtils.saveToWhitelist(url); - calculateTabStatus(activeTab, null, function(status) { + calculateTabStatus(activeTab, null, function (status) { setIconStatus(status, activeTab.id); }); } @@ -274,10 +271,10 @@ var tgs = (function() { } function unwhitelistHighlightedTab(callback) { - getCurrentlyActiveTab(function(activeTab) { + getCurrentlyActiveTab(function (activeTab) { if (activeTab) { gsUtils.removeFromWhitelist(activeTab.url); - calculateTabStatus(activeTab, null, function(status) { + calculateTabStatus(activeTab, null, function (status) { setIconStatus(status, activeTab.id); if (callback) callback(status); }); @@ -288,7 +285,7 @@ var tgs = (function() { } function requestToggleTempWhitelistStateOfHighlightedTab(callback) { - getCurrentlyActiveTab(function(activeTab) { + getCurrentlyActiveTab(function (activeTab) { if (!activeTab) { if (callback) callback(status); return; @@ -303,15 +300,15 @@ var tgs = (function() { return; } - calculateTabStatus(activeTab, null, function(status) { + calculateTabStatus(activeTab, null, function (status) { if ( - status === gsUtils.STATUS_ACTIVE || - status === gsUtils.STATUS_NORMAL + status === gsUtils.STATUS_ACTIVE || + status === gsUtils.STATUS_NORMAL ) { setTempWhitelistStateForTab(activeTab, callback); } else if ( - status === gsUtils.STATUS_TEMPWHITELIST || - status === gsUtils.STATUS_FORMINPUT + status === gsUtils.STATUS_TEMPWHITELIST || + status === gsUtils.STATUS_FORMINPUT ) { unsetTempWhitelistStateForTab(activeTab, callback); } else { @@ -322,20 +319,20 @@ var tgs = (function() { } function setTempWhitelistStateForTab(tab, callback) { - gsMessages.sendTemporaryWhitelistToContentScript(tab.id, function( - error, - response + gsMessages.sendTemporaryWhitelistToContentScript(tab.id, function ( + error, + response ) { if (error) { gsUtils.warning( - tab.id, - 'Failed to sendTemporaryWhitelistToContentScript', - error + tab.id, + 'Failed to sendTemporaryWhitelistToContentScript', + error ); } var contentScriptStatus = - response && response.status ? response.status : null; - calculateTabStatus(tab, contentScriptStatus, function(newStatus) { + response && response.status ? response.status : null; + calculateTabStatus(tab, contentScriptStatus, function (newStatus) { setIconStatus(newStatus, tab.id); //This is a hotfix for issue #723 if (newStatus === 'tempWhitelist' && tab.autoDiscardable) { @@ -349,20 +346,20 @@ var tgs = (function() { } function unsetTempWhitelistStateForTab(tab, callback) { - gsMessages.sendUndoTemporaryWhitelistToContentScript(tab.id, function( - error, - response + gsMessages.sendUndoTemporaryWhitelistToContentScript(tab.id, function ( + error, + response ) { if (error) { gsUtils.warning( - tab.id, - 'Failed to sendUndoTemporaryWhitelistToContentScript', - error + tab.id, + 'Failed to sendUndoTemporaryWhitelistToContentScript', + error ); } var contentScriptStatus = - response && response.status ? response.status : null; - calculateTabStatus(tab, contentScriptStatus, function(newStatus) { + response && response.status ? response.status : null; + calculateTabStatus(tab, contentScriptStatus, function (newStatus) { setIconStatus(newStatus, tab.id); //This is a hotfix for issue #723 if (newStatus !== 'tempWhitelist' && !tab.autoDiscardable) { @@ -378,7 +375,7 @@ var tgs = (function() { function openLinkInSuspendedTab(parentTab, linkedUrl) { //imitate chromes 'open link in new tab' behaviour in how it selects the correct index - chrome.tabs.query({ windowId: chrome.windows.WINDOW_ID_CURRENT }, tabs => { + chrome.tabs.query({windowId: chrome.windows.WINDOW_ID_CURRENT}, tabs => { var newTabIndex = parentTab.index + 1; var nextTab = tabs[newTabIndex]; while (nextTab && nextTab.openerTabId === parentTab.id) { @@ -430,12 +427,12 @@ var tgs = (function() { getCurrentlyActiveTab(activeTab => { if (!activeTab) { gsUtils.warning( - 'background', - 'Could not determine currently active window.' + 'background', + 'Could not determine currently active window.' ); return; } - chrome.windows.get(activeTab.windowId, { populate: true }, curWindow => { + chrome.windows.get(activeTab.windowId, {populate: true}, curWindow => { for (const tab of curWindow.tabs) { if (!tab.active) { gsTabSuspendManager.queueTabForSuspension(tab, forceLevel); @@ -455,15 +452,15 @@ var tgs = (function() { } function unsuspendAllTabs() { - getCurrentlyActiveTab(function(activeTab) { + getCurrentlyActiveTab(function (activeTab) { if (!activeTab) { gsUtils.warning( - 'background', - 'Could not determine currently active window.' + 'background', + 'Could not determine currently active window.' ); return; } - chrome.windows.get(activeTab.windowId, { populate: true }, curWindow => { + chrome.windows.get(activeTab.windowId, {populate: true}, curWindow => { for (const tab of curWindow.tabs) { gsTabSuspendManager.unqueueTabForSuspension(tab); if (gsUtils.isSuspendedTab(tab)) { @@ -503,32 +500,32 @@ var tgs = (function() { function suspendSelectedTabs() { chrome.tabs.query( - { highlighted: true, lastFocusedWindow: true }, - selectedTabs => { - for (const tab of selectedTabs) { - gsTabSuspendManager.queueTabForSuspension(tab, 1); + {highlighted: true, lastFocusedWindow: true}, + selectedTabs => { + for (const tab of selectedTabs) { + gsTabSuspendManager.queueTabForSuspension(tab, 1); + } } - } ); } function unsuspendSelectedTabs() { chrome.tabs.query( - { highlighted: true, lastFocusedWindow: true }, - selectedTabs => { - for (const tab of selectedTabs) { - gsTabSuspendManager.unqueueTabForSuspension(tab); - if (gsUtils.isSuspendedTab(tab)) { - unsuspendTab(tab); + {highlighted: true, lastFocusedWindow: true}, + selectedTabs => { + for (const tab of selectedTabs) { + gsTabSuspendManager.unqueueTabForSuspension(tab); + if (gsUtils.isSuspendedTab(tab)) { + unsuspendTab(tab); + } } } - } ); } function queueSessionTimer() { clearTimeout(_sessionSaveTimer); - _sessionSaveTimer = setTimeout(function() { + _sessionSaveTimer = setTimeout(function () { gsUtils.log('background', 'updating current session'); gsSession.updateCurrentSession(); //async }, 1000); @@ -540,9 +537,9 @@ var tgs = (function() { const suspendTime = gsStorage.getOption(gsStorage.SUSPEND_TIME); const timeToSuspend = suspendTime * (1000 * 60); if ( - gsUtils.isProtectedActiveTab(tab) || - isNaN(suspendTime) || - suspendTime <= 0 + gsUtils.isProtectedActiveTab(tab) || + isNaN(suspendTime) || + suspendTime <= 0 ) { return; } @@ -550,7 +547,7 @@ var tgs = (function() { const timerDetails = {}; timerDetails.tabId = tab.id; timerDetails.suspendDateTime = new Date( - new Date().getTime() + timeToSuspend + new Date().getTime() + timeToSuspend ); timerDetails.timer = setTimeout(async () => { @@ -563,8 +560,8 @@ var tgs = (function() { gsTabSuspendManager.queueTabForSuspension(updatedTab, 3); }, timeToSuspend); gsUtils.log( - tab.id, - 'Adding tab timer for: ' + timerDetails.suspendDateTime + tab.id, + 'Adding tab timer for: ' + timerDetails.suspendDateTime ); setTabStatePropForTabId(tab.id, STATE_TIMER_DETAILS, timerDetails); @@ -593,12 +590,14 @@ var tgs = (function() { function getTabStatePropForTabId(tabId, prop) { return _tabStateByTabId[tabId] ? _tabStateByTabId[tabId][prop] : undefined; } + function setTabStatePropForTabId(tabId, prop, value) { // gsUtils.log(tabId, `Setting tab state prop: ${prop}:`, value); const tabState = _tabStateByTabId[tabId] || {}; tabState[prop] = value; _tabStateByTabId[tabId] = tabState; } + function clearTabStateForTabId(tabId) { gsUtils.log(tabId, 'Clearing tab state props:', _tabStateByTabId[tabId]); clearAutoSuspendTimerForTabId(tabId); @@ -624,7 +623,7 @@ var tgs = (function() { // chrome.tabs.update if this is set to true. This gets unset again after tab // has reloaded via the STATE_SET_AUTODISCARDABLE flag. gsUtils.log(tab.id, 'Unsuspending tab via chrome.tabs.update'); - chrome.tabs.update(tab.id, { url: originalUrl, autoDiscardable: false }); + chrome.tabs.update(tab.id, {url: originalUrl, autoDiscardable: false}); return; } @@ -655,25 +654,25 @@ var tgs = (function() { function handleUnsuspendedTabStateChanged(tab, changeInfo) { if ( - !changeInfo.hasOwnProperty('status') && - !changeInfo.hasOwnProperty('audible') && - !changeInfo.hasOwnProperty('pinned') && - !changeInfo.hasOwnProperty('discarded') + !changeInfo.hasOwnProperty('status') && + !changeInfo.hasOwnProperty('audible') && + !changeInfo.hasOwnProperty('pinned') && + !changeInfo.hasOwnProperty('discarded') ) { return; } gsUtils.log( - tab.id, - 'unsuspended tab state changed. changeInfo: ', - changeInfo + tab.id, + 'unsuspended tab state changed. changeInfo: ', + changeInfo ); // Ensure we clear the STATE_UNLOADED_URL flag during load in case the // tab is suspended again before loading can finish (in which case on // suspended tab complete, the tab will reload again) if ( - changeInfo.hasOwnProperty('status') && - changeInfo.status === 'loading' + changeInfo.hasOwnProperty('status') && + changeInfo.status === 'loading' ) { setTabStatePropForTabId(tab.id, STATE_UNLOADED_URL, null); } @@ -681,8 +680,8 @@ var tgs = (function() { // Check if tab has just been discarded if (changeInfo.hasOwnProperty('discarded') && changeInfo.discarded) { const existingSuspendReason = getTabStatePropForTabId( - tab.id, - STATE_SUSPEND_REASON + tab.id, + STATE_SUSPEND_REASON ); if (existingSuspendReason && existingSuspendReason === 3) { // For some reason the discarded changeInfo gets called twice (chrome bug?) @@ -692,8 +691,8 @@ var tgs = (function() { return; } gsUtils.log( - tab.id, - 'Unsuspended tab has been discarded. Url: ' + tab.url + tab.id, + 'Unsuspended tab has been discarded. Url: ' + tab.url ); gsTabDiscardManager.handleDiscardedUnsuspendedTab(tab); //async. unhandled promise. @@ -709,8 +708,8 @@ var tgs = (function() { // Requeue tab to wake it from possible sleep delete queuedTabDetails.executionProps.refetchTab; gsTabSuspendManager.queueTabForSuspension( - tab, - queuedTabDetails.executionProps.forceLevel + tab, + queuedTabDetails.executionProps.forceLevel ); return; } @@ -736,18 +735,18 @@ var tgs = (function() { if (changeInfo.hasOwnProperty('status')) { if (changeInfo.status === 'complete') { const tempWhitelistOnReload = getTabStatePropForTabId( - tab.id, - STATE_TEMP_WHITELIST_ON_RELOAD + tab.id, + STATE_TEMP_WHITELIST_ON_RELOAD ); const scrollPos = - getTabStatePropForTabId(tab.id, STATE_SCROLL_POS) || null; + getTabStatePropForTabId(tab.id, STATE_SCROLL_POS) || null; const historyUrlToRemove = getTabStatePropForTabId( - tab.id, - STATE_HISTORY_URL_TO_REMOVE + tab.id, + STATE_HISTORY_URL_TO_REMOVE ); const setAutodiscardable = getTabStatePropForTabId( - tab.id, - STATE_SET_AUTODISCARDABLE + tab.id, + STATE_SET_AUTODISCARDABLE ); clearTabStateForTabId(tab.id); @@ -755,21 +754,21 @@ var tgs = (function() { removeTabHistoryForUnuspendedTab(historyUrlToRemove); } if (setAutodiscardable) { - gsChrome.tabsUpdate(tab.id, { autoDiscardable: true }); + gsChrome.tabsUpdate(tab.id, {autoDiscardable: true}); } //init loaded tab resetAutoSuspendTimerForTab(tab); initialiseTabContentScript(tab, tempWhitelistOnReload, scrollPos) - .catch(error => { - gsUtils.warning( - tab.id, - 'Failed to send init to content script. Tab may not behave as expected.' - ); - }) - .then(() => { - // could use returned tab status here below - }); + .catch(error => { + gsUtils.warning( + tab.id, + 'Failed to send init to content script. Tab may not behave as expected.' + ); + }) + .then(() => { + // could use returned tab status here below + }); } hasTabStatusChanged = true; @@ -777,16 +776,16 @@ var tgs = (function() { //if tab is currently visible then update popup icon if (hasTabStatusChanged && isCurrentFocusedTab(tab)) { - calculateTabStatus(tab, null, function(status) { + calculateTabStatus(tab, null, function (status) { setIconStatus(status, tab.id); }); } } function removeTabHistoryForUnuspendedTab(suspendedUrl) { - chrome.history.deleteUrl({ url: suspendedUrl }); + chrome.history.deleteUrl({url: suspendedUrl}); const originalUrl = gsUtils.getOriginalUrl(suspendedUrl); - chrome.history.getVisits({ url: originalUrl }, visits => { + chrome.history.getVisits({url: originalUrl}, visits => { //assume history entry will be the second to latest one (latest one is the currently visible page) //NOTE: this will break if the same url has been visited by another tab more recently than the //suspended tab (pre suspension) @@ -794,11 +793,12 @@ var tgs = (function() { const previousVisit = visits.pop(); if (previousVisit) { chrome.history.deleteRange( - { - startTime: previousVisit.visitTime - 0.1, - endTime: previousVisit.visitTime + 0.1, - }, - () => {} + { + startTime: previousVisit.visitTime - 0.1, + endTime: previousVisit.visitTime + 0.1, + }, + () => { + } ); } }); @@ -808,52 +808,52 @@ var tgs = (function() { return new Promise((resolve, reject) => { const ignoreForms = gsStorage.getOption(gsStorage.IGNORE_FORMS); gsMessages.sendInitTabToContentScript( - tab.id, - ignoreForms, - isTempWhitelist, - scrollPos, - (error, response) => { - if (error) { - reject(error); - } else { - resolve(response); + tab.id, + ignoreForms, + isTempWhitelist, + scrollPos, + (error, response) => { + if (error) { + reject(error); + } else { + resolve(response); + } } - } ); }); } function handleSuspendedTabStateChanged(tab, changeInfo) { if ( - !changeInfo.hasOwnProperty('status') && - !changeInfo.hasOwnProperty('discarded') + !changeInfo.hasOwnProperty('status') && + !changeInfo.hasOwnProperty('discarded') ) { return; } gsUtils.log( - tab.id, - 'suspended tab status changed. changeInfo: ', - changeInfo + tab.id, + 'suspended tab status changed. changeInfo: ', + changeInfo ); if (changeInfo.status && changeInfo.status === 'loading') { tgs.setTabStatePropForTabId( - tab.id, - tgs.STATE_INITIALISE_SUSPENDED_TAB, - true + tab.id, + tgs.STATE_INITIALISE_SUSPENDED_TAB, + true ); return; } if ( - (changeInfo.status && changeInfo.status === 'complete') || - changeInfo.discarded + (changeInfo.status && changeInfo.status === 'complete') || + changeInfo.discarded ) { gsTabSuspendManager.unqueueTabForSuspension(tab); //safety precaution const shouldInitTab = getTabStatePropForTabId( - tab.id, - STATE_INITIALISE_SUSPENDED_TAB + tab.id, + STATE_INITIALISE_SUSPENDED_TAB ); if (shouldInitTab) { initialiseSuspendedTab(tab); @@ -864,8 +864,8 @@ var tgs = (function() { function initialiseSuspendedTab(tab) { const unloadedUrl = getTabStatePropForTabId(tab.id, STATE_UNLOADED_URL); const disableUnsuspendOnReload = getTabStatePropForTabId( - tab.id, - STATE_DISABLE_UNSUSPEND_ON_RELOAD + tab.id, + STATE_DISABLE_UNSUSPEND_ON_RELOAD ); clearTabStateForTabId(tab.id); @@ -882,15 +882,15 @@ var tgs = (function() { const tabView = tgs.getInternalViewByTabId(tab.id); const quickInit = - gsStorage.getOption(gsStorage.DISCARD_AFTER_SUSPEND) && !tab.active; + gsStorage.getOption(gsStorage.DISCARD_AFTER_SUSPEND) && !tab.active; gsSuspendedTab - .initTab(tab, tabView, { quickInit }) - .catch(error => { - gsUtils.warning(tab.id, error); - }) - .then(() => { - gsTabCheckManager.queueTabCheck(tab, { refetchTab: true }, 3000); - }); + .initTab(tab, tabView, {quickInit}) + .catch(error => { + gsUtils.warning(tab.id, error); + }) + .then(() => { + gsTabCheckManager.queueTabCheck(tab, {refetchTab: true}, 3000); + }); } function updateTabIdReferences(newTabId, oldTabId) { @@ -945,7 +945,7 @@ var tgs = (function() { _currentFocusedWindowId = windowId; // Get the active tab in the newly focused window - chrome.tabs.query({ active: true }, function(tabs) { + chrome.tabs.query({active: true}, function (tabs) { if (!tabs || !tabs.length) { return; } @@ -957,14 +957,14 @@ var tgs = (function() { } if (!focusedTab) { gsUtils.warning( - 'background', - `Couldnt find active tab with windowId: ${windowId}. Window may have been closed.` + 'background', + `Couldnt find active tab with windowId: ${windowId}. Window may have been closed.` ); return; } //update icon - calculateTabStatus(focusedTab, null, function(status) { + calculateTabStatus(focusedTab, null, function (status) { setIconStatus(status, focusedTab.id); }); @@ -984,8 +984,8 @@ var tgs = (function() { // If so, then a subsequeunt chrome.tabs.onActivated event will be called // with the new discarded id gsUtils.log( - tabId, - 'Could not find newly focused tab. Assuming it has been discarded' + tabId, + 'Could not find newly focused tab. Assuming it has been discarded' ); return; } @@ -1014,14 +1014,14 @@ var tgs = (function() { contentScriptStatus = await getContentScriptStatus(focusedTab.id); if (!contentScriptStatus) { contentScriptStatus = await gsTabCheckManager.queueTabCheckAsPromise( - focusedTab, - {}, - 0 + focusedTab, + {}, + 0 ); } gsUtils.log( - focusedTab.id, - 'Content script status: ' + contentScriptStatus + focusedTab.id, + 'Content script status: ' + contentScriptStatus ); } @@ -1046,7 +1046,7 @@ var tgs = (function() { } let discardAfterSuspend = gsStorage.getOption( - gsStorage.DISCARD_AFTER_SUSPEND + gsStorage.DISCARD_AFTER_SUSPEND ); if (!discardAfterSuspend) { return; @@ -1054,12 +1054,12 @@ var tgs = (function() { //queue job to discard previously focused tab const previouslyFocusedTab = previouslyFocusedTabId - ? await gsChrome.tabsGet(previouslyFocusedTabId) - : null; + ? await gsChrome.tabsGet(previouslyFocusedTabId) + : null; if (!previouslyFocusedTab) { gsUtils.log( - previouslyFocusedTabId, - 'Could not find tab. Has probably already been discarded' + previouslyFocusedTabId, + 'Could not find tab. Has probably already been discarded' ); return; } @@ -1070,26 +1070,26 @@ var tgs = (function() { //queue tabCheck for previouslyFocusedTab. that will force a discard afterwards //but also avoids conflicts if this tab is already scheduled for checking gsUtils.log( - previouslyFocusedTabId, - 'Queueing previously focused tab for discard via tabCheckManager' + previouslyFocusedTabId, + 'Queueing previously focused tab for discard via tabCheckManager' ); gsTabCheckManager.queueTabCheck(previouslyFocusedTab, {}, 1000); } function queueNewWindowFocusTimer(tabId, windowId, focusedTab) { clearTimeout(_newWindowFocusTimer); - _newWindowFocusTimer = setTimeout(function() { + _newWindowFocusTimer = setTimeout(function () { var previousStationaryWindowId = _currentStationaryWindowId; _currentStationaryWindowId = windowId; var previousStationaryTabId = - _currentStationaryTabIdByWindowId[previousStationaryWindowId]; + _currentStationaryTabIdByWindowId[previousStationaryWindowId]; handleNewStationaryTabFocus(tabId, previousStationaryTabId, focusedTab); }, focusDelay); } function queueNewTabFocusTimer(tabId, windowId, focusedTab) { clearTimeout(_newTabFocusTimer); - _newTabFocusTimer = setTimeout(function() { + _newTabFocusTimer = setTimeout(function () { var previousStationaryTabId = _currentStationaryTabIdByWindowId[windowId]; _currentStationaryTabIdByWindowId[windowId] = focusedTab.id; handleNewStationaryTabFocus(tabId, previousStationaryTabId, focusedTab); @@ -1097,9 +1097,9 @@ var tgs = (function() { } function handleNewStationaryTabFocus( - focusedTabId, - previousStationaryTabId, - focusedTab + focusedTabId, + previousStationaryTabId, + focusedTab ) { gsUtils.log(focusedTabId, 'new stationary tab focus handled'); @@ -1107,7 +1107,7 @@ var tgs = (function() { handleSuspendedTabFocusGained(focusedTab); //async. unhandled promise. } else if (gsUtils.isNormalTab(focusedTab)) { const queuedTabDetails = gsTabSuspendManager.getQueuedTabDetails( - focusedTab + focusedTab ); //if focusedTab is already in the queue for suspension then remove it. if (queuedTabDetails) { @@ -1115,7 +1115,7 @@ var tgs = (function() { //from the popup menu disappearing. in these cases the previousStationaryTabId //should match the current tabId (fix for issue #735) const isRealTabFocus = - previousStationaryTabId && previousStationaryTabId !== focusedTabId; + previousStationaryTabId && previousStationaryTabId !== focusedTabId; //also, only cancel suspension if the tab suspension request has a forceLevel > 1 const isLowForceLevel = queuedTabDetails.executionProps.forceLevel > 1; @@ -1134,15 +1134,15 @@ var tgs = (function() { //Reset timer on tab that lost focus. //NOTE: This may be due to a change in window focus in which case the tab may still have .active = true if (previousStationaryTabId && previousStationaryTabId !== focusedTabId) { - chrome.tabs.get(previousStationaryTabId, function(previousStationaryTab) { + chrome.tabs.get(previousStationaryTabId, function (previousStationaryTab) { if (chrome.runtime.lastError) { //Tab has probably been removed return; } if ( - previousStationaryTab && - gsUtils.isNormalTab(previousStationaryTab) && - !gsUtils.isProtectedActiveTab(previousStationaryTab) + previousStationaryTab && + gsUtils.isNormalTab(previousStationaryTab) && + !gsUtils.isProtectedActiveTab(previousStationaryTab) ) { resetAutoSuspendTimerForTab(previousStationaryTab); } @@ -1153,7 +1153,7 @@ var tgs = (function() { async function handleSuspendedTabFocusGained(focusedTab) { if (focusedTab.status !== 'loading') { //safety check to ensure suspended tab has been initialised - gsTabCheckManager.queueTabCheck(focusedTab, { refetchTab: false }, 0); + gsTabCheckManager.queueTabCheck(focusedTab, {refetchTab: false}, 0); } //check for auto-unsuspend @@ -1182,6 +1182,7 @@ var tgs = (function() { function requestNotice() { return _noticeToDisplay; } + function clearNotice() { _noticeToDisplay = undefined; } @@ -1199,7 +1200,7 @@ var tgs = (function() { timerUp: timerDetails ? timerDetails.suspendDateTime : '-', }; - chrome.tabs.get(tabId, function(tab) { + chrome.tabs.get(tabId, function (tab) { if (chrome.runtime.lastError) { gsUtils.error(tabId, chrome.runtime.lastError); callback(info); @@ -1209,15 +1210,15 @@ var tgs = (function() { info.windowId = tab.windowId; info.tabId = tab.id; if (gsUtils.isNormalTab(tab, true)) { - gsMessages.sendRequestInfoToContentScript(tab.id, function( - error, - tabInfo + gsMessages.sendRequestInfoToContentScript(tab.id, function ( + error, + tabInfo ) { if (error) { gsUtils.warning(tab.id, 'Failed to getDebugInfo', error); } if (tabInfo) { - calculateTabStatus(tab, tabInfo.status, function(status) { + calculateTabStatus(tab, tabInfo.status, function (status) { info.status = status; callback(info); }); @@ -1226,7 +1227,7 @@ var tgs = (function() { } }); } else { - calculateTabStatus(tab, null, function(status) { + calculateTabStatus(tab, null, function (status) { info.status = status; callback(info); }); @@ -1235,13 +1236,13 @@ var tgs = (function() { } function getContentScriptStatus(tabId, knownContentScriptStatus) { - return new Promise(function(resolve) { + return new Promise(function (resolve) { if (knownContentScriptStatus) { resolve(knownContentScriptStatus); } else { - gsMessages.sendRequestInfoToContentScript(tabId, function( - error, - tabInfo + gsMessages.sendRequestInfoToContentScript(tabId, function ( + error, + tabInfo ) { if (error) { gsUtils.warning(tabId, 'Failed to getContentScriptStatus', error); @@ -1311,61 +1312,61 @@ var tgs = (function() { return; } getContentScriptStatus(tab.id, knownContentScriptStatus).then( - contentScriptStatus => { - if ( - contentScriptStatus && - contentScriptStatus !== gsUtils.STATUS_NORMAL - ) { - callback(contentScriptStatus); - return; - } - //check running on battery - if ( - gsStorage.getOption(gsStorage.IGNORE_WHEN_CHARGING) && - _isCharging - ) { - callback(gsUtils.STATUS_CHARGING); - return; - } - //check internet connectivity - if ( - gsStorage.getOption(gsStorage.IGNORE_WHEN_OFFLINE) && - !navigator.onLine - ) { - callback(gsUtils.STATUS_NOCONNECTIVITY); - return; - } - //check pinned tab - if (gsUtils.isProtectedPinnedTab(tab)) { - callback(gsUtils.STATUS_PINNED); - return; - } - //check audible tab - if (gsUtils.isProtectedAudibleTab(tab)) { - callback(gsUtils.STATUS_AUDIBLE); - return; - } - //check active - if (gsUtils.isProtectedActiveTab(tab)) { - callback(gsUtils.STATUS_ACTIVE); - return; - } - if (contentScriptStatus) { - callback(contentScriptStatus); // should be 'normal' - return; + contentScriptStatus => { + if ( + contentScriptStatus && + contentScriptStatus !== gsUtils.STATUS_NORMAL + ) { + callback(contentScriptStatus); + return; + } + //check running on battery + if ( + gsStorage.getOption(gsStorage.IGNORE_WHEN_CHARGING) && + _isCharging + ) { + callback(gsUtils.STATUS_CHARGING); + return; + } + //check internet connectivity + if ( + gsStorage.getOption(gsStorage.IGNORE_WHEN_OFFLINE) && + !navigator.onLine + ) { + callback(gsUtils.STATUS_NOCONNECTIVITY); + return; + } + //check pinned tab + if (gsUtils.isProtectedPinnedTab(tab)) { + callback(gsUtils.STATUS_PINNED); + return; + } + //check audible tab + if (gsUtils.isProtectedAudibleTab(tab)) { + callback(gsUtils.STATUS_AUDIBLE); + return; + } + //check active + if (gsUtils.isProtectedActiveTab(tab)) { + callback(gsUtils.STATUS_ACTIVE); + return; + } + if (contentScriptStatus) { + callback(contentScriptStatus); // should be 'normal' + return; + } + callback(gsUtils.STATUS_UNKNOWN); } - callback(gsUtils.STATUS_UNKNOWN); - } ); } function getActiveTabStatus(callback) { - getCurrentlyActiveTab(function(tab) { + getCurrentlyActiveTab(function (tab) { if (!tab) { callback(gsUtils.STATUS_UNKNOWN); return; } - calculateTabStatus(tab, null, function(status) { + calculateTabStatus(tab, null, function (status) { callback(status); }); }); @@ -1375,25 +1376,25 @@ var tgs = (function() { function setIconStatus(status, tabId) { // gsUtils.log(tabId, 'Setting icon status: ' + status); var icon = ![gsUtils.STATUS_NORMAL, gsUtils.STATUS_ACTIVE].includes(status) - ? ICON_SUSPENSION_PAUSED - : ICON_SUSPENSION_ACTIVE; - chrome.browserAction.setIcon({ path: icon, tabId: tabId }, function() { + ? ICON_SUSPENSION_PAUSED + : ICON_SUSPENSION_ACTIVE; + chrome.browserAction.setIcon({path: icon, tabId: tabId}, function () { if (chrome.runtime.lastError) { gsUtils.warning( - tabId, - chrome.runtime.lastError, - `Failed to set icon for tab. Tab may have been closed.` + tabId, + chrome.runtime.lastError, + `Failed to set icon for tab. Tab may have been closed.` ); } }); } function setIconStatusForActiveTab() { - getCurrentlyActiveTab(function(tab) { + getCurrentlyActiveTab(function (tab) { if (!tab) { return; } - calculateTabStatus(tab, null, function(status) { + calculateTabStatus(tab, null, function (status) { setIconStatus(status, tab.id); }); }); @@ -1463,21 +1464,21 @@ var tgs = (function() { }); chrome.contextMenus.create({ title: chrome.i18n.getMessage( - 'js_context_soft_suspend_other_tabs_in_window' + 'js_context_soft_suspend_other_tabs_in_window' ), contexts: allContexts, onclick: () => suspendAllTabs(false), }); chrome.contextMenus.create({ title: chrome.i18n.getMessage( - 'js_context_force_suspend_other_tabs_in_window' + 'js_context_force_suspend_other_tabs_in_window' ), contexts: allContexts, onclick: () => suspendAllTabs(true), }); chrome.contextMenus.create({ title: chrome.i18n.getMessage( - 'js_context_unsuspend_all_tabs_in_window' + 'js_context_unsuspend_all_tabs_in_window' ), contexts: allContexts, onclick: () => unsuspendAllTabs(), @@ -1508,27 +1509,38 @@ var tgs = (function() { //HANDLERS FOR KEYBOARD SHORTCUTS function addCommandListeners() { - chrome.commands.onCommand.addListener(function(command) { - if (command === '1-suspend-tab') { - toggleSuspendedStateOfHighlightedTab(); - } else if (command === '2-toggle-temp-whitelist-tab') { - requestToggleTempWhitelistStateOfHighlightedTab(); - } else if (command === '2a-suspend-selected-tabs') { - suspendSelectedTabs(); - } else if (command === '2b-unsuspend-selected-tabs') { - unsuspendSelectedTabs(); - } else if (command === '3-suspend-active-window') { - suspendAllTabs(false); - } else if (command === '3b-force-suspend-active-window') { - suspendAllTabs(true); - } else if (command === '4-unsuspend-active-window') { - unsuspendAllTabs(); - } else if (command === '4b-soft-suspend-all-windows') { - suspendAllTabsInAllWindows(false); - } else if (command === '5-suspend-all-windows') { - suspendAllTabsInAllWindows(true); - } else if (command === '6-unsuspend-all-windows') { - unsuspendAllTabsInAllWindows(); + chrome.commands.onCommand.addListener(function (command) { + switch (command) { + case '1-suspend-tab': + toggleSuspendedStateOfHighlightedTab(); + break; + case '2-toggle-temp-whitelist-tab': + requestToggleTempWhitelistStateOfHighlightedTab(); + break; + case '2a-suspend-selected-tabs': + suspendSelectedTabs(); + break; + case '2b-unsuspend-selected-tabs': + unsuspendSelectedTabs(); + break; + case '3-suspend-active-window': + suspendAllTabs(false); + break; + case '3b-force-suspend-active-window': + suspendAllTabs(true); + break; + case '4-unsuspend-active-window': + unsuspendAllTabs(); + break; + case '4b-soft-suspend-all-windows': + suspendAllTabsInAllWindows(false); + break; + case '5-suspend-all-windows': + suspendAllTabsInAllWindows(true); + break; + case '6-unsuspend-all-windows': + unsuspendAllTabsInAllWindows(); + break; } }); } @@ -1537,25 +1549,25 @@ var tgs = (function() { function messageRequestListener(request, sender, sendResponse) { gsUtils.log( - sender.tab.id, - 'background messageRequestListener', - request.action + sender.tab.id, + 'background messageRequestListener', + request.action ); if (request.action === 'reportTabState') { var contentScriptStatus = - request && request.status ? request.status : null; + request && request.status ? request.status : null; if ( - contentScriptStatus === 'formInput' || - contentScriptStatus === 'tempWhitelist' + contentScriptStatus === 'formInput' || + contentScriptStatus === 'tempWhitelist' ) { - chrome.tabs.update(sender.tab.id, { autoDiscardable: false }); + chrome.tabs.update(sender.tab.id, {autoDiscardable: false}); } else if (!sender.tab.autoDiscardable) { - chrome.tabs.update(sender.tab.id, { autoDiscardable: true }); + chrome.tabs.update(sender.tab.id, {autoDiscardable: true}); } // If tab is currently visible then update popup icon if (sender.tab && isCurrentFocusedTab(sender.tab)) { - calculateTabStatus(sender.tab, contentScriptStatus, function(status) { + calculateTabStatus(sender.tab, contentScriptStatus, function (status) { setIconStatus(status, sender.tab.id); }); } @@ -1565,9 +1577,9 @@ var tgs = (function() { if (request.action === 'savePreviewData') { gsTabSuspendManager.handlePreviewImageResponse( - sender.tab, - request.previewUrl, - request.errorMsg + sender.tab, + request.previewUrl, + request.errorMsg ); // async. unhandled promise sendResponse(); return false; @@ -1587,7 +1599,7 @@ var tgs = (function() { } // wrap this in an anonymous async function so we can use await - (async function() { + (async function () { let tab; if (request.tabId) { if (typeof request.tabId !== 'number') { @@ -1639,21 +1651,21 @@ var tgs = (function() { //attach listener to runtime for external messages, to allow //interoperability with other extensions in the manner of an API chrome.runtime.onMessageExternal.addListener( - externalMessageRequestListener + externalMessageRequestListener ); } function addChromeListeners() { - chrome.windows.onFocusChanged.addListener(function(windowId) { + chrome.windows.onFocusChanged.addListener(function (windowId) { handleWindowFocusChanged(windowId); }); - chrome.tabs.onActivated.addListener(function(activeInfo) { + chrome.tabs.onActivated.addListener(function (activeInfo) { handleTabFocusChanged(activeInfo.tabId, activeInfo.windowId); // async. unhandled promise }); - chrome.tabs.onReplaced.addListener(function(addedTabId, removedTabId) { + chrome.tabs.onReplaced.addListener(function (addedTabId, removedTabId) { updateTabIdReferences(addedTabId, removedTabId); }); - chrome.tabs.onCreated.addListener(async function(tab) { + chrome.tabs.onCreated.addListener(async function (tab) { gsUtils.log(tab.id, 'tab created. tabUrl: ' + tab.url); queueSessionTimer(); @@ -1665,12 +1677,12 @@ var tgs = (function() { gsTabCheckManager.queueTabCheck(tab, {}, 5000); } }); - chrome.tabs.onRemoved.addListener(function(tabId, removeInfo) { + chrome.tabs.onRemoved.addListener(function (tabId, removeInfo) { gsUtils.log(tabId, 'tab removed.'); queueSessionTimer(); removeTabIdReferences(tabId); }); - chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) { + chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) { if (!changeInfo) return; // if url has changed @@ -1686,16 +1698,16 @@ var tgs = (function() { handleUnsuspendedTabStateChanged(tab, changeInfo); } }); - chrome.windows.onCreated.addListener(function(window) { + chrome.windows.onCreated.addListener(function (window) { gsUtils.log(window.id, 'window created.'); queueSessionTimer(); var noticeToDisplay = requestNotice(); if (noticeToDisplay) { - chrome.tabs.create({ url: chrome.extension.getURL('notice.html') }); + chrome.tabs.create({url: chrome.extension.getURL('notice.html')}); } }); - chrome.windows.onRemoved.addListener(function(windowId) { + chrome.windows.onRemoved.addListener(function (windowId) { gsUtils.log(windowId, 'window removed.'); queueSessionTimer(); }); @@ -1704,18 +1716,18 @@ var tgs = (function() { function addMiscListeners() { //add listener for battery state changes if (navigator.getBattery) { - navigator.getBattery().then(function(battery) { + navigator.getBattery().then(function (battery) { _isCharging = battery.charging; - battery.onchargingchange = function() { + battery.onchargingchange = function () { _isCharging = battery.charging; gsUtils.log('background', `_isCharging: ${_isCharging}`); setIconStatusForActiveTab(); //restart timer on all normal tabs //NOTE: some tabs may have been prevented from suspending when computer was charging if ( - !_isCharging && - gsStorage.getOption(gsStorage.IGNORE_WHEN_CHARGING) + !_isCharging && + gsStorage.getOption(gsStorage.IGNORE_WHEN_CHARGING) ) { resetAutoSuspendTimerForAllTabs(); } @@ -1724,7 +1736,7 @@ var tgs = (function() { } //add listeners for online/offline state changes - window.addEventListener('online', function() { + window.addEventListener('online', function () { gsUtils.log('background', 'Internet is online.'); //restart timer on all normal tabs //NOTE: some tabs may have been prevented from suspending when internet was offline @@ -1733,20 +1745,12 @@ var tgs = (function() { } setIconStatusForActiveTab(); }); - window.addEventListener('offline', function() { + window.addEventListener('offline', function () { gsUtils.log('background', 'Internet is offline.'); setIconStatusForActiveTab(); }); } - function startSessionMetricsJob() { - gsSession.updateSessionMetrics(true); - window.setInterval( - gsSession.updateSessionMetrics, - sessionMetricsCheckInterval - ); - } - return { STATE_TIMER_DETAILS, STATE_UNLOADED_URL, @@ -1766,7 +1770,6 @@ var tgs = (function() { setViewGlobals, getInternalViewByTabId, getInternalViewsByViewName, - startTimers, requestNotice, clearNotice, buildContextMenu, @@ -1798,29 +1801,26 @@ var tgs = (function() { })(); Promise.resolve() - .then(tgs.backgroundScriptsReadyAsPromised) // wait until all gsLibs have loaded - .then(gsStorage.initSettingsAsPromised) // ensure settings have been loaded and synced - .then(() => { - // initialise other gsLibs - return Promise.all([ - gsFavicon.initAsPromised(), - gsTabSuspendManager.initAsPromised(), - gsTabCheckManager.initAsPromised(), - gsTabDiscardManager.initAsPromised(), - gsSession.initAsPromised(), - ]); - }) - .catch(error => { - gsUtils.error('background init error: ', error); - }) - .then(gsSession.runStartupChecks) // performs crash check (and maybe recovery) and tab responsiveness checks - .catch(error => { - gsUtils.error('background startup checks error: ', error); - }) - .then(tgs.initAsPromised) // adds handle(Un)SuspendedTabChanged listeners! - .catch(error => { - gsUtils.error('background init error: ', error); - }) - .finally(() => { - tgs.startTimers(); - }); + .then(tgs.backgroundScriptsReadyAsPromised) // wait until all gsLibs have loaded + .then(gsStorage.initSettingsAsPromised) // ensure settings have been loaded and synced + .then(() => { + // initialise other gsLibs + return Promise.all([ + gsFavicon.initAsPromised(), + gsTabSuspendManager.initAsPromised(), + gsTabCheckManager.initAsPromised(), + gsTabDiscardManager.initAsPromised(), + gsSession.initAsPromised(), + ]); + }) + .catch(error => { + gsUtils.error('background init error: ', error); + }) + .then(gsSession.runStartupChecks) // performs crash check (and maybe recovery) and tab responsiveness checks + .catch(error => { + gsUtils.error('background startup checks error: ', error); + }) + .then(tgs.initAsPromised) // adds handle(Un)SuspendedTabChanged listeners! + .catch(error => { + gsUtils.error('background init error: ', error); + }); diff --git a/src/js/gsSession.js b/src/js/gsSession.js index e05cf34a..753c128c 100644 --- a/src/js/gsSession.js +++ b/src/js/gsSession.js @@ -50,16 +50,16 @@ var gsSession = (function() { const newVersion = newVersionDetails.version; gsUtils.log( - 'gsSession', - 'A new version is available: ' + currentVersion + ' -> ' + newVersion + 'gsSession', + 'A new version is available: ' + currentVersion + ' -> ' + newVersion ); let sessionRestorePoint; const currentSession = await buildCurrentSession(); if (currentSession) { sessionRestorePoint = await gsIndexedDb.createOrUpdateSessionRestorePoint( - currentSession, - currentVersion + currentSession, + currentVersion ); } @@ -87,21 +87,20 @@ var gsSession = (function() { async function buildCurrentSession() { const currentWindows = await gsChrome.windowsGetAll(); const tabsExist = currentWindows.some( - window => window.tabs && window.tabs.length + window => window.tabs && window.tabs.length ); if (!tabsExist) { gsUtils.warning( - 'gsSession', - 'Failed to build current session. Could not find any tabs.' + 'gsSession', + 'Failed to build current session. Could not find any tabs.' ); return null; } - const currentSession = { + return { sessionId: getSessionId(), windows: currentWindows, date: new Date().toISOString(), }; - return currentSession; } async function updateCurrentSession() { @@ -197,33 +196,33 @@ var gsSession = (function() { async function performTabChecks() { const initStartTime = Date.now(); gsUtils.log( - 'gsSession', - '\n\n------------------------------------------------\n' + + 'gsSession', + '\n\n------------------------------------------------\n' + `Checking tabs for responsiveness..\n` + '------------------------------------------------\n\n' ); const postRecoverySessionTabs = await gsChrome.tabsQuery(); gsUtils.log( - 'gsSession', - 'postRecoverySessionTabs:', - postRecoverySessionTabs + 'gsSession', + 'postRecoverySessionTabs:', + postRecoverySessionTabs ); const tabCheckResults = await gsTabCheckManager.performInitialisationTabChecks( - postRecoverySessionTabs + postRecoverySessionTabs ); const totalTabCheckCount = tabCheckResults.length; const successfulTabChecksCount = tabCheckResults.filter( - o => o === gsUtils.STATUS_SUSPENDED || o === gsUtils.STATUS_DISCARDED + o => o === gsUtils.STATUS_SUSPENDED || o === gsUtils.STATUS_DISCARDED ).length; startupTabCheckTimeTakenInSeconds = parseInt( - (Date.now() - initStartTime) / 1000 + (Date.now() - initStartTime) / 1000 ); gsUtils.log( - 'gsSession', - '\n\n------------------------------------------------\n' + + 'gsSession', + '\n\n------------------------------------------------\n' + `Checking tabs finished. Time taken: ${startupTabCheckTimeTakenInSeconds} sec\n` + `${successfulTabChecksCount} / ${totalTabCheckCount} initialised successfully\n` + '------------------------------------------------\n\n' @@ -235,8 +234,8 @@ var gsSession = (function() { if (shouldRecoverTabs) { const lastExtensionRecoveryTimestamp = gsStorage.fetchLastExtensionRecoveryTimestamp(); const hasCrashedRecently = - lastExtensionRecoveryTimestamp && - Date.now() - lastExtensionRecoveryTimestamp < 1000 * 60 * 5; + lastExtensionRecoveryTimestamp && + Date.now() - lastExtensionRecoveryTimestamp < 1000 * 60 * 5; gsStorage.setLastExtensionRecoveryTimestamp(Date.now()); if (!hasCrashedRecently) { @@ -263,8 +262,8 @@ var gsSession = (function() { // If settings sync contains non-default options, then we can assume it's only // a new install for this computer if ( - !syncedSettingsOnInit || - Object.keys(syncedSettingsOnInit).length === 0 + !syncedSettingsOnInit || + Object.keys(syncedSettingsOnInit).length === 0 ) { //show welcome message const optionsUrl = chrome.extension.getURL('options.html?firstTime'); @@ -287,19 +286,19 @@ var gsSession = (function() { } const sessionRestorePoint = await gsIndexedDb.fetchSessionRestorePoint( - lastVersion + lastVersion ); if (!sessionRestorePoint) { const lastSession = await gsIndexedDb.fetchLastSession(); if (lastSession) { await gsIndexedDb.createOrUpdateSessionRestorePoint( - lastSession, - lastVersion + lastSession, + lastVersion ); } else { gsUtils.error( - 'gsSession', - 'No session restore point found, and no lastSession exists!' + 'gsSession', + 'No session restore point found, and no lastSession exists!' ); } } @@ -349,24 +348,24 @@ var gsSession = (function() { async function checkForCrashRecovery(currentSessionTabs) { gsUtils.log( - 'gsSession', - 'Checking for crash recovery: ' + new Date().toISOString() + 'gsSession', + 'Checking for crash recovery: ' + new Date().toISOString() ); //try to detect whether the extension has crashed as apposed to chrome restarting //if it is an extension crash, then in theory all suspended tabs will be gone //and all normal tabs will still exist with the same ids const currentSessionSuspendedTabs = currentSessionTabs.filter( - tab => !gsUtils.isSpecialTab(tab) && gsUtils.isSuspendedTab(tab) + tab => !gsUtils.isSpecialTab(tab) && gsUtils.isSuspendedTab(tab) ); const currentSessionNonExtensionTabs = currentSessionTabs.filter( - o => o.url.indexOf(chrome.runtime.id) === -1 + o => o.url.indexOf(chrome.runtime.id) === -1 ); if (currentSessionSuspendedTabs.length > 0) { gsUtils.log( - 'gsSession', - 'Aborting tab recovery. Browser has open suspended tabs.' + + 'gsSession', + 'Aborting tab recovery. Browser has open suspended tabs.' + ' Assuming user has "On start-up -> Continue where you left off" set' + ' or is restarting with suspended pinned tabs.' ); @@ -376,28 +375,28 @@ var gsSession = (function() { const lastSession = await gsIndexedDb.fetchLastSession(); if (!lastSession) { gsUtils.log( - 'gsSession', - 'Aborting tab recovery. Could not find last session.' + 'gsSession', + 'Aborting tab recovery. Could not find last session.' ); return false; } gsUtils.log('gsSession', 'lastSession: ', lastSession); const lastSessionTabs = lastSession.windows.reduce( - (a, o) => a.concat(o.tabs), - [] + (a, o) => a.concat(o.tabs), + [] ); const lastSessionSuspendedTabs = lastSessionTabs.filter(o => - gsUtils.isSuspendedTab(o) + gsUtils.isSuspendedTab(o) ); const lastSessionNonExtensionTabs = lastSessionTabs.filter( - o => o.url.indexOf(chrome.runtime.id) === -1 + o => o.url.indexOf(chrome.runtime.id) === -1 ); if (lastSessionSuspendedTabs.length === 0) { gsUtils.log( - 'gsSession', - 'Aborting tab recovery. Last session contained no suspended tabs.' + 'gsSession', + 'Aborting tab recovery. Last session contained no suspended tabs.' ); return false; } @@ -411,23 +410,23 @@ var gsSession = (function() { return lastSessionTabs.some(o => o.id === tab.id && o.url === tab.url); } const matchingTabIdsCount = currentSessionNonExtensionTabs.reduce( - (a, o) => (matchingTabExists(o) ? a + 1 : a), - 0 + (a, o) => (matchingTabExists(o) ? a + 1 : a), + 0 ); const maxMatchableTabsCount = Math.max( - lastSessionNonExtensionTabs.length, - currentSessionNonExtensionTabs.length + lastSessionNonExtensionTabs.length, + currentSessionNonExtensionTabs.length ); gsUtils.log( - 'gsSession', - matchingTabIdsCount + + 'gsSession', + matchingTabIdsCount + ' / ' + maxMatchableTabsCount + ' tabs have the same id between the last session and the current session.' ); if ( - matchingTabIdsCount === 0 || - maxMatchableTabsCount - matchingTabIdsCount > 1 + matchingTabIdsCount === 0 || + maxMatchableTabsCount - matchingTabIdsCount > 1 ) { gsUtils.log('gsSession', 'Aborting tab recovery. Tab IDs do not match.'); return false; @@ -444,8 +443,8 @@ var gsSession = (function() { const recoveryStartTime = Date.now(); gsUtils.log( - 'gsSession', - '\n\n------------------------------------------------\n' + + 'gsSession', + '\n\n------------------------------------------------\n' + 'Recovery mode started.\n' + '------------------------------------------------\n\n' ); @@ -454,8 +453,8 @@ var gsSession = (function() { const currentWindows = await gsChrome.windowsGetAll(); const matchedCurrentWindowBySessionWindowId = matchCurrentWindowsWithLastSessionWindows( - lastSession.windows, - currentWindows + lastSession.windows, + currentWindows ); //attempt to automatically restore any lost tabs/windows in their proper positions @@ -463,7 +462,7 @@ var gsSession = (function() { const lastFocusedWindowId = lastFocusedWindow ? lastFocusedWindow.id : null; for (let sessionWindow of lastSession.windows) { const matchedCurrentWindow = - matchedCurrentWindowBySessionWindowId[sessionWindow.id]; + matchedCurrentWindowBySessionWindowId[sessionWindow.id]; await restoreSessionWindow(sessionWindow, matchedCurrentWindow, 0); } if (lastFocusedWindowId) { @@ -471,11 +470,11 @@ var gsSession = (function() { } startupRecoveryTimeTakenInSeconds = parseInt( - (Date.now() - recoveryStartTime) / 1000 + (Date.now() - recoveryStartTime) / 1000 ); gsUtils.log( - 'gsSession', - '\n\n------------------------------------------------\n' + + 'gsSession', + '\n\n------------------------------------------------\n' + 'Recovery mode finished. Time taken: ' + startupRecoveryTimeTakenInSeconds + ' sec\n' + @@ -487,30 +486,30 @@ var gsSession = (function() { //try to match session windows with currently open windows function matchCurrentWindowsWithLastSessionWindows( - unmatchedSessionWindows, - unmatchedCurrentWindows + unmatchedSessionWindows, + unmatchedCurrentWindows ) { const matchedCurrentWindowBySessionWindowId = {}; //if there is a current window open that matches the id of the session window id then match it unmatchedSessionWindows.slice().forEach(function(sessionWindow) { const matchingCurrentWindow = unmatchedCurrentWindows.find(function( - window + window ) { return window.id === sessionWindow.id; }); if (matchingCurrentWindow) { matchedCurrentWindowBySessionWindowId[ - sessionWindow.id - ] = matchingCurrentWindow; + sessionWindow.id + ] = matchingCurrentWindow; //remove from unmatchedSessionWindows and unmatchedCurrentWindows unmatchedSessionWindows = unmatchedSessionWindows.filter(function( - window + window ) { return window.id !== sessionWindow.id; }); unmatchedCurrentWindows = unmatchedCurrentWindows.filter(function( - window + window ) { return window.id !== matchingCurrentWindow.id; }); @@ -518,68 +517,68 @@ var gsSession = (function() { }); if ( - unmatchedSessionWindows.length === 0 || - unmatchedCurrentWindows.length === 0 + unmatchedSessionWindows.length === 0 || + unmatchedCurrentWindows.length === 0 ) { return matchedCurrentWindowBySessionWindowId; } //if we still have session windows that haven't been matched to a current window then attempt matching based on tab urls let tabMatchingObjects = generateTabMatchingObjects( - unmatchedSessionWindows, - unmatchedCurrentWindows + unmatchedSessionWindows, + unmatchedCurrentWindows ); //find the tab matching objects with the highest tabMatchCounts while ( - unmatchedSessionWindows.length > 0 && - unmatchedCurrentWindows.length > 0 - ) { + unmatchedSessionWindows.length > 0 && + unmatchedCurrentWindows.length > 0 + ) { const maxTabMatchCount = Math.max( - ...tabMatchingObjects.map(function(o) { - return o.tabMatchCount; - }) + ...tabMatchingObjects.map(function(o) { + return o.tabMatchCount; + }) ); const bestTabMatchingObject = tabMatchingObjects.find(function(o) { return o.tabMatchCount === maxTabMatchCount; }); matchedCurrentWindowBySessionWindowId[ - bestTabMatchingObject.sessionWindow.id - ] = - bestTabMatchingObject.currentWindow; + bestTabMatchingObject.sessionWindow.id + ] = + bestTabMatchingObject.currentWindow; //remove from unmatchedSessionWindows and unmatchedCurrentWindows const unmatchedSessionWindowsLengthBefore = - unmatchedSessionWindows.length; + unmatchedSessionWindows.length; unmatchedSessionWindows = unmatchedSessionWindows.filter(function( - window + window ) { return window.id !== bestTabMatchingObject.sessionWindow.id; }); unmatchedCurrentWindows = unmatchedCurrentWindows.filter(function( - window + window ) { return window.id !== bestTabMatchingObject.currentWindow.id; }); gsUtils.log( - 'gsUtils', - 'Matched with tab count of ' + maxTabMatchCount + ': ', - bestTabMatchingObject.sessionWindow, - bestTabMatchingObject.currentWindow + 'gsUtils', + 'Matched with tab count of ' + maxTabMatchCount + ': ', + bestTabMatchingObject.sessionWindow, + bestTabMatchingObject.currentWindow ); //remove from tabMatchingObjects tabMatchingObjects = tabMatchingObjects.filter(function(o) { return ( - (o.sessionWindow !== bestTabMatchingObject.sessionWindow) & - (o.currentWindow !== bestTabMatchingObject.currentWindow) + (o.sessionWindow !== bestTabMatchingObject.sessionWindow) & + (o.currentWindow !== bestTabMatchingObject.currentWindow) ); }); //safety check to make sure we dont get stuck in infinite loop. should never happen though. if ( - unmatchedSessionWindows.length >= unmatchedSessionWindowsLengthBefore + unmatchedSessionWindows.length >= unmatchedSessionWindowsLengthBefore ) { break; } @@ -612,9 +611,9 @@ var gsSession = (function() { sessionWindows.forEach(function(sessionWindow) { currentWindows.forEach(function(currentWindow) { const unsuspendedSessionUrls = - unsuspendedSessionUrlsByWindowId[sessionWindow.id]; + unsuspendedSessionUrlsByWindowId[sessionWindow.id]; const unsuspendedCurrentUrls = - unsuspendedCurrentUrlsByWindowId[currentWindow.id]; + unsuspendedCurrentUrlsByWindowId[currentWindow.id]; const matchCount = unsuspendedCurrentUrls.filter(function(url) { return unsuspendedSessionUrls.includes(url); }).length; @@ -634,9 +633,9 @@ var gsSession = (function() { // 1: Open all unsuspended tabs as suspended // 2: Open all suspended tabs as unsuspended async function restoreSessionWindow( - sessionWindow, - existingWindow, - suspendMode + sessionWindow, + existingWindow, + suspendMode ) { if (sessionWindow.tabs.length === 0) { gsUtils.log('gsUtils', 'SessionWindow contains no tabs to restore'); @@ -645,10 +644,10 @@ var gsSession = (function() { // if we have been provided with a current window to recover into if (existingWindow) { gsUtils.log( - 'gsUtils', - 'Matched sessionWindow with existingWindow: ', - sessionWindow, - existingWindow + 'gsUtils', + 'Matched sessionWindow with existingWindow: ', + sessionWindow, + existingWindow ); const currentTabIds = []; const currentTabUrls = []; @@ -661,22 +660,22 @@ var gsSession = (function() { for (const [i, sessionTab] of sessionWindow.tabs.entries()) { //if current tab does not exist then recreate it if ( - !gsUtils.isSpecialTab(sessionTab) && - !currentTabUrls.includes(sessionTab.url) && - !currentTabIds.includes(sessionTab.id) + !gsUtils.isSpecialTab(sessionTab) && + !currentTabUrls.includes(sessionTab.url) && + !currentTabIds.includes(sessionTab.id) ) { tabPromises.push( - new Promise(async resolve => { - await gsUtils.setTimeout(i * 20); - // dont await createNewTab as we want them to happen concurrently (but staggered) - createNewTabFromSessionTab( - sessionTab, - existingWindow.id, - sessionTab.index, - suspendMode - ); - resolve(); - }) + new Promise(async resolve => { + await gsUtils.setTimeout(i * 20); + // dont await createNewTab as we want them to happen concurrently (but staggered) + createNewTabFromSessionTab( + sessionTab, + existingWindow.id, + sessionTab.index, + suspendMode + ); + resolve(); + }) ); } } @@ -686,9 +685,9 @@ var gsSession = (function() { // else restore entire window gsUtils.log( - 'gsUtils', - 'Could not find match for sessionWindow: ', - sessionWindow + 'gsUtils', + 'Could not find match for sessionWindow: ', + sessionWindow ); const restoringUrl = chrome.extension.getURL('restoring-window.html'); @@ -697,8 +696,8 @@ var gsSession = (function() { // out the GPU memory in the chrome task manager // TODO: Report chrome bug const newWindow = await gsUtils.createWindowAndWaitForFinishLoading( - { url: restoringUrl, focused: false }, - 500 // dont actually wait + { url: restoringUrl, focused: false }, + 500 // dont actually wait ); const placeholderTab = newWindow.tabs[0]; await gsChrome.tabsUpdate(placeholderTab.id, { pinned: true }); @@ -706,17 +705,17 @@ var gsSession = (function() { const tabPromises = []; for (const [i, sessionTab] of sessionWindow.tabs.entries()) { tabPromises.push( - new Promise(async resolve => { - await gsUtils.setTimeout(i * (1000 / tabsToRestorePerSecond)); - // dont await createNewTab as we want them to happen concurrently (but staggered) - createNewTabFromSessionTab( - sessionTab, - newWindow.id, - i + 1, - suspendMode - ); - resolve(); - }) + new Promise(async resolve => { + await gsUtils.setTimeout(i * (1000 / tabsToRestorePerSecond)); + // dont await createNewTab as we want them to happen concurrently (but staggered) + createNewTabFromSessionTab( + sessionTab, + newWindow.id, + i + 1, + suspendMode + ); + resolve(); + }) ); } await Promise.all(tabPromises); @@ -726,10 +725,10 @@ var gsSession = (function() { } async function createNewTabFromSessionTab( - sessionTab, - windowId, - index, - suspendMode + sessionTab, + windowId, + index, + suspendMode ) { let url = sessionTab.url; if (suspendMode === 1 && gsUtils.isNormalTab(sessionTab)) { @@ -751,58 +750,10 @@ var gsSession = (function() { } } - async function updateSessionMetrics(reset) { - reset = reset || false; - - const tabs = await gsChrome.tabsQuery(); - let curSuspendedTabCount = 0; - for (let tab of tabs) { - if (gsUtils.isSuspendedTab(tab)) { - curSuspendedTabCount += 1; - } - } - let sessionMetrics; - if (reset) { - gsUtils.log('gsSession', 'Resetting session metrics'); - } else { - sessionMetrics = gsStorage.fetchSessionMetrics(); - } - - // If no session metrics exist then create a new one - if (!sessionMetrics || !sessionMetrics[gsStorage.SM_TIMESTAMP]) { - sessionMetrics = createNewSessionMetrics( - curSuspendedTabCount, - tabs.length - ); - gsStorage.setSessionMetrics(sessionMetrics); - gsUtils.log('gsSession', 'Created new session metrics', sessionMetrics); - return; - } - - // Else update metrics (if new max reached) - const lastSuspendedTabCount = - sessionMetrics[gsStorage.SM_SUSPENDED_TAB_COUNT]; - if (lastSuspendedTabCount < curSuspendedTabCount) { - sessionMetrics[gsStorage.SM_SUSPENDED_TAB_COUNT] = curSuspendedTabCount; - sessionMetrics[gsStorage.SM_TOTAL_TAB_COUNT] = tabs.length; - gsStorage.setSessionMetrics(sessionMetrics); - gsUtils.log('gsSession', 'Updated session metrics', sessionMetrics); - } - } - - function createNewSessionMetrics(suspendedTabCount, totalTabCount) { - const sessionMetrics = { - [gsStorage.SM_TIMESTAMP]: Date.now(), - [gsStorage.SM_SUSPENDED_TAB_COUNT]: suspendedTabCount, - [gsStorage.SM_TOTAL_TAB_COUNT]: totalTabCount, - }; - return sessionMetrics; - } - async function unsuspendActiveTabInEachWindow() { const activeTabs = await gsChrome.tabsQuery({ active: true }); const suspendedActiveTabs = activeTabs.filter(tab => - gsUtils.isSuspendedTab(tab) + gsUtils.isSuspendedTab(tab) ); if (suspendedActiveTabs.length === 0) { return; @@ -833,7 +784,6 @@ var gsSession = (function() { restoreSessionWindow, prepareForUpdate, getUpdateType, - updateSessionMetrics, unsuspendActiveTabInEachWindow, }; })(); diff --git a/src/js/gsStorage.js b/src/js/gsStorage.js index 4037868e..58c06886 100755 --- a/src/js/gsStorage.js +++ b/src/js/gsStorage.js @@ -28,14 +28,10 @@ var gsStorage = { LAST_NOTICE: 'gsNotice', LAST_EXTENSION_RECOVERY: 'gsExtensionRecovery', - SM_SESSION_METRICS: 'gsSessionMetrics', - SM_TIMESTAMP: 'sessionTimestamp', - SM_SUSPENDED_TAB_COUNT: 'suspendedTabCount', - SM_TOTAL_TAB_COUNT: 'totalTabCount', - - noop: function() {}, + noop: function () { + }, - getSettingsDefaults: function() { + getSettingsDefaults: function () { const defaults = {}; defaults[gsStorage.SCREEN_CAPTURE] = '0'; defaults[gsStorage.SCREEN_CAPTURE_FORCE] = false; @@ -66,11 +62,11 @@ var gsStorage = { */ //populate localstorage settings with sync settings where undefined - initSettingsAsPromised: function() { - return new Promise(function(resolve) { + initSettingsAsPromised: function () { + return new Promise(function (resolve) { var defaultSettings = gsStorage.getSettingsDefaults(); var defaultKeys = Object.keys(defaultSettings); - chrome.storage.sync.get(defaultKeys, function(syncedSettings) { + chrome.storage.sync.get(defaultKeys, function (syncedSettings) { gsUtils.log('gsStorage', 'syncedSettings on init: ', syncedSettings); gsSession.setSynchedSettingsOnInit(syncedSettings); @@ -79,9 +75,9 @@ var gsStorage = { rawLocalSettings = JSON.parse(localStorage.getItem('gsSettings')); } catch (e) { gsUtils.error( - 'gsStorage', - 'Failed to parse gsSettings: ', - localStorage.getItem('gsSettings') + 'gsStorage', + 'Failed to parse gsSettings: ', + localStorage.getItem('gsSettings') ); } if (!rawLocalSettings) { @@ -90,7 +86,7 @@ var gsStorage = { //if we have some rawLocalSettings but SYNC_SETTINGS is not defined //then define it as FALSE (as opposed to default of TRUE) rawLocalSettings[gsStorage.SYNC_SETTINGS] = - rawLocalSettings[gsStorage.SYNC_SETTINGS] || false; + rawLocalSettings[gsStorage.SYNC_SETTINGS] || false; } gsUtils.log('gsStorage', 'localSettings on init: ', rawLocalSettings); var shouldSyncSettings = rawLocalSettings[gsStorage.SYNC_SETTINGS]; @@ -102,17 +98,17 @@ var gsStorage = { mergedSettings[key] = false; } else { mergedSettings[key] = rawLocalSettings.hasOwnProperty(key) - ? rawLocalSettings[key] - : defaultSettings[key]; + ? rawLocalSettings[key] + : defaultSettings[key]; } continue; } // If nags are disabled locally, then ensure we disable them on synced profile if ( - key === gsStorage.NO_NAG && - shouldSyncSettings && - rawLocalSettings.hasOwnProperty(gsStorage.NO_NAG) && - rawLocalSettings[gsStorage.NO_NAG] + key === gsStorage.NO_NAG && + shouldSyncSettings && + rawLocalSettings.hasOwnProperty(gsStorage.NO_NAG) && + rawLocalSettings[gsStorage.NO_NAG] ) { mergedSettings[gsStorage.NO_NAG] = true; continue; @@ -120,8 +116,8 @@ var gsStorage = { // if synced setting exists and local setting does not exist or // syncing is enabled locally then overwrite with synced value if ( - syncedSettings.hasOwnProperty(key) && - (!rawLocalSettings.hasOwnProperty(key) || shouldSyncSettings) + syncedSettings.hasOwnProperty(key) && + (!rawLocalSettings.hasOwnProperty(key) || shouldSyncSettings) ) { mergedSettings[key] = syncedSettings[key]; } @@ -131,12 +127,12 @@ var gsStorage = { } //fallback on defaultSettings if ( - typeof mergedSettings[key] === 'undefined' || - mergedSettings[key] === null + typeof mergedSettings[key] === 'undefined' || + mergedSettings[key] === null ) { gsUtils.errorIfInitialised( - 'gsStorage', - 'Missing key: ' + key + '! Will init with default.' + 'gsStorage', + 'Missing key: ' + key + '! Will init with default.' ); mergedSettings[key] = defaultSettings[key]; } @@ -148,8 +144,8 @@ var gsStorage = { var triggerResync = false; for (const key of defaultKeys) { if ( - key !== gsStorage.SYNC_SETTINGS && - syncedSettings[key] !== mergedSettings[key] + key !== gsStorage.SYNC_SETTINGS && + syncedSettings[key] !== mergedSettings[key] ) { triggerResync = true; } @@ -165,8 +161,8 @@ var gsStorage = { }, // Listen for changes to synced settings - addSettingsSyncListener: function() { - chrome.storage.onChanged.addListener(function(remoteSettings, namespace) { + addSettingsSyncListener: function () { + chrome.storage.onChanged.addListener(function (remoteSettings, namespace) { if (namespace !== 'sync' || !remoteSettings) { return; } @@ -176,7 +172,7 @@ var gsStorage = { var changedSettingKeys = []; var oldValueBySettingKey = {}; var newValueBySettingKey = {}; - Object.keys(remoteSettings).forEach(function(key) { + Object.keys(remoteSettings).forEach(function (key) { var remoteSetting = remoteSettings[key]; // If nags are disabled locally, then ensure we disable them on synced profile @@ -188,10 +184,10 @@ var gsStorage = { if (localSettings[key] !== remoteSetting.newValue) { gsUtils.log( - 'gsStorage', - 'Changed value from sync', - key, - remoteSetting.newValue + 'gsStorage', + 'Changed value from sync', + key, + remoteSetting.newValue ); changedSettingKeys.push(key); oldValueBySettingKey[key] = localSettings[key]; @@ -203,9 +199,9 @@ var gsStorage = { if (changedSettingKeys.length > 0) { gsStorage.saveSettings(localSettings); gsUtils.performPostSaveUpdates( - changedSettingKeys, - oldValueBySettingKey, - newValueBySettingKey + changedSettingKeys, + oldValueBySettingKey, + newValueBySettingKey ); } } @@ -214,7 +210,7 @@ var gsStorage = { //due to migration issues and new settings being added, i have built in some redundancy //here so that getOption will always return a valid value. - getOption: function(prop) { + getOption: function (prop) { var settings = gsStorage.getSettings(); if (typeof settings[prop] === 'undefined' || settings[prop] === null) { settings[prop] = gsStorage.getSettingsDefaults()[prop]; @@ -223,7 +219,7 @@ var gsStorage = { return settings[prop]; }, - setOption: function(prop, value) { + setOption: function (prop, value) { var settings = gsStorage.getSettings(); settings[prop] = value; // gsUtils.log('gsStorage', 'gsStorage', 'setting prop: ' + prop + ' to value ' + value); @@ -234,20 +230,20 @@ var gsStorage = { // syncSettings saves to chrome.storage. // Calling syncSettings has the unfortunate side-effect of triggering the chrome.storage.onChanged // listener which the re-saves the setting to localStorage a second time. - setOptionAndSync: function(prop, value) { + setOptionAndSync: function (prop, value) { gsStorage.setOption(prop, value); gsStorage.syncSettings(); }, - getSettings: function() { + getSettings: function () { var settings; try { settings = JSON.parse(localStorage.getItem('gsSettings')); } catch (e) { gsUtils.error( - 'gsStorage', - 'Failed to parse gsSettings: ', - localStorage.getItem('gsSettings') + 'gsStorage', + 'Failed to parse gsSettings: ', + localStorage.getItem('gsSettings') ); } if (!settings) { @@ -257,155 +253,111 @@ var gsStorage = { return settings; }, - saveSettings: function(settings) { + saveSettings: function (settings) { try { localStorage.setItem('gsSettings', JSON.stringify(settings)); } catch (e) { gsUtils.error( - 'gsStorage', - 'failed to save gsSettings to local storage', - e + 'gsStorage', + 'failed to save gsSettings to local storage', + e ); } }, // Push settings to sync - syncSettings: function() { + syncSettings: function () { var settings = gsStorage.getSettings(); if (settings[gsStorage.SYNC_SETTINGS]) { // Since sync is a local setting, delete it to simplify things. delete settings[gsStorage.SYNC_SETTINGS]; gsUtils.log( - 'gsStorage', - 'gsStorage', - 'Pushing local settings to sync', - settings + 'gsStorage', + 'gsStorage', + 'Pushing local settings to sync', + settings ); chrome.storage.sync.set(settings, () => { if (chrome.runtime.lastError) { gsUtils.error( - 'gsStorage', - 'failed to save to chrome.storage.sync: ', - chrome.runtime.lastError + 'gsStorage', + 'failed to save to chrome.storage.sync: ', + chrome.runtime.lastError ); } }); } }, - fetchLastVersion: function() { + fetchLastVersion: function () { var version; try { version = JSON.parse(localStorage.getItem(gsStorage.APP_VERSION)); } catch (e) { gsUtils.error( - 'gsStorage', - 'Failed to parse ' + gsStorage.APP_VERSION + ': ', - localStorage.getItem(gsStorage.APP_VERSION) + 'gsStorage', + 'Failed to parse ' + gsStorage.APP_VERSION + ': ', + localStorage.getItem(gsStorage.APP_VERSION) ); } version = version || '0.0.0'; return version + ''; }, - setLastVersion: function(newVersion) { + + setLastVersion: function (newVersion) { try { localStorage.setItem(gsStorage.APP_VERSION, JSON.stringify(newVersion)); } catch (e) { gsUtils.error( - 'gsStorage', - 'failed to save ' + gsStorage.APP_VERSION + ' to local storage', - e + 'gsStorage', + 'failed to save ' + gsStorage.APP_VERSION + ' to local storage', + e ); } }, - fetchNoticeVersion: function() { - var lastNoticeVersion; - try { - lastNoticeVersion = JSON.parse( - localStorage.getItem(gsStorage.LAST_NOTICE) - ); - } catch (e) { - gsUtils.error( - 'gsStorage', - 'Failed to parse ' + gsStorage.LAST_NOTICE + ': ', - localStorage.getItem(gsStorage.LAST_NOTICE) - ); - } - lastNoticeVersion = lastNoticeVersion || '0'; - return lastNoticeVersion + ''; - }, - setNoticeVersion: function(newVersion) { + setNoticeVersion: function (newVersion) { try { localStorage.setItem(gsStorage.LAST_NOTICE, JSON.stringify(newVersion)); } catch (e) { gsUtils.error( - 'gsStorage', - 'failed to save ' + gsStorage.LAST_NOTICE + ' to local storage', - e + 'gsStorage', + 'failed to save ' + gsStorage.LAST_NOTICE + ' to local storage', + e ); } }, - fetchLastExtensionRecoveryTimestamp: function() { + fetchLastExtensionRecoveryTimestamp: function () { var lastExtensionRecoveryTimestamp; try { lastExtensionRecoveryTimestamp = JSON.parse( - localStorage.getItem(gsStorage.LAST_EXTENSION_RECOVERY) + localStorage.getItem(gsStorage.LAST_EXTENSION_RECOVERY) ); } catch (e) { gsUtils.error( - 'gsStorage', - 'Failed to parse ' + gsStorage.LAST_EXTENSION_RECOVERY + ': ', - localStorage.getItem(gsStorage.LAST_EXTENSION_RECOVERY) + 'gsStorage', + 'Failed to parse ' + gsStorage.LAST_EXTENSION_RECOVERY + ': ', + localStorage.getItem(gsStorage.LAST_EXTENSION_RECOVERY) ); } return lastExtensionRecoveryTimestamp; }, - setLastExtensionRecoveryTimestamp: function(extensionRecoveryTimestamp) { + setLastExtensionRecoveryTimestamp: function (extensionRecoveryTimestamp) { try { localStorage.setItem( - gsStorage.LAST_EXTENSION_RECOVERY, - JSON.stringify(extensionRecoveryTimestamp) + gsStorage.LAST_EXTENSION_RECOVERY, + JSON.stringify(extensionRecoveryTimestamp) ); } catch (e) { gsUtils.error( - 'gsStorage', - 'failed to save ' + + 'gsStorage', + 'failed to save ' + gsStorage.LAST_EXTENSION_RECOVERY + ' to local storage', - e + e ); } }, - fetchSessionMetrics: function() { - var sessionMetrics = {}; - try { - sessionMetrics = JSON.parse( - localStorage.getItem(gsStorage.SM_SESSION_METRICS) - ); - } catch (e) { - gsUtils.error( - 'gsStorage', - 'Failed to parse ' + gsStorage.SM_SESSION_METRICS + ': ', - localStorage.getItem(gsStorage.SM_SESSION_METRICS) - ); - } - return sessionMetrics; - }, - setSessionMetrics: function(sessionMetrics) { - try { - localStorage.setItem( - gsStorage.SM_SESSION_METRICS, - JSON.stringify(sessionMetrics) - ); - } catch (e) { - gsUtils.error( - 'gsStorage', - 'failed to save ' + gsStorage.SM_SESSION_METRICS + ' to local storage', - e - ); - } - }, }; diff --git a/src/manifest.json b/src/manifest.json index f2badfc4..0692b88f 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -8,23 +8,42 @@ "storage", "history", "unlimitedStorage", - "http://*/*", - "https://*/*", - "file://*/*", "chrome://favicon/*", "contextMenus", - "cookies" + "cookies", + "http://*/*", + "https://*/*", + "file://*/*" ], "background": { - "scripts": ["js/gsUtils.js", "js/gsChrome.js", "js/gsStorage.js", "js/db.js", "js/gsIndexedDb.js", - "js/gsMessages.js", "js/gsSession.js", "js/gsTabQueue.js", "js/gsTabCheckManager.js", "js/gsFavicon.js", - "js/gsTabSuspendManager.js", "js/gsTabDiscardManager.js", "js/gsSuspendedTab.js", "js/background.js"], + "scripts": [ + "js/gsUtils.js", + "js/gsChrome.js", + "js/gsStorage.js", + "js/db.js", + "js/gsIndexedDb.js", + "js/gsMessages.js", + "js/gsSession.js", + "js/gsTabQueue.js", + "js/gsTabCheckManager.js", + "js/gsFavicon.js", + "js/gsTabSuspendManager.js", + "js/gsTabDiscardManager.js", + "js/gsSuspendedTab.js", + "js/background.js" + ], "persistent": true }, "content_scripts": [ { - "matches": ["http://*/*", "https://*/*", "file://*/*"], - "js": ["js/contentscript.js"] + "matches": [ + "http://*/*", + "https://*/*", + "file://*/*" + ], + "js": [ + "js/contentscript.js" + ] } ], "browser_action": { @@ -42,16 +61,19 @@ "48": "img/ic_suspendy_48x48.png", "128": "img/ic_suspendy_128x128.png" }, - "web_accessible_resources": ["suspended.html"], + "web_accessible_resources": [ + "suspended.html" + ], "content_security_policy": "script-src 'self'; object-src 'self'; child-src 'self'; connect-src 'self'; img-src 'self' data: chrome:; style-src 'self'; default-src 'self'", "incognito": "split", "manifest_version": 2, "minimum_chrome_version": "55", - "commands": { "1-suspend-tab": { "description": "__MSG_ext_cmd_toggle_tab_suspension_description__", - "suggested_key": { "default": "Ctrl+Shift+S" } + "suggested_key": { + "default": "Ctrl+Shift+S" + } }, "2-toggle-temp-whitelist-tab": { "description": "__MSG_ext_cmd_toggle_tab_pause_description__"