Merge branch 'develop' into feature/hash-routed

This commit is contained in:
Roger Braun 2017-02-26 11:39:42 +01:00
commit 290180a987
23 changed files with 389 additions and 202 deletions

View file

@ -17,9 +17,9 @@
"babel-plugin-lodash": "^3.2.11",
"diff": "^3.0.1",
"karma-mocha-reporter": "^2.2.1",
"lz-string": "^1.4.4",
"node-sass": "^3.10.1",
"object-path": "^0.11.3",
"pako": "^1.0.4",
"sanitize-html": "^1.13.0",
"sass-loader": "^4.0.2",
"tributejs": "^2.1.0",
@ -84,7 +84,7 @@
"sinon-chai": "^2.8.0",
"url-loader": "^0.5.7",
"vue-loader": "^11.1.0",
"vue-style-loader": "^1.0.0",
"vue-style-loader": "^2.0.0",
"webpack": "^1.13.2",
"webpack-dev-middleware": "^1.8.3",
"webpack-hot-middleware": "^2.12.2",

View file

@ -32,9 +32,10 @@ a {
button{
border: none;
border-radius: 5px;
cursor: pointer;
&:hover {
background-color: white;
opacity: 0.8;
}
}
@ -102,11 +103,11 @@ main-router {
flex-direction: column;
margin: 0.5em;
border-radius: 0.5em;
border-radius: 10px;
}
.panel-heading {
border-radius: 0.5em 0.5em 0 0;
border-radius: 10px 10px 0 0;
background-size: cover;
padding: 0.6em 0;
text-align: center;
@ -115,7 +116,7 @@ main-router {
}
.panel-footer {
border-radius: 0 0 0.5em 0.5em;
border-radius: 0 0 10px 10px;
}
.panel-body > p {
@ -128,7 +129,7 @@ main-router {
#content {
margin: auto;
max-width: 980px;
border-radius: 1em;
border-radius: 10px;
padding-bottom: 1em;
background-color: rgba(0,0,0,0.1);
}
@ -142,46 +143,10 @@ main-router {
min-width: 0px;
}
.user-info {
color: white;
padding: 1em;
img {
border: 2px solid;
border-radius: 0.5em
}
text-shadow: 0 1px 1px rgba(0, 0, 0, 0.5);
.user-name{
margin-top: 0.2em;
}
.user-screen-name {
margin-top: 0.3em;
font-weight: lighter;
padding-right: 0.1em;
}
}
.user-counts {
display: flex;
line-height:16px;
padding: 1em 1.5em 0em 1em;
text-align: center;
}
.user-count {
flex: 1;
h5 {
font-size:1em;
font-weight: bolder;
margin: 0 0 0.25em;
}
}
.fa {
color: grey;
}
.status-actions {
width: 50%;
display: flex;
@ -210,7 +175,7 @@ status-text-container {
margin-top: 0.2em;
float: right;
margin-right: 0.3em;
border-radius: 20%;
border-radius: 5px;
}
}

View file

@ -7,16 +7,19 @@ const Attachment = {
'nsfw',
'statusId'
],
data: () => ({
nsfwImage,
showHidden: false
}),
data () {
return {
nsfwImage,
hideNsfwLocal: this.$store.state.config.hideNsfw,
showHidden: false
}
},
computed: {
type () {
return fileTypeService.fileType(this.attachment.mimetype)
},
hidden () {
return this.nsfw && !this.showHidden
return this.nsfw && this.hideNsfwLocal && !this.showHidden
}
},
methods: {

View file

@ -3,7 +3,7 @@
<a class="image-attachment" v-if="hidden" v-on:click.prevent="toggleHidden()">
<img :key="nsfwImage" :src="nsfwImage"></img>
</a>
<div class="hider" v-if="nsfw && !hidden">
<div class="hider" v-if="nsfw && hideNsfwLocal && !hidden">
<a href="#" @click.prevent="toggleHidden()">Hide</a>
</div>
@ -16,8 +16,6 @@
<audio v-if="type === 'audio'" :src="attachment.url" controls></audio>
<span v-if="type === 'unknown'">Don't know how to display this...</span>
<div @click.prevent="linkClicked" v-if="type === 'html' && attachment.oembed" class="oembed">
<div v-if="attachment.thumb_url" class="image">
<img :src="attachment.thumb_url"></img>
@ -36,14 +34,15 @@
.attachments {
display: flex;
flex-wrap: wrap;
margin-right: -0.8em;
.attachment {
flex: 1 0 30%;
display: flex;
margin: 0.5em 0.8em 0.6em 0.1em;
margin: 0.5em 0.8em 0.6em 0.0em;
align-self: flex-start;
&.html {
flex-basis: 100%;
display: flex;
}
.hider {
@ -51,14 +50,14 @@
margin: 10px;
padding: 5px;
background: rgba(230,230,230,0.6);
border-radius: 0.5em;
border-radius: 5px;
font-weight: bold;
}
video {
height: 100%;
border: 1px solid;
border-radius: 0.5em;
border-radius: 5px;
width: 100%;
}
@ -71,7 +70,7 @@
height: 100%;
flex: 1;
border: 1px solid;
border-radius: 0.5em;
border-radius: 5px;
}
@ -91,7 +90,7 @@
flex: 1;
img {
border: 0px;
border-radius: 0;
border-radius: 5px;
height: 100%;
object-fit: cover;
}
@ -115,7 +114,7 @@
width: 100%;
border-style: solid;
border-width: 1px;
border-radius: 0.5em;
border-radius: 5px;
width: 100%;
height: 100%; /* If this isn't here, chrome will stretch the images */
}

View file

@ -2,7 +2,7 @@ const DeleteButton = {
props: [ 'status' ],
methods: {
deleteStatus () {
const confirmed = confirm('Do you really want to delete this status?')
const confirmed = window.confirm('Do you really want to delete this status?')
if (confirmed) {
this.$store.dispatch('deleteStatus', { id: this.status.id })
}
@ -10,7 +10,7 @@ const DeleteButton = {
},
computed: {
currentUser () { return this.$store.state.users.currentUser },
canDelete () { return this.currentUser.rights.delete_others_notice || this.status.user.id == this.currentUser.id }
canDelete () { return this.currentUser.rights.delete_others_notice || this.status.user.id === this.currentUser.id }
}
}

View file

@ -1,11 +1,11 @@
<template>
<div class="login panel panel-default base00-background">
<!-- Default panel contents -->
<div class="panel-heading base01-background base04">
<div class="panel-heading base01-background">
Log in
</div>
<div class="panel-body">
<form v-on:submit.prevent='submit(user)'>
<form v-on:submit.prevent='submit(user)' class='login-form'>
<div class='form-group'>
<label for='username'>Username</label>
<input :disabled="loggingIn" v-model='user.username' class='form-control' id='username' placeholder='e.g. lain'>
@ -15,7 +15,7 @@
<input :disabled="loggingIn" v-model='user.password' class='form-control' id='password' type='password'>
</div>
<div class='form-group'>
<button :disabled="loggingIn" type='submit' class='btn btn-default'>Submit</button>
<button :disabled="loggingIn" type='submit' class='btn btn-default base05 base01-background'>Submit</button>
</div>
</form>
</div>
@ -23,3 +23,22 @@
</template>
<script src="./login_form.js" ></script>
<style lang="scss">
.login-form {
input {
border-width: 1px;
border-style: solid;
border-color: silver;
border-radius: 5px;
padding: 0.1em 0.2em 0.2em 0.2em;
}
.btn {
margin-top: 1.0em;
min-height: 28px;
}
}
</style>

View file

@ -3,12 +3,22 @@ import statusPosterService from '../../services/status_poster/status_poster.serv
const mediaUpload = {
mounted () {
const store = this.$store
const input = this.$el.querySelector('input')
const self = this
input.addEventListener('change', ({target}) => {
const file = target.files[0]
this.uploadFile(file)
})
},
data () {
return {
uploading: false
}
},
methods: {
uploadFile (file) {
const self = this
const store = this.$store
const formData = new FormData()
formData.append('media', file)
@ -19,15 +29,34 @@ const mediaUpload = {
.then((fileData) => {
self.$emit('uploaded', fileData)
self.uploading = false
}, (error) => {
}, (error) => { // eslint-disable-line handle-callback-err
self.$emit('upload-failed')
self.uploading = false
})
})
},
fileDrop (e) {
if (e.dataTransfer.files.length > 0) {
e.preventDefault() // allow dropping text like before
this.uploadFile(e.dataTransfer.files[0])
}
},
fileDrag (e) {
let types = e.dataTransfer.types
if (types.contains('Files')) {
e.dataTransfer.dropEffect = 'copy'
} else {
e.dataTransfer.dropEffect = 'none'
}
}
},
data () {
return {
uploading: false
props: [
'dropFiles'
],
watch: {
'dropFiles': function (fileInfos) {
if (!this.uploading) {
this.uploadFile(fileInfos[0])
}
}
}
}

View file

@ -1,5 +1,5 @@
<template>
<div class="media-upload">
<div class="media-upload" @drop.prevent @dragover.prevent="fileDrag" @drop="fileDrop">
<label class="btn btn-default">
<i class="fa icon-spin4 animate-spin" v-if="uploading"></i>
<i class="fa icon-upload" v-if="!uploading"></i>

View file

@ -1,45 +1,65 @@
@import '../../_variables.scss';
.notification {
padding: 0.4em 0 0 0.7em;
display: flex;
border-bottom: 1px solid silver;
.text {
min-width: 0px;
word-wrap: break-word;
line-height:18px;
.notifications {
.icon-retweet {
color: $green;
}
.icon-reply {
color: $blue;
}
h1 {
margin: 0 0 0.3em;
padding: 0;
font-size: 1em;
line-height:20px;
}
padding: 0.3em 0.8em 0.5em;
p {
margin: 0;
margin-top: 0;
margin-bottom: 0.3em;
.panel-heading {
// force the text to stay centered, while keeping
// the button in the right side of the panel heading
position: relative;
button {
position: absolute;
padding: 0.1em 0.3em 0.25em 0.3em;
right: 0.6em;
}
}
.avatar {
padding-top: 0.3em;
width: 32px;
height: 32px;
border-radius: 50%;
.unseen {
border-left: 4px solid rgba(255, 48, 16, 0.65);
}
&:last-child {
border: none
.notification {
padding: 0.4em 0 0 0.7em;
display: flex;
border-bottom: 1px solid silver;
.text {
min-width: 0px;
word-wrap: break-word;
line-height:18px;
.icon-retweet {
color: $green;
}
.icon-reply {
color: $blue;
}
h1 {
margin: 0 0 0.3em;
padding: 0;
font-size: 1em;
line-height:20px;
}
padding: 0.3em 0.8em 0.5em;
p {
margin: 0;
margin-top: 0;
margin-bottom: 0.3em;
}
}
.avatar {
padding-top: 0.3em;
width: 32px;
height: 32px;
border-radius: 50%;
}
&:last-child {
border: none
}
}
}

View file

@ -1,9 +1,12 @@
<template>
<div class="notifications">
<div class="panel panel-default base00-background">
<div class="panel-heading base01-background base04">Notifications ({{unseenCount}}) <button @click.prevent="markAsSeen">Read!</button></div>
<div class="panel-heading base01-background base04">
Notifications ({{unseenCount}})
<button @click.prevent="markAsSeen" class="base05 base02-background">Read!</button>
</div>
<div class="panel-body">
<div v-for="notification in visibleNotifications" class="notification" :class='{"base01-background": notification.seen}'>
<div v-for="notification in visibleNotifications" class="notification" :class='{"unseen": !notification.seen}'>
<a :href="notification.action.user.statusnet_profile_url">
<img class='avatar' :src="notification.action.user.profile_image_url_original">
</a>

View file

@ -49,7 +49,7 @@ const defaultCollection = {
menuContainer: document.body,
// column to search against in the object (accepts function or string)
lookup: ({name, screen_name}) => `${name} (@${screen_name})`,
lookup: ({name, screen_name}) => `${name} (@${screen_name})`, // eslint-disable-line camelcase
// column that contains the content to insert by default
fillAttr: 'screen_name',
@ -84,6 +84,7 @@ const PostStatusForm = {
}
return {
dropFiles: [],
submitDisabled: false,
newStatus: {
status: statusText,
@ -141,6 +142,15 @@ const PostStatusForm = {
},
type (fileInfo) {
return fileTypeService.fileType(fileInfo.mimetype)
},
fileDrop (e) {
if (e.dataTransfer.files.length > 0) {
e.preventDefault() // allow dropping text like before
this.dropFiles = e.dataTransfer.files
}
},
fileDrag (e) {
e.dataTransfer.dropEffect = 'copy'
}
}
}

View file

@ -2,20 +2,20 @@
<div class="post-status-form">
<form @submit.prevent="postStatus(newStatus)">
<div class="form-group" >
<textarea v-model="newStatus.status" placeholder="Just landed in L.A." rows="3" class="form-control" @keyup.ctrl.enter="postStatus(newStatus)"></textarea>
<textarea v-model="newStatus.status" placeholder="Just landed in L.A." rows="3" class="form-control" @keyup.meta.enter="postStatus(newStatus)" @keyup.ctrl.enter="postStatus(newStatus)" @drop="fileDrop" @dragover.prevent="fileDrag"></textarea>
</div>
<div class="attachments">
<div class="attachment" v-for="file in newStatus.files">
<i class="fa icon-cancel" @click="removeMediaFile(file)"></i>
<img class="thumbnail media-upload" :src="file.image" v-if="type(file) === 'image'"></img>
<video v-if="type(file) === 'video'" :src="file.image" controls></video>
<audio v-if="type(file) === 'audio'" :src="file.image" controls></audio>
<a v-if="type(file) === 'unknown'" :href="file.image">{{file.url}}</a>
<i class="fa icon-cancel" @click="removeMediaFile(file)"></i>
</div>
</div>
<div class='form-bottom'>
<media-upload @uploading="disableSubmit" @uploaded="addMediaFile" @upload-failed="enableSubmit"></media-upload>
<button :disabled="submitDisabled" type="submit" class="btn btn-default">Submit</button>
<media-upload @uploading="disableSubmit" @uploaded="addMediaFile" @upload-failed="enableSubmit" :drop-files="dropFiles"></media-upload>
<button :disabled="submitDisabled" type="submit" class="btn btn-default base05 base01-background">Submit</button>
</div>
</form>
</div>
@ -52,6 +52,15 @@
.attachments {
padding: 0.5em;
i {
position: absolute;
margin: 10px;
padding: 5px;
background: rgba(230,230,230,0.6);
border-radius: 5px;
font-weight: bold;
}
}
form {
@ -68,10 +77,12 @@
}
form textarea {
border: none;
border-radius: 2px;
border: solid;
border-width: 1px;
border-color: silver;
border-radius: 5px;
line-height:16px;
padding: 0.5em;
padding: 5px;
resize: vertical;
}

View file

@ -1,8 +1,22 @@
import StyleSwitcher from '../style_switcher/style_switcher.vue'
const settings = {
data () {
return {
hideAttachmentsLocal: this.$store.state.config.hideAttachments,
hideNsfwLocal: this.$store.state.config.hideNsfw
}
},
components: {
StyleSwitcher
},
watch: {
hideAttachmentsLocal (value) {
this.$store.dispatch('setOption', { name: 'hideAttachments', value })
},
hideNsfwLocal (value) {
this.$store.dispatch('setOption', { name: 'hideNsfw', value })
}
}
}

View file

@ -8,6 +8,13 @@
<h2>Theme</h2>
<style-switcher></style-switcher>
</div>
<div class="setting-item">
<h2>Attachments</h2>
<input type="checkbox" id="hideAttachments" v-model="hideAttachmentsLocal">
<label for="hideAttachments">Hide Attachments</label>
<input type="checkbox" id="hideNsfw" v-model="hideNsfwLocal">
<label for="hideNsfw">Enable clickthrough NSFW attachment hiding</label>
</div>
</div>
</div>
</template>

View file

@ -17,6 +17,7 @@ const Status = {
userExpanded: false
}),
computed: {
hideAttachments () { return this.$store.state.config.hideAttachments },
retweet () { return !!this.statusoid.retweeted_status },
retweeter () { return this.statusoid.user.name },
status () {

View file

@ -57,7 +57,7 @@
<div @click.prevent="linkClicked" class="status-content" v-html="status.statusnet_html"></div>
<div v-if='status.attachments' class='attachments'>
<attachment :status-id="status.id" :nsfw="status.nsfw" :attachment="attachment" v-for="attachment in status.attachments">
<attachment v-if="!hideAttachments" :status-id="status.id" :nsfw="status.nsfw" :attachment="attachment" v-for="attachment in status.attachments">
</attachment>
</div>
</div>
@ -157,7 +157,8 @@
.usercard {
border-style: solid;
border-width: 1px;
border-radius: 1em;
border-radius: 10px;
margin-bottom: 1em;
margin-top: 0.2em;
}
</style>

View file

@ -1,40 +1,42 @@
<template>
<div>
<div class="base00-background panel-heading text-center" v-bind:style="style">
<div id="heading" class="profile-panel-background" :style="headingStyle">
<div class="panel-heading text-center">
<div class='user-info'>
<img :src="user.profile_image_url">
<span class="glyphicon glyphicon-user"></span>
<div class='user-name'>{{user.name}}</div>
<div class='user-screen-name'>@{{user.screen_name}}</div>
<div class='container'>
<img :src="user.profile_image_url">
<span class="glyphicon glyphicon-user"></span>
<div class='user-name'>{{user.name}}</div>
<div class='user-screen-name'>@{{user.screen_name}}</div>
</div>
<div v-if="isOtherUser" class="user-interactions">
<div v-if="user.follows_you" class="following base06">
<div v-if="user.follows_you && loggedIn" class="following base06">
Follows you!
</div>
<div class="follow">
<div class="follow" v-if="loggedIn">
<span v-if="user.following">
<!--Following them!-->
<button @click="unfollowUser" class="base06 base01-background base06-border">
Unfollow
<button @click="unfollowUser" class="base04 base00-background pressed">
Following!
</button>
</span>
<span v-if="!user.following">
<button @click="followUser" class="base01 base04-background base01-border">
<button @click="followUser" class="base05 base02-background">
Follow
</button>
</span>
</div>
<div class='mute' v-if='isOtherUser'>
<span v-if='user.muted'>
<button @click="toggleMute" class="base04 base01-background base06-border">Unmute</button>
<button @click="toggleMute" class="base04 base00-background pressed">Muted</button>
</span>
<span v-if='!user.muted'>
<button @click="toggleMute" class="base01 base04-background base01-border">Mute</button>
<button @click="toggleMute" class="base05 base02-background">Mute</button>
</span>
</div>
</div>
</div>
</div>
<div class="panel-body base00-background">
<div class="panel-body profile-panel-body" :style="bodyStyle">
<div class="user-counts">
<div class="user-count">
<h5>Statuses</h5>
@ -58,14 +60,25 @@
export default {
props: [ 'user' ],
computed: {
style () {
headingStyle () {
let rgb = this.$store.state.config.colors['base00'].match(/\d+/g)
return {
color: `#${this.user.profile_link_color}`,
'background-image': `url(${this.user.cover_photo})`
backgroundColor: 'rgb(' + Math.floor(rgb[0] * 0.53) + ', ' +
Math.floor(rgb[1] * 0.56) + ', ' +
Math.floor(rgb[2] * 0.59) + ')',
backgroundImage: `url(${this.user.cover_photo})`
}
},
bodyStyle () {
return {
background: 'linear-gradient(to bottom, rgba(0, 0, 0, 0), ' + this.$store.state.config.colors['base00'] + ' 80%)'
}
},
isOtherUser () {
return this.user !== this.$store.state.users.currentUser
},
loggedIn () {
return this.$store.state.users.currentUser
}
},
methods: {
@ -87,3 +100,118 @@
}
}
</script>
<style lang="scss">
.profile-panel-background {
background-size: cover;
border-radius: 10px;
}
.profile-panel-body {
padding-top: 0em;
top: -0em;
padding-top: 4em;
}
.user-info {
color: white;
padding: 16px 16px 16px 16px;
margin-bottom: -4em;
.container{
display: flex;
flex-wrap: wrap;
flex-direction: column;
align-content: flex-start;
justify-content: center;
max-height: 60px;
}
img {
border: 2px solid;
border-radius: 5px;
flex: 1 0 100%;
max-width: 48px;
max-height: 48px;
}
text-shadow: 0px 1px 1.5px rgba(0, 0, 0, 1.0);
.user-name{
margin-top: 0.0em;
margin-left: 0.6em;
flex: 0 0 auto;
align-self: flex-start;
}
.user-screen-name {
margin-top: 0.0em;
margin-left: 0.6em;
font-weight: lighter;
font-size: 15px;
padding-right: 0.1em;
flex: 0 0 auto;
align-self: flex-start;
}
.user-interactions {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
div {
flex: 1;
}
margin-top: 0.7em;
margin-bottom: -1.0em;
.following {
color: white;
font-size: 14px;
flex: 0 0 100%;
margin: -0.7em 0.0em 0.3em 0.0em;
padding-left: 16px;
text-align: left;
}
.mute {
max-width: 220px;
min-height: 28px;
}
.follow {
max-width: 220px;
min-height: 28px;
}
button {
border: solid;
border-width: 1px;
width: 92%;
height: 100%;
}
.pressed {
border: solid;
border-width: 1px;
}
}
}
.user-counts {
display: flex;
line-height:16px;
padding: 1em 1.5em 0em 1em;
text-align: center;
}
.user-count {
flex: 1;
h5 {
font-size:1em;
font-weight: bolder;
margin: 0 0 0.25em;
}
}
</style>

View file

@ -7,45 +7,10 @@
<script src="./user_profile.js"></script>
<style lang="scss">
.user-profile {
flex: 2;
flex-basis: 500px;
}
.user-info {
.user-interactions {
display: flex;
flex-flow: row wrap;
justify-content: center;
.user-profile {
flex: 2;
flex-basis: 500px;
}
div {
flex: 1;
}
margin-top: 0.5em;
margin-bottom: -1.2em;
.following {
font-size: 14px;
flex: 0 0 100%;
margin-bottom: 0.5em;
}
.mute {
max-width: 200px;
}
.follow {
max-width: 200px;
}
button {
width: 80%;
height: 100%;
border: 1px solid;
}
}
.user-screen-name {
margin-top: 0.4em;
}
}
</style>

View file

@ -1,7 +1,7 @@
import merge from 'lodash.merge'
import objectPath from 'object-path'
import { throttle } from 'lodash'
import { inflate, deflate } from 'pako'
import lzstring from 'lz-string'
const defaultReducer = (state, paths) => (
paths.length === 0 ? state : paths.reduce((substate, path) => {
@ -36,22 +36,22 @@ const defaultStorage = (() => {
})()
const defaultSetState = (key, state, storage) => {
return storage.setItem(key, deflate(JSON.stringify(state), { to: 'string' }))
return storage.setItem(key, lzstring.compressToUTF16(JSON.stringify(state)))
}
export default function createPersistedState ({
key = 'vuex',
key = 'vuex-lz',
paths = [],
getState = (key, storage) => {
let value = storage.getItem(key)
try {
value = inflate(value, { to: 'string' })
value = lzstring.decompressFromUTF16(value) // inflate(value, { to: 'string' })
} catch (e) {
console.log("Couldn't inflate value... Maybe upgrading")
}
return value && value !== 'undefined' ? JSON.parse(value) : undefined
},
setState = throttle(defaultSetState, 5000),
setState = throttle(defaultSetState, 60000),
reducer = defaultReducer,
storage = defaultStorage,
subscriber = store => handler => store.subscribe(handler)

View file

@ -29,7 +29,12 @@ Vue.use(VueTimeago, {
})
const persistedStateOptions = {
paths: ['users.users', 'statuses.notifications']
paths: [
'config.hideAttachments',
'config.hideNsfw',
'statuses.notifications',
'users.users'
]
}
const store = new Vuex.Store({

View file

@ -2,7 +2,10 @@ import { set } from 'vue'
import StyleSetter from '../services/style_setter/style_setter.js'
const defaultState = {
name: 'Pleroma FE'
name: 'Pleroma FE',
colors: {},
hideAttachments: false,
hideNsfw: true
}
const config = {
@ -24,7 +27,7 @@ const config = {
break
case 'theme':
const fullPath = `/static/css/${value}`
StyleSetter.setStyle(fullPath)
StyleSetter.setStyle(fullPath, commit)
}
}
}

View file

@ -1,4 +1,6 @@
const setStyle = (href) => {
import { times } from 'lodash'
const setStyle = (href, commit) => {
/***
What's going on here?
I want to make it easy for admins to style this application. To have
@ -23,18 +25,26 @@ const setStyle = (href) => {
const setDynamic = () => {
const baseEl = document.createElement('div')
body.appendChild(baseEl)
baseEl.setAttribute('class', 'base05')
const base05Color = window.getComputedStyle(baseEl).getPropertyValue('color')
baseEl.setAttribute('class', 'base08')
const base08Color = window.getComputedStyle(baseEl).getPropertyValue('color')
let colors = {}
times(16, (n) => {
const name = `base0${n.toString(16).toUpperCase()}`
baseEl.setAttribute('class', name)
const color = window.getComputedStyle(baseEl).getPropertyValue('color')
colors[name] = color
})
commit('setOption', { name: 'colors', value: colors })
body.removeChild(baseEl)
const styleEl = document.createElement('style')
head.appendChild(styleEl)
const styleSheet = styleEl.sheet
body.removeChild(baseEl)
styleSheet.insertRule(`a { color: ${base08Color}`, 'index-max')
styleSheet.insertRule(`body { color: ${base05Color}`, 'index-max')
styleSheet.insertRule(`.base05-border { border-color: ${base05Color}`, 'index-max')
styleSheet.insertRule(`a { color: ${colors['base08']}`, 'index-max')
styleSheet.insertRule(`body { color: ${colors['base05']}`, 'index-max')
styleSheet.insertRule(`.base05-border { border-color: ${colors['base05']}`, 'index-max')
body.style.display = 'initial'
}
cssEl.addEventListener('load', setDynamic)

View file

@ -3549,6 +3549,10 @@ lru-cache@~2.6.5:
version "2.6.5"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.6.5.tgz#e56d6354148ede8d7707b58d143220fd08df0fd5"
lz-string@^1.4.4:
version "1.4.4"
resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26"
macaddress@^0.2.8:
version "0.2.8"
resolved "https://registry.yarnpkg.com/macaddress/-/macaddress-0.2.8.tgz#5904dc537c39ec6dbefeae902327135fa8511f12"
@ -4052,10 +4056,6 @@ pac-resolver@~1.2.1:
regenerator "~0.8.13"
thunkify "~2.1.1"
pako@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.4.tgz#412cc97c3b7ff06dc6c2557fd4f03d06f5e708d4"
pako@~0.2.0:
version "0.2.9"
resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75"
@ -5629,12 +5629,6 @@ vue-router@^2.2.0:
version "2.2.1"
resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-2.2.1.tgz#b027f9fac2cf13462725e843d6dc631b6aa077f6"
vue-style-loader@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/vue-style-loader/-/vue-style-loader-1.0.0.tgz#abeb7bd0f46313083741244d3079d4f14449e049"
dependencies:
loader-utils "^0.2.7"
vue-style-loader@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/vue-style-loader/-/vue-style-loader-2.0.0.tgz#1a3bb55239ac541ee3af0301d66f16fc86786543"