diff --git a/browserAction/browserAction.html b/browserAction/browserAction.html index 2a47a2d..1350ce8 100644 --- a/browserAction/browserAction.html +++ b/browserAction/browserAction.html @@ -10,6 +10,7 @@ + diff --git a/lib/settingContainers.js b/lib/settingContainers.js new file mode 100644 index 0000000..0559494 --- /dev/null +++ b/lib/settingContainers.js @@ -0,0 +1,138 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +(function(){ + "use strict"; + + var scope; + if ((typeof exports) !== "undefined"){ + scope = exports; + } + else { + scope = {}; + window.scope.settingContainers = scope; + } + + const logging = require("./logging"); + + scope.urlContainer = null; + scope.hideContainer = null; + scope.expandContainer = null; + + scope.getUrlValueContainer = function(name, url){ + var matching = scope.urlContainer.get().filter(function(urlSetting){ + return urlSetting.hasOwnProperty(name); + }).filter(function(urlSetting){ + return urlSetting.match(url); + }); + if (matching.length){ + return matching[0]; + } + else { + return null; + } + }; + scope.setUrlValue = function(name, value, url){ + var urlContainerValue = scope.urlContainer.get(); + var matching = urlContainerValue.filter(function(urlSetting){ + return urlSetting.match(url); + }); + if (!matching.length){ + let newEntry = {url}; + newEntry[name] = value; + urlContainerValue.push(newEntry); + matching = [newEntry]; + } + matching[0][name] = value; + return scope.urlContainer.set(urlContainerValue); + }; + scope.resetUrlValue = function(name, url){ + var urlContainerValue = scope.urlContainer.get(); + var matching = urlContainerValue.filter(function(urlSetting){ + return urlSetting.match(url); + }); + if (matching.length){ + delete matching[0][name]; + if (Object.keys(matching[0]).every(function(key){return key === "url";})){ + urlContainerValue = urlContainerValue.filter(function(urlSetting){ + return urlSetting !== matching[0]; + }); + } + scope.urlContainer.set(urlContainerValue); + } + }; + + scope.check = function(settingDefinition){ + if (settingDefinition.isUrlContainer){ + scope.urlContainer = settingDefinition; + settingDefinition.refresh = function(){ + settingDefinition.set(settingDefinition.get()); + }; + } + + if (settingDefinition.isHideContainer){ + scope.hideContainer = settingDefinition; + let changeListeners = {}; + settingDefinition.setHideByName = function(name, value){ + logging.verbose("set hide of", name, "to", value); + const hideStore = settingDefinition.get(); + hideStore[name] = value; + settingDefinition.set(hideStore); + (changeListeners[name] || []).forEach(function(listener){ + listener(value); + }); + }; + settingDefinition.getHideByName = function(name){ + const hideStore = settingDefinition.get(); + return hideStore[name] || false; + }; + settingDefinition.onHideChange = function(name, listener){ + if (!changeListeners[name]){ + changeListeners[name] = []; + } + changeListeners[name].push(listener); + }; + settingDefinition.on(function(event){ + const value = event.newValue; + Object.keys(value).forEach(function(name){ + (changeListeners[name] || []).forEach(function(listener){ + listener(value[name]); + }); + }); + }); + settingDefinition.hideAble = false; + } + + if (settingDefinition.isExpandContainer){ + scope.expandContainer = settingDefinition; + let changeListeners = {}; + settingDefinition.setExpandByName = function(name, value){ + logging.verbose("set expand of", name, "to", value); + const expandStore = settingDefinition.get(); + expandStore[name] = value; + settingDefinition.set(expandStore); + (changeListeners[name] || []).forEach(function(listener){ + listener(value); + }); + }; + settingDefinition.getExpandByName = function(name){ + const expandStore = settingDefinition.get(); + return expandStore[name] || false; + }; + settingDefinition.onExpandChange = function(name, listener){ + if (!changeListeners[name]){ + changeListeners[name] = []; + } + changeListeners[name].push(listener); + }; + settingDefinition.on(function(event){ + const value = event.newValue; + Object.keys(value).forEach(function(name){ + (changeListeners[name] || []).forEach(function(listener){ + listener(value[name]); + }); + }); + }); + } + }; +}()); \ No newline at end of file diff --git a/lib/settingDefinitions.js b/lib/settingDefinitions.js index 5df64d3..70828dc 100644 --- a/lib/settingDefinitions.js +++ b/lib/settingDefinitions.js @@ -13,19 +13,19 @@ { name: "urlSettings", defaultValue: [], - urlContainer: true, + isUrlContainer: true, entries: [ {name: "url", defaultValue: ""} ] }, { name: "hiddenSettings", - hideContainer: true, + isHideContainer: true, defaultValue: {} }, { name: "expandStatus", - expandContainer: true, + isExpandContainer: true, defaultValue: {} }, { diff --git a/lib/settings.js b/lib/settings.js index 902e787..f1c6d93 100644 --- a/lib/settings.js +++ b/lib/settings.js @@ -15,6 +15,7 @@ const logging = require("./logging"); const settingDefinitions = require("./settingDefinitions.js"); + const settingContainers = require("./settingContainers"); const definitionsByName = {}; const defaultSymbol = ""; @@ -22,9 +23,6 @@ eventHandler.any[defaultSymbol] = []; eventHandler.all = eventHandler.any; const settings = {}; - let urlContainer; - let hideContainer; - let expandContainer; function isDefinitionInvalid(settingDefinition, newValue){ if (newValue === undefined && settingDefinition.optional){ @@ -77,13 +75,9 @@ else if (settingDefinition.urlSpecific){ return function getValue(url){ if (url){ - var matching = urlContainer.get().filter(function(urlSetting){ - return urlSetting.hasOwnProperty(settingDefinition.name); - }).filter(function(urlSetting){ - return urlSetting.match(url); - }); - if (matching.length){ - return matching[0][settingDefinition.name]; + var match = settingContainers.getUrlValueContainer(settingDefinition.name, url); + if (match){ + return match[settingDefinition.name]; } } return settings[settingDefinition.name]; @@ -147,18 +141,7 @@ logging.verbose("New value for %s (%s):", name, url, newValue); if (isValid(newValue)){ if (url){ - var urlContainerValue = urlContainer.get(); - var matching = urlContainerValue.filter(function(urlSetting){ - return urlSetting.match(url); - }); - if (!matching.length){ - let newEntry = {url}; - newEntry[settingDefinition.name] = newValue; - urlContainerValue.push(newEntry); - matching = [newEntry]; - } - matching[0][settingDefinition.name] = newValue; - return urlContainer.set(urlContainerValue); + return settingContainers.setUrlValue(name, newValue, url); } else { return storeValue(newValue); @@ -196,19 +179,7 @@ if (settingDefinition.urlSpecific){ return function(url){ if (url){ - var urlContainerValue = urlContainer.get(); - var matching = urlContainerValue.filter(function(urlSetting){ - return urlSetting.match(url); - }); - if (matching.length){ - delete matching[0][name]; - if (Object.keys(matching[0]).every(function(key){return key === "url";})){ - urlContainerValue = urlContainerValue.filter(function(urlSetting){ - return urlSetting !== matching[0]; - }); - } - urlContainer.set(urlContainerValue); - } + settingContainers.resetUrlValue(name, url); } else { reset(); @@ -244,13 +215,6 @@ }; settingDefinitions.forEach(function(settingDefinition){ - if (settingDefinition.urlContainer){ - urlContainer = settingDefinition; - settingDefinition.refresh = function(){ - settingDefinition.set(settingDefinition.get()); - }; - } - var name = settingDefinition.name; definitionsByName[name] = settingDefinition; if (typeof settingDefinition.defaultValue === "function"){ @@ -281,14 +245,14 @@ settingDefinition.reset = createResetter(settingDefinition); if (settingDefinition.urlSpecific){ - if (!urlContainer){ + if (!settingContainers.urlContainer){ logging.error("Unable to use url specific settings without url-container"); } else { - settingDefinition.urlContainer = urlContainer; + settingDefinition.urlContainer = settingContainers.urlContainer; let entry = Object.create(settingDefinition); entry.optional = true; - urlContainer.entries.push(entry); + settingContainers.urlContainer.entries.push(entry); } } @@ -302,74 +266,7 @@ } ); - if (settingDefinition.hideContainer){ - hideContainer = settingDefinition; - let changeListeners = {}; - settingDefinition.setHideByName = function(name, value){ - logging.verbose("set hide of", name, "to", value); - const hideStore = settingDefinition.get(); - hideStore[name] = value; - settingDefinition.set(hideStore); - (changeListeners[name] || []).forEach(function(listener){ - listener(value); - }); - }; - settingDefinition.getHideByName = function(name){ - const hideStore = settingDefinition.get(); - return hideStore[name] || false; - }; - settingDefinition.onHideChange = function(name, listener){ - if (!changeListeners[name]){ - changeListeners[name] = []; - } - changeListeners[name].push(listener); - }; - settingDefinition.on(function(event){ - const value = event.newValue; - Object.keys(value).forEach(function(name){ - if (value[name]){ - (changeListeners[name] || []).forEach(function(listener){ - listener(true); - }); - } - }); - }); - settingDefinition.hideAble = false; - } - - if (settingDefinition.expandContainer){ - expandContainer = settingDefinition; - let changeListeners = {}; - settingDefinition.setExpandByName = function(name, value){ - logging.verbose("set expand of", name, "to", value); - const expandStore = settingDefinition.get(); - expandStore[name] = value; - settingDefinition.set(expandStore); - (changeListeners[name] || []).forEach(function(listener){ - listener(value); - }); - }; - settingDefinition.getExpandByName = function(name){ - const expandStore = settingDefinition.get(); - return expandStore[name] || false; - }; - settingDefinition.onExpandChange = function(name, listener){ - if (!changeListeners[name]){ - changeListeners[name] = []; - } - changeListeners[name].push(listener); - }; - settingDefinition.on(function(event){ - const value = event.newValue; - Object.keys(value).forEach(function(name){ - if (value[name]){ - (changeListeners[name] || []).forEach(function(listener){ - listener(true); - }); - } - }); - }); - } + settingContainers.check(settingDefinition); }); scope.getDefinition = function(name){ @@ -384,9 +281,9 @@ scope.getContainers = function(){ return { - url: Object.create(urlContainer), - hide: Object.create(hideContainer), - expand: Object.create(expandContainer) + url: Object.create(settingContainers.urlContainer), + hide: Object.create(settingContainers.hideContainer), + expand: Object.create(settingContainers.expandContainer) }; }; @@ -431,7 +328,7 @@ }); if (settingDefinition.urlSpecific){ - urlContainer.get().forEach(function(entry){ + settingContainers.urlContainer.get().forEach(function(entry){ if (!entry.hasOwnProperty(name)){ ((eventHandler[name] || {})[entry.url] || []).forEach(function(callback){ callback({name, newValue, oldValue, url: entry.url}); @@ -449,7 +346,7 @@ var delayedChange = []; Object.entries(changes).forEach(function(entry){ const [name, change] = entry; - if (urlContainer && name === urlContainer.name){ + if (settingContainers.urlContainer && name === settingContainers.urlContainer.name){ // changes in the url container have to trigger after the other changes delayedChange.push(entry); } @@ -477,8 +374,8 @@ } }); - if (urlContainer){ - urlContainer.on(function({newValue, oldValue}){ + if (settingContainers.urlContainer){ + settingContainers.urlContainer.on(function({newValue, oldValue}){ newValue.forEach(function(urlSetting){ var regExp; var domain = !!urlSetting.url.match(/^[A-Za-z0-9_.-]+$/); @@ -534,7 +431,7 @@ Object.keys(matching).forEach(function(url){ var oldEntry = oldValue[matching[url].old] || {}; var newEntry = newValue[matching[url].new] || {}; - urlContainer.entries.forEach(function(settingDefinition){ + settingContainers.urlContainer.entries.forEach(function(settingDefinition){ var name = settingDefinition.name; var oldValue = oldEntry[name]; var newValue = newEntry[name]; @@ -564,12 +461,15 @@ logging.message("settings loaded"); if (require.exists("./settingsMigration")){ const settingsMigration = require("./settingsMigration"); - settingsMigration.check(storage, {settings, logging, changeValue, urlContainer}); + settingsMigration.check( + storage, + {settings, logging, changeValue, urlContainer: settingContainers.urlContainer} + ); } var delayedChange = []; Object.entries(storage).forEach(function(entry){ const [name, value] = entry; - if (urlContainer && name === urlContainer.name){ + if (settingContainers.urlContainer && name === settingContainers.urlContainer.name){ // changes in the url container have to trigger after the other changes delayedChange.push(entry); } diff --git a/manifest.json b/manifest.json index a0a4a32..33ef0ce 100644 --- a/manifest.json +++ b/manifest.json @@ -12,6 +12,7 @@ "lib/require.js", "lib/logging.js", "lib/settingDefinitions.js", + "lib/settingContainers.js", "lib/settingsMigration.js", "lib/settings.js", "lib/lists.js", @@ -31,6 +32,7 @@ "lib/logging.js", "lib/settingDefinitions.js", + "lib/settingContainers.js", "lib/settings.js", "lib/colorStatistics.js", diff --git a/options/export.html b/options/export.html index 0dd686b..044d43e 100644 --- a/options/export.html +++ b/options/export.html @@ -10,6 +10,7 @@ + diff --git a/options/options.html b/options/options.html index 82c4fe7..c0ee525 100644 --- a/options/options.html +++ b/options/options.html @@ -9,6 +9,7 @@ + diff --git a/pageAction/pageAction.html b/pageAction/pageAction.html index fde113a..cd62f63 100644 --- a/pageAction/pageAction.html +++ b/pageAction/pageAction.html @@ -13,6 +13,7 @@ +