/* * Copyright (c) 2016-2017, Michael A. Updike All rights reserved. * Licensed under Apache 2.0 * https://opensource.org/licenses/Apache-2.0 * https://github.com/opus1269/chrome-extension-utils/blob/master/LICENSE.md */ window.Chrome = window.Chrome || {}; /** * Manage items in localStorage * @namespace */ Chrome.Storage = (function() { 'use strict'; new ExceptionHandler(); const chromep = new ChromePromise(); return { /** * Get a JSON parsed value from localStorage * @param {!string} key - key to get value for * @param {?Object} [def=null] - return value if key not found * @returns {?Object} JSON object, null if key does not exist * @memberOf Chrome.Storage */ get: function(key, def = null) { let value = def; let item = localStorage.getItem(key); if (item !== null) { value = Chrome.JSONUtils.parse(item); } return value; }, /** * Get integer value from localStorage * @param {!string} key - key to get value for * @param {?int} [def=null] - optional value to return, if NaN * @returns {int} value as integer, NaN on error * @memberOf Chrome.Storage */ getInt: function(key, def = null) { let item = localStorage.getItem(key); let value = parseInt(item, 10); if (Number.isNaN(value)) { value = (def === null) ? value : def; if (def === null) { Chrome.GA.error(`NaN value for: ${key} equals ${item}`, 'Storage.getInt'); } } return value; }, /** * Get boolean value from localStorage * @param {!string} key - key to get value for * @param {?boolean} [def=null] - return value if key not found * @returns {?boolean} value as boolean, null if key does not exist * @memberOf Chrome.Storage */ getBool: function(key, def = null) { return Chrome.Storage.get(key, def); }, /** * JSON stringify and save a value to localStorage * @param {!string} key - key to set value for * @param {?Object} [value=null] - new value, if null remove item * @memberOf Chrome.Storage */ set: function(key, value = null) { if (value === null) { localStorage.removeItem(key); } else { const val = JSON.stringify(value); localStorage.setItem(key, val); } }, /** * Save a value to localStorage only if there is enough room * @param {!string} key - localStorage Key * @param {Object} value - value to save * @param {string} [keyBool] - key to a boolean value * that is true if the primary key has non-empty value * @returns {boolean} true if value was set successfully * @memberOf Chrome.Storage */ safeSet: function(key, value, keyBool) { let ret = true; const oldValue = Chrome.Storage.get(key); try { Chrome.Storage.set(key, value); } catch (e) { ret = false; if (oldValue) { // revert to old value Chrome.Storage.set(key, oldValue); } if (keyBool) { // revert to old value if (oldValue && oldValue.length) { Chrome.Storage.set(keyBool, true); } else { Chrome.Storage.set(keyBool, false); } } // notify listeners Chrome.Msg.send(Chrome.Msg.STORAGE_EXCEEDED).catch(() => { }); } return ret; }, /** * An error that can be persisted * Usage: const err = new LastError(message, title) * @param {?string} [message=''] - the message * @param {?string} [title='An error occurred'] - the title * @property {string} name - Error name * @property {string} stack - stack trace * @memberOf Chrome.Storage */ LastError: function(message = '', title = 'An error occurred') { this.name = 'LastError'; this.message = message; this.title = title; this.stack = (new Error).stack; Chrome.Storage.LastError.prototype = Object.create(Error.prototype); Chrome.Storage.LastError.prototype.constructor = Chrome.Storage.LastError; }, /** * Get the LastError from chrome.storage.local * @returns {Promise<Chrome.Msg.LastError>} last error * @memberOf Chrome.Storage */ getLastError: function() { return chromep.storage.local.get('lastError').then((values) => { if (values.lastError) { return Promise.resolve(values.lastError); } return new Chrome.Storage.LastError(); }); }, /** * Save the LastError to chrome.storage.local * @see https://developer.chrome.com/apps/storage * @param {Chrome.Storage.LastError} error - the LastError * @returns {Promise<void>} void * @memberOf Chrome.Storage */ setLastError: function(error) { // Save it using the Chrome storage API. return chromep.storage.local.set({'lastError': error}); }, /** * Set the LastError to an empty message in chrome.storage.local * @returns {Promise<void>} void * @memberOf Chrome.Storage */ clearLastError: function() { return Chrome.Storage.setLastError(new Chrome.Storage.LastError()); }, }; })();