simplify theme definitions (#574)

* simplify theme definitions

* remove rollup dep which is overkill

* fix syntax error

* fix lint

* fix test
This commit is contained in:
Nolan Lawson 2018-09-23 12:26:01 -07:00 committed by GitHub
parent 2387a18ddb
commit 9b2b90b46e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 32 additions and 94 deletions

View file

@ -1,18 +1,23 @@
#!/usr/bin/env node
const crypto = require('crypto')
const fs = require('fs')
const pify = require('pify')
import crypto from 'crypto'
import fs from 'fs'
import pify from 'pify'
import path from 'path'
import { themes } from '../routes/_static/themes.js'
import { fromPairs } from 'lodash-es'
const readFile = pify(fs.readFile.bind(fs))
const writeFile = pify(fs.writeFile.bind(fs))
const path = require('path')
async function main () {
let headScriptFilepath = path.join(__dirname, '../inline-script.js')
let headScript = await readFile(headScriptFilepath, 'utf8')
headScript = `(function () {'use strict'; ${headScript}})()`
let inlineScriptPath = path.join(__dirname, '../inline-script.js')
let code = await readFile(inlineScriptPath, 'utf8')
let checksum = crypto.createHash('sha256').update(headScript).digest('base64')
code = code.replace('process.env.THEME_COLORS', JSON.stringify(fromPairs(themes.map(_ => ([_.name, _.color])))))
code = `(function () {'use strict'\n${code}})()`
let checksum = crypto.createHash('sha256').update(code).digest('base64')
let checksumFilepath = path.join(__dirname, '../inline-script-checksum.json')
await writeFile(checksumFilepath, JSON.stringify({ checksum }), 'utf8')
@ -21,7 +26,7 @@ async function main () {
let html2xxFile = await readFile(html2xxFilepath, 'utf8')
html2xxFile = html2xxFile.replace(
/<!-- insert inline script here -->[\s\S]+<!-- end insert inline script here -->/,
'<!-- insert inline script here --><script>' + headScript + '</script><!-- end insert inline script here -->'
'<!-- insert inline script here --><script>' + code + '</script><!-- end insert inline script here -->'
)
await writeFile(html2xxFilepath, html2xxFile, 'utf8')
}

View file

@ -11,48 +11,17 @@ body.theme-foobar {
> Note: You can find all the SCSS variables available in `scss/themes/_default.scss` while the all CSS Custom Properties available are listed in `scss/themes/_base.scss`.
Add the CSS class you just define to `scss/themes/_offlines`.
```scss
...
body.offline,
body.theme-foobar.offline, // <-
body.theme-hotpants.offline,
body.theme-majesty.offline,
body.theme-oaken.offline,
body.theme-scarlet.offline,
body.theme-seafoam.offline,
body.theme-gecko.offline {
@include baseTheme();
}
```
Add your theme to `routes/_static/themes.js`
```js
const themes = [
...
{
name: 'foobar',
label: 'Foobar'
label: 'Foobar', // user-visible name
color: 'magenta', // main theme color
dark: true // whether it's a dark theme or not
}
]
export { themes }
```
Add your theme in `inline-script.js`.
```js
window.__themeColors = {
'default': "royalblue",
scarlet: "#e04e41",
seafoam: "#177380",
hotpants: "hotpink",
oaken: "saddlebrown",
majesty: "blueviolet",
gecko: "#4ab92f",
foobar: "#BADA55", // <-
offline: "#999999"
}
```
Start the development server (`npm run dev`), go to `http://localhost:4002/settings/instances/your-instance-name` and select your newly created theme. Once you've done that, you can update your theme, and refresh the page to see the change (you don't have to restart the server).

View file

@ -1,23 +1,8 @@
// For perf reasons, this script is run inline to quickly set certain styles.
// To allow CSP to work correctly, we also calculate a sha256 hash during
// the build process and write it to inline-script-checksum.json.
// TODO: these should not have to be defined twice, once here and again in themes.js
window.__themeColors = {
'default': 'royalblue',
scarlet: '#e04e41',
seafoam: '#177380',
hotpants: 'hotpink',
oaken: 'saddlebrown',
majesty: 'blueviolet',
gecko: '#4ab92f',
ozark: '#5263af',
cobalt: '#08439b',
sorcery: '#ae91e8',
punk: '#e04e41',
riot: 'hotpink',
hacker: '#4ab92f',
offline: '#999999'
}
window.__themeColors = process.env.THEME_COLORS
if (localStorage.store_currentInstance && localStorage.store_instanceThemes) {
let safeParse = (str) => str === 'undefined' ? undefined : JSON.parse(str)
let theme = safeParse(localStorage.store_instanceThemes)[safeParse(localStorage.store_currentInstance)]
@ -32,6 +17,7 @@ if (localStorage.store_currentInstance && localStorage.store_instanceThemes) {
}
}
}
if (!localStorage.store_currentInstance) {
// if not logged in, show all these 'hidden-from-ssr' elements
let style = document.createElement('style')

View file

@ -14,7 +14,7 @@
"start": "cross-env NODE_ENV=production npm run serve",
"build-and-start": "run-s build start",
"build-svg": "node ./bin/build-svg.js",
"build-inline-script": "node ./bin/build-inline-script.js",
"build-inline-script": "node -r esm ./bin/build-inline-script.js",
"build-sass": "node ./bin/build-sass.js",
"build-sass-watch": "node ./bin/build-sass.js --watch",
"run-mastodon": "node -r esm ./bin/run-mastodon.js",

View file

@ -12,18 +12,6 @@ $compose-background: lighten($main-theme-color, 17%);
@import "_base.scss";
body.offline,
body.theme-hotpants.offline,
body.theme-majesty.offline,
body.theme-oaken.offline,
body.theme-scarlet.offline,
body.theme-seafoam.offline,
body.theme-gecko.offline,
body.theme-ozark.offline,
body.theme-cobalt.offline,
body.theme-sorcery.offline,
body.theme-riot.offline,
body.theme-punk.offline,
body.theme-hacker.offline {
body.the-body.offline { /* "the-body" is a specificity hack to allow offline to always trump themes */
@include baseTheme();
}

View file

@ -18,7 +18,7 @@
/* auto-generated w/ build-sass.js */
body{--button-primary-bg: #6081e6;--button-primary-text: #fff;--button-primary-border: #132c76;--button-primary-bg-active: #456ce2;--button-primary-bg-hover: #6988e7;--button-bg: #e6e6e6;--button-text: #333;--button-border: #a7a7a7;--button-bg-active: #bfbfbf;--button-bg-hover: #f2f2f2;--input-border: #dadada;--anchor-text: #4169e1;--main-bg: #fff;--body-bg: #e8edfb;--body-text-color: #333;--main-border: #dadada;--svg-fill: #4169e1;--form-bg: #f7f7f7;--form-border: #c1c1c1;--nav-bg: #4169e1;--nav-border: #214cce;--nav-a-border: #4169e1;--nav-a-selected-border: #fff;--nav-a-selected-bg: #6d8ce8;--nav-svg-fill: #fff;--nav-text-color: #fff;--nav-a-selected-border-hover: #fff;--nav-a-selected-bg-hover: #839deb;--nav-a-bg-hover: #577ae4;--nav-a-border-hover: #4169e1;--nav-svg-fill-hover: #fff;--nav-text-color-hover: #fff;--action-button-fill-color: #90a8ee;--action-button-fill-color-hover: #a2b6f0;--action-button-fill-color-active: #577ae4;--action-button-fill-color-pressed: #2351dc;--action-button-fill-color-pressed-hover: #3862e0;--action-button-fill-color-pressed-active: #1d44b8;--action-button-deemphasized-fill-color: #666;--action-button-deemphasized-fill-color-hover: #9e9e9e;--action-button-deemphasized-fill-color-active: #737373;--action-button-deemphasized-fill-color-pressed: #545454;--action-button-deemphasized-fill-color-pressed-hover: #616161;--action-button-deemphasized-fill-color-pressed-active: #404040;--settings-list-item-bg: #fff;--settings-list-item-text: #4169e1;--settings-list-item-text-hover: #4169e1;--settings-list-item-border: #dadada;--settings-list-item-bg-active: #e6e6e6;--settings-list-item-bg-hover: #fafafa;--toast-bg: #333;--toast-border: #fafafa;--toast-text: #fff;--mask-bg: #333;--mask-svg-fill: #fff;--mask-opaque-bg: rgba(51,51,51,0.8);--loading-bg: #ededed;--account-profile-bg-backdrop-filter: rgba(255,255,255,0.7);--account-profile-bg: rgba(255,255,255,0.9);--deemphasized-text-color: #666;--focus-outline: #c5d1f6;--very-deemphasized-link-color: rgba(65,105,225,0.6);--very-deemphasized-text-color: rgba(102,102,102,0.6);--status-direct-background: #d2dcf8;--main-theme-color: #4169e1;--warning-color: #e01f19;--alt-input-bg: rgba(255,255,255,0.7);--muted-modal-bg: transparent;--muted-modal-focus: #999;--muted-modal-hover: rgba(255,255,255,0.2);--compose-autosuggest-item-hover: #ced8f7;--compose-autosuggest-item-active: #b8c7f4;--compose-autosuggest-outline: #dbe3f9;--compose-button-halo: rgba(255,255,255,0.1)}
body{margin:0;font-family:system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;font-size:14px;line-height:1.4;color:var(--body-text-color);background:var(--body-bg);-webkit-tap-highlight-color:transparent}.container{overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch;position:absolute;top:42px;left:0;right:0;bottom:0}@media (max-width: 991px){.container{top:52px}}@media (max-width: 767px){.container{top:62px}}main{position:relative;width:602px;max-width:100vw;padding:0;box-sizing:border-box;margin:30px auto 15px;background:var(--main-bg);border:1px solid var(--main-border);border-radius:1px;min-height:70vh}@media (max-width: 767px){main{margin:5px auto 15px}}footer{width:602px;max-width:100vw;box-sizing:border-box;margin:15px auto;border-radius:1px;background:var(--main-bg);font-size:0.9em;padding:20px;border:1px solid var(--main-border)}h1,h2,h3,h4,h5,h6{margin:0 0 0.5em 0;font-weight:400;line-height:1.2}h1{font-size:2em}a{color:var(--anchor-text);text-decoration:none}a:visited{color:var(--anchor-text)}a:hover{text-decoration:underline}input{border:1px solid var(--input-border);padding:5px;box-sizing:border-box}input,textarea{background:inherit;color:inherit}button,.button{font-size:1.2em;background:var(--button-bg);border-radius:2px;padding:10px 15px;border:1px solid var(--button-border);cursor:pointer;color:var(--button-text)}button:hover,.button:hover{background:var(--button-bg-hover);text-decoration:none}button:active,.button:active{background:var(--button-bg-active)}button[disabled],.button[disabled]{opacity:0.35;pointer-events:none;cursor:not-allowed}button.primary,.button.primary{border:1px solid var(--button-primary-border);background:var(--button-primary-bg);color:var(--button-primary-text)}button.primary:hover,.button.primary:hover{background:var(--button-primary-bg-hover)}button.primary:active,.button.primary:active{background:var(--button-primary-bg-active)}p,label,input{font-size:1.3em}ul,li,p{padding:0;margin:0}.hidden{opacity:0}*:focus{outline:2px solid var(--focus-outline)}.container:focus{outline:none}button::-moz-focus-inner{border:0}input:required,input:invalid{box-shadow:none}textarea{font-family:inherit;font-size:inherit;box-sizing:border-box}@keyframes spin{0%{transform:rotate(0deg)}25%{transform:rotate(90deg)}50%{transform:rotate(180deg)}75%{transform:rotate(270deg)}100%{transform:rotate(360deg)}}.spin{animation:spin 1.5s infinite linear}.ellipsis::after{content:"\2026"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.inline-custom-emoji{width:1.4em;height:1.4em;margin:-0.1em 0;object-fit:contain;vertical-align:middle}
body.offline,body.theme-hotpants.offline,body.theme-majesty.offline,body.theme-oaken.offline,body.theme-scarlet.offline,body.theme-seafoam.offline,body.theme-gecko.offline,body.theme-ozark.offline,body.theme-cobalt.offline,body.theme-sorcery.offline,body.theme-riot.offline,body.theme-punk.offline,body.theme-hacker.offline{--button-primary-bg: #ababab;--button-primary-text: #fff;--button-primary-border: #4d4d4d;--button-primary-bg-active: #9c9c9c;--button-primary-bg-hover: #b0b0b0;--button-bg: #e6e6e6;--button-text: #333;--button-border: #a7a7a7;--button-bg-active: #bfbfbf;--button-bg-hover: #f2f2f2;--input-border: #dadada;--anchor-text: #999;--main-bg: #fff;--body-bg: #fafafa;--body-text-color: #333;--main-border: #dadada;--svg-fill: #999;--form-bg: #f7f7f7;--form-border: #c1c1c1;--nav-bg: #999;--nav-border: gray;--nav-a-border: #999;--nav-a-selected-border: #fff;--nav-a-selected-bg: #b3b3b3;--nav-svg-fill: #fff;--nav-text-color: #fff;--nav-a-selected-border-hover: #fff;--nav-a-selected-bg-hover: #bfbfbf;--nav-a-bg-hover: #a6a6a6;--nav-a-border-hover: #999;--nav-svg-fill-hover: #fff;--nav-text-color-hover: #fff;--action-button-fill-color: #c7c7c7;--action-button-fill-color-hover: #d1d1d1;--action-button-fill-color-active: #a6a6a6;--action-button-fill-color-pressed: #878787;--action-button-fill-color-pressed-hover: #949494;--action-button-fill-color-pressed-active: #737373;--action-button-deemphasized-fill-color: #666;--action-button-deemphasized-fill-color-hover: #9e9e9e;--action-button-deemphasized-fill-color-active: #737373;--action-button-deemphasized-fill-color-pressed: #545454;--action-button-deemphasized-fill-color-pressed-hover: #616161;--action-button-deemphasized-fill-color-pressed-active: #404040;--settings-list-item-bg: #fff;--settings-list-item-text: #999;--settings-list-item-text-hover: #999;--settings-list-item-border: #dadada;--settings-list-item-bg-active: #e6e6e6;--settings-list-item-bg-hover: #fafafa;--toast-bg: #333;--toast-border: #fafafa;--toast-text: #fff;--mask-bg: #333;--mask-svg-fill: #fff;--mask-opaque-bg: rgba(51,51,51,0.8);--loading-bg: #ededed;--account-profile-bg-backdrop-filter: rgba(255,255,255,0.7);--account-profile-bg: rgba(255,255,255,0.9);--deemphasized-text-color: #666;--focus-outline: #bfbfbf;--very-deemphasized-link-color: rgba(153,153,153,0.6);--very-deemphasized-text-color: rgba(102,102,102,0.6);--status-direct-background: #ededed;--main-theme-color: #999;--warning-color: #e01f19;--alt-input-bg: rgba(255,255,255,0.7);--muted-modal-bg: transparent;--muted-modal-focus: #999;--muted-modal-hover: rgba(255,255,255,0.2);--compose-autosuggest-item-hover: #c4c4c4;--compose-autosuggest-item-active: #b8b8b8;--compose-autosuggest-outline: #ccc;--compose-button-halo: rgba(255,255,255,0.1)}
body.the-body.offline{--button-primary-bg: #ababab;--button-primary-text: #fff;--button-primary-border: #4d4d4d;--button-primary-bg-active: #9c9c9c;--button-primary-bg-hover: #b0b0b0;--button-bg: #e6e6e6;--button-text: #333;--button-border: #a7a7a7;--button-bg-active: #bfbfbf;--button-bg-hover: #f2f2f2;--input-border: #dadada;--anchor-text: #999;--main-bg: #fff;--body-bg: #fafafa;--body-text-color: #333;--main-border: #dadada;--svg-fill: #999;--form-bg: #f7f7f7;--form-border: #c1c1c1;--nav-bg: #999;--nav-border: gray;--nav-a-border: #999;--nav-a-selected-border: #fff;--nav-a-selected-bg: #b3b3b3;--nav-svg-fill: #fff;--nav-text-color: #fff;--nav-a-selected-border-hover: #fff;--nav-a-selected-bg-hover: #bfbfbf;--nav-a-bg-hover: #a6a6a6;--nav-a-border-hover: #999;--nav-svg-fill-hover: #fff;--nav-text-color-hover: #fff;--action-button-fill-color: #c7c7c7;--action-button-fill-color-hover: #d1d1d1;--action-button-fill-color-active: #a6a6a6;--action-button-fill-color-pressed: #878787;--action-button-fill-color-pressed-hover: #949494;--action-button-fill-color-pressed-active: #737373;--action-button-deemphasized-fill-color: #666;--action-button-deemphasized-fill-color-hover: #9e9e9e;--action-button-deemphasized-fill-color-active: #737373;--action-button-deemphasized-fill-color-pressed: #545454;--action-button-deemphasized-fill-color-pressed-hover: #616161;--action-button-deemphasized-fill-color-pressed-active: #404040;--settings-list-item-bg: #fff;--settings-list-item-text: #999;--settings-list-item-text-hover: #999;--settings-list-item-border: #dadada;--settings-list-item-bg-active: #e6e6e6;--settings-list-item-bg-hover: #fafafa;--toast-bg: #333;--toast-border: #fafafa;--toast-text: #fff;--mask-bg: #333;--mask-svg-fill: #fff;--mask-opaque-bg: rgba(51,51,51,0.8);--loading-bg: #ededed;--account-profile-bg-backdrop-filter: rgba(255,255,255,0.7);--account-profile-bg: rgba(255,255,255,0.9);--deemphasized-text-color: #666;--focus-outline: #bfbfbf;--very-deemphasized-link-color: rgba(153,153,153,0.6);--very-deemphasized-text-color: rgba(102,102,102,0.6);--status-direct-background: #ededed;--main-theme-color: #999;--warning-color: #e01f19;--alt-input-bg: rgba(255,255,255,0.7);--muted-modal-bg: transparent;--muted-modal-focus: #999;--muted-modal-hover: rgba(255,255,255,0.2);--compose-autosuggest-item-hover: #c4c4c4;--compose-autosuggest-item-active: #b8b8b8;--compose-autosuggest-outline: #ccc;--compose-button-halo: rgba(255,255,255,0.1)}
</style>
@ -39,27 +39,14 @@ body.offline,body.theme-hotpants.offline,body.theme-majesty.offline,body.theme-o
the current page has one -->
%sapper.head%
</head>
<body>
<body class="the-body">
<!-- auto-generated w/ build-inline-script.js -->
<!-- insert inline script here --><script>(function () {'use strict'; // For perf reasons, this script is run inline to quickly set certain styles.
<!-- insert inline script here --><script>(function () {'use strict'
// For perf reasons, this script is run inline to quickly set certain styles.
// To allow CSP to work correctly, we also calculate a sha256 hash during
// the build process and write it to inline-script-checksum.json.
window.__themeColors = {
'default': 'royalblue',
scarlet: '#e04e41',
seafoam: '#177380',
hotpants: 'hotpink',
oaken: 'saddlebrown',
majesty: 'blueviolet',
gecko: '#4ab92f',
ozark: '#5263af',
cobalt: '#08439b',
sorcery: '#ae91e8',
punk: '#e04e41',
riot: 'hotpink',
hacker: '#4ab92f',
offline: '#999999'
}
window.__themeColors = {"default":"royalblue","scarlet":"#e04e41","seafoam":"#177380","hotpants":"hotpink","oaken":"saddlebrown","majesty":"blueviolet","gecko":"#4ab92f","ozark":"#5263af","cobalt":"#08439b","sorcery":"#ae91e8","punk":"#e04e41","riot":"hotpink","hacker":"#4ab92f"}
if (localStorage.store_currentInstance && localStorage.store_instanceThemes) {
let safeParse = (str) => str === 'undefined' ? undefined : JSON.parse(str)
let theme = safeParse(localStorage.store_instanceThemes)[safeParse(localStorage.store_currentInstance)]
@ -74,6 +61,7 @@ if (localStorage.store_currentInstance && localStorage.store_instanceThemes) {
}
}
}
if (!localStorage.store_currentInstance) {
// if not logged in, show all these 'hidden-from-ssr' elements
let style = document.createElement('style')

View file

@ -89,7 +89,9 @@ export const getComposeSelectionStart = exec(() => composeInput().selectionStart
dependencies: { composeInput }
})
export const getBodyClassList = exec(() => Array.prototype.slice.apply(document.body.classList))
export const getBodyClassList = exec(() => (
Array.prototype.slice.apply(document.body.classList).filter(_ => _ !== 'the-body'))
)
export const scrollContainerToTop = exec(() => {
document.getElementsByClassName('container')[0].scrollTop = 0