Optimized website

Server-side rendering for syntax highlighting and DOM tree optimizations.
This commit is contained in:
Angelos Chalaris
2018-01-04 00:01:11 +02:00
parent d0dd4182b3
commit 13c27db7dc
9 changed files with 1316 additions and 1328 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -34,6 +34,10 @@ $card-section-double-padded-padding: calc(1.5 * var(#{$universal-padding-var}))
margin: var(#{$universal-margin-var}) calc(var(#{$universal-margin-var}) / 2);
}
.#{$card-name} + .#{$card-name} {
margin-top: calc(5 * var(#{$universal-margin-var}));
}
@import 'input_control';
/*
@ -85,7 +89,7 @@ code {
transform: scale(1); /* Deals with the issue described in #243 */
}
pre {
font-size: 1rem;
font-size: 0.8125rem;
border: 0.0625rem solid var(--secondary-border-color);
border-radius: var(--universal-border-radius);
}
@ -140,7 +144,6 @@ header #title {
header h1 small {
display:block;
font-size: 0.875rem;
font-style: italic;
color: #888;
margin-top: -0.8rem;
@media screen and (max-width: 768px) { font-size: 0.75rem; }
@ -188,7 +191,7 @@ label.#{$collapse-name} {
}
+ pre {
box-sizing: border-box;
height: 1px;
height: 0;
max-height: 1px;
overflow: auto;
margin: 0;
@ -231,7 +234,7 @@ pre[class*="language-"] {
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 1.5;
line-height: 1.8;
-moz-tab-size: 2;
-o-tab-size: 2;
@ -290,13 +293,18 @@ pre[class*="language-"] {
.token.property,
.token.tag,
.token.boolean,
.token.number,
.token.constant,
.token.symbol,
.token.deleted {
.token.deleted,
.token.function {
color: #005cc5;
}
.token.number{
color: #8132b5;
}
.token.selector,
.token.attr-name,
.token.string,
@ -310,21 +318,16 @@ pre[class*="language-"] {
.token.entity,
.token.url,
.language-css .token.string,
.style .token.string {
color: #d73a49;
}
.style .token.string,
.token.atrule,
.token.attr-value,
.token.keyword {
color: #d73a49;
}
.token.function {
color: #005cc5;
.token.regex {
color: #007972;
}
.token.regex,
.token.important,
.token.variable {
color: #e90;

View File

@ -1,147 +0,0 @@
/*
===============================================================================
WE ARE ONLY KEEPING THIS AS A REFERENCE, PLEASE REFER TO FLAVOR FOR
OUR ACTUAL HIGHLIGHTING STYLES.
===============================================================================
*/
/* PrismJS 1.9.0
http://prismjs.com/download.html?themes=prism&languages=clike+javascript */
/**
* prism.js default theme for JavaScript, CSS and HTML
* Based on dabblet (http://dabblet.com)
* @author Lea Verou
*/
code[class*="language-"],
pre[class*="language-"] {
color: black;
background: none;
text-shadow: 0 1px white;
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 1.5;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
text-shadow: none;
background: #b3d4fc;
}
pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
code[class*="language-"]::selection, code[class*="language-"] ::selection {
text-shadow: none;
background: #b3d4fc;
}
@media print {
code[class*="language-"],
pre[class*="language-"] {
text-shadow: none;
}
}
/* Code blocks */
pre[class*="language-"] {
padding: 1em;
margin: .5em 0;
overflow: auto;
}
:not(pre) > code[class*="language-"],
pre[class*="language-"] {
background: #f5f2f0;
}
/* Inline code */
:not(pre) > code[class*="language-"] {
padding: .1em;
border-radius: .3em;
white-space: normal;
}
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: slategray;
}
.token.punctuation {
color: #999;
}
.namespace {
opacity: .7;
}
.token.property,
.token.tag,
.token.boolean,
.token.number,
.token.constant,
.token.symbol,
.token.deleted {
color: #905;
}
.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.builtin,
.token.inserted {
color: #690;
}
.token.operator,
.token.entity,
.token.url,
.language-css .token.string,
.style .token.string {
color: #a67f59;
background: hsla(0, 0%, 100%, .5);
}
.token.atrule,
.token.attr-value,
.token.keyword {
color: #07a;
}
.token.function {
color: #DD4A68;
}
.token.regex,
.token.important,
.token.variable {
color: #e90;
}
.token.important,
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}

128
package-lock.json generated
View File

@ -67,6 +67,18 @@
"integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=",
"dev": true
},
"ansi-regex": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
"dev": true
},
"ansi-styles": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
"dev": true
},
"aproba": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
@ -1307,6 +1319,17 @@
"integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
"dev": true
},
"clipboard": {
"version": "1.7.1",
"resolved": "https://registry.npmjs.org/clipboard/-/clipboard-1.7.1.tgz",
"integrity": "sha1-Ng1taUbpmnof7zleQrqStem1oWs=",
"optional": true,
"requires": {
"good-listener": "1.2.2",
"select": "1.1.2",
"tiny-emitter": "2.0.2"
}
},
"cliui": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
@ -1574,6 +1597,12 @@
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
"dev": true
},
"delegate": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz",
"integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==",
"optional": true
},
"delegates": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
@ -2355,6 +2384,15 @@
"minimatch": "3.0.4"
}
},
"good-listener": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz",
"integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=",
"optional": true,
"requires": {
"delegate": "3.2.0"
}
},
"graceful-fs": {
"version": "4.1.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
@ -2439,6 +2477,15 @@
"function-bind": "1.1.1"
}
},
"has-ansi": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
"integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
"dev": true,
"requires": {
"ansi-regex": "2.1.1"
}
},
"has-unicode": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
@ -3124,7 +3171,8 @@
"mini.css": {
"version": "2.3.7",
"resolved": "https://registry.npmjs.org/mini.css/-/mini.css-2.3.7.tgz",
"integrity": "sha1-H9AzeX7kVsgHX+gEgnHzX7ICq+U="
"integrity": "sha1-H9AzeX7kVsgHX+gEgnHzX7ICq+U=",
"dev": true
},
"minimatch": {
"version": "3.0.4",
@ -3496,6 +3544,12 @@
"error-ex": "1.3.1"
}
},
"parse-ms": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-1.0.1.tgz",
"integrity": "sha1-VjRtR0nXjyNDDKDHE4UK75GqNh0=",
"dev": true
},
"path-exists": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
@ -3607,6 +3661,12 @@
"find-up": "1.1.2"
}
},
"plur": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/plur/-/plur-1.0.0.tgz",
"integrity": "sha1-24XGgU9eXlo7Se/CjWBP7GKXUVY=",
"dev": true
},
"pluralize": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz",
@ -3625,6 +3685,25 @@
"integrity": "sha512-piXx9N2WT8hWb7PBbX1glAuJVIkEyUV9F5fMXFINpZ0x3otVOFKKeGmeuiclFJlP/UrgTckyV606VjH2rNK4bw==",
"dev": true
},
"pretty-ms": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-2.1.0.tgz",
"integrity": "sha1-QlfCVt8/sLRR1q/6qwIYhBJpgdw=",
"dev": true,
"requires": {
"is-finite": "1.0.2",
"parse-ms": "1.0.1",
"plur": "1.0.0"
}
},
"prismjs": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.9.0.tgz",
"integrity": "sha1-+j4tntw8OIfB8fMJXUHx+bQgDw8=",
"requires": {
"clipboard": "1.7.1"
}
},
"private": {
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
@ -4030,6 +4109,12 @@
"source-map": "0.4.4"
}
},
"select": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz",
"integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=",
"optional": true
},
"semistandard": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/semistandard/-/semistandard-11.0.0.tgz",
@ -4258,6 +4343,15 @@
"integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=",
"dev": true
},
"strip-ansi": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"dev": true,
"requires": {
"ansi-regex": "2.1.1"
}
},
"strip-bom": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
@ -4287,6 +4381,12 @@
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
"dev": true
},
"supports-color": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
"dev": true
},
"table": {
"version": "3.8.3",
"resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz",
@ -4374,8 +4474,10 @@
"duplexer": "0.1.1",
"figures": "1.7.0",
"lodash": "3.10.1",
"pretty-ms": "2.1.0",
"repeat-string": "1.6.1",
"tap-out": "1.4.2"
"tap-out": "1.4.2",
"through2": "2.0.3"
},
"dependencies": {
"chalk": {
@ -4384,7 +4486,11 @@
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"dev": true,
"requires": {
"escape-string-regexp": "1.0.5"
"ansi-styles": "2.2.1",
"escape-string-regexp": "1.0.5",
"has-ansi": "2.0.0",
"strip-ansi": "3.0.1",
"supports-color": "2.0.0"
}
},
"lodash": {
@ -4450,6 +4556,22 @@
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
"dev": true
},
"through2": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
"integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
"dev": true,
"requires": {
"readable-stream": "2.3.3",
"xtend": "4.0.1"
}
},
"tiny-emitter": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.0.2.tgz",
"integrity": "sha512-2NM0auVBGft5tee/OxP4PI3d8WItkDM+fPnaRAVo6xTDI2knbz9eC5ArWGqtGlYqiH3RU5yMpdyTTO7MguC4ow==",
"optional": true
},
"to-fast-properties": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz",

View File

@ -13,7 +13,8 @@
"semistandard": "^11.0.0",
"tape": "^4.8.0",
"tap-spec": "^4.1.1",
"mini.css": "^2.3.7"
"mini.css": "^2.3.7",
"prismjs": "^1.9.0"
},
"name": "30-seconds-of-code",
"description": "A collection of useful JavaScript snippets.",

View File

@ -8,8 +8,21 @@ const fs = require('fs-extra'),
chalk = require('chalk'),
md = require('markdown-it')(),
minify = require('html-minifier').minify;
var Prism = require('prismjs');
// Load helper functions (these are from existing snippets in 30 seconds of code!)
const isTravisCI = () => 'TRAVIS' in process.env && 'CI' in process.env;
const unescapeHTML = str =>
str.replace(
/&|<|>|'|"/g,
tag =>
({
'&': '&',
'&lt;': '<',
'&gt;': '>',
'&#39;': "'",
'&quot;': '"'
}[tag] || tag)
);
if(isTravisCI() && /^Travis build: \d+/g.test(process.env['TRAVIS_COMMIT_MESSAGE'])) {
console.log(`${chalk.green('NOBUILD')} index build terminated, parent commit is a Travis build!`);
process.exit(0);
@ -149,8 +162,10 @@ try {
md
.render(`\n${snippets[taggedSnippet[0] + '.md']}`)
.replace(/<h3/g, `<h3 id="${taggedSnippet[0].toLowerCase()}" class="section double-padded"`)
.replace(/<\/h3>/g, '</h3><div class="section double-padded">') +
'</div></div><br/>';
.replace(/<pre><code class="language-js">([^\0]*?)<\/code><\/pre>/gm, (match, p1) => `<pre class="language-js">${Prism.highlight(unescapeHTML(p1), Prism.languages.javascript)}</pre>`)
.replace(/<\/pre>\s+<pre/g, '</pre><label class="collapse">Show examples</label><pre') +
'<button class="primary clipboard-copy"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-clipboard"><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"></path><rect x="8" y="2" width="8" height="4" rx="1" ry="1"></rect></svg>&nbsp;Copy to clipboard</button>' +
'</div></div>';
} else {
output += md
.render(`## ${capitalize(tag, true)}\n`)
@ -162,14 +177,49 @@ try {
.render(`\n${snippets[taggedSnippet[0] + '.md']}`)
.replace(/<h3/g, `<h3 id="${taggedSnippet[0].toLowerCase()}" class="section double-padded"`)
.replace(/<\/h3>/g, '</h3><div class="section double-padded">')
.replace(/<\/pre>\s+<pre>/g, '</pre><label class="collapse">Show examples</label><pre>') +
.replace(/<pre><code class="language-js">([^\0]*?)<\/code><\/pre>/gm, (match, p1) => `<pre class="language-js">${Prism.highlight(unescapeHTML(p1), Prism.languages.javascript)}</pre>`)
.replace(/<\/pre>\s+<pre/g, '</pre><label class="collapse">Show examples</label><pre') +
'<button class="primary clipboard-copy"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-clipboard"><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"></path><rect x="8" y="2" width="8" height="4" rx="1" ry="1"></rect></svg>&nbsp;Copy to clipboard</button>' +
'</div></div><br/>';
'</div></div>';
}
}
output += uncategorizedOutput;
// Add the ending static part
output += `\n${endPart + '\n'}`;
// Optimize punctuation nodes
let count = 0;
do {
const punctuationRegex = /<span class="token punctuation">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token punctuation">([^\0]*?)<\/span>/gm;
output = output.replace(punctuationRegex,
(match, p1, p2, p3) => `<span class="token punctuation">${p1}${p2}${p3}</span>`
);
count = 0;
while (punctuationRegex.exec(output) !== null) {
++count;
}
} while (count > 0);
// Optimize operator nodes
do {
const operatorRegex = /<span class="token operator">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token operator">([^\0]*?)<\/span>/gm;
output = output.replace(operatorRegex,
(match, p1, p2, p3) => `<span class="token operator">${p1}${p2}${p3}</span>`
);
count = 0;
while (operatorRegex.exec(output) !== null) {
++count;
}
} while (count > 0);
// Optimize keyword nodes
do {
const keyWordRegex = /<span class="token keyword">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token keyword">([^\0]*?)<\/span>/gm;
output = output.replace(keyWordRegex,
(match, p1, p2, p3) => `<span class="token keyword">${p1}${p2}${p3}</span>`
);
count = 0;
while (keyWordRegex.exec(output) !== null) {
++count;
}
} while (count > 0);
// Minify output
output = minify(output, {
collapseBooleanAttributes: true,

View File

@ -4,6 +4,5 @@
</footer>
</main>
</div>
<script src="prism.js"></script>
</body>
</html>

View File

@ -30,28 +30,8 @@
})
}
function loader() {
clipboard();
exampleMaker();
registerClickListener();
}
function clipboard() {
// const snippets = document.querySelectorAll(":not(label) + pre");
// snippets.forEach(snippet => {
// const button = document.createElement("button");
// button.className = 'primary clipboard-copy';
// button.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-clipboard"><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"></path><rect x="8" y="2" width="8" height="4" rx="1" ry="1"></rect></svg>&nbsp;Copy to clipboard';
// snippet.parentElement.appendChild(button);
// });
}
function exampleMaker() {
// const examples = document.querySelectorAll("pre + pre");
// examples.forEach(el => {
// let label = document.createElement('label');
// label.className = 'collapse';
// label.innerHTML = 'Show examples';
// el.parentNode.insertBefore(label, el);
// });
}
function registerClickListener() {
document.addEventListener('click', function (event) {
if ( event.target.classList.contains('collapse') ) {