diff --git a/src/background/main.js b/src/background/main.js index 427b45d..986aedb 100644 --- a/src/background/main.js +++ b/src/background/main.js @@ -394,21 +394,21 @@ async function removeMenuItem(menuItemId, {throwError = false} = {}) { } async function createMenu() { - const menuKey = browser.extension.inIncognitoContext - ? 'privateMenuItems' - : 'menuItems'; + const context = { + name: 'private', + active: browser.extension.inIncognitoContext + }; - const {showInContextMenu, [menuKey]: currentItems} = await storage.get([ - 'showInContextMenu', - menuKey - ]); + const {menuItems: currentItems} = await storage.get('menuItems', {context}); for (const itemId of currentItems) { await removeMenuItem(itemId); } + const {showInContextMenu} = await storage.get('showInContextMenu'); const newItems = showInContextMenu ? await getMenuItems() : []; - await storage.set({[menuKey]: newItems.map(item => item.id)}); + + await storage.set({menuItems: newItems.map(item => item.id)}, {context}); try { for (const item of newItems) { diff --git a/src/storage/storage.js b/src/storage/storage.js index 2e86a4b..af65165 100755 --- a/src/storage/storage.js +++ b/src/storage/storage.js @@ -1,3 +1,4 @@ +import {capitalizeFirstLetter, lowercaseFirstLetter} from 'utils/common'; import {storageRevisions} from 'utils/config'; async function isStorageArea({area = 'local'} = {}) { @@ -49,19 +50,71 @@ async function ensureStorageReady({area = 'local'} = {}) { } } -async function get(keys = null, {area = 'local'} = {}) { +function processStorageKey(key, contextName, {encode = true} = {}) { + if (encode) { + return `${contextName}${capitalizeFirstLetter(key)}`; + } else { + return lowercaseFirstLetter(key.replace(new RegExp(`^${contextName}`), '')); + } +} + +function processStorageData(data, contextName, {encode = true} = {}) { + if (typeof data === 'string') { + return processStorageKey(data, contextName, {encode}); + } else if (Array.isArray(data)) { + const items = []; + + for (const item of data) { + items.push(processStorageKey(item, contextName, {encode})); + } + + return items; + } else { + const items = {}; + + for (const [key, value] of Object.entries(data)) { + items[processStorageKey(key, contextName, {encode})] = value; + } + + return items; + } +} + +function encodeStorageData(data, context) { + if (context?.active) { + return processStorageData(data, context.name, {encode: true}); + } + + return data; +} + +function decodeStorageData(data, context) { + if (context?.active) { + return processStorageData(data, context.name, {encode: false}); + } + + return data; +} + +async function get(keys = null, {area = 'local', context = null} = {}) { await ensureStorageReady({area}); - return browser.storage[area].get(keys); + + return decodeStorageData( + await browser.storage[area].get(encodeStorageData(keys, context)), + context + ); } -async function set(obj, {area = 'local'} = {}) { +async function set(obj, {area = 'local', context = null} = {}) { await ensureStorageReady({area}); - return browser.storage[area].set(obj); + + return browser.storage[area].set(encodeStorageData(obj, context)); } -async function remove(keys, {area = 'local'} = {}) { +async function remove(keys, {area = 'local', context = null} = {}) { await ensureStorageReady({area}); - return browser.storage[area].remove(keys); + + return browser.storage[area].remove(encodeStorageData(keys, context)); } async function clear({area = 'local'} = {}) { @@ -70,4 +123,4 @@ async function clear({area = 'local'} = {}) { } export default {get, set, remove, clear}; -export {isStorageArea, isStorageReady, ensureStorageReady}; +export {isStorageArea, isStorageReady, encodeStorageData, decodeStorageData}; diff --git a/src/utils/common.js b/src/utils/common.js index 9e9587c..da2fa10 100644 --- a/src/utils/common.js +++ b/src/utils/common.js @@ -754,6 +754,14 @@ function getRandomString(length) { return text; } +function capitalizeFirstLetter(string, {locale = 'en-US'} = {}) { + return string.replace(/^\p{CWU}/u, char => char.toLocaleUpperCase(locale)); +} + +function lowercaseFirstLetter(string, {locale = 'en-US'} = {}) { + return string.replace(/^\p{CWL}/u, char => char.toLocaleLowerCase(locale)); +} + function* splitAsciiString(string, maxBytes) { let start = 0; while (start < string.length) { @@ -853,6 +861,8 @@ export { blobToDataUrl, getRandomInt, getRandomString, + capitalizeFirstLetter, + lowercaseFirstLetter, splitAsciiString, stringToInt, getAbsoluteUrl,