manage: collapsible #options block

This commit is contained in:
tophf 2017-11-29 19:05:47 +03:00
parent c0a227fa39
commit 189342472e
8 changed files with 77 additions and 33 deletions

View File

@ -166,7 +166,7 @@
<button id="to-mozilla" i18n-text="exportLabel"></button>
</div>
</section>
<details id="options">
<details id="options" data-pref="editor.options.expanded">
<summary><h2 id="options-heading" i18n-text="optionsHeading"></h2></summary>
<div class="option">
<input id="editor.lineWrapping" type="checkbox">
@ -242,7 +242,7 @@
</span>
</div>
</details>
<details id="lint" class="hidden">
<details id="lint" class="hidden" data-pref="editor.lint.expanded">
<summary>
<h2 i18n-text="linterIssues">: <span id="issue-count"></span><!-- EAT SPACE
--><svg id="lint-help" class="svg-icon info intercepts-click">

View File

@ -139,7 +139,7 @@ input:invalid {
}
#header summary h2 {
display: inline-block;
border-bottom: 2px dotted transparent;
border-bottom: 1px dotted transparent;
}
#header summary h2:hover {
border-color: #bbb;

View File

@ -6,6 +6,7 @@
/* global mozParser createSourceEditor */
/* global closeCurrentTab regExpTester messageBox */
/* global initColorpicker */
/* global initCollapsibles */
'use strict';
let styleId = null;
@ -1430,28 +1431,6 @@ function addSections(sections, onAdded = () => {}) {
}
}
function initCollapsibles() {
function saveStateDelayed(event) {
if (event.target.closest('.intercepts-click')) {
event.preventDefault();
} else {
setTimeout(saveState, 0, event.target.closest('details'));
}
}
function saveState(el) {
prefs.set(`editor.${el.id}.expanded`, el.open);
}
function loadState(key, value) {
$('#' + key.split('.')[1]).open = value;
}
const collapsibles = $$('#header details');
for (const el of collapsibles) {
el.open = prefs.get(`editor.${el.id}.expanded`);
$('h2', el).addEventListener('click', saveStateDelayed);
}
prefs.subscribe(collapsibles.map(el => `editor.${el.id}.expanded`), loadState);
}
function initHooks() {
if (initHooks.alreadyDone) {
return;

View File

@ -211,3 +211,35 @@ function makeLink(href = '', content) {
}
return $element(opt);
}
function initCollapsibles({bindClickOn = 'h2'} = {}) {
const prefMap = {};
const elements = $$('details[data-pref]');
for (const el of elements) {
const key = el.dataset.pref;
prefMap[key] = el;
el.open = prefs.get(key);
(bindClickOn && $(bindClickOn, el) || el).addEventListener('click', onClick);
}
prefs.subscribe(Object.keys(prefMap), (key, value) => {
const el = prefMap[key];
if (el.open !== value) {
el.open = value;
}
});
function onClick(event) {
if (event.target.closest('.intercepts-click')) {
event.preventDefault();
} else {
setTimeout(saveState, 0, event.target.closest('details'));
}
}
function saveState(el) {
prefs.set(el.dataset.pref, el.open);
}
}

View File

@ -23,6 +23,8 @@ var prefs = new function Prefs() {
'manage.onlyEnabled.invert': false, // display only disabled styles
'manage.onlyLocal.invert': false, // display only externally installed styles
'manage.onlyUsercss.invert': false, // display only non-usercss (standard) styles
// UI element state: expanded/collapsed
'manage.options.expanded': true,
// the new compact layout doesn't look good on Android yet
'manage.newUI': !navigator.appVersion.includes('Android'),
'manage.newUI.favicons': false, // show favicons for the sites in applies-to

View File

@ -138,7 +138,7 @@
<template data-id="extraAppliesTo">
<details class="applies-to-extra">
<summary i18n-text="appliesDisplayTruncatedSuffix"></summary>
<summary class="applies-to-extra-expander" i18n-text="appliesDisplayTruncatedSuffix"></summary>
</details>
</template>
@ -229,8 +229,8 @@
</a>
</label>
</p>
<div id="options">
<h2 id="options-heading" i18n-text="optionsHeading"></h2>
<details id="options" data-pref="manage.options.expanded">
<summary><h2 id="options-heading" i18n-text="optionsHeading"></h2></summary>
<label><input id="manage.newUI" type="checkbox"><span i18n-text="manageNewUI"></span></label>
<div id="newUIoptions">
<div>
@ -258,7 +258,7 @@
i18n-title="editorStylesButton"
target="_blank"><button i18n-text="cm_theme"></button></a>
</p>
</div>
</details>
<div id="backup">
<h2 id="backup-title" i18n-text="backupButtons"></h2>
<span id="backup-message" i18n-text="backupMessage"></span>

View File

@ -188,17 +188,17 @@ label.nobreak input {
margin-left: 1ex;
}
summary {
.applies-to-extra-expander {
font-weight: bold;
cursor: pointer;
outline: none;
}
.applies-to-extra summary {
.applies-to-extra-expander {
list-style-type: none; /* for FF, allegedly */
}
.applies-to-extra summary::-webkit-details-marker {
.applies-to-extra-expander::-webkit-details-marker {
display: none;
}
@ -239,6 +239,30 @@ summary {
display: none;
}
/* collapsibles */
#header details:not([open]) h2 {
margin-bottom: -.25em;
}
#header summary {
align-items: center;
margin-left: -13px;
cursor: pointer;
outline: none;
}
#header summary h2 {
display: inline-block;
border-bottom: 1px dotted transparent;
margin-top: .2em;
margin-bottom: .4em;
}
#header summary h2:hover {
border-color: #bbb;
}
/* compact layout */
.newUI #installed {

View File

@ -3,6 +3,7 @@
/* global checkUpdate, handleUpdateInstalled */
/* global objectDiff */
/* global configDialog */
/* global initCollapsibles */
'use strict';
let installed;
@ -74,6 +75,9 @@ function initGlobalEvents() {
// N.B. triggers existing onchange listeners
setupLivePrefs();
// the options block
initCollapsibles();
$$('[id^="manage.newUI"]')
.forEach(el => (el.oninput = (el.onchange = switchUI)));
@ -519,10 +523,13 @@ function usePrefsDuringPageLoad() {
for (const mutation of mutations) {
for (const node of mutation.addedNodes) {
// [naively] assuming each element of addedNodes is a childless element
const prefValue = node.id ? prefs.readOnlyValues[node.id] : undefined;
const key = node.dataset && node.dataset.pref || node.id;
const prefValue = key ? prefs.readOnlyValues[key] : undefined;
if (prefValue !== undefined) {
if (node.type === 'checkbox') {
node.checked = prefValue;
} else if (node.localName === 'details') {
node.open = prefValue;
} else {
node.value = prefValue;
}