Skip to content

Commit

Permalink
Switch localStorage to chrome.storage.local.
Browse files Browse the repository at this point in the history
  • Loading branch information
dstein64 committed Feb 24, 2022
1 parent bf0bc04 commit 0d92b5f
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 105 deletions.
4 changes: 2 additions & 2 deletions manifest.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"name": "Auto Highlight",
"version": "3.4.9",
"version": "3.4.10",
"description": "*Auto Highlight* automatically highlights the important content on article pages.",
"options_ui": {
"page": "src/options/options.html"
},
"permissions": ["activeTab", "contextMenus"],
"permissions": ["activeTab", "contextMenus", "storage"],
"optional_permissions": ["<all_urls>", "tabs", "clipboardWrite"],
"background": {
"scripts": ["src/utils.js", "src/matchPattern.js", "src/eventPage.js"],
Expand Down
5 changes: 3 additions & 2 deletions src/content.js
Original file line number Diff line number Diff line change
Expand Up @@ -1341,8 +1341,9 @@ chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
const method = request.method;
if (method === 'highlight') {
if (compatibleDocument(document)) {
chrome.runtime.sendMessage({message: 'getOptions'}, function (response) {
const options = response;
chrome.storage.local.get(['options'], (storage) => {
const options = storage.options;
if (!options) return;
chrome.runtime.sendMessage({message: 'getParams'}, function (response) {
const params = response;
const highlightState = request.highlightState;
Expand Down
153 changes: 84 additions & 69 deletions src/eventPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,19 +67,9 @@ function getPermissions(scope) {
}
}

// This is called from options.js (see scope warning above).
function getOptions() {
// Don't check for permissions here, in order to keep the funtion synchronous.
let opts = localStorage['options'];
if (opts) {
opts = JSON.parse(opts);
}
return opts;
}

// This is called from options.js (see scope warning above).
// Saves options (asynchronously).
function saveOptions(options, callback=null) {
function saveOptions(options, callback=function() {}) {
// Deep copy so this function is not destructive.
options = JSON.parse(JSON.stringify(options));
// Disable autonomous highlighting if its required permissions were
Expand All @@ -89,14 +79,17 @@ function saveOptions(options, callback=null) {
function(result) {
if (!result)
options.autonomous_highlights = false;
// Don't save if there are no changes (to prevent 'storage' event listeners
// from responding when they don't need to).
// XXX: The comparison will fail if the keys are in different order.
const json = JSON.stringify(options);
if (json !== localStorage['options'])
localStorage['options'] = JSON.stringify(options);
if (callback !== null)
callback();
chrome.storage.local.get(['options'], function(storage) {
const json = JSON.stringify(storage.options);
// Don't save if there are no changes (to prevent 'storage' event listeners
// from responding when they don't need to).
// XXX: The comparison will fail if the keys are in different order.
if (JSON.stringify(storage.options) !== JSON.stringify(options)) {
chrome.storage.local.set({options: options}, callback);
} else {
callback();
}
});
});
}

Expand All @@ -122,38 +115,55 @@ function defaultOptions() {
}

// Validate options
(function() {
let opts = getOptions();
if (!opts) {
opts = Object.create(null);
}
const validateOptions = function() {
chrome.storage.local.get({options: {}}, function(result) {
let opts = result.options;
if (!opts) {
opts = Object.create(null);
}

const defaults = defaultOptions();
const defaults = defaultOptions();

// Set missing options using defaults.
const default_keys = Object.keys(defaults);
for (let i = 0; i < default_keys.length; i++) {
const default_key = default_keys[i];
if (!(default_key in opts)) {
opts[default_key] = defaults[default_key];
// Set missing options using defaults.
const default_keys = Object.keys(defaults);
for (let i = 0; i < default_keys.length; i++) {
const default_key = default_keys[i];
if (!(default_key in opts)) {
opts[default_key] = defaults[default_key];
}
}
}

// Remove unknown options (these may have been set
// by previous versions of the extension).
const opt_keys = Object.keys(opts);
for (let i = 0; i < opt_keys.length; i++) {
const opt_key = opt_keys[i];
if (!(opt_key in defaults)) {
delete opts[opt_key];
// Remove unknown options (these may have been set
// by previous versions of the extension).
const opt_keys = Object.keys(opts);
for (let i = 0; i < opt_keys.length; i++) {
const opt_key = opt_keys[i];
if (!(opt_key in defaults)) {
delete opts[opt_key];
}
}
}

// Convert invalid settings to valid settings.
if (![...Array(NUM_HIGHLIGHT_STATES).keys()].includes(opts.autonomous_state))
opts.autonomous_state = defaults['autonomous_state'];
// Convert invalid settings to valid settings.
if (![...Array(NUM_HIGHLIGHT_STATES).keys()].includes(opts.autonomous_state))
opts.autonomous_state = defaults['autonomous_state'];

saveOptions(opts);
saveOptions(opts);
});
};

(function() {
if ('options' in localStorage) {
// If there are localStorage options, transfer them to chrome.storage.local.
// TODO: This can eventually be removed, at which point the validateOptions()
// function should be deleted, and its code moved here.
let opts = localStorage['options'];
localStorage.clear();
chrome.storage.local.set({options: JSON.parse(opts)}, function() {
validateOptions();
});
} else {
validateOptions();
}
})();

// *****************************
Expand Down Expand Up @@ -223,8 +233,6 @@ chrome.runtime.onMessage.addListener(function(request, sender, response) {
response({
'curHighlight': highlightState.highlight,
'curSuccess': highlightState.success});
} else if (message === 'getOptions') {
response(getOptions());
} else if (message === 'getParams') {
response({'numHighlightStates': NUM_HIGHLIGHT_STATES});
} else if (message === 'copyText') {
Expand Down Expand Up @@ -347,17 +355,20 @@ chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
}
return false;
};
const options = getOptions();
if (options.autonomous_highlights && changeInfo.status === 'complete') {
if (options.autonomous_blocklist) {
const url = tab.url;
if (url === undefined) return;
const exception = url_matches(url, options.autonomous_blocklist_exceptions);
if (!exception && url_matches(url, options.autonomous_blocklist_items))
return;
chrome.storage.local.get(['options'], (storage) => {
const options = storage.options;
if (options.autonomous_highlights && changeInfo.status === 'complete') {
if (options.autonomous_blocklist) {
const url = tab.url;
if (url === undefined) return;
const exception = url_matches(url, options.autonomous_blocklist_exceptions);
if (!exception && url_matches(url, options.autonomous_blocklist_items))
return;
}
highlight(
tab.id, false, options.autonomous_state, 'document_idle', options.autonomous_delay);
}
highlight(tab.id, false, options.autonomous_state, 'document_idle', options.autonomous_delay);
}
});
});

// This is called from options.js (see scope warning above).
Expand All @@ -374,8 +385,10 @@ chrome.browserAction.onClicked.addListener(function(tab) {
});

chrome.permissions.onRemoved.addListener(function() {
// saveOptions() handles the check for missing permissions.
saveOptions(getOptions());
chrome.storage.local.get(['options'], (storage) => {
// saveOptions() handles the check for missing permissions.
saveOptions(storage.options);
});
});

// *****************************
Expand Down Expand Up @@ -632,17 +645,19 @@ chrome.permissions.onRemoved.addListener(function() {
} else {
throw new Error('Unhandled item type: ' + item_type);
}
const options = getOptions();
let key;
if (target === 'blocklist') {
key = 'autonomous_blocklist_items';
} else if (target === 'exception') {
key = 'autonomous_blocklist_exceptions';
} else {
throw new Error('Unhandled target: ' + target);
}
options[key].push(item);
saveOptions(options);
chrome.storage.local.get(['options'], (storage) => {
const options = storage.options;
let key;
if (target === 'blocklist') {
key = 'autonomous_blocklist_items';
} else if (target === 'exception') {
key = 'autonomous_blocklist_exceptions';
} else {
throw new Error('Unhandled target: ' + target);
}
options[key].push(item);
saveOptions(options);
});
} else {
throw new Error('Unhandled menu ID: ' + id);
}
Expand Down
72 changes: 40 additions & 32 deletions src/options/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -221,10 +221,12 @@ const populateBlocklistTable = function(opts) {
};
autonomousBlocklistNewInput.value = '';
const list_source = autonomousBlocklistView.getAttribute('data-list-source');
const opts = backgroundPage.getOptions();
const key = 'autonomous_blocklist_' + list_source;
opts[key].push(item);
backgroundPage.saveOptions(opts);
chrome.storage.local.get(['options'], (storage) => {
const opts = storage.options;
const key = 'autonomous_blocklist_' + list_source;
opts[key].push(item);
backgroundPage.saveOptions(opts);
});
};

autonomousBlocklistNew.addEventListener('submit', function (e) {
Expand All @@ -238,8 +240,6 @@ const populateBlocklistTable = function(opts) {
* Options Form
***********************************/

const initOpts = backgroundPage.getOptions();

// 'active' indicates whether the function is initiated through a user gesture. This
// is required to avoid "This function must be called during a user gesture".
const setAutonomousHighlights = function(value, active=false, callback=null) {
Expand Down Expand Up @@ -335,10 +335,12 @@ const saveOptions = function() {
// DOM prior to saving (which is what's done above for the other options.
// This is because blocklist items are handled differently than the
// other form inputs, getting saved directly when they're added.
const existing_opts = backgroundPage.getOptions();
options['autonomous_blocklist_items'] = existing_opts.autonomous_blocklist_items;
options['autonomous_blocklist_exceptions'] = existing_opts.autonomous_blocklist_exceptions;
backgroundPage.saveOptions(options);
chrome.storage.local.get(['options'], (storage) => {
const existing_opts = storage.options;
options['autonomous_blocklist_items'] = existing_opts.autonomous_blocklist_items;
options['autonomous_blocklist_exceptions'] = existing_opts.autonomous_blocklist_exceptions;
backgroundPage.saveOptions(options);
});
};

// Loads options (asynchronously).
Expand Down Expand Up @@ -373,32 +375,36 @@ const loadOptions = function(opts) {
});
};

// restore saved options
document.addEventListener('DOMContentLoaded', function() {
loadOptions(initOpts);
});
chrome.storage.local.get(['options'], (result) => {
const initOpts = result.options;

// load default options
document.getElementById('defaults').addEventListener('click', function() {
const defaults = backgroundPage.defaultOptions();
// this will trigger updates to the input settings
backgroundPage.saveOptions(defaults, function() {
statusMessage('Defaults Loaded', 1200);
});
});
// Restore saved options.
loadOptions(initOpts);

document.getElementById('revert').addEventListener('click', function() {
let permissions = {};
if (initOpts.autonomous_highlights)
permissions = autonomousHighlightsPermissions;
chrome.permissions.request(
permissions,
function() {
// Load default options.
document.getElementById('defaults').addEventListener('click', () => {
const defaults = backgroundPage.defaultOptions();
// this will trigger updates to the input settings
backgroundPage.saveOptions(initOpts, function() {
statusMessage('Options Reverted', 1200);
backgroundPage.saveOptions(defaults, function() {
statusMessage('Defaults Loaded', 1200);
});
});

document.getElementById('revert').addEventListener('click', () => {
let permissions = {};
if (initOpts.autonomous_highlights)
permissions = autonomousHighlightsPermissions;
chrome.permissions.request(
permissions,
function() {
// this will trigger updates to the input settings
backgroundPage.saveOptions(initOpts, () => {
statusMessage('Options Reverted', 1200);
});
});
});
});
});

// hide elements that are not relevant with less than three highlight states,
Expand Down Expand Up @@ -501,9 +507,11 @@ chrome.permissions.onRemoved.addListener(function() {
// the options page.
});

window.addEventListener('storage', function() {
chrome.storage.onChanged.addListener(function (changes, namespace) {
// Reload options when there are any external updates that modify settings
// saved in local storage (e.g., additions to the blocklist, options changes
// on other options pages).
loadOptions(backgroundPage.getOptions());
chrome.storage.local.get(['options'], (storage) => {
loadOptions(storage.options);
});
});

0 comments on commit 0d92b5f

Please sign in to comment.