feat: added code highlighting

This commit is contained in:
Joshua Seigler 2016-10-25 23:07:44 -04:00
parent 8a850aab22
commit faafc32d03
5 changed files with 79 additions and 26 deletions

View file

@ -3,6 +3,7 @@
<head>
<meta charset="utf-8">
<title>Tech Talk: Responsive Typography</title>
<link rel="stylesheet" href="libs/highlight.js/monokai-sublime.css">
<link rel="stylesheet" href="styles/main.css" charset="utf-8">
<script type="text/javascript" src="libs/prefixfree/prefixfree.min.js"></script>
</head>
@ -44,7 +45,7 @@
</blockquote>
</section>
<section id="demo1" style="--mouse-x: 0.5">
<section id="demo1">
<div class="live-coding col" style="justify-content: center;">
<div class="browser" style="max-width: calc(100vw * var(--mouse-x)); min-width: 2em; margin-bottom: 0.2em;">
<iframe src="about:blank" frameborder="0"></iframe>
@ -53,7 +54,8 @@
<input type="radio" id="demo1-markup" name="demo1" janus-sync>
<div class="live-coding__component" style="--theme-color: #E34F26;">
<label for="demo1-markup">HTML</label>
<textarea name="html" cols="1" id="demo1-html" spellcheck="false" janus-sync>
<div class="live-coding__code">
<textarea name="html" cols="1" id="demo1-html" spellcheck="false" janus-sync>
<nav>
<a href="#">Home</a>
<a href="#">Shop</a>
@ -71,10 +73,13 @@
</div>
<footer>&copy; by us, forever. Neener neener.</footer>
</textarea>
<div class="highlight"></div>
</div>
</div>
<input type="radio" id="demo1-styles" name="demo1" checked janus-sync>
<div class="live-coding__component" style="--theme-color: #0070BA;">
<label for="demo1-styles">CSS</label>
<div class="live-coding__code">
<textarea name="css" cols="1" id="demo1-css" spellcheck="false" janus-sync>* { margin: 0; padding: 0; box-size: border-box; }
body {
display: flex;
@ -122,12 +127,17 @@ section + section {
margin-top: -0.1em;
}
</textarea>
<div class="highlight"></div>
</div>
</div>
<input type="radio" id="demo1-script" name="demo1" janus-sync>
<div class="live-coding__component" style="--theme-color: #F7DF1E;">
<label for="demo1-script">JS</label>
<div class="live-coding__code">
<textarea name="js" cols="1" id="demo1-js" spellcheck="false" janus-sync>// no JS needed
</textarea>
<div class="highlight"></div>
</div>
</div>
</div>
</div>
@ -140,6 +150,7 @@ section + section {
</main>
<script type="text/javascript" src="libs/openjs-shortcut/shortcut.js"></script>
<script type="text/javascript" src="libs/behave/behave.js"></script>
<script type="text/javascript" src="libs/highlight.js/highlight.min.js"></script>
<script type="text/javascript" src="scripts/app.js"></script>
</body>
</html>

3
libs/highlight.js/highlight.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
.hljs{display:block;overflow-x:auto;padding:0.5em;background:#23241f}.hljs,.hljs-tag,.hljs-subst{color:#f8f8f2}.hljs-strong,.hljs-emphasis{color:#a8a8a2}.hljs-bullet,.hljs-quote,.hljs-number,.hljs-regexp,.hljs-literal,.hljs-link{color:#ae81ff}.hljs-code,.hljs-title,.hljs-section,.hljs-selector-class{color:#a6e22e}.hljs-strong{font-weight:bold}.hljs-emphasis{font-style:italic}.hljs-keyword,.hljs-selector-tag,.hljs-name,.hljs-attr{color:#f92672}.hljs-symbol,.hljs-attribute{color:#66d9ef}.hljs-params,.hljs-class .hljs-title{color:#f8f8f2}.hljs-string,.hljs-type,.hljs-built_in,.hljs-builtin-name,.hljs-selector-id,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-addition,.hljs-variable,.hljs-template-variable{color:#e6db74}.hljs-comment,.hljs-deletion,.hljs-meta{color:#75715e}

View file

@ -1,5 +1,5 @@
/*jslint browser: true*/
/*global shortcut, Behave*/
/*global shortcut, Behave, hljs*/
(function () {
"use strict";
@ -116,11 +116,18 @@
}
function editorListenerGenerator(editor) {
var markupEl, styleEl, scriptEl, frameEl, frameWindow, listener;
markupEl = editor.querySelector("[name=\"html\"]");
styleEl = editor.querySelector("[name=\"css\"]");
scriptEl = editor.querySelector("[name=\"js\"]");
frameEl = editor.querySelector("iframe");
var frameWindow, listener,
textareas = [
editor.querySelector("[name=\"html\"]"),
editor.querySelector("[name=\"css\"]"),
editor.querySelector("[name=\"js\"]")
],
highlights = [
editor.querySelector("[name=\"html\"] + .highlight"),
editor.querySelector("[name=\"css\"] + .highlight"),
editor.querySelector("[name=\"js\"] + .highlight")
],
frameEl = editor.querySelector("iframe");
if (frameEl.contentWindow) {
frameWindow = frameEl.contentWindow;
} else {
@ -131,12 +138,15 @@
}
}
function editorAction() {
var compiled = "<!DOCTYPE html><html><head><style>" + styleEl.value + "</style></head><body>" + markupEl.value + "<scr" + "ipt>" + scriptEl.value + "</scr" + "ipt></body></html>";
var compiled = "<!DOCTYPE html><html><head><style>" + textareas[1].value + "</style></head><body>" + textareas[0].value + "<scr" + "ipt>" + textareas[2].value + "</scr" + "ipt></body></html>";
frameWindow.document.open();
frameWindow.document.write(compiled);
frameWindow.document.close();
textareas.forEach(function (current, index, array) {
highlights[index].innerHTML = hljs.highlight(["html", "css", "js"][index], current.value + "\n", true).value;
});
}
[markupEl, styleEl, scriptEl].forEach(function (current, index, array) {
textareas.forEach(function (current, index, array) {
var syncFormElementsIndex = syncFormElements.indexOf(current), editor;
editor = new Behave({
textarea: current,
@ -151,8 +161,14 @@
});
// add a listener to build the source when the fields are changed
current.addEventListener('input', editorAction);
current.addEventListener('keydown', editorAction);
// add a listener to sync the highlight element and the textarea
current.addEventListener('scroll', function (event) {
highlights[index].scrollTop = current.scrollTop;
highlights[index].scrollLeft = current.scrollLeft;
}, { passive: true });
// add a listener to receive changes from localStorage
if (syncFormElementsIndex >= 0) {
// add a listener to receive changes from localStorage
localStorageActions["janus-input-" + syncFormElementsIndex] = function (event) {
var storedValue = event.newValue,
decodedValue = storedValue.split("/", 2);

View file

@ -9,7 +9,7 @@
:root {
--main-font: sans-serif;
--monospace-font: monospace;
--mouse-x: 100vw;
--mouse-x: 0.5;
box-sizing: border-box;
font-family: var(--main-font);
@ -59,7 +59,6 @@ textarea {
font-family: monospace;
font-family: var(--monospace-font, monospace);
font-size: 0.5em;
height: 100%;
}
h1 {
@ -253,20 +252,43 @@ section {
flex: 1 1 100%;
}
.live-coding textarea {
font-size: 0.5em;
resize: none;
flex: 1 1 auto;
color: white;
background: #333;
border: none;
padding: 0.1em;
outline: none;
.live-coding__code {
position: relative;
width: 100%;
}
.live-coding textarea::selection {
.live-coding__code textarea, .live-coding__code .highlight {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
padding: 0.1em;
font-size: 0.4em;
resize: none;
color: white;
font-family: monospace;
white-space: pre-wrap;
word-wrap: break-word;
overflow: auto;
border: none;
outline: none;
text-align: left;
line-height: 1.1;
}
.live-coding__code textarea {
background: #333;
-webkit-text-stroke: 2px #333;
}
.live-coding__code .highlight {
pointer-events: none;
}
.live-coding__code textarea::selection {
background-color: black;
color: var(--theme-color, white);
color: transparent;
}
.live-coding__component {
@ -286,8 +308,8 @@ section {
.hidden,
.live-coding input[type="radio"],
.live-coding input[type="checkbox"],
.live-coding input[type="radio"]:not(:checked) + .live-coding__component > textarea,
.live-coding input[type="checkbox"]:not(:checked) + .live-coding__component > textarea {
.live-coding input[type="radio"]:not(:checked) + .live-coding__component > .live-coding__code,
.live-coding input[type="checkbox"]:not(:checked) + .live-coding__component > .live-coding__code {
position: fixed;
visibility: hidden;
right: 110vw;