| Index: src/js/polyfills/storage.polyfill.js
|
| diff --git a/src/js/polyfills/storage.polyfill.js b/src/js/polyfills/storage.polyfill.js
|
| index 6255c477799ce45bd8152b5252ca2e192b90cba4..b913d5762db09de89541d75d2c5c37df29cccc6d 100644
|
| --- a/src/js/polyfills/storage.polyfill.js
|
| +++ b/src/js/polyfills/storage.polyfill.js
|
| @@ -21,6 +21,8 @@
|
| if (!chrome.storage)
|
| chrome.storage = {};
|
|
|
| +chrome.caterpillar.storage = {};
|
| +
|
| (function() {
|
|
|
| /**
|
| @@ -38,6 +40,11 @@ function triggerOnChanged(items) {
|
| };
|
|
|
| /**
|
| + * Stores onChanged event listeners.
|
| + */
|
| +var onChangedListeners = [];
|
| +
|
| +/**
|
| * Represents a change in stored data.
|
| */
|
| chrome.storage.StorageChange = class {
|
| @@ -48,7 +55,7 @@ chrome.storage.StorageChange = class {
|
| constructor(opt_oldValue, opt_newValue) {
|
| this.oldValue = opt_oldValue;
|
| this.newValue = opt_newValue;
|
| - };
|
| + }
|
| };
|
|
|
| /**
|
| @@ -60,13 +67,13 @@ chrome.storage.StorageArea = class {
|
| /**
|
| * Gets one or more items from storage.
|
| *
|
| - * @param {string | string[] | object} opt_keys A single key to get, list
|
| + * @param {string= | string[]= | object=} opt_keys A single key to get, list
|
| * of keys to get, or a dictionary specifying default values. Empty lists
|
| * or objects return empty results. Pass null to get all contents.
|
| * @param {function} callback Callback with storage items, or on failure.
|
| */
|
| get(opt_keys, callback) {
|
| - // Handle the optional argument being *first*.
|
| + // Juggle arguments.
|
| if (callback === undefined) {
|
| // Keys wasn't actually given, the callback was.
|
| callback = opt_keys;
|
| @@ -85,6 +92,9 @@ chrome.storage.StorageArea = class {
|
| callback();
|
| }
|
|
|
| + if (typeof opt_keys === 'string')
|
| + opt_keys = [opt_keys];
|
| +
|
| if (opt_keys === null) {
|
| // null input; get all key/value pairs.
|
| var items = {};
|
| @@ -105,13 +115,6 @@ chrome.storage.StorageArea = class {
|
| callback(items);
|
| })
|
| .catch(handleError);
|
| - } else if (typeof opt_keys === 'string') {
|
| - // String input; get associated value of the key.
|
| - localforage.getItem(opt_keys).then(value => {
|
| - var items = {};
|
| - items[opt_keys] = value;
|
| - callback(items);
|
| - }).catch(handleError);
|
| } else {
|
| // Object input; get associated values with defaults.
|
| var keys = Object.keys(opt_keys);
|
| @@ -130,6 +133,121 @@ chrome.storage.StorageArea = class {
|
| .catch(handleError);
|
| }
|
| }
|
| +
|
| + /**
|
| + * Gets the amount of space (in bytes) being used by one or more items.
|
| + *
|
| + * Not implemented in this polyfill.
|
| + *
|
| + * @param {string= | string[]= | object=} opt_keys A single key to get,
|
| + * list of keys to get, or a dictionary specifying default values. Empty
|
| + * lists or objects return 0. Pass null to get total usage.
|
| + * @param {function} callback Callback with bytes in use, or failure.
|
| + */
|
| + getBytesInUse(opt_keys, callback) {
|
| + // Juggle arguments.
|
| + if (callback === undefined) {
|
| + callback = opt_keys;
|
| + opt_keys = null;
|
| + }
|
| + // IndexedDB doesn't support this, so neither does localforage.
|
| + chrome.caterpillar.setError('getBytesInUse not implemented.');
|
| + callback();
|
| + }
|
| +
|
| + /**
|
| + * Sets multiple items.
|
| + *
|
| + * @param {object} items An object which gives key/value pairs to update
|
| + * storage with. Other key/value pairs in storage will not be affected.
|
| + * @param {function=} opt_callback Callback on success or failure.
|
| + */
|
| + set(items, opt_callback) {
|
| + var keys = Object.keys(items);
|
| + try {
|
| + // We need to trigger an event containing all the old values and new values.
|
| + // To do that, we first need the old values.
|
| + this.get(keys, function (oldItems) {
|
| + // Now that we have the old values, we can set the new values.
|
| + Promise.all(keys.map(key => localforage.setItem(key, items[key])))
|
| + // Then setup the input and trigger the event.
|
| + .then(function() {
|
| + var changes = {};
|
| + for (var key of keys) {
|
| + changes[key] = new chrome.storage.StorageChange(
|
| + oldItems[key], items[key]);
|
| + }
|
| + triggerOnChanged(changes);
|
| + if (opt_callback)
|
| + opt_callback();
|
| + });
|
| + });
|
| + } catch (e) {
|
| + chrome.caterpillar.setError('Error setting values: ' + (e.message || e));
|
| + if (opt_callback)
|
| + opt_callback();
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Removes one or more items from storage.
|
| + *
|
| + * @param {string || string[]} keys A single key or a list of keys to
|
| + * remove.
|
| + * @param {function=} opt_callback Callback on success or failure.
|
| + */
|
| + remove(keys, opt_callback) {
|
| + var handleError = function(err) {
|
| + chrome.caterpillar.setError('Error removing keys: ' + err);
|
| + if (opt_callback)
|
| + opt_callback();
|
| + };
|
| + try {
|
| + this.get(keys, function(items) {
|
| + if (typeof keys === 'string')
|
| + keys = [keys];
|
| +
|
| + Promise.all(keys.map(key => localforage.removeItem(key)))
|
| + .then(function() {
|
| + var changes = {};
|
| + for (var key of keys) {
|
| + changes[key] = new chrome.storage.StorageChange(
|
| + items[key], null);
|
| + }
|
| + triggerOnChanged(changes);
|
| + if (opt_callback)
|
| + opt_callback();
|
| + })
|
| + });
|
| + } catch (e) {
|
| + handleError(e.message || e);
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Removes all items from storage.
|
| + *
|
| + * @param {function=} opt_callback Callback on success or failure.
|
| + */
|
| + clear(opt_callback) {
|
| + try {
|
| + this.get(function(items) {
|
| + var changes = {};
|
| + for (var key in items) {
|
| + changes[key] = new chrome.storage.StorageChange(items[key], null);
|
| + }
|
| + localforage.clear().then(function() {
|
| + triggerOnChanged(changes);
|
| + if (opt_callback)
|
| + opt_callback();
|
| + });
|
| + });
|
| + } catch (e) {
|
| + chrome.caterpillar.setError('Error clearing values: ' + (e.message || e));
|
| + if (opt_callback)
|
| + opt_callback();
|
| + }
|
| + }
|
| };
|
|
|
| /**
|
| @@ -157,13 +275,27 @@ chrome.storage.onChanged = {};
|
| /**
|
| * Adds an event listener for the onChanged event.
|
| *
|
| - * @param {function} callback Function taking a changes object of key/value
|
| - * pairs.
|
| + * @param {function} callback Function taking an object mapping changed keys to
|
| + * StorageChanges and an area name (though the latter will always be null).
|
| */
|
| chrome.storage.onChanged.addListener = function(callback) {
|
| - self.addEventListener('chrome.storage.onChanged', e => {
|
| - callback(e.detail);
|
| - });
|
| + var listener = function(e) {
|
| + callback(e.detail, null);
|
| + };
|
| +
|
| + self.addEventListener('chrome.storage.onChanged', listener);
|
| + onChangedListeners.push(listener);
|
| +};
|
| +
|
| +/**
|
| + * Resets onChanged event listeners. Used for testing.
|
| + */
|
| +chrome.caterpillar.storage.resetOnChangedListenersForTests = function() {
|
| + for (var listener of onChangedListeners) {
|
| + self.removeEventListener('chrome.storage.onChanged', listener);
|
| + }
|
| +
|
| + onChangedListeners.length = 0;
|
| };
|
|
|
| }).call(this);
|
|
|