kopia lustrzana https://github.com/nolanlawson/pinafore
simplify theme definitions (#574)
* simplify theme definitions * remove rollup dep which is overkill * fix syntax error * fix lint * fix testsafari-search-bar
rodzic
2387a18ddb
commit
9b2b90b46e
docs
scss/themes
templates
tests
|
@ -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')
|
||||
}
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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
|
||||
|
|
Ładowanie…
Reference in New Issue