fix/deduplicate/simplify installer html/css/js (#1383)
This commit is contained in:
parent
936f5b40d2
commit
0705392fb2
38
edit.html
38
edit.html
|
@ -230,44 +230,6 @@
|
||||||
</table>
|
</table>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template data-id="styleSettings">
|
|
||||||
<div>
|
|
||||||
<fieldset class="style-settings can-close-on-esc">
|
|
||||||
<label i18n-text="styleUpdateUrlLabel">
|
|
||||||
<input id="ss-update-url" type="text">
|
|
||||||
</label>
|
|
||||||
<div>
|
|
||||||
<div i18n-text="installPreferSchemeLabel"></div>
|
|
||||||
<label i18n-text-append="installPreferSchemeNone">
|
|
||||||
<input name="ss-scheme" type="radio" value="none">
|
|
||||||
</label>
|
|
||||||
<label i18n-text-append="installPreferSchemeDark">
|
|
||||||
<input name="ss-scheme" type="radio" value="dark">
|
|
||||||
</label>
|
|
||||||
<label i18n-text-append="installPreferSchemeLight">
|
|
||||||
<input name="ss-scheme" type="radio" value="light">
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<label i18n-text="styleIncludeLabel">
|
|
||||||
<textarea id="ss-inclusions" spellcheck="false"
|
|
||||||
placeholder="*://site1.com/* *://site2.com/*"></textarea>
|
|
||||||
</label>
|
|
||||||
<label i18n-text="styleExcludeLabel">
|
|
||||||
<textarea id="ss-exclusions" spellcheck="false"
|
|
||||||
placeholder="*://site1.com/* *://site2.com/*"></textarea>
|
|
||||||
</label>
|
|
||||||
</fieldset>
|
|
||||||
<div class="buttons">
|
|
||||||
<button id="ss-save" i18n-text="confirmSave" disabled></button>
|
|
||||||
<label i18n-title="configOnChangeTooltip" i18n-text-append="configOnChange">
|
|
||||||
<input id="config.autosave" type="checkbox">
|
|
||||||
<svg class="svg-icon checked"><use xlink:href="#svg-icon-checked"/></svg>
|
|
||||||
</label>
|
|
||||||
<button id="ss-close" i18n-text="confirmClose"></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<link href="vendor/codemirror/lib/codemirror.css" rel="stylesheet">
|
<link href="vendor/codemirror/lib/codemirror.css" rel="stylesheet">
|
||||||
<link href="vendor/codemirror/addon/dialog/dialog.css" rel="stylesheet">
|
<link href="vendor/codemirror/addon/dialog/dialog.css" rel="stylesheet">
|
||||||
<link href="vendor/codemirror/addon/fold/foldgutter.css" rel="stylesheet">
|
<link href="vendor/codemirror/addon/fold/foldgutter.css" rel="stylesheet">
|
||||||
|
|
35
edit/settings.html
Normal file
35
edit/settings.html
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<div>
|
||||||
|
<fieldset class="style-settings can-close-on-esc">
|
||||||
|
<label i18n-text="styleUpdateUrlLabel">
|
||||||
|
<input id="ss-update-url" type="text">
|
||||||
|
</label>
|
||||||
|
<div id="ss-scheme">
|
||||||
|
<div i18n-text="installPreferSchemeLabel"></div>
|
||||||
|
<label i18n-text-append="installPreferSchemeNone">
|
||||||
|
<input name="ss-scheme" type="radio" value="none">
|
||||||
|
</label>
|
||||||
|
<label i18n-text-append="installPreferSchemeDark">
|
||||||
|
<input name="ss-scheme" type="radio" value="dark">
|
||||||
|
</label>
|
||||||
|
<label i18n-text-append="installPreferSchemeLight">
|
||||||
|
<input name="ss-scheme" type="radio" value="light">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<label i18n-text="styleIncludeLabel">
|
||||||
|
<textarea id="ss-inclusions" spellcheck="false"
|
||||||
|
placeholder="*://site1.com/* *://site2.com/*"></textarea>
|
||||||
|
</label>
|
||||||
|
<label i18n-text="styleExcludeLabel">
|
||||||
|
<textarea id="ss-exclusions" spellcheck="false"
|
||||||
|
placeholder="*://site1.com/* *://site2.com/*"></textarea>
|
||||||
|
</label>
|
||||||
|
</fieldset>
|
||||||
|
<div class="buttons">
|
||||||
|
<button id="ss-save" i18n-text="confirmSave" disabled></button>
|
||||||
|
<label i18n-title="configOnChangeTooltip" i18n-text-append="configOnChange">
|
||||||
|
<input id="config.autosave" type="checkbox">
|
||||||
|
<svg class="svg-icon checked"><use xlink:href="#svg-icon-checked"/></svg>
|
||||||
|
</label>
|
||||||
|
<button id="ss-close" i18n-text="confirmClose"></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -7,9 +7,10 @@
|
||||||
/* exported StyleSettings */
|
/* exported StyleSettings */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
function StyleSettings() {
|
async function StyleSettings() {
|
||||||
const AUTOSAVE_DELAY = 500; // same as config-dialog.js
|
const AUTOSAVE_DELAY = 500; // same as config-dialog.js
|
||||||
const SS_ID = 'styleSettings';
|
const SS_ID = 'styleSettings';
|
||||||
|
await t.fetchTemplate('/edit/settings.html', SS_ID);
|
||||||
const {style} = editor;
|
const {style} = editor;
|
||||||
const ui = t.template[SS_ID].cloneNode(true);
|
const ui = t.template[SS_ID].cloneNode(true);
|
||||||
const elAuto = $('[id="config.autosave"]', ui);
|
const elAuto = $('[id="config.autosave"]', ui);
|
||||||
|
|
|
@ -11,13 +11,12 @@
|
||||||
<script src="js/polyfill.js"></script>
|
<script src="js/polyfill.js"></script>
|
||||||
<script src="js/msg.js"></script>
|
<script src="js/msg.js"></script>
|
||||||
<script src="js/toolbox.js"></script>
|
<script src="js/toolbox.js"></script>
|
||||||
|
|
||||||
<script src="install-usercss/preinit.js"></script>
|
|
||||||
|
|
||||||
<script src="js/prefs.js"></script>
|
<script src="js/prefs.js"></script>
|
||||||
<script src="js/dom.js"></script>
|
<script src="js/dom.js"></script>
|
||||||
<script src="js/localization.js"></script>
|
<script src="js/localization.js"></script>
|
||||||
|
|
||||||
|
<script src="install-usercss/preinit.js"></script>
|
||||||
|
|
||||||
<script src="content/style-injector.js"></script>
|
<script src="content/style-injector.js"></script>
|
||||||
<script src="content/apply.js"></script>
|
<script src="content/apply.js"></script>
|
||||||
|
|
||||||
|
@ -25,66 +24,59 @@
|
||||||
<link href="install-usercss/install-usercss.css" rel="stylesheet">
|
<link href="install-usercss/install-usercss.css" rel="stylesheet">
|
||||||
</head>
|
</head>
|
||||||
<body id="stylus-install-usercss">
|
<body id="stylus-install-usercss">
|
||||||
<div class="container">
|
<div id="header">
|
||||||
<div id="header">
|
<div id="header-contents">
|
||||||
<div id="header-content-wrapper">
|
<h1 class="w100">
|
||||||
<h1>
|
<span class="meta-name"></span>
|
||||||
<span class="meta-name"></span>
|
<small class="meta-version"></small>
|
||||||
<small class="meta-version"></small>
|
</h1>
|
||||||
</h1>
|
<div id="install-wrapper">
|
||||||
<div class="actions">
|
<h2 class="install-show" i18n-text="installButtonInstalled"></h2>
|
||||||
<h2 hidden class="installed" i18n-text="installButtonInstalled"></h2>
|
<button class="install install-hide" i18n-text="installButton"></button>
|
||||||
<button class="install" i18n-text="installButton"></button>
|
<a class="configure-usercss" i18n-title="configureStyle" tabindex="0">
|
||||||
<a class="configure-usercss" i18n-title="configureStyle" tabindex="0">
|
<svg class="svg-icon config"><use xlink:href="#svg-icon-config"></use></svg>
|
||||||
<svg class="svg-icon config"><use xlink:href="#svg-icon-config"></use></svg>
|
</a>
|
||||||
</a>
|
<div class="install-show w100-full">
|
||||||
<p id="live-reload-install-hint" hidden></p>
|
<a href="manage.html"><button i18n-text="openManage"></button></a>
|
||||||
<label class="set-update-url">
|
<a id="edit" href="edit.html?id="><button i18n-text="editStyleLabel"></button></a>
|
||||||
<input type="checkbox">
|
<a id="delete" tabindex="0"><button i18n-text="deleteStyleLabel"></button></a>
|
||||||
<svg class="svg-icon checked"><use xlink:href="#svg-icon-checked"/></svg>
|
|
||||||
<span i18n-text="installUpdateFromLabel"></span>
|
|
||||||
<p></p>
|
|
||||||
</label>
|
|
||||||
<label class="live-reload">
|
|
||||||
<input type="checkbox">
|
|
||||||
<svg class="svg-icon checked"><use xlink:href="#svg-icon-checked"/></svg>
|
|
||||||
<span i18n-text="liveReloadLabel"></span>
|
|
||||||
</label>
|
|
||||||
<label class="set-prefer-scheme">
|
|
||||||
<span i18n-text="installPreferSchemeLabel"></span>
|
|
||||||
<select>
|
|
||||||
<option value="none" i18n-text="installPreferSchemeNone"></option>
|
|
||||||
<option value="dark" i18n-text="installPreferSchemeDark"></option>
|
|
||||||
<option value="light" i18n-text="installPreferSchemeLight"></option>
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
<p hidden class="installed-actions">
|
|
||||||
<a href="manage.html" tabindex="0"><button i18n-text="openManage"></button></a>
|
|
||||||
<a href="edit.html?id=" tabindex="0"><button i18n-text="editStyleLabel"></button></a>
|
|
||||||
<a id="delete" tabindex="0"><button i18n-text="deleteStyleLabel"></button></a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<p class="meta-description"></p>
|
|
||||||
<div>
|
|
||||||
<h3 i18n-text="author"></h3>
|
|
||||||
<span class="meta-author"></span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<h3 i18n-text="license"></h3>
|
|
||||||
<span class="meta-license"></span>
|
|
||||||
</div>
|
|
||||||
<div class="external-link"></div>
|
|
||||||
<div id="applies-to-wrapper">
|
|
||||||
<h3 i18n-text="appliesLabel"></h3>
|
|
||||||
<ul class="applies-to">
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="header-resizer" i18n-title="headerResizerHint"></div>
|
<div id="ss-scheme" class="install-dim"></div>
|
||||||
</div>
|
<div class="set-update-url w100 checkbox-wrapper install-disable">
|
||||||
<div class="main">
|
<label>
|
||||||
<div class="warnings"></div>
|
<input type="checkbox">
|
||||||
|
<svg class="svg-icon checked"><use xlink:href="#svg-icon-checked"/></svg>
|
||||||
|
<span i18n-text="installUpdateFromLabel"></span>
|
||||||
|
</label>
|
||||||
|
<p></p>
|
||||||
|
</div>
|
||||||
|
<label class="live-reload checkbox-wrapper">
|
||||||
|
<input type="checkbox">
|
||||||
|
<svg class="svg-icon checked"><use xlink:href="#svg-icon-checked"/></svg>
|
||||||
|
<span i18n-text="liveReloadLabel"></span>
|
||||||
|
</label>
|
||||||
|
<div id="live-reload-install-hint" class="w100" hidden></div>
|
||||||
|
<div class="meta-description w100 hide-empty"></div>
|
||||||
|
<div>
|
||||||
|
<h3 i18n-text="author"></h3>
|
||||||
|
<span class="meta-author"></span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 i18n-text="license"></h3>
|
||||||
|
<span class="meta-license"></span>
|
||||||
|
</div>
|
||||||
|
<div class="external-link hide-empty"></div>
|
||||||
|
<div class="w100">
|
||||||
|
<h3 i18n-text="appliesLabel"></h3>
|
||||||
|
<ul class="applies-to">
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="header-resizer" i18n-title="headerResizerHint"></div>
|
||||||
|
</div>
|
||||||
|
<div class="main">
|
||||||
|
<div class="warnings"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" style="display: none !important;">
|
<svg xmlns="http://www.w3.org/2000/svg" style="display: none !important;">
|
||||||
|
|
|
@ -2,6 +2,8 @@ body {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
background: white;
|
background: white;
|
||||||
|
display: flex;
|
||||||
|
height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
|
@ -22,25 +24,29 @@ input:disabled + span {
|
||||||
color: rgb(128, 128, 128);
|
color: rgb(128, 128, 128);
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
|
||||||
display: flex;
|
|
||||||
height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
#header,
|
#header,
|
||||||
.warnings {
|
.warnings {
|
||||||
flex: 0 0 var(--header-width);
|
flex: 0 0 var(--header-width);
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
box-shadow: 0 0 50px -18px black;
|
box-shadow: 0 0 50px -18px black;
|
||||||
|
word-break: break-all;
|
||||||
overflow-wrap: break-word;
|
overflow-wrap: break-word;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
}
|
}
|
||||||
|
#header {
|
||||||
|
--child-gap: 1rem;
|
||||||
|
}
|
||||||
|
#header-contents > :nth-last-child(n + 2) {
|
||||||
|
margin-bottom: var(--child-gap);
|
||||||
|
}
|
||||||
#header.meta-init-error {
|
#header.meta-init-error {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
#header-contents ul {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.warnings {
|
.warnings {
|
||||||
display: none;
|
display: none;
|
||||||
|
@ -72,26 +78,44 @@ input:disabled + span {
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
.meta-name {
|
||||||
h1 small {
|
margin-right: .5em;
|
||||||
|
}
|
||||||
|
.meta-version {
|
||||||
font-size: 0.6em;
|
font-size: 0.6em;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.meta-version::before {
|
.meta-version::before {
|
||||||
content: " v";
|
content: "v";
|
||||||
}
|
}
|
||||||
|
.checkbox-wrapper {
|
||||||
.actions {
|
padding-left: 16px;
|
||||||
margin-bottom: 1em;
|
position: relative;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: block;
|
||||||
}
|
}
|
||||||
|
.set-update-url p {
|
||||||
.actions label {
|
word-break: break-all;
|
||||||
max-width: -moz-fit-content;
|
opacity: .5;
|
||||||
max-width: fit-content;
|
margin: .25em 0 0;
|
||||||
|
}
|
||||||
|
#install-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin: 0.5em 0;
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
#install-wrapper > :nth-last-child(n + 2) {
|
||||||
|
margin-right: .5rem;
|
||||||
|
}
|
||||||
|
#live-reload-install-hint {
|
||||||
|
color: darkcyan;
|
||||||
|
}
|
||||||
|
.w100 {
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.install {
|
.install {
|
||||||
|
@ -107,7 +131,6 @@ h1 small {
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
-moz-appearance: none;
|
-moz-appearance: none;
|
||||||
border-style: none;
|
border-style: none;
|
||||||
margin-bottom: 1ex;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
box-shadow: inset 0 -1px 0 0 hsl(0, 0%, 24%), inset 0 1px 0 0 hsl(0, 0%, 30%), inset 1px 0 0 0 hsl(0, 0%, 24%);
|
box-shadow: inset 0 -1px 0 0 hsl(0, 0%, 24%), inset 0 1px 0 0 hsl(0, 0%, 30%), inset 1px 0 0 0 hsl(0, 0%, 24%);
|
||||||
transition: color .25s, background-color .25s;
|
transition: color .25s, background-color .25s;
|
||||||
|
@ -212,44 +235,25 @@ h1 small {
|
||||||
filter: hue-rotate(-18deg) brightness(.7) contrast(2);
|
filter: hue-rotate(-18deg) brightness(.7) contrast(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.install.installed {
|
h2 {
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2.installed.active {
|
|
||||||
display: inline-block;
|
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
margin-top: 0;
|
margin: 0;
|
||||||
color: darkcyan;
|
color: darkcyan;
|
||||||
}
|
}
|
||||||
h2.installed.active ~ .configure-usercss svg {
|
.installed .configure-usercss svg {
|
||||||
fill: hsl(180, 100%, 20%);
|
fill: hsl(180, 100%, 20%);
|
||||||
}
|
}
|
||||||
h2.installed.active ~ .configure-usercss:hover svg {
|
.installed .configure-usercss:hover svg {
|
||||||
fill: hsl(180, 100%, 30%);
|
fill: hsl(180, 100%, 30%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.actions label input {
|
#header-contents > .hide-empty:empty,
|
||||||
margin: 0 0.5em 0 0;
|
body:not(.installed) .install-show,
|
||||||
flex: 0 0 auto;
|
.installed .install-hide {
|
||||||
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
.installed .install-dim {
|
||||||
.actions label span {
|
|
||||||
min-width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.set-update-url {
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
.set-update-url p {
|
|
||||||
word-break: break-all;
|
|
||||||
opacity: .5;
|
opacity: .5;
|
||||||
width: 100%;
|
|
||||||
margin: .25em 0 .25em;
|
|
||||||
}
|
|
||||||
|
|
||||||
label.set-prefer-scheme:not(.unavailable) {
|
|
||||||
padding-left: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.external {
|
.external {
|
||||||
|
@ -270,8 +274,8 @@ li {
|
||||||
|
|
||||||
.main,
|
.main,
|
||||||
.main .CodeMirror {
|
.main .CodeMirror {
|
||||||
height: 100% !important;
|
height: 100%;
|
||||||
width: 100% !important;
|
width: 100%;
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,22 +294,13 @@ li {
|
||||||
}
|
}
|
||||||
|
|
||||||
#header.meta-init > * {
|
#header.meta-init > * {
|
||||||
opacity: 1;
|
|
||||||
transition: opacity .5s;
|
transition: opacity .5s;
|
||||||
-moz-user-select: auto;
|
|
||||||
user-select: auto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#header.meta-init[data-arrived-fast="true"] > * {
|
.meta-init[data-arrived-fast="true"] > * {
|
||||||
transition-duration: .1s;
|
transition-duration: .1s;
|
||||||
}
|
}
|
||||||
|
|
||||||
label {
|
|
||||||
/* FIXME: why do we want to give all labels a padding? */
|
|
||||||
padding-left: 16px;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.lds-spinner {
|
.lds-spinner {
|
||||||
top: 50px;
|
top: 50px;
|
||||||
opacity: .2;
|
opacity: .2;
|
||||||
|
@ -316,7 +311,6 @@ label {
|
||||||
.configure-usercss .svg-icon.config {
|
.configure-usercss .svg-icon.config {
|
||||||
width: 20px;
|
width: 20px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
margin-top: -3px;
|
|
||||||
}
|
}
|
||||||
#message-box.config-dialog {
|
#message-box.config-dialog {
|
||||||
width: 0;
|
width: 0;
|
||||||
|
@ -331,118 +325,74 @@ label {
|
||||||
|
|
||||||
@media (max-width: 850px) {
|
@media (max-width: 850px) {
|
||||||
body {
|
body {
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.container {
|
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
#header {
|
#header {
|
||||||
flex: 0 1 auto;
|
|
||||||
border-right: none;
|
|
||||||
border-bottom: 1px dashed #AAA;
|
border-bottom: 1px dashed #AAA;
|
||||||
overflow-x: auto;
|
min-height: 6rem;
|
||||||
overflow-y: hidden;
|
max-height: 40vh;
|
||||||
padding: 0;
|
resize: vertical;
|
||||||
|
flex: 0 1 auto;
|
||||||
|
--child-gap: .75rem;
|
||||||
}
|
}
|
||||||
#header:not(.meta-init) {
|
#header:not(.meta-init) {
|
||||||
min-height: 300px;
|
min-height: 300px;
|
||||||
}
|
}
|
||||||
.main {
|
#header-contents {
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
#header-content-wrapper {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
padding: .5rem 0 0 1rem;
|
|
||||||
box-sizing: border-box;
|
|
||||||
height: min-content;
|
|
||||||
}
|
|
||||||
#header-content-wrapper > * {
|
|
||||||
flex-grow: 1;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0 1rem .5rem 0;
|
|
||||||
min-width: 0;
|
|
||||||
}
|
|
||||||
#header-content-wrapper > .meta-description + .flex-wrapper {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
#header-content-wrapper > .meta-description + .flex-wrapper > * {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
flex: 1;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
white-space: nowrap;
|
|
||||||
padding: 0 1rem .5rem 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
.flex-wrapper ul {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
#header-content-wrapper > .meta-description {
|
|
||||||
flex-basis: 100%;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
.actions {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
align-content: flex-start;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
}
|
}
|
||||||
.set-update-url p {
|
#header-contents > :not(.w100) {
|
||||||
|
margin-right: 1rem;
|
||||||
|
}
|
||||||
|
.set-update-url {
|
||||||
|
display: flex;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.set-update-url p {
|
||||||
|
margin: 0 0 0 1rem;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
.actions label {
|
|
||||||
min-width: 100px;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
.actions label span {
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
.has-warnings #header {
|
|
||||||
min-height: 4em;
|
|
||||||
max-height: 20%;
|
|
||||||
}
|
|
||||||
.warnings {
|
|
||||||
max-height: 20%;
|
|
||||||
}
|
|
||||||
.warning:not(:last-child) {
|
.warning:not(:last-child) {
|
||||||
border-bottom: 1px dashed #b57c7c;
|
border-bottom: 1px dashed #b57c7c;
|
||||||
padding-bottom: 1em;
|
padding-bottom: 1em;
|
||||||
}
|
}
|
||||||
ul.applies-to,
|
#header-contents h3 {
|
||||||
.actions label {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
#header-content-wrapper > h1 {
|
|
||||||
font-size: 1.75em;
|
|
||||||
display: flex;
|
|
||||||
align-items: baseline;
|
|
||||||
}
|
|
||||||
#header-content-wrapper > h1 > .meta-version {
|
|
||||||
padding-left: 3px;
|
|
||||||
}
|
|
||||||
#header-content-wrapper > h1 > .meta-name {
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
#header-content-wrapper > * h3 {
|
|
||||||
margin: 0 0 .5rem;
|
margin: 0 0 .5rem;
|
||||||
}
|
}
|
||||||
.install {
|
|
||||||
flex-shrink: 0;
|
|
||||||
margin-right: 1em;
|
|
||||||
}
|
|
||||||
#message-box.config-dialog > div {
|
#message-box.config-dialog > div {
|
||||||
top: auto;
|
top: auto;
|
||||||
bottom: 3rem;
|
bottom: 3rem;
|
||||||
}
|
}
|
||||||
|
h1 {
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
}
|
||||||
|
.meta-name {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.main {
|
||||||
|
height: auto;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 850px) {
|
||||||
|
#header {
|
||||||
|
height: 100% !important; /* overrides user resize */
|
||||||
|
}
|
||||||
|
#ss-scheme > label {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.w100-full {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: var(--child-gap);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Retina-specific stuff here */
|
/* Retina-specific stuff here */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* global $ $create $createLink $$remove showSpinner */// dom.js
|
/* global $$ $ $create $createLink $$remove showSpinner */// dom.js
|
||||||
/* global API */// msg.js
|
/* global API */// msg.js
|
||||||
/* global URLS closeCurrentTab deepEqual */// toolbox.js
|
/* global URLS closeCurrentTab deepEqual */// toolbox.js
|
||||||
/* global messageBox */
|
/* global messageBox */
|
||||||
|
@ -7,6 +7,9 @@
|
||||||
/* global t */// localization.js
|
/* global t */// localization.js
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const CFG_SEL = '#message-box.config-dialog';
|
||||||
|
let cfgShown = true;
|
||||||
|
|
||||||
let cm;
|
let cm;
|
||||||
let initialUrl;
|
let initialUrl;
|
||||||
let installed;
|
let installed;
|
||||||
|
@ -44,6 +47,7 @@ setTimeout(() => !cm && showSpinner($('#header')), 200);
|
||||||
'/vendor/codemirror/keymap/emacs',
|
'/vendor/codemirror/keymap/emacs',
|
||||||
'/vendor/codemirror/keymap/vim', // TODO: load conditionally
|
'/vendor/codemirror/keymap/vim', // TODO: load conditionally
|
||||||
'/vendor/codemirror/mode/css/css',
|
'/vendor/codemirror/mode/css/css',
|
||||||
|
'/vendor/codemirror/mode/stylus/stylus',
|
||||||
'/vendor/codemirror/addon/search/searchcursor',
|
'/vendor/codemirror/addon/search/searchcursor',
|
||||||
'/vendor/codemirror/addon/fold/foldcode',
|
'/vendor/codemirror/addon/fold/foldcode',
|
||||||
'/vendor/codemirror/addon/fold/foldgutter',
|
'/vendor/codemirror/addon/fold/foldgutter',
|
||||||
|
@ -63,6 +67,7 @@ setTimeout(() => !cm && showSpinner($('#header')), 200);
|
||||||
|
|
||||||
({tabId, initialUrl} = preinit);
|
({tabId, initialUrl} = preinit);
|
||||||
liveReload = initLiveReload();
|
liveReload = initLiveReload();
|
||||||
|
preinit.tpl.then(el => $('#ss-scheme').append(...$('[id=ss-scheme]', el).children));
|
||||||
|
|
||||||
const [
|
const [
|
||||||
{dup, style, error, sourceCode},
|
{dup, style, error, sourceCode},
|
||||||
|
@ -97,12 +102,10 @@ setTimeout(() => !cm && showSpinner($('#header')), 200);
|
||||||
|
|
||||||
// update UI
|
// update UI
|
||||||
if (versionTest < 0) {
|
if (versionTest < 0) {
|
||||||
$('.actions').parentNode.insertBefore(
|
$('h1').after($create('.warning', t('versionInvalidOlder')));
|
||||||
$create('.warning', t('versionInvalidOlder')),
|
|
||||||
$('.actions')
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
$('button.install').onclick = () => {
|
$('button.install').onclick = () => {
|
||||||
|
shouldShowConfig();
|
||||||
(!dup ?
|
(!dup ?
|
||||||
Promise.resolve(true) :
|
Promise.resolve(true) :
|
||||||
messageBox.confirm($create('span', t('styleInstallOverwrite', [
|
messageBox.confirm($create('span', t('styleInstallOverwrite', [
|
||||||
|
@ -136,11 +139,9 @@ setTimeout(() => !cm && showSpinner($('#header')), 200);
|
||||||
updateUrl.href.slice(0, 300) + '...';
|
updateUrl.href.slice(0, 300) + '...';
|
||||||
|
|
||||||
// set prefer scheme
|
// set prefer scheme
|
||||||
const preferScheme = $('.set-prefer-scheme select');
|
$('#ss-scheme').onchange = e => {
|
||||||
preferScheme.onchange = () => {
|
style.preferScheme = e.target.value;
|
||||||
style.preferScheme = preferScheme.value;
|
|
||||||
};
|
};
|
||||||
preferScheme.onchange();
|
|
||||||
|
|
||||||
if (URLS.isLocalhost(initialUrl)) {
|
if (URLS.isLocalhost(initialUrl)) {
|
||||||
$('.live-reload input').onchange = liveReload.onToggled;
|
$('.live-reload input').onchange = liveReload.onToggled;
|
||||||
|
@ -170,41 +171,28 @@ function updateMeta(style, dup = installedDup) {
|
||||||
!dup ? 'install' :
|
!dup ? 'install' :
|
||||||
versionTest > 0 ? 'update' :
|
versionTest > 0 ? 'update' :
|
||||||
'reinstall');
|
'reinstall');
|
||||||
$('.set-update-url').title = dup && dup.updateUrl && t('installUpdateFrom', dup.updateUrl) || '';
|
$('.set-update-url').title = dup && dup.updateUrl &&
|
||||||
|
(t('installUpdateFrom', dup.updateUrl) || '').replace(/\S+$/, '\n$&');
|
||||||
$('.meta-name').textContent = data.name;
|
$('.meta-name').textContent = data.name;
|
||||||
$('.meta-version').textContent = data.version;
|
$('.meta-version').textContent = data.version;
|
||||||
$('.meta-description').textContent = data.description;
|
$('.meta-description').textContent = data.description;
|
||||||
$('.set-prefer-scheme select').value =
|
$$('#ss-scheme input').forEach(el => {
|
||||||
style.preferScheme === 'dark' ? 'dark' :
|
el.checked = el.value === (style.preferScheme || 'none');
|
||||||
style.preferScheme === 'light' ? 'light' : 'none';
|
});
|
||||||
|
|
||||||
if (data.author) {
|
replaceChildren($('.meta-author'), makeAuthor(data.author), true);
|
||||||
$('.meta-author').parentNode.style.display = '';
|
replaceChildren($('.meta-license'), data.license, true);
|
||||||
$('.meta-author').textContent = '';
|
replaceChildren($('.external-link'), makeExternalLink());
|
||||||
$('.meta-author').appendChild(makeAuthor(data.author));
|
|
||||||
} else {
|
|
||||||
$('.meta-author').parentNode.style.display = 'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
$('.meta-license').parentNode.style.display = data.license ? '' : 'none';
|
|
||||||
$('.meta-license').textContent = data.license;
|
|
||||||
|
|
||||||
$('.applies-to').textContent = '';
|
|
||||||
getAppliesTo(style).then(list =>
|
getAppliesTo(style).then(list =>
|
||||||
$('.applies-to').append(...list.map(s => $create('li', s))));
|
replaceChildren($('.applies-to'), list.map(s => $create('li', s))));
|
||||||
|
|
||||||
$('.external-link').textContent = '';
|
|
||||||
const externalLink = makeExternalLink();
|
|
||||||
if (externalLink) {
|
|
||||||
$('.external-link').appendChild(externalLink);
|
|
||||||
}
|
|
||||||
|
|
||||||
Object.assign($('.configure-usercss'), {
|
Object.assign($('.configure-usercss'), {
|
||||||
hidden: !data.vars,
|
hidden: !data.vars,
|
||||||
onclick: openConfigDialog,
|
onclick: openConfigDialog,
|
||||||
});
|
});
|
||||||
if (!data.vars) {
|
if (!data.vars) {
|
||||||
$$remove('#message-box.config-dialog');
|
cfgShown = false;
|
||||||
|
$$remove(CFG_SEL);
|
||||||
} else if (!deepEqual(data.vars, vars)) {
|
} else if (!deepEqual(data.vars, vars)) {
|
||||||
vars = data.vars;
|
vars = data.vars;
|
||||||
// Use the user-customized vars from the installed style
|
// Use the user-customized vars from the installed style
|
||||||
|
@ -214,6 +202,8 @@ function updateMeta(style, dup = installedDup) {
|
||||||
v.value = dv.value;
|
v.value = dv.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (shouldShowConfig()) {
|
||||||
openConfigDialog();
|
openConfigDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,26 +217,26 @@ function updateMeta(style, dup = installedDup) {
|
||||||
if (dup) enablePostActions();
|
if (dup) enablePostActions();
|
||||||
|
|
||||||
function makeAuthor(text) {
|
function makeAuthor(text) {
|
||||||
const match = text.match(/^(.+?)(?:\s+<(.+?)>)?(?:\s+\((.+?)\))?$/);
|
const match = text && text.match(/^(.+?)(?:\s+<(.+?)>)?(?:\s+\((.+?)\))?$/);
|
||||||
if (!match) {
|
if (!match) {
|
||||||
return document.createTextNode(text);
|
return text;
|
||||||
}
|
}
|
||||||
const [, name, email, url] = match;
|
const [, name, email, url] = match;
|
||||||
const frag = document.createDocumentFragment();
|
const elems = [];
|
||||||
if (email) {
|
if (email) {
|
||||||
frag.appendChild($createLink(`mailto:${email}`, name));
|
elems.push($createLink(`mailto:${email}`, name));
|
||||||
} else {
|
} else {
|
||||||
frag.appendChild($create('span', name));
|
elems.push($create('span', name));
|
||||||
}
|
}
|
||||||
if (url) {
|
if (url) {
|
||||||
frag.appendChild($createLink(url,
|
elems.push($createLink(url,
|
||||||
$create('SVG:svg.svg-icon', {viewBox: '0 0 20 20'},
|
$create('SVG:svg.svg-icon', {viewBox: '0 0 20 20'},
|
||||||
$create('SVG:path', {
|
$create('SVG:path', {
|
||||||
d: 'M4,4h5v2H6v8h8v-3h2v5H4V4z M11,3h6v6l-2-2l-4,4L9,9l4-4L11,3z',
|
d: 'M4,4h5v2H6v8h8v-3h2v5H4V4z M11,3h6v6l-2-2l-4,4L9,9l4-4L11,3z',
|
||||||
}))
|
}))
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
return frag;
|
return elems;
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeExternalLink() {
|
function makeExternalLink() {
|
||||||
|
@ -274,7 +264,7 @@ function updateMeta(style, dup = installedDup) {
|
||||||
function showError(err) {
|
function showError(err) {
|
||||||
$('.warnings').textContent = '';
|
$('.warnings').textContent = '';
|
||||||
$('.warnings').classList.toggle('visible', Boolean(err));
|
$('.warnings').classList.toggle('visible', Boolean(err));
|
||||||
$('.container').classList.toggle('has-warnings', Boolean(err));
|
document.body.classList.toggle('has-warnings', Boolean(err));
|
||||||
err = Array.isArray(err) ? err : [err];
|
err = Array.isArray(err) ? err : [err];
|
||||||
if (err[0]) {
|
if (err[0]) {
|
||||||
let i;
|
let i;
|
||||||
|
@ -310,12 +300,11 @@ function install(style) {
|
||||||
$$remove('.warning');
|
$$remove('.warning');
|
||||||
$('button.install').disabled = true;
|
$('button.install').disabled = true;
|
||||||
$('button.install').classList.add('installed');
|
$('button.install').classList.add('installed');
|
||||||
$('#live-reload-install-hint').classList.toggle('hidden', !liveReload.enabled);
|
$('#live-reload-install-hint').hidden = !liveReload.enabled;
|
||||||
$('h2.installed').classList.add('active');
|
|
||||||
$('.set-update-url input[type=checkbox]').disabled = true;
|
|
||||||
$('.set-update-url').title = style.updateUrl ?
|
$('.set-update-url').title = style.updateUrl ?
|
||||||
t('installUpdateFrom', style.updateUrl) : '';
|
t('installUpdateFrom', style.updateUrl) : '';
|
||||||
$('.set-prefer-scheme select').disabled = true;
|
$$('.install-disable input').forEach(el => (el.disabled = true));
|
||||||
|
document.body.classList.add('installed');
|
||||||
enablePostActions();
|
enablePostActions();
|
||||||
updateMeta(style);
|
updateMeta(style);
|
||||||
}
|
}
|
||||||
|
@ -323,9 +312,7 @@ function install(style) {
|
||||||
function enablePostActions() {
|
function enablePostActions() {
|
||||||
const {id} = installed || installedDup;
|
const {id} = installed || installedDup;
|
||||||
sessionStorage.justEditedStyleId = id;
|
sessionStorage.justEditedStyleId = id;
|
||||||
$('h2.installed').hidden = !installed;
|
$('#edit').search = `?id=${id}`;
|
||||||
$('.installed-actions').hidden = false;
|
|
||||||
$('.installed-actions a[href*="edit.html"]').search = `?id=${id}`;
|
|
||||||
$('#delete').onclick = async () => {
|
$('#delete').onclick = async () => {
|
||||||
if (await messageBox.confirm(t('deleteStyleConfirm'), 'danger center', t('confirmDelete'))) {
|
if (await messageBox.confirm(t('deleteStyleConfirm'), 'danger center', t('confirmDelete'))) {
|
||||||
await API.styles.delete(id);
|
await API.styles.delete(id);
|
||||||
|
@ -434,3 +421,16 @@ function initLiveReload() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function shouldShowConfig() {
|
||||||
|
// TODO: rewrite message-box to support multiple instances or find an existing tiny library
|
||||||
|
const prev = cfgShown;
|
||||||
|
cfgShown = $(CFG_SEL) != null;
|
||||||
|
return prev && !cfgShown;
|
||||||
|
}
|
||||||
|
|
||||||
|
function replaceChildren(el, children, toggleParent) {
|
||||||
|
if (el.firstChild) el.textContent = '';
|
||||||
|
if (children) el.append(...Array.isArray(children) ? children : [children]);
|
||||||
|
if (toggleParent) el.parentNode.hidden = !el.firstChild;
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/* global API */// msg.js
|
/* global API */// msg.js
|
||||||
/* global closeCurrentTab download */// toolbox.js
|
/* global closeCurrentTab download */// toolbox.js
|
||||||
|
/* global t */// localization.js
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/* exported preinit */
|
/* exported preinit */
|
||||||
|
@ -89,5 +90,7 @@ const preinit = (() => {
|
||||||
return {error, sourceCode};
|
return {error, sourceCode};
|
||||||
}
|
}
|
||||||
})(),
|
})(),
|
||||||
|
|
||||||
|
tpl: t.fetchTemplate('/edit/settings.html', 'styleSettings'),
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* global download */// toolbox.js
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
//#region Exports
|
//#region Exports
|
||||||
|
@ -118,6 +119,16 @@ Object.assign(t, {
|
||||||
return bin;
|
return bin;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async fetchTemplate(url, name) {
|
||||||
|
let el = t.template[name];
|
||||||
|
if (!el) {
|
||||||
|
el = (await download(url, {responseType: 'document'})).body.firstElementChild;
|
||||||
|
t.NodeList(el.getElementsByTagName('*'));
|
||||||
|
t.template[name] = el;
|
||||||
|
}
|
||||||
|
return el;
|
||||||
|
},
|
||||||
|
|
||||||
sanitizeHtml(root) {
|
sanitizeHtml(root) {
|
||||||
const toRemove = [];
|
const toRemove = [];
|
||||||
const walker = document.createTreeWalker(root);
|
const walker = document.createTreeWalker(root);
|
||||||
|
|
|
@ -438,7 +438,7 @@ function download(url, {
|
||||||
const usoVars = [];
|
const usoVars = [];
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const xhr = new XMLHttpRequest();
|
const xhr = new XMLHttpRequest();
|
||||||
const u = new URL(collapseUsoVars(url));
|
const u = new URL(collapseUsoVars(url), location);
|
||||||
const onTimeout = () => {
|
const onTimeout = () => {
|
||||||
xhr.abort();
|
xhr.abort();
|
||||||
reject(new Error('Timeout fetching ' + u.href));
|
reject(new Error('Timeout fetching ' + u.href));
|
||||||
|
|
Loading…
Reference in New Issue
Block a user