Skip to content

Instantly share code, notes, and snippets.

@pearofducks
Created May 1, 2017 12:44
Show Gist options
  • Save pearofducks/f1820fc64897953d7e576feeb2f584ba to your computer and use it in GitHub Desktop.
Save pearofducks/f1820fc64897953d7e576feeb2f584ba to your computer and use it in GitHub Desktop.
quick project goofing around with hljs and vue to make a color scheme
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>schemer</title>
<style>
.circle { height: 10px; width: 10px; border-radius: 10px; margin-left: 5px; }
.color-control { display: flex; align-items: center;}
</style>
</head>
<body>
<div id="app">
<quick-load></quick-load>
<primary-control name="backgroundColor"></primary-control>
<primary-control name="color"></primary-control>
<color-control name="keyword"></color-control>
<color-control name="attr"></color-control>
<color-control name="string"></color-control>
<color-control name="function"></color-control>
<color-control name="params"></color-control>
<pre v-highlight><code class="javascript">{{ js1 | pre }}</code></pre>
</div>
<script src="https://cdn.polyfill.io/v2/polyfill.min.js"></script>
<script src="https://unpkg.com/vue@2.2.6/dist/vue.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.11.0/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<script type="text/x-template" id="quick-load-template">
<div><button @click="getStyles">get</button><textarea @change="loadStyles($event)"></div>
</script>
<script type="text/x-template" id="color-control-template">
<div class="color-control"><label>{{ name }}:<input :name="name" @change="onChange($event)"></label><div class="circle" :class="name"></div></div>
</script>
<script>
Vue.component('quick-load', {
template: "#quick-load-template",
methods: {
getStyles() {
var styles = {}
document.querySelectorAll("input").forEach((e) => { styles[e.name] = e.value })
document.querySelector("textarea").value = JSON.stringify(styles)
},
loadStyles(e) {
var styles = JSON.parse(e.target.value)
for (e of Object.keys(styles)) {
document.querySelector(`input[name=${e}]`).value = styles[e]
}
}
}
})
Vue.component('primary-control', {
template: "#color-control-template",
methods: {
onChange(event) {
var e = document.querySelector('body')
e.style[event.target.name] = event.target.value
document.querySelector(`.circle.${event.target.name}`).style.backgroundColor = event.target.value
}
},
props: ['name']
})
Vue.component('color-control', {
template: "#color-control-template",
methods: {
onChange(event) {
var elems = document.querySelectorAll(`.hljs-${event.target.name}`)
elems.forEach( (e) => {
e.style.color = event.target.value
})
document.querySelector(`.circle.${event.target.name}`).style.backgroundColor = event.target.value
}
},
props: ['name']
})
Vue.directive('highlight', {
deep: true,
bind(el, binding) {
// on first bind, highlight all targets
const targets = el.querySelectorAll('code')
for (const target of Array.from(targets)) {
// if a value is directly assigned to the directive, use this
// instead of the element content.
if (binding.value) {
target.innerHTML = binding.value
}
hljs.highlightBlock(target)
}
},
componentUpdated(el, binding) {
// after an update, re-fill the content and then highlight
const targets = el.querySelectorAll('code')
for (const target of Array.from(targets)) {
if (binding.value) {
target.innerHTML = binding.value
hljs.highlightBlock(target)
}
}
}
})
Vue.filter('pre', (text) => {
if (!text) return
// Remove first blank line
text = text.replace(/^\s*[\r\n]/g, '')
// Find how many whitespaces before the first character of the first line
const whitespaces = /^[ \t]*./.exec(text).toString().slice(0, -1)
// Replace first occurrance of whitespace on each line
let newText = []
text.split(/\r\n|\r|\n/).forEach((line) => {
newText.push(line.replace(whitespaces, ''))
})
newText = newText.join('\r\n')
return newText
})
new Vue({
el: '#app',
data: {
js1: `
Vue.component('color-control', {
template: "#color-control-template",
methods: {
onChange(event) {
elems.forEach( (e) => {
e.style.color = event.target.value
})
}
},
props: ['name']
})`
}
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment