set classes dynamically
* `sticky` on #header when scrolled * `sectioned` on html for sectioned editor
This commit is contained in:
parent
aad4828e4a
commit
d25ef97205
18
edit/base.js
18
edit/base.js
|
@ -1,4 +1,4 @@
|
||||||
/* global $ $$ $create setupLivePrefs waitForSelector */// dom.js
|
/* global $ $$ $create $root setupLivePrefs waitForSelector */// dom.js
|
||||||
/* global API */// msg.js
|
/* global API */// msg.js
|
||||||
/* global CODEMIRROR_THEMES */
|
/* global CODEMIRROR_THEMES */
|
||||||
/* global CodeMirror */
|
/* global CodeMirror */
|
||||||
|
@ -32,7 +32,7 @@ const editor = {
|
||||||
cancel: () => location.assign('/manage.html'),
|
cancel: () => location.assign('/manage.html'),
|
||||||
|
|
||||||
updateClass() {
|
updateClass() {
|
||||||
document.documentElement.classList.toggle('is-new-style', !editor.style.id);
|
$root.classList.toggle('is-new-style', !editor.style.id);
|
||||||
},
|
},
|
||||||
|
|
||||||
updateTitle(isDirty = editor.dirty.isDirty()) {
|
updateTitle(isDirty = editor.dirty.isDirty()) {
|
||||||
|
@ -49,16 +49,14 @@ const editor = {
|
||||||
|
|
||||||
const baseInit = (() => {
|
const baseInit = (() => {
|
||||||
const domReady = waitForSelector('#sections');
|
const domReady = waitForSelector('#sections');
|
||||||
const mq = matchMedia('(max-width: 850px)');
|
const mqCompact = matchMedia('(max-width: 850px)');
|
||||||
(mq.onchange = e => {
|
const toggleCompact = mq => $root.classList.toggle('compact-layout', mq.matches);
|
||||||
document.documentElement.classList.toggle('compact-layout', e.matches);
|
mqCompact.on('change', toggleCompact);
|
||||||
for (const el of $$('details[data-pref]')) {
|
toggleCompact(mqCompact);
|
||||||
el.open = e.matches ? false : prefs.get(el.dataset.pref);
|
|
||||||
}
|
|
||||||
})(mq);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
domReady,
|
domReady,
|
||||||
|
mqCompact,
|
||||||
ready: Promise.all([
|
ready: Promise.all([
|
||||||
domReady,
|
domReady,
|
||||||
loadStyle(),
|
loadStyle(),
|
||||||
|
@ -94,7 +92,7 @@ const baseInit = (() => {
|
||||||
editor.style = style;
|
editor.style = style;
|
||||||
editor.updateClass();
|
editor.updateClass();
|
||||||
editor.updateTitle(false);
|
editor.updateTitle(false);
|
||||||
document.documentElement.classList.toggle('usercss', editor.isUsercss);
|
$root.classList.add(editor.isUsercss ? 'usercss' : 'sectioned');
|
||||||
sessionStore.justEditedStyleId = style.id || '';
|
sessionStore.justEditedStyleId = style.id || '';
|
||||||
// no such style so let's clear the invalid URL parameters
|
// no such style so let's clear the invalid URL parameters
|
||||||
if (!style.id) history.replaceState({}, '', location.pathname);
|
if (!style.id) history.replaceState({}, '', location.pathname);
|
||||||
|
|
|
@ -379,11 +379,11 @@ input:invalid {
|
||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
pointer-events: auto !important; /* FF bug */
|
pointer-events: auto !important; /* FF bug */
|
||||||
}
|
}
|
||||||
.section-editor .section {
|
.sectioned .section {
|
||||||
margin: 0 0.7rem;
|
margin: 0 0.7rem;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
}
|
}
|
||||||
.section-editor .section:not(:first-child) {
|
.sectioned .section:not(:first-child) {
|
||||||
border-top: 2px solid hsl(0, 0%, 80%);
|
border-top: 2px solid hsl(0, 0%, 80%);
|
||||||
}
|
}
|
||||||
.add-section:after {
|
.add-section:after {
|
||||||
|
@ -419,10 +419,10 @@ input:invalid {
|
||||||
content: counter(codebox) ": " attr(data-text);
|
content: counter(codebox) ": " attr(data-text);
|
||||||
margin-left: 0.25rem;
|
margin-left: 0.25rem;
|
||||||
}
|
}
|
||||||
.single-editor .applies-to {
|
.usercss .applies-to {
|
||||||
border-width: 1px 0;
|
border-width: 1px 0;
|
||||||
}
|
}
|
||||||
.single-editor .applies-to > label::before {
|
.usercss .applies-to > label::before {
|
||||||
content: attr(data-index) ":";
|
content: attr(data-index) ":";
|
||||||
margin-right: 0.25rem;
|
margin-right: 0.25rem;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
@ -586,7 +586,7 @@ body:not(.find-open) [data-match-highlight-count="1"] .CodeMirror-selection-high
|
||||||
padding: 0;
|
padding: 0;
|
||||||
line-height: var(--input-height);
|
line-height: var(--input-height);
|
||||||
}
|
}
|
||||||
.section-editor .applies-to label {
|
.sectioned .applies-to label {
|
||||||
margin-left: -24px;
|
margin-left: -24px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
}
|
||||||
|
@ -948,7 +948,7 @@ body:not(.find-open) [data-match-highlight-count="1"] .CodeMirror-selection-high
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
html:not(.usercss) .usercss-only,
|
.sectioned .usercss-only,
|
||||||
.usercss .sectioned-only {
|
.usercss .sectioned-only {
|
||||||
display: none !important; /* hide during page init */
|
display: none !important; /* hide during page init */
|
||||||
}
|
}
|
||||||
|
@ -1020,28 +1020,40 @@ html:not(.usercss) .usercss-only,
|
||||||
|
|
||||||
/************ reponsive layouts ************/
|
/************ reponsive layouts ************/
|
||||||
@media(max-width: 850px) {
|
@media(max-width: 850px) {
|
||||||
html:not(.usercss) body {
|
.sectioned body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
.usercss body {
|
.usercss body {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
.usercss #header {
|
.usercss #header,
|
||||||
position: inherit;
|
#header:not(.sticky) {
|
||||||
|
position: static;
|
||||||
}
|
}
|
||||||
#header {
|
#header {
|
||||||
display: block;
|
display: block;
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
height: unset;
|
height: unset;
|
||||||
width: unset;
|
width: 100%;
|
||||||
position: sticky;
|
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border-right: none;
|
border-right: none;
|
||||||
border-bottom: 1px dashed #AAA;
|
border-bottom: 1px dashed #AAA;
|
||||||
padding: var(--pad05) var(--pad05) 0;
|
padding: var(--pad05) var(--pad05) 0;
|
||||||
}
|
}
|
||||||
|
#header.sticky {
|
||||||
|
box-shadow: 0 0 3rem -.75rem black;
|
||||||
|
}
|
||||||
|
#header.sticky #basic-info,
|
||||||
|
#header.sticky #mozilla-format-buttons,
|
||||||
|
#header.sticky .buttons > button,
|
||||||
#heading,
|
#heading,
|
||||||
|
#header-sticker {
|
||||||
|
top: 0;
|
||||||
|
height: 1px;
|
||||||
|
position: absolute;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
h2 {
|
h2 {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
@ -1092,7 +1104,6 @@ html:not(.usercss) .usercss-only,
|
||||||
#sections {
|
#sections {
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
}
|
}
|
||||||
/* TODO: switch from .single-editor to the global .usercss */
|
|
||||||
#sections > :not(.single-editor) {
|
#sections > :not(.single-editor) {
|
||||||
margin: 0 .5rem;
|
margin: 0 .5rem;
|
||||||
padding: .5rem 0;
|
padding: .5rem 0;
|
||||||
|
|
34
edit/edit.js
34
edit/edit.js
|
@ -25,11 +25,7 @@ baseInit.ready.then(async () => {
|
||||||
await editor.ready;
|
await editor.ready;
|
||||||
editor.ready = true;
|
editor.ready = true;
|
||||||
editor.dirty.onChange(editor.updateDirty);
|
editor.dirty.onChange(editor.updateDirty);
|
||||||
|
prefs.subscribe('editor.linter', () => linterMan.run());
|
||||||
prefs.subscribe('editor.linter', (key, value) => {
|
|
||||||
document.body.classList.toggle('linter-disabled', value === '');
|
|
||||||
linterMan.run();
|
|
||||||
});
|
|
||||||
|
|
||||||
// enabling after init to prevent flash of validation failure on an empty name
|
// enabling after init to prevent flash of validation failure on an empty name
|
||||||
$('#name').required = !editor.isUsercss;
|
$('#name').required = !editor.isUsercss;
|
||||||
|
@ -74,6 +70,34 @@ baseInit.ready.then(async () => {
|
||||||
'/edit/drafts',
|
'/edit/drafts',
|
||||||
'/edit/global-search',
|
'/edit/global-search',
|
||||||
]);
|
]);
|
||||||
|
}).then(() => {
|
||||||
|
// Set up mini-header on scroll
|
||||||
|
const {isUsercss} = editor;
|
||||||
|
const el = $create('#header-sticker');
|
||||||
|
const scroller = isUsercss ? $('.CodeMirror-scroll') : document.body;
|
||||||
|
const xo = new IntersectionObserver(onScrolled, {root: isUsercss ? scroller : document});
|
||||||
|
scroller.appendChild(el);
|
||||||
|
onCompactToggled(baseInit.mqCompact);
|
||||||
|
baseInit.mqCompact.on('change', onCompactToggled);
|
||||||
|
|
||||||
|
/** @param {MediaQueryList} mq */
|
||||||
|
function onCompactToggled(mq) {
|
||||||
|
for (const el of $$('details[data-pref]')) {
|
||||||
|
el.open = mq.matches ? false : prefs.get(el.dataset.pref);
|
||||||
|
}
|
||||||
|
if (mq.matches) {
|
||||||
|
xo.observe(el);
|
||||||
|
} else {
|
||||||
|
xo.disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/** @param {IntersectionObserverEntry[]} entries */
|
||||||
|
function onScrolled([e]) {
|
||||||
|
const h = $('#header');
|
||||||
|
const sticky = !e.isIntersecting;
|
||||||
|
if (!isUsercss) scroller.style.paddingTop = sticky ? h.offsetHeight + 'px' : '';
|
||||||
|
h.classList.toggle('sticky', sticky);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
|
@ -27,6 +27,8 @@ Object.assign(EventTarget.prototype, {
|
||||||
|
|
||||||
//#region Exports
|
//#region Exports
|
||||||
|
|
||||||
|
const $root = document.documentElement;
|
||||||
|
|
||||||
// Makes the focus outline appear on keyboard tabbing, but not on mouse clicks.
|
// Makes the focus outline appear on keyboard tabbing, but not on mouse clicks.
|
||||||
const focusAccessibility = {
|
const focusAccessibility = {
|
||||||
// last event's focusedViaClick
|
// last event's focusedViaClick
|
||||||
|
@ -474,10 +476,9 @@ const dom = {};
|
||||||
const lazyScripts = [
|
const lazyScripts = [
|
||||||
'/js/dom-on-load',
|
'/js/dom-on-load',
|
||||||
];
|
];
|
||||||
const elHtml = document.documentElement;
|
if (!UA.windows) $root.classList.add('non-windows');
|
||||||
if (!UA.windows) elHtml.classList.add('non-windows');
|
|
||||||
// set language for a) CSS :lang pseudo and b) hyphenation
|
// set language for a) CSS :lang pseudo and b) hyphenation
|
||||||
elHtml.setAttribute('lang', chrome.i18n.getUILanguage());
|
$root.setAttribute('lang', chrome.i18n.getUILanguage());
|
||||||
// set up header width resizer
|
// set up header width resizer
|
||||||
const HW = 'headerWidth.';
|
const HW = 'headerWidth.';
|
||||||
const HWprefId = HW + location.pathname.match(/^.(\w*)/)[1];
|
const HWprefId = HW + location.pathname.match(/^.(\w*)/)[1];
|
||||||
|
@ -489,7 +490,7 @@ const dom = {};
|
||||||
// If this is a small window on a big monitor the user can maximize it later
|
// If this is a small window on a big monitor the user can maximize it later
|
||||||
const max = (innerWidth < 850 ? screen.availWidth : innerWidth) / 3;
|
const max = (innerWidth < 850 ? screen.availWidth : innerWidth) / 3;
|
||||||
width = Math.round(Math.max(200, Math.min(max, Number(width) || 0)));
|
width = Math.round(Math.max(200, Math.min(max, Number(width) || 0)));
|
||||||
elHtml.style.setProperty('--header-width', width + 'px');
|
$root.style.setProperty('--header-width', width + 'px');
|
||||||
return width;
|
return width;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue
Block a user