diff --git a/edit.html b/edit.html
index 05936741..8dd7cf5e 100644
--- a/edit.html
+++ b/edit.html
@@ -418,17 +418,15 @@
-
+
- :
+
-
+
diff --git a/edit/base.js b/edit/base.js
index a42b5f65..0e9afaf5 100644
--- a/edit/base.js
+++ b/edit/base.js
@@ -6,14 +6,7 @@
/* global initBeautifyButton */// beautify.js
/* global prefs */
/* global t */// localization.js
-/* global
- FIREFOX
- debounce
- getOwnTab
- sessionStore
- tryJSONparse
- tryURL
-*/// toolbox.js
+/* global FIREFOX getOwnTab sessionStore tryJSONparse tryURL */// toolbox.js
'use strict';
/**
@@ -56,6 +49,13 @@ const editor = {
const baseInit = (() => {
const domReady = waitForSelector('#sections');
+ const mq = matchMedia('(max-width: 850px)');
+ (mq.onchange = e => {
+ document.documentElement.classList.toggle('compact-layout', e.matches);
+ for (const el of $$('details[data-pref]')) {
+ el.open = e.matches ? false : prefs.get(el.dataset.pref);
+ }
+ })(mq);
return {
domReady,
@@ -120,45 +120,6 @@ const baseInit = (() => {
}
})();
-//#endregion
-//#region init layout/resize
-
-baseInit.domReady.then(() => {
- let headerHeight;
- detectLayout(true);
- window.on('resize', () => detectLayout());
-
- function detectLayout(now) {
- const compact = window.innerWidth <= 850;
- if (compact) {
- document.body.classList.add('compact-layout');
- if (!editor.isUsercss) {
- if (now) fixedHeader();
- else debounce(fixedHeader, 250);
- window.on('scroll', fixedHeader, {passive: true});
- }
- } else {
- document.body.classList.remove('compact-layout', 'fixed-header');
- window.off('scroll', fixedHeader);
- }
- for (const el of $$('details[data-pref]')) {
- el.open = compact ? false : prefs.get(el.dataset.pref);
- }
- }
-
- function fixedHeader() {
- const headerFixed = $('.fixed-header');
- if (!headerFixed) headerHeight = $('#header').clientHeight;
- const scrollPoint = headerHeight - 43;
- if (window.scrollY >= scrollPoint && !headerFixed) {
- $('body').style.setProperty('--fixed-padding', ` ${headerHeight}px`);
- $('body').classList.add('fixed-header');
- } else if (window.scrollY < scrollPoint && headerFixed) {
- $('body').classList.remove('fixed-header');
- }
- }
-});
-
//#endregion
//#region init header
diff --git a/edit/edit.css b/edit/edit.css
index 2bad83a1..e771619e 100644
--- a/edit/edit.css
+++ b/edit/edit.css
@@ -1,5 +1,6 @@
:root {
- --fixed-padding: unset;
+ --pad: 1rem;
+ --pad05: calc(0.5 * var(--pad));
}
body {
@@ -70,7 +71,7 @@ html:not(.is-new-style) #heading::after {
#popup-button:hover {
filter: drop-shadow(0 0 3px hsl(180, 70%, 50%));
}
-.usercss body:not(.compact-layout) #popup-button {
+.usercss:not(.compact-layout) #popup-button {
right: 24px;
}
/************ checkbox & select************/
@@ -91,10 +92,10 @@ label {
#header {
width: var(--header-width);
height: 100vh;
- overflow: auto;
+ overflow: hidden;
position: fixed;
top: 0;
- padding: 1rem;
+ padding-top: var(--pad);
box-shadow: 0 0 3rem -1.2rem black;
box-sizing: border-box;
z-index: 10;
@@ -222,56 +223,61 @@ input:invalid {
margin-left: 0;
}
/* collapsibles */
+#header details {
+ margin-right: var(--header-resizer-width);
+}
+#header details[open] {
+ overflow-y: auto;
+ margin-top: calc(1.5*var(--pad));
+}
+#header details[open] summary {
+ position: absolute;
+ margin-top: calc(-1.5*var(--pad));
+}
#header summary {
align-items: center;
- margin-left: -13px;
+ margin-left: .25em;
cursor: pointer;
-}
-#header summary + * {
- padding: .5rem 0;
+ white-space: nowrap;
}
#header summary h2 {
display: inline-block;
border-bottom: 1px dotted transparent;
- margin-top: .1em;
- margin-bottom: .1em;
- margin-left: -13px;
+ margin: 0 0 0 -13px;
padding-left: 13px; /* clicking directly on details-marker doesn't set pref so we cover it with h2 */
+ max-width: calc(var(--header-width) - 2*var(--pad));
+ vertical-align: middle;
+}
+#header summary h2,
+#header summary h2 > :first-child {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
}
-
#header summary:hover h2 {
border-color: #bbb;
}
-
#header summary svg {
margin-top: -3px;
}
-
+#header details > :not(summary) {
+ margin: 0 0 0 var(--pad);
+ padding: calc(var(--pad)/4) 0;
+}
#details-wrapper {
display: flex;
flex-direction: column;
flex-grow: 1;
+ overflow: hidden;
+ margin-top: var(--pad05);
}
-
-#header details[open] + details[open] {
- margin-top: .5rem;
-}
-
#actions .buttons {
display: inline-flex;
flex-wrap: wrap;
align-items: center;
}
-
#actions .buttons > * {
- margin: 0 .25rem .5rem 0;
-}
-
-#options:not([open]) + #lint h2 {
- margin-top: 0;
-}
-#lint:not([open]) h2 {
- margin-bottom: 0;
+ margin: 0 .25rem var(--pad05) 0;
}
#publish > div > * {
@@ -426,8 +432,6 @@ input:invalid {
}
#toc {
counter-reset: codelabel;
- margin: 0;
- padding: .5rem 0;
}
#toc li {
white-space: nowrap;
@@ -829,40 +833,13 @@ body:not(.find-open) [data-match-highlight-count="1"] .CodeMirror-selection-high
/************ lint ************/
#lint {
- overflow: hidden;
- margin-left: -1rem;
- margin-right: -1rem;
- padding: 0;
- box-sizing: border-box;
- display: flex;
- flex-grow: 1;
- position: relative;
-}
-#lint > summary {
- position: relative;
- margin-left: 0;
- padding-left: 4px;
-}
-#lint[open]:not(.hidden-unless-compact) {
- min-height: 102px;
-}
-#lint summary h2 {
- text-indent: -2px;
-}
-#lint > .lint-scroll-container {
- margin: 1rem 10px 0;
- position: absolute;
- top: 0;
- bottom: 0;
- left: 0;
- right: 0;
- overflow-y: auto;
overflow-x: hidden;
}
+#lint summary h2 {
+ display: inline-flex;
+}
#lint table {
- font-size: 100%;
border-spacing: 0;
- margin-bottom: 1rem;
line-height: 1.0;
width: 100%;
}
@@ -878,7 +855,7 @@ body:not(.find-open) [data-match-highlight-count="1"] .CodeMirror-selection-high
#lint table.empty {
display: none;
}
-#lint caption {
+#lint caption:not(:empty) {
text-align: left;
font-weight: bold;
padding-bottom: 6px;
@@ -908,6 +885,9 @@ body:not(.find-open) [data-match-highlight-count="1"] .CodeMirror-selection-high
text-align: left;
white-space: nowrap;
}
+#issue-count::before {
+ content: ':\A0';
+}
#message-box.center.lint-config #message-box-contents {
text-align: left;
}
@@ -970,11 +950,6 @@ html:not(.usercss) .usercss-only,
display: none !important; /* hide during page init */
}
-body:not(.compact-layout) .hidden-unless-compact,
-body.linter-disabled .hidden-unless-compact {
- display: none !important;
-}
-
#options:not([open]) + #lint {
margin-top: 0;
}
@@ -1021,152 +996,100 @@ body.linter-disabled .hidden-unless-compact {
margin-left: 0.2rem;
}
+/************ full-width only ************/
+/* TODO: maybe move more rules here so we don't need to reset them in @media(max-width: 850px) */
+@media (min-width: 851px) {
+ #header > :not(#details-wrapper):not(#header-resizer) {
+ margin-left: var(--pad);
+ margin-right: var(--pad);
+ }
+ #publish[open],
+ #header details:not([open]) {
+ flex: 0 0 auto;
+ }
+ #header details[open]:not(:last-child) {
+ margin-bottom: var(--pad05);
+ }
+ #header details:last-child {
+ padding-bottom: var(--pad);
+ }
+}
+
/************ reponsive layouts ************/
@media(max-width: 850px) {
- body {
+ html:not(.usercss) body {
+ height: 100%;
+ }
+ .usercss body {
display: flex;
flex-direction: column;
}
+ .usercss #header {
+ position: inherit;
+ }
#header {
- flex: 0 1 auto;
+ display: block;
+ flex: 0 0 auto;
height: unset;
width: unset;
- position: inherit;
+ position: sticky;
+ background: #fff;
border-right: none;
border-bottom: 1px dashed #AAA;
- padding: .5rem 1rem .5rem .5rem;
- }
- .fixed-header {
- --fixed-height: 40px;
- padding-top: var(--fixed-padding);
- }
- .fixed-header #header {
- min-height: var(--fixed-height);
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- padding: 0;
- background-color: #fff;
- }
- .fixed-header #header > *:not(#details-wrapper),
- .fixed-header #options {
- display: none !important;
- }
- .fixed-header #details-wrapper {
- padding-top: calc((var(--fixed-height) - 1.2rem) / 2); /* 1.2 is the normal line height */
- }
- #header summary + *,
- #lint > .lint-scroll-container {
- margin-left: 1rem;
- padding: .25rem 0 .5rem;
- }
- #header input[type="checkbox"] {
- vertical-align: middle;
- }
- #header details {
- margin: 0;
+ padding: var(--pad05) var(--pad05) 0;
}
#heading,
h2 {
display: none;
}
#basic-info {
- margin-bottom: .5rem;
+ margin: 0 16px var(--pad05) 0; /* for popup icon in simple window */
box-sizing: border-box;
display: flex;
flex-wrap: wrap;
}
+ #basic-info #name,
#basic-info > *:first-child {
flex-grow: 1;
}
#basic-info > *:not(:last-child) {
margin-right: 0.8rem;
}
- #basic-info #name {
- flex-grow: 1;
+ #header details > :not(summary) {
+ margin-left: var(--pad05);
}
- #options-wrapper {
- display: flex;
- flex-wrap: wrap;
- box-sizing: border-box;
+ #header h2 {
+ font-size: 14px;
+ }
+ #actions {
+ display: inline-block;
}
#details-wrapper {
+ display: inline-flex;
+ vertical-align: top;
+ max-width: 100%;
flex-direction: row;
- flex-wrap: wrap;
+ margin: .25em 0 var(--pad05);
}
- #options[open] {
- width: 100%;
+ #details-wrapper details[open] {
+ max-height: 10vh;
}
- #sections-list[open] {
- max-height: 102px;
- }
- #sections-list[open] #toc {
- max-height: 60px;
- overflow-y: auto;
- }
- #header details:not(#options) {
+ #details-wrapper[data-open^=".."] details {
max-width: 50%;
}
- .options-column {
- flex-grow: 1;
- padding-right: .5rem;
- box-sizing: border-box;
+ #details-wrapper[data-open^="..."] {
+ flex-wrap: wrap;
}
- .options-column > .usercss-only {
- margin-bottom: 0;
- }
- #options-wrapper .options-column:nth-child(2) {
- margin-top: 0;
- }
- #options:not([open]),
+ #options[open],
+ #publish[open],
#lint:not([open]) {
- overflow: initial;
- }
- #options:not([open]) + #lint:not([open]) {
- margin-top: 0;
- }
- #lint summary {
- position: static;
- margin-bottom: 0;
- }
- #header summary {
- margin-left: 0;
- padding-left: 4px;
- }
- #header summary h2 {
- margin: 0;
- padding: 0;
- }
- .option label {
- margin: 0;
- }
- #options [type="number"] {
- text-align: left; /* workaround the column flow bug in webkit */
- padding-left: 0.2rem;
- }
- #options #tabSize-label {
- position: relative;
- top: 0.2rem;
- }
- #lint > .lint-scroll-container {
- padding-top: 0;
- margin-right: 0;
- }
- #lint {
- padding: 0;
- margin: .5rem 0 0;
- }
- #lint:not([open]) + #footer {
- margin: .25em 0 -1em .25em;
+ flex: 0 0 auto;
+ overflow-x: hidden;
}
#sections {
- height: unset !important;
padding-left: 0;
- display: flex;
- flex-direction: column;
- flex: 1;
}
+ /* TODO: switch from .single-editor to the global .usercss */
#sections > :not(.single-editor) {
margin: 0 .5rem;
padding: .5rem 0;
@@ -1175,10 +1098,6 @@ body.linter-disabled .hidden-unless-compact {
overflow: hidden;
flex: 1;
}
- .usercss #options:not([open]) ~ #lint.hidden ~ #footer,
- .usercss #lint:not([open]) + #footer {
- margin-top: -.25em;
- }
#help-popup.big[style="display: block;"],
#help-popup[style="display: block;"] {
width: max-content;
diff --git a/edit/edit.js b/edit/edit.js
index 64e5c0ea..89a945b5 100644
--- a/edit/edit.js
+++ b/edit/edit.js
@@ -1,4 +1,4 @@
-/* global $ $create messageBoxProxy waitForSheet */// dom.js
+/* global $$ $ $create messageBoxProxy waitForSheet */// dom.js
/* global API msg */// msg.js
/* global CodeMirror */
/* global SectionsEditor */
@@ -43,6 +43,19 @@ baseInit.ready.then(async () => {
new MutationObserver(() => elSec.open && editor.updateToc())
.observe(elSec, {attributes: true, attributeFilter: ['open']});
+ // Auto-update `data-open` attribute to the number of open details
+ {
+ const wrapper = $('#details-wrapper');
+ const details = $$('details', wrapper);
+ const ds = wrapper.dataset;
+ const update = () => {
+ ds.open = '.'.repeat(details.reduce((res, el) => res + (el.open ? 1 : 0), 0));
+ };
+ for (const el of details) {
+ new MutationObserver(update).observe(el, {attributes: true, attributeFilter: ['open']});
+ }
+ }
+
$('#toc').onclick = e =>
editor.jumpToEditor([...$('#toc').children].indexOf(e.target));
$('#keyMap-help').onclick = () =>
diff --git a/edit/linter-manager.js b/edit/linter-manager.js
index a4c26751..d6b65a71 100644
--- a/edit/linter-manager.js
+++ b/edit/linter-manager.js
@@ -312,7 +312,7 @@ linterMan.DEFAULTS = {
function updateCount() {
const issueCount = Array.from(tables.values())
.reduce((sum, table) => sum + table.trs.length, 0);
- $('#lint').classList.toggle('hidden-unless-compact', issueCount === 0);
+ $('#lint').hidden = !issueCount;
$('#issue-count').textContent = issueCount;
}
diff --git a/global.css b/global.css
index cbb92c9e..8af35744 100644
--- a/global.css
+++ b/global.css
@@ -277,13 +277,15 @@ input[type="number"][data-focused-via-click]:focus {
/* header resizer */
:root {
--header-width: 280px;
+ --header-resizer-width: 8px;
}
#header-resizer {
position: absolute;
top: 0;
right: 0;
bottom: 0;
- width: 6px;
+ width: var(--header-resizer-width);
+ box-sizing: border-box;
cursor: e-resize;
border-width: 0 1px;
border-style: solid;
diff --git a/manifest.json b/manifest.json
index a6a4ef9b..c0e75c0c 100644
--- a/manifest.json
+++ b/manifest.json
@@ -1,7 +1,7 @@
{
"name": "Stylus",
"version": "1.5.22",
- "minimum_chrome_version": "55",
+ "minimum_chrome_version": "56",
"description": "__MSG_description__",
"homepage_url": "https://add0n.com/stylus.html",
"manifest_version": 2,