2018-09-16 01:22:40 +02:00
|
|
|
/* 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";
|
2018-09-16 12:27:50 +02:00
|
|
|
|
2019-11-28 01:26:35 +01:00
|
|
|
let scope;
|
2018-09-16 01:22:40 +02:00
|
|
|
if ((typeof exports) !== "undefined"){
|
|
|
|
scope = exports;
|
|
|
|
}
|
|
|
|
else {
|
2019-03-12 22:24:23 +01:00
|
|
|
scope = require.register("./settingContainers", {});
|
2018-09-16 01:22:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
const logging = require("./logging");
|
|
|
|
|
|
|
|
scope.urlContainer = null;
|
|
|
|
scope.hideContainer = null;
|
|
|
|
scope.expandContainer = null;
|
|
|
|
|
|
|
|
scope.getUrlValueContainer = function(name, url){
|
2019-11-28 01:26:35 +01:00
|
|
|
const matching = scope.urlContainer.get().filter(function(urlSetting){
|
2018-09-16 01:22:40 +02:00
|
|
|
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){
|
2019-11-28 01:26:35 +01:00
|
|
|
const urlContainerValue = scope.urlContainer.get();
|
|
|
|
let matching = urlContainerValue.filter(function(urlSetting){
|
2018-09-16 01:22:40 +02:00
|
|
|
return urlSetting.match(url);
|
|
|
|
});
|
|
|
|
if (!matching.length){
|
|
|
|
let newEntry = {url};
|
|
|
|
newEntry[name] = value;
|
|
|
|
urlContainerValue.push(newEntry);
|
2021-03-06 11:10:18 +01:00
|
|
|
initializeUrlSetting(newEntry);
|
2018-09-16 01:22:40 +02:00
|
|
|
matching = [newEntry];
|
|
|
|
}
|
|
|
|
matching[0][name] = value;
|
|
|
|
return scope.urlContainer.set(urlContainerValue);
|
|
|
|
};
|
|
|
|
scope.resetUrlValue = function(name, url){
|
2019-11-28 01:26:35 +01:00
|
|
|
let urlContainerValue = scope.urlContainer.get();
|
2021-05-25 16:44:20 +02:00
|
|
|
urlContainerValue.filter(function(urlSetting){
|
2018-09-16 01:22:40 +02:00
|
|
|
return urlSetting.match(url);
|
2021-05-25 16:44:20 +02:00
|
|
|
}).forEach(function(match){
|
|
|
|
delete match[name];
|
|
|
|
if (Object.keys(match).every(function(key){return key === "url";})){
|
2018-09-16 01:22:40 +02:00
|
|
|
urlContainerValue = urlContainerValue.filter(function(urlSetting){
|
2021-05-25 16:44:20 +02:00
|
|
|
return urlSetting !== match;
|
2018-09-16 01:22:40 +02:00
|
|
|
});
|
|
|
|
}
|
2021-05-25 16:44:20 +02:00
|
|
|
});
|
|
|
|
scope.urlContainer.set(urlContainerValue);
|
2018-09-16 01:22:40 +02:00
|
|
|
};
|
|
|
|
|
2019-11-28 01:26:35 +01:00
|
|
|
function processHideContainer(settingDefinition){
|
|
|
|
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]);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
const oldValue = event.oldValue;
|
|
|
|
Object.keys(oldValue).filter(function(name){
|
|
|
|
return !value.hasOwnProperty(name);
|
|
|
|
}).forEach(function(name){
|
|
|
|
(changeListeners[name] || []).forEach(function(listener){
|
|
|
|
listener(false);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
settingDefinition.hideAble = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
function processExpandContainer(settingDefinition){
|
|
|
|
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, defaultValue = false){
|
|
|
|
const expandStore = settingDefinition.get();
|
|
|
|
if ((typeof expandStore[name]) !== "undefined"){
|
|
|
|
return expandStore[name] || false;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return defaultValue;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
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]);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
const oldValue = event.oldValue;
|
|
|
|
Object.keys(oldValue).filter(function(name){
|
|
|
|
return !value.hasOwnProperty(name);
|
|
|
|
}).forEach(function(name){
|
|
|
|
(changeListeners[name] || []).forEach(function(listener){
|
|
|
|
listener(false);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-09-16 01:22:40 +02:00
|
|
|
scope.check = function(settingDefinition){
|
|
|
|
if (settingDefinition.isUrlContainer){
|
|
|
|
scope.urlContainer = settingDefinition;
|
|
|
|
settingDefinition.refresh = function(){
|
|
|
|
settingDefinition.set(settingDefinition.get());
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
if (settingDefinition.isHideContainer){
|
2019-11-28 01:26:35 +01:00
|
|
|
processHideContainer(settingDefinition);
|
2018-09-16 01:22:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (settingDefinition.isExpandContainer){
|
2019-11-28 01:26:35 +01:00
|
|
|
processExpandContainer(settingDefinition);
|
2018-09-16 01:22:40 +02:00
|
|
|
}
|
|
|
|
};
|
2018-09-16 12:27:50 +02:00
|
|
|
|
2021-03-06 11:10:18 +01:00
|
|
|
function initializeUrlSetting(urlSetting){
|
|
|
|
let regExp;
|
2022-04-26 17:08:28 +02:00
|
|
|
const domain = !!urlSetting.url.match(/^[A-Za-z0-9_.*-]+$/);
|
2021-03-06 11:10:18 +01:00
|
|
|
if (domain){
|
|
|
|
regExp = new RegExp(
|
2022-04-26 17:08:28 +02:00
|
|
|
"(?:^|\\.)" + urlSetting.url.replace(/([\\+?[^\]$(){}=!|.])/g, "\\$1").replace(/\*/g, ".+") + "\\.?$",
|
2021-03-06 11:10:18 +01:00
|
|
|
"i"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
else {
|
2022-01-30 13:11:44 +01:00
|
|
|
try {
|
|
|
|
regExp = new RegExp(urlSetting.url, "i");
|
|
|
|
}
|
|
|
|
catch (error){
|
|
|
|
logging.error("Error in regular expression", urlSetting.url, error);
|
|
|
|
regExp = new RegExp(
|
|
|
|
"(?:^|\\.)" + urlSetting.url.replace(/([\\+*?[^\]$(){}=!|.])/g, "\\$1") + "\\.?$",
|
|
|
|
"i"
|
|
|
|
);
|
|
|
|
}
|
2021-03-06 11:10:18 +01:00
|
|
|
}
|
|
|
|
const match = function(url){
|
|
|
|
if (!url){
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else if (
|
|
|
|
url instanceof String ||
|
|
|
|
(typeof url) === "string"
|
|
|
|
){
|
|
|
|
return url === urlSetting.url;
|
|
|
|
}
|
|
|
|
else if (domain){
|
|
|
|
return (url.hostname || "").match(regExp);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return url.href.match(regExp);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Object.defineProperty(
|
|
|
|
urlSetting,
|
|
|
|
"match",
|
|
|
|
{
|
|
|
|
enumerable: false,
|
|
|
|
writable: true,
|
|
|
|
configurable: true,
|
|
|
|
value: match
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2018-09-16 12:27:50 +02:00
|
|
|
scope.initializeUrlContainer = function(eventHandler){
|
2019-12-29 00:18:05 +01:00
|
|
|
if (!scope.urlContainer){
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
scope.urlContainer.on(function({newValue, oldValue}){
|
2021-03-06 11:10:18 +01:00
|
|
|
newValue.forEach(initializeUrlSetting);
|
2019-12-29 00:18:05 +01:00
|
|
|
|
|
|
|
const newUrls = newValue.map(function(entry){return entry.url;});
|
|
|
|
const oldUrls = oldValue.map(function(entry){return entry.url;});
|
|
|
|
const matching = {};
|
|
|
|
newUrls.forEach(function(url, i){
|
|
|
|
matching[url] = {new: i, old: oldUrls.indexOf(url)};
|
|
|
|
});
|
|
|
|
oldUrls.forEach(function(url, i){
|
|
|
|
if (!matching[url]){
|
|
|
|
matching[url] = {new: -1, old: i};
|
|
|
|
}
|
|
|
|
});
|
|
|
|
Object.keys(matching).forEach(function(url){
|
|
|
|
const oldEntry = oldValue[matching[url].old] || {};
|
|
|
|
const newEntry = newValue[matching[url].new] || {};
|
|
|
|
scope.urlContainer.entries.forEach(function(settingDefinition){
|
|
|
|
const name = settingDefinition.name;
|
|
|
|
const oldValue = oldEntry[name];
|
|
|
|
const newValue = newEntry[name];
|
|
|
|
|
|
|
|
if (oldValue !== newValue){
|
|
|
|
((eventHandler[name] || {})[url] || []).forEach(function(callback){
|
|
|
|
callback({name, newValue, oldValue, url});
|
|
|
|
});
|
2018-09-16 12:27:50 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
2019-12-29 00:18:05 +01:00
|
|
|
});
|
2018-09-16 12:27:50 +02:00
|
|
|
};
|
2018-09-16 01:22:40 +02:00
|
|
|
}());
|