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); |