manage: collapsible #options block
This commit is contained in:
parent
c0a227fa39
commit
189342472e
|
@ -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">
|
||||
|
|
|
@ -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;
|
||||
|
|
23
edit/edit.js
23
edit/edit.js
|
@ -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;
|
||||
|
|
32
js/dom.js
32
js/dom.js
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user