Chromium Code Reviews| 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..de9ad3d67f592a5648dba377f26ddcc5b24ea2a1 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; |
| @@ -130,6 +137,122 @@ 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 |
|
raymes
2016/01/18 00:25:20
nit: 4 space indent (here and below)
Matthew Alger
2016/01/18 00:37:37
Done.
|
| + * 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 !== undefined) |
| + opt_callback(); |
| + }); |
| + }); |
| + } catch (e) { |
| + chrome.caterpillar.setError('Error setting values: ' + (e.message || e)); |
| + opt_callback(); |
|
raymes
2016/01/18 00:25:20
what if opt_callback is undefined?
Matthew Alger
2016/01/18 00:37:37
Done.
|
| + } |
| + } |
| + |
| + /** |
| + * 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); |
| + opt_callback(); |
|
raymes
2016/01/18 00:25:20
what if opt_callback is undefined?
Matthew Alger
2016/01/18 00:37:37
Done.
|
| + }; |
| + try { |
| + this.get(keys, function(items) { |
| + if (Array.isArray(keys)) { |
|
raymes
2016/01/18 00:25:20
If keys is a string, you could turn it into an arr
Matthew Alger
2016/01/18 00:37:37
Oh, good idea! Done, and done in get too.
|
| + 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); |
| + opt_callback(); |
|
raymes
2016/01/18 00:25:20
what if opt_callback is undefined?
Matthew Alger
2016/01/18 00:37:37
Done.
|
| + }) |
| + } else { |
| + localforage.removeItem(keys).then(function() { |
| + var changes = {}; |
| + changes[keys] = new chrome.storage.StorageChange( |
| + items[keys], null); |
| + triggerOnChanged(changes); |
| + 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); |
| + } |
| + triggerOnChanged(changes); |
| + localforage.clear(opt_callback); |
|
raymes
2016/01/18 00:25:20
I think it's probably better to clear things befor
Matthew Alger
2016/01/18 00:37:37
Do you mean it's better to clear things before the
|
| + }); |
| + } catch (e) { |
| + chrome.caterpillar.setError('Error clearing values: ' + (e.message || e)); |
| + if (opt_callback) |
|
raymes
2016/01/18 00:25:20
This is inconsistent with other places where you h
Matthew Alger
2016/01/18 00:37:37
Changed everything to just check opt_callback's tr
|
| + opt_callback(); |
| + } |
| + } |
| }; |
| /** |
| @@ -157,13 +280,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); |