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": "" "description": ""
}, },
"displayHiddenSettings_title": {
"message": "Versteckte Einstellungen anzeigen",
"description": ""
},
"displayHiddenSettings_description": {
"message": "Aktivieren, um versteckte Einstellungen anzuzeigen.",
"description": ""
},
"allowPDFCanvas_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.", "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": "" "description": ""

View File

@ -91,6 +91,15 @@
"description": "" "description": ""
}, },
"displayHiddenSettings_title": {
"message": "Display hidden settings",
"description": ""
},
"displayHiddenSettings_description": {
"message": "Activate to display the hidden settings.",
"description": ""
},
"allowPDFCanvas_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.", "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": "" "description": ""

View File

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

View File

@ -39,6 +39,7 @@
eventHandler.all = eventHandler.any; eventHandler.all = eventHandler.any;
const settings = {}; const settings = {};
let urlContainer; let urlContainer;
let hideContainer;
function isDefinitionInvalid(settingDefinition, newValue){ function isDefinitionInvalid(settingDefinition, newValue){
if (newValue === undefined && settingDefinition.optional){ 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){ settingDefinitions.forEach(function(settingDefinition){
if (settingDefinition.urlContainer){ if (settingDefinition.urlContainer){
urlContainer = settingDefinition; urlContainer = settingDefinition;
@ -255,7 +278,7 @@
settingDefinition.set = createSetter(settingDefinition); settingDefinition.set = createSetter(settingDefinition);
settingDefinition.reset = createResetter(settingDefinition); settingDefinition.reset = createResetter(settingDefinition);
if (settingDefinition.urlSpecific){ if (settingDefinition.urlSpecific){
if (!urlContainer){ if (!urlContainer){
logging.error("Unable to use url specific settings without url-container"); logging.error("Unable to use url specific settings without url-container");
@ -277,6 +300,41 @@
enumerable: true 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){ scope.getDefinition = function(name){
@ -288,6 +346,13 @@
return undefined; return undefined;
} }
}; };
scope.getContainers = function(){
return {
url: Object.create(urlContainer),
hide: Object.create(hideContainer)
};
};
scope.set = function(name, ...args){ scope.set = function(name, ...args){
var foundDefinition = definitionsByName[name]; var foundDefinition = definitionsByName[name];
@ -316,28 +381,6 @@
}).forEach(...args); }).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"); const resetSymbol = Symbol("reset");
function changeValue(name, newValue){ function changeValue(name, newValue){
var settingDefinition = scope.getDefinition(name); 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 { .settings .settingRow .content {
display: block;
overflow: visible; overflow: visible;
padding: 0.5em 0; padding: 0.5em 0;
border-top: 1px solid #c1c1c1; border-top: 1px solid #c1c1c1;
position: relative; position: relative;
} }
.settings .settingRow td:first-child .content { .settings .settingRow td:first-child .content, td.hideColumn label {
margin-left: 0.6em; margin-left: 0.6em;
} }
.settings .settingRow td:last-child .content { .settings .settingRow td:last-child .content {
@ -159,4 +160,30 @@ input[type=""], input[type="text"], input[type="number"], select {
} }
.urlValues .notSpecifiedForUrl { .urlValues .notSpecifiedForUrl {
opacity: 0.5; 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); document.body.appendChild(table);
const displayHidden = settings.getDefinition(settingsDisplay.displayHidden);
table.appendChild(optionsGui.createThead(displayHidden));
let lastSection = null; let lastSection = null;
let addSection = function addSection(name){ let addSection = function addSection(name){
let body = document.createElement("tbody"); let body = document.createElement("tbody");
@ -73,7 +76,7 @@
let row = document.createElement("tr"); let row = document.createElement("tr");
row.className = "section"; row.className = "section";
let cell = document.createElement("td"); let cell = document.createElement("td");
cell.colSpan = 2; cell.colSpan = 3;
row.appendChild(cell); row.appendChild(cell);
let heading = document.createElement("h2"); let heading = document.createElement("h2");
heading.textContent = browser.i18n.getMessage("section_" + name); heading.textContent = browser.i18n.getMessage("section_" + name);
@ -108,6 +111,7 @@
}; };
addSection(); addSection();
const {hide: hideContainer} = settings.getContainers();
settingsDisplay.forEach(function(display){ settingsDisplay.forEach(function(display){
if (typeof display === "string"){ if (typeof display === "string"){
addSection(display); addSection(display);
@ -129,32 +133,69 @@
} }
} }
if (setting){ if (setting){
var row = optionsGui.createSettingRow(setting); let hideChangeListeners = [];
let section = lastSection; setting.setHide = function setHide(value){
section.addRow(row); if (hideContainer){
if (display.displayDependencies){ hideContainer.setHideByName(display.name, value);
var displayDependencies = display.displayDependencies; if (computeDependencies){
displayDependencies = Array.isArray(displayDependencies)? computeDependencies();
displayDependencies: }
[displayDependencies]; }
var computeDependencies = function(){ };
logging.verbose("evaluate display dependencies for", setting); setting.onHideChange = function(listener){
row.classList[( hideChangeListeners.push(listener);
displayDependencies.some(function(displayDependency){ };
return Object.keys(displayDependency).every(function(key){ setting.getHide = function getHide(){
return displayDependency[key].indexOf(settings[key]) !== -1; if (hideContainer){
}); return hideContainer.getHideByName(display.name);
}) }
)? "remove": "add"]("hidden"); else {
section.updateDisplay(); return false;
}; }
computeDependencies(); };
displayDependencies.forEach(function(displayDependency){ if (hideContainer){
Object.keys(displayDependency).forEach(function(name){ hideContainer.onHideChange(display.name, function(value){
settings.on(name, computeDependencies); 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

@ -303,10 +303,36 @@
c.appendChild(interaction); c.appendChild(interaction);
return c; 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){ function createSettingRow(setting){
var tr = document.createElement("tr"); var tr = document.createElement("tr");
tr.className = "settingRow"; tr.className = "settingRow";
var hide = document.createElement("td");
hide.className = "hideColumn";
hide.appendChild(createHide(setting));
tr.appendChild(hide);
var left = document.createElement("td"); var left = document.createElement("td");
left.appendChild(createDescription(setting)); left.appendChild(createDescription(setting));
@ -320,4 +346,29 @@
} }
scope.createSettingRow = createSettingRow; 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"){ if ((typeof module) !== "undefined"){
module.exports = settingsDisplay; 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: new features:
- Can protect Audio API - Can protect Audio API
- Settings can be hidden
fixes: fixes:
- -