1
0
mirror of https://github.com/kkapsner/CanvasBlocker synced 2024-12-22 12:50:36 +01:00

Added feature to hide settings.

This commit is contained in:
kkapsner 2018-07-02 00:29:41 +02:00
parent 22fda1eac7
commit 720a9bc9a5
11 changed files with 387 additions and 49 deletions

View File

@ -91,6 +91,15 @@
"description": ""
},
"displayHiddenSettings_title": {
"message": "Versteckte Einstellungen anzeigen",
"description": ""
},
"displayHiddenSettings_description": {
"message": "Aktivieren, um versteckte Einstellungen anzuzeigen.",
"description": ""
},
"allowPDFCanvas_description": {
"message": "Die native pdf.js verwendet <canvas> um den Inhalt von PDFs anzuzeigen. Wenn viele Nachfragedialoge erscheinen oder die PDF-Ansicht nicht funktioniert, müssen diese erlaubt werden.",
"description": ""

View File

@ -91,6 +91,15 @@
"description": ""
},
"displayHiddenSettings_title": {
"message": "Display hidden settings",
"description": ""
},
"displayHiddenSettings_description": {
"message": "Activate to display the hidden settings.",
"description": ""
},
"allowPDFCanvas_description": {
"message": "Firefox's native PDF reader uses the API to display PDF content. If too many ask dialogs appear or the PDF reader does not work at all, these have to be allowed.",
"description": ""

View File

@ -18,6 +18,15 @@
{name: "url", defaultValue: ""}
]
},
{
name: "hiddenSettings",
hideContainer: true,
defaultValue: {}
},
{
name: "displayHiddenSettings",
defaultValue: false
},
{
name: "urls",
defaultValue: [],

View File

@ -39,6 +39,7 @@
eventHandler.all = eventHandler.any;
const settings = {};
let urlContainer;
let hideContainer;
function isDefinitionInvalid(settingDefinition, newValue){
if (newValue === undefined && settingDefinition.optional){
@ -219,6 +220,28 @@
}
}
scope.on = function onSettingsChange(name, callback, url){
if (Array.isArray(name)){
name.forEach(function(name){
onSettingsChange(name, callback, url);
});
}
else {
if (eventHandler.hasOwnProperty(name)){
if (!url){
url = defaultSymbol;
}
if (!eventHandler[name].hasOwnProperty(url)){
eventHandler[name][url] = [];
}
eventHandler[name][url].push(callback);
}
else {
logging.warning("Unable to register event handler for unknown setting", name);
}
}
};
settingDefinitions.forEach(function(settingDefinition){
if (settingDefinition.urlContainer){
urlContainer = settingDefinition;
@ -277,6 +300,41 @@
enumerable: true
}
);
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;
}
});
scope.getDefinition = function(name){
@ -289,6 +347,13 @@
}
};
scope.getContainers = function(){
return {
url: Object.create(urlContainer),
hide: Object.create(hideContainer)
};
};
scope.set = function(name, ...args){
var foundDefinition = definitionsByName[name];
if (foundDefinition){
@ -316,28 +381,6 @@
}).forEach(...args);
};
scope.on = function onSettingsChange(name, callback, url){
if (Array.isArray(name)){
name.forEach(function(name){
onSettingsChange(name, callback, url);
});
}
else {
if (eventHandler.hasOwnProperty(name)){
if (!url){
url = defaultSymbol;
}
if (!eventHandler[name].hasOwnProperty(url)){
eventHandler[name][url] = [];
}
eventHandler[name][url].push(callback);
}
else {
logging.warning("Unable to register event handler for unknown setting", name);
}
}
};
const resetSymbol = Symbol("reset");
function changeValue(name, newValue){
var settingDefinition = scope.getDefinition(name);

76
options/notVisible.svg Normal file
View File

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="30"
height="20"
viewBox="0 0 7.9374998 5.2916668"
version="1.1"
id="svg8"
inkscape:version="0.92.2 2405546, 2018-03-11"
sodipodi:docname="notVisible.svg">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="3.959798"
inkscape:cx="18.761306"
inkscape:cy="54.832316"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1600"
inkscape:window-height="841"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
units="px" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-291.70832)">
<path
style="fill:none;stroke:#000000;stroke-width:0.07936867;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;opacity:1"
d="m 0.14548308,294.43593 c 2.59575882,2.03078 4.92396642,2.03973 7.67986362,-0.06 -3.6044602,-0.64366 -3.6257846,-2.34887 -7.67986362,0.06 z"
id="path4520"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<ellipse
style="fill:#bbbbbb;fill-opacity:1;stroke:#bbbbbb;stroke-width:0.04199925;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;opacity:1"
id="path4522"
cx="4.0754137"
cy="294.64594"
rx="0.92998338"
ry="0.86998433" />
<path
style="opacity:1;fill:none;stroke:#919191;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 1.2695302,296.79953 5.6794774,-4.27631"
id="path4543"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -42,13 +42,14 @@ header .bookmarkNotice {
}
.settings .settingRow .content {
display: block;
overflow: visible;
padding: 0.5em 0;
border-top: 1px solid #c1c1c1;
position: relative;
}
.settings .settingRow td:first-child .content {
.settings .settingRow td:first-child .content, td.hideColumn label {
margin-left: 0.6em;
}
.settings .settingRow td:last-child .content {
@ -160,3 +161,29 @@ input[type=""], input[type="text"], input[type="number"], select {
.urlValues .notSpecifiedForUrl {
opacity: 0.5;
}
td.hideColumn {
width: 35px;
}
.content.hideContent {
position: relative;
}
.content .hide, .displayHidden {
opacity: 0;
position: absolute;
}
.content .hide ~ .display, .displayHidden ~ .display {
display: inline-block;
margin-right: 5px;
width: 30px;
height: 20px;
background-repeat: no-repeat;
background-position-y: 50%;
}
.content .hide ~ .display, .displayHidden ~ .display {
background-image: url(visible.svg);
}
.content .hide:checked ~ .display, .displayHidden:checked ~ .display {
background-image: url(notVisible.svg);
}

View File

@ -66,6 +66,9 @@
});
document.body.appendChild(table);
const displayHidden = settings.getDefinition(settingsDisplay.displayHidden);
table.appendChild(optionsGui.createThead(displayHidden));
let lastSection = null;
let addSection = function addSection(name){
let body = document.createElement("tbody");
@ -73,7 +76,7 @@
let row = document.createElement("tr");
row.className = "section";
let cell = document.createElement("td");
cell.colSpan = 2;
cell.colSpan = 3;
row.appendChild(cell);
let heading = document.createElement("h2");
heading.textContent = browser.i18n.getMessage("section_" + name);
@ -108,6 +111,7 @@
};
addSection();
const {hide: hideContainer} = settings.getContainers();
settingsDisplay.forEach(function(display){
if (typeof display === "string"){
addSection(display);
@ -129,32 +133,69 @@
}
}
if (setting){
var row = optionsGui.createSettingRow(setting);
let section = lastSection;
section.addRow(row);
if (display.displayDependencies){
var displayDependencies = display.displayDependencies;
displayDependencies = Array.isArray(displayDependencies)?
displayDependencies:
[displayDependencies];
var computeDependencies = function(){
logging.verbose("evaluate display dependencies for", setting);
row.classList[(
displayDependencies.some(function(displayDependency){
return Object.keys(displayDependency).every(function(key){
return displayDependency[key].indexOf(settings[key]) !== -1;
});
})
)? "remove": "add"]("hidden");
section.updateDisplay();
};
computeDependencies();
displayDependencies.forEach(function(displayDependency){
Object.keys(displayDependency).forEach(function(name){
settings.on(name, computeDependencies);
let hideChangeListeners = [];
setting.setHide = function setHide(value){
if (hideContainer){
hideContainer.setHideByName(display.name, value);
if (computeDependencies){
computeDependencies();
}
}
};
setting.onHideChange = function(listener){
hideChangeListeners.push(listener);
};
setting.getHide = function getHide(){
if (hideContainer){
return hideContainer.getHideByName(display.name);
}
else {
return false;
}
};
if (hideContainer){
hideContainer.onHideChange(display.name, function(value){
if (computeDependencies){
computeDependencies();
}
hideChangeListeners.forEach(function(listener){
listener(value);
});
});
}
var row = optionsGui.createSettingRow(setting);
let section = lastSection;
section.addRow(row);
if (!display.displayDependencies){
display.displayDependencies = {};
}
var displayDependencies = display.displayDependencies;
displayDependencies = Array.isArray(displayDependencies)?
displayDependencies:
[displayDependencies];
var computeDependencies = function(){
logging.verbose("evaluate display dependencies for", setting);
row.classList[(
(
displayHidden.get() ||
!setting.getHide()
) &&
displayDependencies.some(function(displayDependency){
return Object.keys(displayDependency).every(function(key){
return displayDependency[key].indexOf(settings[key]) !== -1;
});
})
)? "remove": "add"]("hidden");
section.updateDisplay();
};
computeDependencies();
displayDependencies.forEach(function(displayDependency){
Object.keys(displayDependency).forEach(function(name){
settings.on(name, computeDependencies);
});
});
displayHidden.on(computeDependencies);
}
}
});

View File

@ -304,10 +304,36 @@
return c;
}
function createHide(setting){
var label = document.createElement("label");
label.className = "content hideContent";
var input = document.createElement("input");
input.type = "checkbox";
input.className = "hide";
input.checked = setting.getHide();
input.addEventListener("change", function(){
setting.setHide(this.checked);
});
setting.onHideChange(function(value){
input.checked = value;
});
label.appendChild(input);
var display = document.createElement("span");
display.className = "display";
label.appendChild(display);
return label;
}
function createSettingRow(setting){
var tr = document.createElement("tr");
tr.className = "settingRow";
var hide = document.createElement("td");
hide.className = "hideColumn";
hide.appendChild(createHide(setting));
tr.appendChild(hide);
var left = document.createElement("td");
left.appendChild(createDescription(setting));
tr.appendChild(left);
@ -320,4 +346,29 @@
}
scope.createSettingRow = createSettingRow;
function createThead(displayHidden){
const tHead = document.createElement("thead");
const headRow = document.createElement("tr");
const hideHeadCell = document.createElement("td");
hideHeadCell.className = "hideColumn";
hideHeadCell.title = browser.i18n.getMessage(displayHidden.name + "_description");
const label = document.createElement("label");
const input = createInput(displayHidden);
input.className = "displayHidden";
label.appendChild(input);
const display = document.createElement("span");
display.className = "display";
label.appendChild(display);
hideHeadCell.appendChild(label);
headRow.appendChild(hideHeadCell);
const restHeadCell = document.createElement("td");
restHeadCell.colSpan = 2;
headRow.appendChild(restHeadCell);
tHead.appendChild(headRow);
return tHead;
}
scope.createThead = createThead;
}());

View File

@ -402,6 +402,7 @@
}
}
];
settingsDisplay.displayHidden = "displayHiddenSettings";
if ((typeof module) !== "undefined"){
module.exports = settingsDisplay;

71
options/visible.svg Normal file
View File

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="30"
height="20"
viewBox="0 0 7.9374998 5.2916668"
version="1.1"
id="svg8"
inkscape:version="0.92.2 2405546, 2018-03-11"
sodipodi:docname="visible.svg">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="3.959798"
inkscape:cx="18.761306"
inkscape:cy="54.832316"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1600"
inkscape:window-height="841"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
units="px" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-291.70832)">
<path
style="fill:none;stroke:#000000;stroke-width:0.07936867;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 0.14548308,294.43593 c 2.59575882,2.03078 4.92396642,2.03973 7.67986362,-0.06 -3.6044602,-0.64366 -3.6257846,-2.34887 -7.67986362,0.06 z"
id="path4520"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<ellipse
style="fill:#919191;fill-opacity:1;stroke:#919191;stroke-width:0.04199925;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4522"
cx="4.0754137"
cy="294.64594"
rx="0.92998338"
ry="0.86998433" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -5,6 +5,7 @@ Version 0.4.6:
new features:
- Can protect Audio API
- Settings can be hidden
fixes:
-