diff --git a/source/js/functions.js b/source/js/functions.js index a2303b1..101e640 100644 --- a/source/js/functions.js +++ b/source/js/functions.js @@ -2,7 +2,6 @@ const BADGE_BACKGROUND_COLOR = '#d73f31'; const OPTIONS_VERSION = 3; // Increment when there are new options -let refreshTimeout; let last_unread_count = 0; let notificationTimeout; let retryCount = 0; @@ -146,7 +145,10 @@ function updateIcon(count) { last_unread_count = countInt; } -function getCountersFromHTTP() { +function getCountersFromHTTP(Alarm) { + // if invoked by Alarm: check if it's 'refreshAlarm' + if (Alarm && Alarm.name != 'refreshAlarm') { return; } + // If request times out or if we get unexpected output, report error and reschedule function refreshFailed(details) { window.clearTimeout(requestTimeout); @@ -206,6 +208,8 @@ function getCountersFromHTTP() { } function scheduleRefresh() { +/* + // old code let interval = (localStorage.refresh_interval || 15) * 60 * 1000; window.clearTimeout(refreshTimeout); if (retryCount) { // There was an error @@ -213,6 +217,24 @@ function scheduleRefresh() { // 0:05 -> 0:10 -> 0:20 -> 0:40 -> 1:20 -> 2:40 -> 5:20 -> ... } refreshTimeout = window.setTimeout(getCountersFromHTTP, interval); +*/ + let interval = +(localStorage.refresh_interval || 15); + /* + // there's no need to clear alarm before setting new with the same name + chrome.alarms.clear('refreshAlarm'); //chrome.alarms.clear(string name, function callback); + */ + if (retryCount) { // There was an error + interval = Math.min( interval, Math.max(1, retryCount-2)); + // 1:00 -> 1:00 -> 1:00 -> 2:00 -> 3:00 -> 4:00 -> 5:00 -> ... + // chrome alarms cannot go off more frequently than every 1 minute + /* we can think of making errors retries with window.setTimeout */ + } + chrome.alarms.onAlarm.addListener(getCountersFromHTTP); //chrome.alarms.onAlarm.addListener(function callback) + chrome.alarms.create('refreshAlarm', {delayInMinutes:interval}); //chrome.alarms.create(string name, object alarmInfo) + /* + // delayInMinutes runs fn once, after delay; periodInMinutes runs periodically + chrome.alarms.create('refreshAlarm', {periodInMinutes:interval}); //chrome.alarms.create(string name, object alarmInfo) + */ } /* exported onMessage */ diff --git a/source/js/menu.js b/source/js/menu.js index a55a5c1..2f85802 100644 --- a/source/js/menu.js +++ b/source/js/menu.js @@ -2,10 +2,11 @@ function addContentMenus() { // add button context menu chrome.contextMenus.create({ + id: "browserActionContextMenu", title: chrome.i18n.getMessage('button_contextMenu_updateFromServerNow'), contexts: ['browser_action'], - onclick: getCountersFromHTTP, }); + contextMenuListener.assignFunctionToMenu('browserActionContextMenu', getCountersFromHTTP); chrome.contextMenus.create( {title: "The Old Reader", id: "root", contexts: ["page"]} @@ -50,11 +51,11 @@ function addContentMenus() { id: "subscribe", parentId: "root", contexts: ["page"], - onclick: function(info, tab) { + }); + contextMenuListener.assignFunctionToMenu('subscribe', function(info, tab) { chrome.tabs.create({ url: baseUrl() + "feeds/subscribe?url=" + encodeURIComponent(tab.url) }); - } }); chrome.contextMenus.create({ @@ -62,21 +63,35 @@ function addContentMenus() { id: "bookmarkPage", parentId: "root", contexts: ["page"], - onclick: function(info) { + }); + contextMenuListener.assignFunctionToMenu('bookmarkPage', function(info) { bookmark(info.pageUrl); - } }); chrome.contextMenus.create({ title: chrome.i18n.getMessage('contextMenu_bookmarkSelection'), id: "bookmarkSelection", contexts: ["selection"], - onclick: function(info) { + }); + contextMenuListener.assignFunctionToMenu('bookmarkSelection', function(info) { bookmark(info.pageUrl, info.selectionText); - } }); } +let contextMenuListener = { + assignFunctionToMenu: function (id, fn){ // assigns fn to id of a contextMenu and stores inside this object + if (id === undefined || fn === undefined) { return; } + this[id] = fn; + }, + call: function (info, tab){ // calls stored fn depending on menuItemId which fired the onclick event + if (this[info.menuItemId]) { + this[info.menuItemId](info, tab); + } + } +} + +chrome.contextMenus.onClicked.addListener(contextMenuListener.call); + function toggleContentMenus(state) { if (state == 'no') { chrome.contextMenus.removeAll(); diff --git a/source/js/storage.js b/source/js/storage.js index 5e5c847..28cc038 100644 --- a/source/js/storage.js +++ b/source/js/storage.js @@ -10,13 +10,13 @@ function loadFromStorage() { }); } -let syncRetryTimeout; +let syncRetry; /* exported saveToStorage */ function saveToStorage(callback) { if (localStorage.use_sync == "no") { return; } - if (syncRetryTimeout) { + if (syncRetry) { console.log("Already waiting for a sync attempt, throttling request"); if (callback) { callback(false); } return; @@ -37,16 +37,29 @@ function retryOnError(retryFunction, callback) { console.warn("Will retry in a minute due to ", chrome.runtime.lastError.message); if (callback) { callback(false); } - syncRetryTimeout = window.setTimeout(function() { - syncRetryTimeout = null; + /* + // old code + syncRetry = window.setTimeout(function() { + syncRetry = null; retryFunction(); }, 60 * 1000); + */ + // transition to chrome.alarms instead of window.setTimeout + syncRetry = true; + chrome.alarms.onAlarm.addListener(retryOnErrorAlarmFn.bind(null, retryFunction)); + chrome.alarms.create('retryAlarm', {delayInMinutes:1}); } else { if (callback) { callback(true); } } }; } +// required if (see above) transition to chrome.alarms instead of window.setTimeout +function retryOnErrorAlarmFn(retryFunction, Alarm) { + if (Alarm.name != 'retryAlarm') { return; } + syncRetry = null; + retryFunction(); +} /* exported onStorageChange */ function onStorageChange(changes, area) { diff --git a/source/manifest-chrome.json b/source/manifest-chrome.json index 2b4befd..ba586e7 100644 --- a/source/manifest-chrome.json +++ b/source/manifest-chrome.json @@ -9,7 +9,8 @@ "128": "img/icon-128.png" }, "background": { - "scripts": [ "js/functions.js", "js/storage.js", "js/background.js", "js/menu.js" ] + "scripts": [ "js/functions.js", "js/storage.js", "js/background.js", "js/menu.js" ], + "persistent": false }, "browser_action": { "default_icon": { @@ -19,10 +20,11 @@ "default_title": "The Old Reader" }, "permissions": [ - "tabs", + "alarms", + "contextMenus", "notifications", + "tabs", "storage", - "contextMenus", "*://theoldreader.com/" ], "web_accessible_resources": [