├── .gitignore ├── LICENSE ├── README.md ├── dist ├── index.html ├── script.js └── style.css ├── gulpfile.js ├── package.json └── src ├── _index.md ├── arrows.md ├── content.md ├── index.html ├── script.js └── style.css /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | node_modules 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Rasmus Prentow (codetower) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # es6-features 2 | Quck rundown of new ES6 features with evaluatable code blocks. 3 | Working demo can be found [here](https://codetower.github.io/es6-features/). 4 | 5 | ## The code 6 | There are currently not much in terms of build process. Minifying and dependency management is not used. 7 | This was a quick demonstration, so i found it unnecessary. The code behind this is all made en es6 and uses no 8 | shims, polyfill, babel etc. Hence the following disclaimer. 9 | 10 | ## Disclaimer 11 | The project uses no polyfills, shims etc. and will therefore only work in browsers supporting ES6. 12 | 13 | 14 | ## Contributions 15 | Contributions are most welcome :) 16 | -------------------------------------------------------------------------------- /dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ES6 Features 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |

ES6 Features

13 | 14 | 15 | 16 |

Arrow Functions

17 |

A short hand notation for function(), but it does not bind this in the same way.

18 |
no-eval
 19 | var odds = evens.map(v => v + 1);  // no parentes and no brackets
 20 | var nums = evens.map((v, i) => v + i);
 21 | var pairs = evens.map(v => ({even: v, odd: v + 1}));
 22 | 
 23 | // Statement bodies
 24 | nums.forEach(v => {
 25 |   if (v % 5 === 0)
 26 |     fives.push(v);
 27 | });
 28 | 
29 |

How does this work?

30 |
var object = {
 31 |     name: "Name", 
 32 |     arrowGetName: () => this.name,
 33 |     regularGetName: function() { return this.name },
 34 |     arrowGetThis: () => this,
 35 |     regularGetThis: function() { return this }
 36 | }
 37 | 
 38 | console.log(this.name)
 39 | console.log(object.arrowGetName());
 40 | console.log(object.arrowGetThis());
 41 | console.log(this)
 42 | console.log(object.regularGetName());
 43 | console.log(object.regularGetThis());
 44 | 
45 |

They work well with classes

46 |
class someClass {
 47 |     constructor() {
 48 |         this.name = "Name"
 49 |     }
 50 | 
 51 |     testRegular() {
 52 |         return function() { return this }
 53 | 
 54 |     }
 55 | 
 56 |     testArrow() {
 57 |         return () => this.name;
 58 |     }
 59 | }
 60 | 
 61 | var obj = new someClass();
 62 | 
 63 | console.log(obj.name)
 64 | console.log(obj.testRegular()());
 65 | console.log(obj.testArrow()());
 66 | 
67 | 68 |

Classes

69 |

As we know them from "real" languages. Syntactic sugar on top of prototype-inheritence.

70 |
no-eval
 71 | class SkinnedMesh extends THREE.Mesh {
 72 |   constructor(geometry, materials) {
 73 |     super(geometry, materials);
 74 | 
 75 |     this.idMatrix = SkinnedMesh.defaultMatrix();
 76 |     this.bones = [];
 77 |     this.boneMatrices = [];
 78 |     //...
 79 |   }
 80 |   update(camera) {
 81 |     //...
 82 |     super.update();
 83 |   }
 84 |   get boneCount() {
 85 |     return this.bones.length;
 86 |   }
 87 |   set matrixType(matrixType) {
 88 |     this.idMatrix = SkinnedMesh[matrixType]();
 89 |   }
 90 |   static defaultMatrix() {
 91 |     return new THREE.Matrix4();
 92 |   }
 93 | }
 94 | 
95 |

Lebab.io

96 |

Enhanced Object Literals

97 |
var theProtoObj = {
 98 |   toString: function() {
 99 |     return "The ProtoOBject To string"
100 |   }
101 | }
102 | 
103 | var handler = () => "handler"
104 | 
105 | 
106 | var obj = {
107 |     // __proto__
108 |     __proto__: theProtoObj,
109 | 
110 |     // Shorthand for ‘handler: handler’
111 |     handler,
112 | 
113 |     // Methods
114 |     toString() {
115 | 
116 |      // Super calls
117 |      return "d " + super.toString();
118 |     },
119 | 
120 |     // Computed (dynamic) property names
121 |     [ "prop_" + (() => 42)() ]: 42
122 | };
123 | 
124 | console.log(obj.handler)
125 | console.log(obj.handler())
126 | console.log(obj.toString())
127 | console.log(obj.prop_42)
128 | 
129 |

String interpolation

130 |

Nice syntax for string interpolation

131 |
var name = "Bob", time = "today";
132 | 
133 | var multiLine = `This
134 | 
135 | Line
136 | 
137 | Spans Multiple
138 | 
139 | Lines`
140 | 
141 | 
142 | console.log(`Hello ${name},how are you ${time}?`)
143 | console.log(multiLine)
144 | 
145 |

Destructuring

146 |
// list "matching"
147 | var [a, , b] = [1,2,3];
148 | console.log(a)
149 | console.log(b)
150 | 
151 |

Objects can be destructured as well.

152 |
nodes = () => { return {op: "a", lhs: "b", rhs: "c"}}
153 | var { op: a, lhs: b , rhs: c } = nodes()
154 | console.log(a)
155 | console.log(b)
156 | console.log(c)
157 | 
158 |

Using Shorthand notation.

159 |
nodes = () => { return {lhs: "a", op: "b", rhs: "c"}}
160 | 
161 | // binds `op`, `lhs` and `rhs` in scope
162 | var {op, lhs, rhs} = nodes()
163 | 
164 | console.log(op)
165 | console.log(lhs)
166 | console.log(rhs)
167 | 
168 |

Can be used in parameter position

169 |

170 | function g({name: x}) {
171 |   return x
172 | }
173 | 
174 | function m({name}) {
175 |   return name
176 | }
177 | 
178 | console.log(g({name: 5}))
179 | console.log(m({name: 5}))
180 | 
181 |

Fail-soft destructuring

182 |
var [a] = []
183 | var [b = 1] = []
184 | var c = [];
185 | console.log(a)
186 | console.log(b);
187 | console.log(c);
188 | 
189 |

Default

190 |
function f(x, y=12) {
191 |   return x + y;
192 | }
193 | 
194 | console.log(f(3))
195 | 
196 |

Spread

197 |

In functions:

198 |
function f(x, y, z) {
199 |   return x + y + z;
200 | }
201 | // Pass each elem of array as argument
202 | console.log(f(...[1,2,3]))
203 | 
204 |

In arrays:

205 |
var parts = ["shoulders", "knees"];
206 | var lyrics = ["head", ...parts, "and", "toes"]; 
207 | 
208 | console.log(lyrics)
209 | 
210 |

Spread + Object Literals

211 |

We can do cool stuff with this in object creations.

212 |
no-eval
213 | let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
214 | console.log(x); // 1
215 | console.log(y); // 2
216 | console.log(z); // { a: 3, b: 4 }
217 | 
218 | // Spread properties
219 | let n = { x, y, ...z };
220 | console.log(n); // { x: 1, y: 2, a: 3, b: 4 }
221 | console.log(obj)
222 | 
223 |

Sadly it is not supported yet:

224 |

npm install --save-dev babel-plugin-transform-object-rest-spread

225 |

Rest

226 |

We can allow unlimited params to function by using the rest operator.

227 |
function demo(part1, ...part2) {
228 |     return {part1, part2}
229 | }
230 | 
231 | console.log(demo(1,2,3,4,5,6))
232 | 
233 |

Let

234 |

Let is the new var. As it has "sane" bindings.

235 |
{
236 |    var globalVar = "from demo1"
237 | }
238 | 
239 | {
240 |    let globalLet = "from demo2";
241 | }
242 | 
243 | console.log(globalVar)
244 | console.log(globalLet)
245 | 
246 |

However, it does not assign anything to window:

247 |
let me = "go";  // globally scoped
248 | var i = "able"; // globally scoped
249 | 
250 | console.log(window.me); 
251 | console.log(window.i);
252 | 
253 |

It is not possible to redeclare a variable using let:

254 |

255 | let me = "foo";
256 | let me = "bar"; 
257 | console.log(me);
258 | 
259 |

260 | var me = "foo";
261 | var me = "bar"; 
262 | console.log(me)
263 | 
264 |

Const

265 |

Const is for read-only variables.

266 |
const a = "b"
267 | a = "a"
268 | 
269 |

It should be noted that const objects can still be mutated.

270 |
const a = { a: "a" }
271 | a.a = "b"
272 | console.log(a)
273 | 
274 |

For..of

275 |

New type of iterator, an alternative to for..in. It returns the values instead of the keys.

276 |
let list = [4, 5, 6];
277 | 
278 | console.log(list)
279 | 
280 | for (let i in list) {
281 |    console.log(i);
282 | }
283 | 
284 |
let list = [4, 5, 6];
285 | 
286 | console.log(list)
287 | 
288 | 
289 | for (let i of list) {
290 |    console.log(i); 
291 | }
292 | 
293 |

Iterators

294 |

The iterator is a more dynamic type than an array.

295 |
let infinite = {
296 |   [Symbol.iterator]() {
297 |     let c = 0;
298 |     return {
299 |       next() {
300 |         c++;
301 |         return { done: false, value: c }
302 |       }
303 |     }
304 |   }
305 | }
306 | 
307 | console.log("start");
308 | 
309 | for (var n of infinite) {
310 |   // truncate the sequence at 1000
311 |   if (n > 10)
312 |     break;
313 |   console.log(n);
314 | }
315 | 
316 |

Using Typescript interfaces we can see how it looks:

317 |
no-eval
318 | interface IteratorResult {
319 |   done: boolean;
320 |   value: any;
321 | }
322 | interface Iterator {
323 |   next(): IteratorResult;
324 | }
325 | interface Iterable {
326 |   [Symbol.iterator](): Iterator
327 | }
328 | 
329 |

Generators

330 |

Generators create iterators, and are more dynamic than iterators. They do not have to keep track of state in the same manner and do not support the concept of done.

331 |
var infinity = {
332 |   [Symbol.iterator]: function*() {
333 |     var c = 1;
334 |     for (;;) {   
335 |       yield c++;
336 |     }
337 |   }
338 | }
339 | 
340 | console.log("start")
341 | for (var n of infinity) {
342 |   // truncate the sequence at 1000
343 |   if (n > 10)
344 |     break;
345 |   console.log(n);
346 | }
347 | 
348 |

Using typescript again to show the interfaces.

349 |
no-eval
350 | interface Generator extends Iterator {
351 |     next(value?: any): IteratorResult;
352 |     throw(exception: any);
353 | }
354 | 
355 |

function* 356 | Iterators and generator

357 |

An example of yield*

358 |
function* anotherGenerator(i) {
359 |   yield i + 1;
360 |   yield i + 2;
361 |   yield i + 3;
362 | }
363 | 
364 | function* generator(i) {
365 |   yield i;
366 |   yield* anotherGenerator(i);
367 |   yield i + 10;
368 | }
369 | 
370 | var gen = generator(10);
371 | 
372 | console.log(gen.next().value); 
373 | console.log(gen.next().value); 
374 | console.log(gen.next().value); 
375 | console.log(gen.next().value); 
376 | console.log(gen.next().value);
377 | 
378 |

Unicode

379 |

ES6 provides better support for Unicode.

380 |
var regex = new RegExp('\u{61}', 'u');
381 | 
382 | console.log(regex.unicode)
383 | console.log("\uD842\uDFD7")
384 | console.log("\uD842\uDFD7".codePointAt())
385 | 
386 |

Modules & Module Loaders

387 |

Native support for modules.

388 |
no-eval
389 | import defaultMember from "module-name";
390 | import * as name from "module-name";
391 | import { member } from "module-name";
392 | import { member as alias } from "module-name";
393 | import { member1 , member2 } from "module-name";
394 | import { member1 , member2 as alias2 , [...] } from "module-name";
395 | import defaultMember, { member [ , [...] ] } from "module-name";
396 | import defaultMember, * as name from "module-name";
397 | import "module-name";
398 | 
399 |
no-eval
400 | export { name1, name2, …, nameN };
401 | export { variable1 as name1, variable2 as name2, …, nameN };
402 | export let name1, name2, …, nameN; // also var
403 | export let name1 = …, name2 = …, …, nameN; // also var, const
404 | 
405 | export expression;
406 | export default expression;
407 | export default function (…) { … } // also class, function*
408 | export default function name1(…) { … } // also class, function*
409 | export { name1 as default, … };
410 | 
411 | export * from …;
412 | export { name1, name2, …, nameN } from …;
413 | export { import1 as name1, import2 as name2, …, nameN } from …;
414 | 
415 |

Import 416 | Export

417 |

Set

418 |

Sets as in the mathematical counterpart where all items are unique. 419 | For people who know SQL this is equivalent to distinct.

420 |
var set = new Set();
421 | set.add("Potato").add("Tomato").add("Tomato");
422 | console.log(set.size)
423 | console.log(set.has("Tomato"))
424 | 
425 | for(var item of set) {
426 |    console.log(item)
427 | }
428 | 
429 |

Set

430 |

WeakSet

431 |

The WeakSet object lets you store weakly held objects in a collection. 432 | Objects without a reference will be garbage collected.

433 |
var item = { a:"Potato"}
434 | var set = new WeakSet();
435 | set.add({ a:"Potato"}).add(item).add({ a:"Tomato"}).add({ a:"Tomato"});
436 | console.log(set.size)
437 | console.log(set.has({a:"Tomato"}))
438 | console.log(set.has(item))
439 | 
440 | for(let item of set) {
441 |    console.log(item)
442 | }
443 | 
444 |

WeakSet

445 |

Map

446 |

Maps, also known as dictionaries.

447 |
var map = new Map();
448 | map.set("Potato", 12);
449 | map.set("Tomato", 34);
450 | 
451 | console.log(map.get("Potato"))
452 | 
453 | 
454 | for(let item of map) {
455 |    console.log(item)
456 | }
457 | 
458 | 
459 | for(let item in map) {
460 |    console.log(item)
461 | }
462 | 
463 |

Other types than strings can be used.

464 |
var map = new Map();
465 | var key = {a: "a"}
466 | map.set(key, 12);
467 | 
468 | 
469 | console.log(map.get(key))
470 | console.log(map.get({a: "a"}))
471 | 
472 |

Map

473 |

WeakMap

474 |

Uses objects for keys, and only keeps weak reference to the keys.

475 |
var wm = new WeakMap();
476 | 
477 | var o1  = {}
478 | var o2  = {}
479 | var o3  = {}
480 | 
481 | 
482 | wm.set(o1, 1);
483 | wm.set(o2, 2);
484 | wm.set(o3, {a: "a"});
485 | wm.set({}, 4);
486 | 
487 | console.log(wm.get(o2));
488 | console.log(wm.has({}))
489 | 
490 | delete o2;
491 | 
492 | console.log(wm.get(o3));
493 | 
494 | for(let item in wm) {
495 |    console.log(item)
496 | }
497 | 
498 | 
499 | for(let item of wm) {
500 |    console.log(item)
501 | }
502 | 
503 |

WeakMap

504 |

Proxies

505 |

Proxies can be used to alter objects' behaviour. They allow us to define traps.

506 |

507 | var obj = function ProfanityGenerator() {
508 |     return {
509 |        words: "Horrible words"    
510 |     }
511 | }()
512 | 
513 | var handler = function CensoringHandler() {
514 |         return {
515 |         get: function (target, key) {
516 |             return target[key].replace("Horrible", "Nice");
517 |         },
518 |     }
519 | 
520 | }()
521 | 
522 | var proxy = new Proxy(obj, handler);
523 | 
524 | console.log(proxy.words);
525 | 
526 |

The following traps are available:

527 |
no-eval
528 | var handler =
529 | {
530 |   get:...,
531 |   set:...,
532 |   has:...,
533 |   deleteProperty:...,
534 |   apply:...,
535 |   construct:...,
536 |   getOwnPropertyDescriptor:...,
537 |   defineProperty:...,
538 |   getPrototypeOf:...,
539 |   setPrototypeOf:...,
540 |   enumerate:...,
541 |   ownKeys:...,
542 |   preventExtensions:...,
543 |   isExtensible:...
544 | }
545 | 
546 |

Proxies

547 |

Symbols

548 |

Symbols are a new type. Can be used to create anonymous properties.

549 |
var typeSymbol = Symbol("type");
550 | 
551 | class Pet {
552 | 
553 |   constructor(type) {
554 | 
555 |     this[typeSymbol] = type;
556 | 
557 |   }
558 |   getType() {
559 |      return this[typeSymbol];
560 |   }
561 | 
562 | }
563 | 
564 | 
565 | var a = new Pet("dog");
566 | console.log(a.getType());
567 | console.log(Object.getOwnPropertyNames(a))
568 | 
569 | 
570 | console.log(Symbol("a") === Symbol("a"))
571 | 
572 |

More info

573 |

Inheritable Built-ins

574 |

We can now inherit from native classes.

575 |

576 | class CustomArray extends Array {
577 | 
578 | }
579 | 
580 | var a = new CustomArray();
581 | 
582 | a[0] = 2
583 | console.log(a[0])
584 | 
585 |

It is not possible to override the getter function without using Proxies of arrays.

586 |

New Library

587 |

Various new methods and constants.

588 |
console.log(Number.EPSILON)
589 | console.log(Number.isInteger(Infinity))
590 | console.log(Number.isNaN("NaN"))
591 | 
592 | console.log(Math.acosh(3))
593 | console.log(Math.hypot(3, 4))
594 | console.log(Math.imul(Math.pow(2, 32) - 1, Math.pow(2, 32) - 2))
595 | 
596 | console.log("abcde".includes("cd") )
597 | console.log("abc".repeat(3) )
598 | 
599 | 
600 | console.log(Array.of(1, 2, 3) )
601 | console.log([0, 0, 0].fill(7, 1) )
602 | console.log([1, 2, 3].find(x => x == 3) )
603 | console.log([1, 2, 3].findIndex(x => x == 2)) 
604 | console.log([1, 2, 3, 4, 5].copyWithin(3, 0)) 
605 | console.log(["a", "b", "c"].entries() )
606 | console.log(["a", "b", "c"].keys() )
607 | console.log(["a", "b", "c"].values() )
608 | 
609 | console.log(Object.assign({}, { origin: new Point(0,0) }))
610 | 
611 |

Documentation: Number, Math, Array.from, Array.of, Array.prototype.copyWithin, Object.assign

612 |

Binary and Octal

613 |

Literals for binary and octal numbering.

614 |
console.log(0b11111)
615 | console.log(0o2342)
616 | 
617 | console.log(0xff); // also in es5
618 | 
619 |

Promises

620 |

The bread and butter for async programing.

621 |
var p1 = new Promise((resolve, reject) => {
622 |   setTimeout(() => resolve("1"), 101)
623 | })
624 | var p2 = new Promise((resolve, reject) => {
625 |   setTimeout(() => resolve("2"), 100)
626 | })
627 | 
628 | Promise.race([p1, p2]).then((res) => {
629 |    console.log(res)
630 | })
631 | 
632 | Promise.all([p1, p2]).then((res) => {
633 |    console.log(res)
634 | })
635 | 
636 |

Quick Promise

637 |

Need a quick always resolved promise?

638 |

639 | var p1 = Promise.resolve("1")
640 | var p2 = Promise.reject("2")
641 | 
642 | Promise.race([p1, p2]).then((res) => {
643 |    console.log(res)
644 | })
645 | 
646 |

Fail fast

647 |

If a promise fails, all and race will reject as well.

648 |
var p1 = new Promise((resolve, reject) => {
649 |   setTimeout(() => resolve("1"), 1001)
650 | })
651 | var p2 = new Promise((resolve, reject) => {
652 |   setTimeout(() => reject("2"), 1)
653 | })
654 | 
655 | Promise.race([p1, p2]).then((res) => {
656 |    console.log("success" + res)
657 | }, res => {
658 |    console.log("error " + res)
659 | })
660 | 
661 | Promise.all([p1, p2]).then((res) => {
662 |    console.log("success" + res)
663 | }, res => {
664 |    console.log("error " + res)
665 | })
666 | 
667 |

More Info

668 |

Reflect

669 |

New type of meta programming with new API for existing and also a few new methods.

670 |

671 | var z = {w: "Super Hello"}
672 | var y = {x: "hello", __proto__: z};
673 | 
674 | console.log(Reflect.getOwnPropertyDescriptor(y, "x"));
675 | console.log(Reflect.has(y, "w"));
676 | console.log(Reflect.ownKeys(y, "w"));
677 | 
678 | console.log(Reflect.has(y, "x"));
679 | console.log(Reflect.deleteProperty(y,"x"))
680 | console.log(Reflect.has(y, "x"));
681 | 
682 |

More Info

683 |

Tail Call Optimization

684 |

ES6 should fix ensure tail calls do not generate stack overflow. (Not all implementations work).

685 |

686 | function factorial(n, acc = 1) {
687 |     if (n <= 1) return acc; 
688 |     return factorial(n - 1, n * acc);
689 | }
690 | console.log(factorial(10))
691 | console.log(factorial(100))
692 | console.log(factorial(1000))
693 | console.log(factorial(10000))
694 | console.log(factorial(100000))
695 | console.log(factorial(1000000))
696 | 
697 | 698 | 699 | 700 | 701 | 702 | 706 | 707 | 708 | -------------------------------------------------------------------------------- /dist/script.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 4 | * This "script" provides functionality to 5 | * turn html "code blocks" into executable blocks while providing 6 | * an index based on headlines. 7 | * 8 | */ 9 | 10 | // ========================================================================= 11 | // Configuration 12 | // ========================================================================= 13 | let config = { 14 | codeBlockSelector: ".lang-javascript,.javascript", 15 | indexSelector: ".content-index", 16 | headlineSelector: "h2" 17 | }; 18 | 19 | 20 | // ========================================================================= 21 | // Helpers 22 | // ========================================================================= 23 | 24 | /** 25 | * Pipes the data through the supplied methods. 26 | */ 27 | function pipe(data, ...methods) { 28 | let result = data; 29 | for (method of methods) { 30 | result = method.bind(this)(result) 31 | } 32 | 33 | return result; 34 | } 35 | 36 | 37 | // ========================================================================= 38 | // Classes 39 | // ========================================================================= 40 | 41 | /** 42 | * CodeConverter class that can convert HTML to executable code with result handling 43 | */ 44 | class CodeConverter { 45 | 46 | constructor(index) { 47 | this.index = index; 48 | 49 | } 50 | 51 | convert(code) { 52 | return pipe.bind(this)(code, 53 | this.removeHtmlEntities, 54 | this.decodeEntities, 55 | this.addResultHandling 56 | ); 57 | } 58 | 59 | addResultHandling(code) { 60 | return code 61 | .replace(/console/, `clearResult("${this.index}"); \nconsole`) 62 | .replace(/console.log\((.*)\).*/g, ` 63 | try {  64 | let _______a = $1; 65 | if(typeof(_______a) === 'object' && _______a != window) { 66 | _______a = JSON.stringify(_______a) 67 | } 68 | addResult('${this.index}', '$1 -> ' + _______a); 69 | } 70 | catch(e) { 71 | addResult('${this.index}', '$1 -> '+ e); 72 | }`) 73 | 74 | } 75 | 76 | decodeEntities(encodedString) { 77 | let textArea = document.createElement('textarea'); 78 | textArea.innerHTML = encodedString; 79 | return textArea.value; 80 | } 81 | 82 | 83 | removeHtmlEntities(text) { 84 | return text.replace(/<(?:.|\/)(?:.|\n)*?>/gm, ''); 85 | } 86 | } 87 | 88 | /** 89 | * CodeBlock class, representing a code block 90 | */ 91 | class CodeBlock { 92 | constructor(element, index) { 93 | this.index = index; 94 | this.codeConverter = new CodeConverter(index) 95 | this.isExecutable = !element.innerHTML.includes("no-eval") 96 | this.element = element 97 | this.addFunctionalityToLangBlock(); 98 | } 99 | 100 | execute() { 101 | try { 102 | this.convertAndExecute(); 103 | } catch (e) { 104 | console.log(e) 105 | addResult(this.index, e) 106 | } 107 | } 108 | 109 | convertAndExecute() { 110 | let code = this.codeConverter.convert(this.element.innerHTML); 111 | eval.apply(window, [code]); 112 | } 113 | 114 | addFunctionalityToLangBlock() { 115 | if (this.isExecutable) { 116 | this.addExecutionButton(); 117 | this.addCodeBlockClass(); 118 | this.addContentEditableAttribute(); 119 | } else { 120 | this.removeNoEval(this.element.innerHTML); 121 | } 122 | } 123 | 124 | addCodeBlockClass() { 125 | $(this.element).addClass("codeblock-" + this.index); 126 | } 127 | 128 | addExecutionButton() { 129 | $(this.element).parent().after(` 130 | 131 |
132 | `) 133 | } 134 | 135 | addContentEditableAttribute() { 136 | $(this.element).prop('contenteditable', 'true'); 137 | } 138 | 139 | removeNoEval(s) { 140 | this.element.innerHTML = this.element.innerHTML.replace(/no-eval.*\n/, "") 141 | } 142 | 143 | } 144 | 145 | /** 146 | * Page class representing the entire page 147 | */ 148 | class Page { 149 | constructor(config) { 150 | this.config = config; 151 | this.codeBlocks = new Map(); 152 | } 153 | 154 | initialize() { 155 | this.initializeCodeBlocks(); 156 | this.addIndex(); 157 | this.addCodeHighlight(); 158 | } 159 | 160 | initializeCodeBlocks() { 161 | $(this.config.codeBlockSelector).each((i, element) => { 162 | this.codeBlocks.set(i, new CodeBlock(element, i)); 163 | }) 164 | } 165 | 166 | addIndex() { 167 | $(this.config.headlineSelector).each((_, element) => { 168 | $(element).wrap(``) 169 | $(this.config.indexSelector).append(`
  • ${element.innerHTML}
  • `); 170 | }) 171 | } 172 | 173 | addCodeHighlight() { 174 | $('pre code').each(function (i, block) { 175 | hljs.highlightBlock(block); 176 | }); 177 | } 178 | 179 | } 180 | 181 | 182 | // ========================================================================= 183 | // Global Methods 184 | // ========================================================================= 185 | 186 | function addResult(id, res) { 187 | document.getElementById(id).innerHTML += res + "
    "; 188 | } 189 | 190 | function clearResult(id) { 191 | document.getElementById(id).innerHTML = ""; 192 | } 193 | 194 | function executeCode(index) { 195 | let codeBlock = page.codeBlocks.get(parseInt(index)); 196 | if (codeBlock) { 197 | codeBlock.execute(); 198 | } 199 | 200 | } 201 | 202 | // ========================================================================= 203 | // Bootstraping 204 | // ========================================================================= 205 | 206 | var page = new Page(config); 207 | 208 | $(document).ready(function () { 209 | page.initialize(); 210 | }) 211 | -------------------------------------------------------------------------------- /dist/style.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: octicons-link; 3 | src: url(data:font/woff;charset=utf-8;base64,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) format('woff'); 4 | } 5 | 6 | body { 7 | -ms-text-size-adjust: 100%; 8 | -webkit-text-size-adjust: 100%; 9 | line-height: 1.5; 10 | color: #333; 11 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; 12 | font-size: 16px; 13 | line-height: 1.5; 14 | word-wrap: break-word; 15 | margin: 0 20px; 16 | } 17 | 18 | a { 19 | background-color: transparent; 20 | -webkit-text-decoration-skip: objects; 21 | } 22 | 23 | a:active, 24 | a:hover { 25 | outline-width: 0; 26 | } 27 | 28 | strong { 29 | font-weight: inherit; 30 | } 31 | 32 | strong { 33 | font-weight: bolder; 34 | } 35 | 36 | h1 { 37 | font-size: 2em; 38 | margin: 0.67em 0; 39 | } 40 | 41 | img { 42 | border-style: none; 43 | } 44 | 45 | svg:not(:root) { 46 | overflow: hidden; 47 | } 48 | 49 | code, 50 | kbd, 51 | pre { 52 | font-family: monospace, monospace; 53 | font-size: 1em; 54 | } 55 | 56 | hr { 57 | box-sizing: content-box; 58 | height: 0; 59 | overflow: visible; 60 | } 61 | 62 | input { 63 | font: inherit; 64 | margin: 0; 65 | } 66 | 67 | input { 68 | overflow: visible; 69 | } 70 | 71 | [type="checkbox"] { 72 | box-sizing: border-box; 73 | padding: 0; 74 | } 75 | 76 | * { 77 | box-sizing: border-box; 78 | } 79 | 80 | input { 81 | font-family: inherit; 82 | font-size: inherit; 83 | line-height: inherit; 84 | } 85 | 86 | a { 87 | color: #4078c0; 88 | text-decoration: none; 89 | } 90 | 91 | a:hover, 92 | a:active { 93 | text-decoration: underline; 94 | } 95 | 96 | strong { 97 | font-weight: 600; 98 | } 99 | 100 | hr { 101 | height: 0; 102 | margin: 15px 0; 103 | overflow: hidden; 104 | background: transparent; 105 | border: 0; 106 | border-bottom: 1px solid #ddd; 107 | } 108 | 109 | hr::before { 110 | display: table; 111 | content: ""; 112 | } 113 | 114 | hr::after { 115 | display: table; 116 | clear: both; 117 | content: ""; 118 | } 119 | 120 | table { 121 | border-spacing: 0; 122 | border-collapse: collapse; 123 | } 124 | 125 | td, 126 | th { 127 | padding: 0; 128 | } 129 | 130 | h1, 131 | h2, 132 | h3, 133 | h4, 134 | h5, 135 | h6 { 136 | margin-top: 0; 137 | margin-bottom: 0; 138 | } 139 | 140 | h1 { 141 | font-size: 32px; 142 | font-weight: 600; 143 | } 144 | 145 | h2 { 146 | font-size: 24px; 147 | font-weight: 600; 148 | } 149 | 150 | h3 { 151 | font-size: 20px; 152 | font-weight: 600; 153 | } 154 | 155 | h4 { 156 | font-size: 16px; 157 | font-weight: 600; 158 | } 159 | 160 | h5 { 161 | font-size: 14px; 162 | font-weight: 600; 163 | } 164 | 165 | h6 { 166 | font-size: 12px; 167 | font-weight: 600; 168 | } 169 | 170 | p { 171 | margin-top: 0; 172 | margin-bottom: 10px; 173 | } 174 | 175 | blockquote { 176 | margin: 0; 177 | } 178 | 179 | ul, 180 | ol { 181 | padding-left: 0; 182 | margin-top: 0; 183 | margin-bottom: 0; 184 | } 185 | 186 | ol ol, 187 | ul ol { 188 | list-style-type: lower-roman; 189 | } 190 | 191 | ul ul ol, 192 | ul ol ol, 193 | ol ul ol, 194 | ol ol ol { 195 | list-style-type: lower-alpha; 196 | } 197 | 198 | dd { 199 | margin-left: 0; 200 | } 201 | 202 | code { 203 | font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; 204 | font-size: 12px; 205 | } 206 | 207 | pre, .results { 208 | margin-top: 0; 209 | margin-bottom: 0; 210 | font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace; 211 | } 212 | 213 | .octicon { 214 | vertical-align: text-bottom; 215 | } 216 | 217 | input { 218 | -webkit-font-feature-settings: "liga" 0; 219 | font-feature-settings: "liga" 0; 220 | } 221 | 222 | .markdown-body::before { 223 | display: table; 224 | content: ""; 225 | } 226 | 227 | .markdown-body::after { 228 | display: table; 229 | clear: both; 230 | content: ""; 231 | } 232 | 233 | .markdown-body>*:first-child { 234 | margin-top: 0 !important; 235 | } 236 | 237 | .markdown-body>*:last-child { 238 | margin-bottom: 0 !important; 239 | } 240 | 241 | a:not([href]) { 242 | color: inherit; 243 | text-decoration: none; 244 | } 245 | 246 | .anchor { 247 | float: left; 248 | padding-right: 4px; 249 | margin-left: -20px; 250 | line-height: 1; 251 | } 252 | 253 | .anchor:focus { 254 | outline: none; 255 | } 256 | 257 | p, 258 | blockquote, 259 | ul, 260 | ol, 261 | dl, 262 | table, 263 | pre { 264 | margin-top: 0; 265 | margin-bottom: 16px; 266 | } 267 | 268 | hr { 269 | height: 0.25em; 270 | padding: 0; 271 | margin: 24px 0; 272 | background-color: #e7e7e7; 273 | border: 0; 274 | } 275 | 276 | blockquote { 277 | padding: 0 1em; 278 | color: #777; 279 | border-left: 0.25em solid #ddd; 280 | } 281 | 282 | blockquote>:first-child { 283 | margin-top: 0; 284 | } 285 | 286 | blockquote>:last-child { 287 | margin-bottom: 0; 288 | } 289 | 290 | kbd { 291 | display: inline-block; 292 | padding: 3px 5px; 293 | font-size: 11px; 294 | line-height: 10px; 295 | color: #555; 296 | vertical-align: middle; 297 | background-color: #fcfcfc; 298 | border: solid 1px #ccc; 299 | border-bottom-color: #bbb; 300 | border-radius: 3px; 301 | box-shadow: inset 0 -1px 0 #bbb; 302 | } 303 | 304 | h1, 305 | h2, 306 | h3, 307 | h4, 308 | h5, 309 | h6 { 310 | margin-top: 24px; 311 | margin-bottom: 16px; 312 | font-weight: 600; 313 | line-height: 1.25; 314 | } 315 | 316 | h1 .octicon-link, 317 | h2 .octicon-link, 318 | h3 .octicon-link, 319 | h4 .octicon-link, 320 | h5 .octicon-link, 321 | h6 .octicon-link { 322 | color: #000; 323 | vertical-align: middle; 324 | visibility: hidden; 325 | } 326 | 327 | h1:hover .anchor, 328 | h2:hover .anchor, 329 | h3:hover .anchor, 330 | h4:hover .anchor, 331 | h5:hover .anchor, 332 | h6:hover .anchor { 333 | text-decoration: none; 334 | } 335 | 336 | h1:hover .anchor .octicon-link, 337 | h2:hover .anchor .octicon-link, 338 | h3:hover .anchor .octicon-link, 339 | h4:hover .anchor .octicon-link, 340 | h5:hover .anchor .octicon-link, 341 | h6:hover .anchor .octicon-link { 342 | visibility: visible; 343 | } 344 | 345 | h1 { 346 | padding-bottom: 0.3em; 347 | font-size: 2em; 348 | border-bottom: 1px solid #eee; 349 | } 350 | 351 | h2 { 352 | padding-bottom: 0.3em; 353 | font-size: 1.5em; 354 | border-bottom: 1px solid #eee; 355 | } 356 | 357 | h3 { 358 | font-size: 1.25em; 359 | } 360 | 361 | h4 { 362 | font-size: 1em; 363 | } 364 | 365 | h5 { 366 | font-size: 0.875em; 367 | } 368 | 369 | h6 { 370 | font-size: 0.85em; 371 | color: #777; 372 | } 373 | 374 | ul, 375 | ol { 376 | padding-left: 2em; 377 | } 378 | 379 | ul ul, 380 | ul ol, 381 | ol ol, 382 | ol ul { 383 | margin-top: 0; 384 | margin-bottom: 0; 385 | } 386 | 387 | li>p { 388 | margin-top: 16px; 389 | } 390 | 391 | li+li { 392 | margin-top: 0.25em; 393 | } 394 | 395 | dl { 396 | padding: 0; 397 | } 398 | 399 | dl dt { 400 | padding: 0; 401 | margin-top: 16px; 402 | font-size: 1em; 403 | font-style: italic; 404 | font-weight: bold; 405 | } 406 | 407 | dl dd { 408 | padding: 0 16px; 409 | margin-bottom: 16px; 410 | } 411 | 412 | table { 413 | display: block; 414 | width: 100%; 415 | overflow: auto; 416 | } 417 | 418 | table th { 419 | font-weight: bold; 420 | } 421 | 422 | table th, 423 | table td { 424 | padding: 6px 13px; 425 | border: 1px solid #ddd; 426 | } 427 | 428 | table tr { 429 | background-color: #fff; 430 | border-top: 1px solid #ccc; 431 | } 432 | 433 | table tr:nth-child(2n) { 434 | background-color: #f8f8f8; 435 | } 436 | 437 | img { 438 | max-width: 100%; 439 | box-sizing: content-box; 440 | background-color: #fff; 441 | } 442 | 443 | code, .results { 444 | padding: 0; 445 | padding-top: 0.2em; 446 | padding-bottom: 0.2em; 447 | margin: 0; 448 | background-color: rgba(0,0,0,0.04); 449 | border-radius: 3px; 450 | } 451 | 452 | code::before, 453 | code::after { 454 | letter-spacing: -0.2em; 455 | content: "\00a0"; 456 | } 457 | 458 | pre { 459 | word-wrap: normal; 460 | } 461 | 462 | pre>code, { 463 | padding: 0; 464 | margin: 0; 465 | font-size: 100%; 466 | word-break: normal; 467 | white-space: pre; 468 | background: transparent; 469 | border: 0; 470 | } 471 | 472 | .highlight { 473 | margin-bottom: 16px; 474 | } 475 | 476 | .highlight pre { 477 | margin-bottom: 0; 478 | word-break: normal; 479 | } 480 | 481 | .highlight pre,.results, 482 | pre { 483 | padding: 16px; 484 | overflow: auto; 485 | font-size: 85%; 486 | line-height: 1.45; 487 | background-color: #f7f7f7; 488 | border-radius: 3px; 489 | } 490 | 491 | pre code { 492 | display: inline; 493 | max-width: auto; 494 | padding: 0; 495 | margin: 0; 496 | overflow: visible; 497 | line-height: inherit; 498 | word-wrap: normal; 499 | background-color: transparent; 500 | border: 0; 501 | } 502 | 503 | pre code::before, 504 | pre code::after { 505 | content: normal; 506 | } 507 | 508 | .pl-0 { 509 | padding-left: 0 !important; 510 | } 511 | 512 | .pl-1 { 513 | padding-left: 3px !important; 514 | } 515 | 516 | .pl-2 { 517 | padding-left: 6px !important; 518 | } 519 | 520 | .pl-3 { 521 | padding-left: 12px !important; 522 | } 523 | 524 | .pl-4 { 525 | padding-left: 24px !important; 526 | } 527 | 528 | .pl-5 { 529 | padding-left: 36px !important; 530 | } 531 | 532 | .pl-6 { 533 | padding-left: 48px !important; 534 | } 535 | 536 | .full-commit .btn-outline:not(:disabled):hover { 537 | color: #4078c0; 538 | border: 1px solid #4078c0; 539 | } 540 | 541 | kbd { 542 | display: inline-block; 543 | padding: 3px 5px; 544 | font: 11px Consolas, "Liberation Mono", Menlo, Courier, monospace; 545 | line-height: 10px; 546 | color: #555; 547 | vertical-align: middle; 548 | background-color: #fcfcfc; 549 | border: solid 1px #ccc; 550 | border-bottom-color: #bbb; 551 | border-radius: 3px; 552 | box-shadow: inset 0 -1px 0 #bbb; 553 | } 554 | 555 | :checked+.radio-label { 556 | position: relative; 557 | z-index: 1; 558 | border-color: #4078c0; 559 | } 560 | 561 | .task-list-item { 562 | list-style-type: none; 563 | } 564 | 565 | .task-list-item+.task-list-item { 566 | margin-top: 3px; 567 | } 568 | 569 | .task-list-item input { 570 | margin: 0 0.2em 0.25em -1.6em; 571 | vertical-align: middle; 572 | } 573 | 574 | hr { 575 | border-bottom-color: #eee; 576 | } 577 | 578 | .results { 579 | margin-top: 10px; 580 | margin-bottom: 10px; 581 | font-size:12px; 582 | } 583 | 584 | 585 | 586 | /* 587 | 588 | github.com style (c) Vasily Polovnyov 589 | 590 | */ 591 | 592 | .hljs { 593 | display: block; 594 | overflow-x: auto; 595 | padding: 0.5em; 596 | color: #333; 597 | background: #f8f8f8; 598 | } 599 | 600 | .hljs-comment, 601 | .hljs-quote { 602 | color: #998; 603 | font-style: italic; 604 | } 605 | 606 | .hljs-keyword, 607 | .hljs-selector-tag, 608 | .hljs-subst { 609 | color: #333; 610 | font-weight: bold; 611 | } 612 | 613 | .hljs-number, 614 | .hljs-literal, 615 | .hljs-variable, 616 | .hljs-template-variable, 617 | .hljs-tag .hljs-attr { 618 | color: #008080; 619 | } 620 | 621 | .hljs-string, 622 | .hljs-doctag { 623 | color: #d14; 624 | } 625 | 626 | .hljs-title, 627 | .hljs-section, 628 | .hljs-selector-id { 629 | color: #900; 630 | font-weight: bold; 631 | } 632 | 633 | .hljs-subst { 634 | font-weight: normal; 635 | } 636 | 637 | .hljs-type, 638 | .hljs-class .hljs-title { 639 | color: #458; 640 | font-weight: bold; 641 | } 642 | 643 | .hljs-tag, 644 | .hljs-name, 645 | .hljs-attribute { 646 | color: #000080; 647 | font-weight: normal; 648 | } 649 | 650 | .hljs-regexp, 651 | .hljs-link { 652 | color: #009926; 653 | } 654 | 655 | .hljs-symbol, 656 | .hljs-bullet { 657 | color: #990073; 658 | } 659 | 660 | .hljs-built_in, 661 | .hljs-builtin-name { 662 | color: #0086b3; 663 | } 664 | 665 | .hljs-meta { 666 | color: #999; 667 | font-weight: bold; 668 | } 669 | 670 | .hljs-deletion { 671 | background: #fdd; 672 | } 673 | 674 | .hljs-addition { 675 | background: #dfd; 676 | } 677 | 678 | .hljs-emphasis { 679 | font-style: italic; 680 | } 681 | 682 | .hljs-strong { 683 | font-weight: bold; 684 | } 685 | 686 | button { 687 | -moz-box-shadow:inset 0px 1px 0px 0px #ffffff; 688 | -webkit-box-shadow:inset 0px 1px 0px 0px #ffffff; 689 | box-shadow:inset 0px 1px 0px 0px #ffffff; 690 | background:-webkit-gradient(linear, left top, left bottom, color-stop(0.05, #ffffff), color-stop(1, #f6f6f6)); 691 | background:-moz-linear-gradient(top, #ffffff 5%, #f6f6f6 100%); 692 | background:-webkit-linear-gradient(top, #ffffff 5%, #f6f6f6 100%); 693 | background:-o-linear-gradient(top, #ffffff 5%, #f6f6f6 100%); 694 | background:-ms-linear-gradient(top, #ffffff 5%, #f6f6f6 100%); 695 | background:linear-gradient(to bottom, #ffffff 5%, #f6f6f6 100%); 696 | filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f6f6f6',GradientType=0); 697 | background-color:#ffffff; 698 | border:1px solid #dcdcdc; 699 | display:inline-block; 700 | cursor:pointer; 701 | color:#666666; 702 | font-family:Arial; 703 | font-size:12px; 704 | font-weight:bold; 705 | padding:6px 11px; 706 | text-decoration:none; 707 | } 708 | button:hover { 709 | background:-webkit-gradient(linear, left top, left bottom, color-stop(0.05, #f6f6f6), color-stop(1, #ffffff)); 710 | background:-moz-linear-gradient(top, #f6f6f6 5%, #ffffff 100%); 711 | background:-webkit-linear-gradient(top, #f6f6f6 5%, #ffffff 100%); 712 | background:-o-linear-gradient(top, #f6f6f6 5%, #ffffff 100%); 713 | background:-ms-linear-gradient(top, #f6f6f6 5%, #ffffff 100%); 714 | background:linear-gradient(to bottom, #f6f6f6 5%, #ffffff 100%); 715 | filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f6f6f6', endColorstr='#ffffff',GradientType=0); 716 | background-color:#f6f6f6; 717 | } 718 | button:active { 719 | position:relative; 720 | top:1px; 721 | } 722 | 723 | button { 724 | outline: none; 725 | } 726 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var inject = require('gulp-inject'); 3 | var print = require('gulp-print'); 4 | var clean = require('gulp-clean'); 5 | var markdown = require('gulp-markdown'); 6 | var gulpCopy = require('gulp-copy'); 7 | var watch = require('gulp-watch'); 8 | 9 | 10 | gulp.task('clean', function() { 11 | return gulp.src('./dist').pipe(clean()) 12 | }) 13 | 14 | gulp.task('index', ['clean'],function () { 15 | 16 | return gulp.src('./src/index.html') 17 | .pipe(inject(gulp.src('./src/*.md').pipe(markdown()), { 18 | starttag: '', 19 | transform: function(filepath, file) { 20 | return file.contents.toString(); 21 | } 22 | })) 23 | .pipe(print(function (file) { 24 | return "Processing " + file; 25 | })) 26 | .pipe(inject(gulp.src('./src/*.css'), {relative: true})) 27 | .pipe(gulp.dest('./dist')); 28 | }); 29 | 30 | 31 | gulp.task('copy',['clean'], function() { 32 | gulp.src(['./src/*.js', './src/*.css']) 33 | // .pipe(gulpCopy('./')) 34 | .pipe(gulp.dest('./dist')) 35 | }) 36 | 37 | gulp.task('watch', function () { 38 | // Endless stream mode 39 | gulp.watch('./src/*', ['default']); 40 | }); 41 | 42 | 43 | gulp.task('default', ['clean', 'copy', 'index']) -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "es6-features", 3 | "version": "1.0.0", 4 | "description": " Guide to ES6-features with evaluatable code blocks", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "build": "cp src/index.html dist/index.html; replace github-markdown src/content.md; " 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/codetower/es6-features.git" 13 | }, 14 | "author": "Rasmus Prentow", 15 | "license": "MIT", 16 | "bugs": { 17 | "url": "https://github.com/codetower/es6-features/issues" 18 | }, 19 | "homepage": "https://github.com/codetower/es6-features#readme", 20 | 21 | "devDependencies": { 22 | "gulp": "^3.9.1", 23 | "gulp-inject": "^4.2.0", 24 | "gulp-print": "^2.0.1", 25 | "markdown-to-html": "0.0.13", 26 | "gulp-clean": "^0.3.2", 27 | "gulp-copy": "^1.0.0", 28 | "gulp-markdown": "^1.2.0", 29 | "gulp-watch": "^4.3.11" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/_index.md: -------------------------------------------------------------------------------- 1 | 2 | # ES6 Features 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/arrows.md: -------------------------------------------------------------------------------- 1 | 2 | ## Arrow Functions 3 | 4 | A short hand notation for `function()`, but it does not bind `this` in the same way. 5 | Instead of `this` being binded to the function, it is binding to the contextual `this`. 6 | 7 | ```javascript 8 | no-eval 9 | var odds = evens.map(v => v + 1); // no parentes and no brackets 10 | var nums = evens.map((v, i) => v + i); 11 | var pairs = evens.map(v => ({even: v, odd: v + 1})); 12 | 13 | // Statement bodies 14 | nums.forEach(v => { 15 | if (v % 5 === 0) 16 | fives.push(v); 17 | }); 18 | ``` 19 | 20 | How does `this` work? 21 | 22 | 23 | ```javascript 24 | var object = { 25 | name: "Name", 26 | arrowGetName: () => this.name, 27 | regularGetName: function() { return this.name }, 28 | arrowGetThis: () => this, 29 | regularGetThis: function() { return this } 30 | } 31 | 32 | console.log(this.name) 33 | console.log(object.arrowGetName()); 34 | console.log(object.arrowGetThis()); 35 | console.log(this) 36 | console.log(object.regularGetName()); 37 | console.log(object.regularGetThis()); 38 | ``` 39 | 40 | They work well with classes 41 | 42 | ```javascript 43 | class someClass { 44 | constructor() { 45 | this.name = "Name" 46 | } 47 | 48 | testRegular() { 49 | return function() { return this } 50 | 51 | } 52 | 53 | testArrow() { 54 | return () => this.name; 55 | } 56 | } 57 | 58 | var obj = new someClass(); 59 | 60 | console.log(obj.name) 61 | console.log(obj.testRegular()()); 62 | console.log(obj.testArrow()()); 63 | ``` -------------------------------------------------------------------------------- /src/content.md: -------------------------------------------------------------------------------- 1 | 2 | ## Classes 3 | 4 | As we know them from "real" languages. Syntactic sugar on top of prototype-inheritence. 5 | 6 | 7 | ```javascript 8 | no-eval 9 | class SkinnedMesh extends THREE.Mesh { 10 | constructor(geometry, materials) { 11 | super(geometry, materials); 12 | 13 | this.idMatrix = SkinnedMesh.defaultMatrix(); 14 | this.bones = []; 15 | this.boneMatrices = []; 16 | //... 17 | } 18 | update(camera) { 19 | //... 20 | super.update(); 21 | } 22 | get boneCount() { 23 | return this.bones.length; 24 | } 25 | set matrixType(matrixType) { 26 | this.idMatrix = SkinnedMesh[matrixType](); 27 | } 28 | static defaultMatrix() { 29 | return new THREE.Matrix4(); 30 | } 31 | } 32 | 33 | ``` 34 | [Lebab.io](https://lebab.io/#) 35 | 36 | 37 | ## Enhanced Object Literals 38 | 39 | ```javascript 40 | var theProtoObj = { 41 | toString: function() { 42 | return "The ProtoOBject To string" 43 | } 44 | } 45 | 46 | var handler = () => "handler" 47 | 48 | 49 | var obj = { 50 | // __proto__ 51 | __proto__: theProtoObj, 52 | 53 | // Shorthand for ‘handler: handler’ 54 | handler, 55 | 56 | // Methods 57 | toString() { 58 | 59 | // Super calls 60 | return "d " + super.toString(); 61 | }, 62 | 63 | // Computed (dynamic) property names 64 | [ "prop_" + (() => 42)() ]: 42 65 | }; 66 | 67 | console.log(obj.handler) 68 | console.log(obj.handler()) 69 | console.log(obj.toString()) 70 | console.log(obj.prop_42) 71 | 72 | ``` 73 | 74 | 75 | ## String interpolation 76 | 77 | Nice syntax for string interpolation 78 | 79 | ```javascript 80 | var name = "Bob", time = "today"; 81 | 82 | var multiLine = `This 83 | 84 | Line 85 | 86 | Spans Multiple 87 | 88 | Lines` 89 | 90 | 91 | console.log(`Hello ${name},how are you ${time}?`) 92 | console.log(multiLine) 93 | ``` 94 | 95 | 96 | 97 | ## Destructuring 98 | 99 | ```javascript 100 | // list "matching" 101 | var [a, , b] = [1,2,3]; 102 | console.log(a) 103 | console.log(b) 104 | ``` 105 | 106 | 107 | Objects can be destructured as well. 108 | 109 | ```javascript 110 | nodes = () => { return {op: "a", lhs: "b", rhs: "c"}} 111 | var { op: a, lhs: b , rhs: c } = nodes() 112 | console.log(a) 113 | console.log(b) 114 | console.log(c) 115 | ``` 116 | Using Shorthand notation. 117 | 118 | ```javascript 119 | nodes = () => { return {lhs: "a", op: "b", rhs: "c"}} 120 | 121 | // binds `op`, `lhs` and `rhs` in scope 122 | var {op, lhs, rhs} = nodes() 123 | 124 | console.log(op) 125 | console.log(lhs) 126 | console.log(rhs) 127 | ``` 128 | 129 | Can be used in parameter position 130 | 131 | ```javascript 132 | 133 | function g({name: x}) { 134 | return x 135 | } 136 | 137 | function m({name}) { 138 | return name 139 | } 140 | 141 | console.log(g({name: 5})) 142 | console.log(m({name: 5})) 143 | ``` 144 | 145 | Fail-soft destructuring 146 | 147 | ```javascript 148 | var [a] = [] 149 | var [b = 1] = [] 150 | var c = []; 151 | console.log(a) 152 | console.log(b); 153 | console.log(c); 154 | ``` 155 | 156 | 157 | ## Default 158 | ```javascript 159 | function f(x, y=12) { 160 | return x + y; 161 | } 162 | 163 | console.log(f(3)) 164 | ``` 165 | 166 | ## Spread 167 | 168 | In functions: 169 | 170 | ```javascript 171 | function f(x, y, z) { 172 | return x + y + z; 173 | } 174 | // Pass each elem of array as argument 175 | console.log(f(...[1,2,3])) 176 | ``` 177 | 178 | In arrays: 179 | 180 | ```javascript 181 | var parts = ["shoulders", "knees"]; 182 | var lyrics = ["head", ...parts, "and", "toes"]; 183 | 184 | console.log(lyrics) 185 | ``` 186 | 187 | ## Spread + Object Literals 188 | 189 | We can do cool stuff with this in object creations. 190 | 191 | ```javascript 192 | no-eval 193 | let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 }; 194 | console.log(x); // 1 195 | console.log(y); // 2 196 | console.log(z); // { a: 3, b: 4 } 197 | 198 | // Spread properties 199 | let n = { x, y, ...z }; 200 | console.log(n); // { x: 1, y: 2, a: 3, b: 4 } 201 | console.log(obj) 202 | ``` 203 | 204 | Sadly it is not supported yet: 205 | 206 | `npm install --save-dev babel-plugin-transform-object-rest-spread` 207 | 208 | 209 | ## Rest 210 | We can allow unlimited params to function by using the rest operator. 211 | ```javascript 212 | function demo(part1, ...part2) { 213 | return {part1, part2} 214 | } 215 | 216 | console.log(demo(1,2,3,4,5,6)) 217 | ``` 218 | 219 | 220 | ## Let 221 | `Let` is the new `var`. As it has "sane" bindings. 222 | 223 | ```javascript 224 | { 225 | var globalVar = "from demo1" 226 | } 227 | 228 | { 229 | let globalLet = "from demo2"; 230 | } 231 | 232 | console.log(globalVar) 233 | console.log(globalLet) 234 | 235 | ``` 236 | However, it does not assign anything to `window`: 237 | 238 | ```javascript 239 | let me = "go"; // globally scoped 240 | var i = "able"; // globally scoped 241 | 242 | console.log(window.me); 243 | console.log(window.i); 244 | ``` 245 | It is not possible to redeclare a variable using `let`: 246 | 247 | ```javascript 248 | 249 | let me = "foo"; 250 | let me = "bar"; 251 | console.log(me); 252 | ``` 253 | 254 | ```javascript 255 | 256 | var me = "foo"; 257 | var me = "bar"; 258 | console.log(me) 259 | ``` 260 | 261 | ## Const 262 | `Const` is for read-only variables. 263 | 264 | ```javascript 265 | const a = "b" 266 | a = "a" 267 | ``` 268 | It should be noted that `const` objects can still be mutated. 269 | 270 | ```javascript 271 | const a = { a: "a" } 272 | a.a = "b" 273 | console.log(a) 274 | ``` 275 | 276 | 277 | 278 | ## For..of 279 | New type of iterator, an alternative to `for..in`. It returns the values instead of the `keys`. 280 | 281 | ```javascript 282 | let list = [4, 5, 6]; 283 | 284 | console.log(list) 285 | 286 | for (let i in list) { 287 | console.log(i); 288 | } 289 | ``` 290 | 291 | ```javascript 292 | let list = [4, 5, 6]; 293 | 294 | console.log(list) 295 | 296 | 297 | for (let i of list) { 298 | console.log(i); 299 | } 300 | ``` 301 | 302 | 303 | ### Iterators 304 | The iterator is a more dynamic type than an array. 305 | 306 | ```javascript 307 | let infinite = { 308 | [Symbol.iterator]() { 309 | let c = 0; 310 | return { 311 | next() { 312 | c++; 313 | return { done: false, value: c } 314 | } 315 | } 316 | } 317 | } 318 | 319 | console.log("start"); 320 | 321 | for (var n of infinite) { 322 | // truncate the sequence at 1000 323 | if (n > 10) 324 | break; 325 | console.log(n); 326 | } 327 | ``` 328 | 329 | Using Typescript interfaces we can see how it looks: 330 | 331 | ```javascript 332 | no-eval 333 | interface IteratorResult { 334 | done: boolean; 335 | value: any; 336 | } 337 | interface Iterator { 338 | next(): IteratorResult; 339 | } 340 | interface Iterable { 341 | [Symbol.iterator](): Iterator 342 | } 343 | ``` 344 | 345 | ### Generators 346 | Generators create iterators, and are more dynamic than iterators. They do not have to keep track of state in the same manner and do not support the concept of `done`. 347 | 348 | ```javascript 349 | var infinity = { 350 | [Symbol.iterator]: function*() { 351 | var c = 1; 352 | for (;;) { 353 | yield c++; 354 | } 355 | } 356 | } 357 | 358 | console.log("start") 359 | for (var n of infinity) { 360 | // truncate the sequence at 1000 361 | if (n > 10) 362 | break; 363 | console.log(n); 364 | } 365 | ``` 366 | 367 | 368 | Using typescript again to show the interfaces. 369 | 370 | ```javascript 371 | no-eval 372 | interface Generator extends Iterator { 373 | next(value?: any): IteratorResult; 374 | throw(exception: any); 375 | } 376 | ``` 377 | 378 | [function*](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*) 379 | [Iterators and generator](https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Iterators_and_Generators) 380 | 381 | An example of yield* 382 | 383 | ```javascript 384 | function* anotherGenerator(i) { 385 | yield i + 1; 386 | yield i + 2; 387 | yield i + 3; 388 | } 389 | 390 | function* generator(i) { 391 | yield i; 392 | yield* anotherGenerator(i); 393 | yield i + 10; 394 | } 395 | 396 | var gen = generator(10); 397 | 398 | console.log(gen.next().value); 399 | console.log(gen.next().value); 400 | console.log(gen.next().value); 401 | console.log(gen.next().value); 402 | console.log(gen.next().value); 403 | ``` 404 | 405 | ## Unicode 406 | ES6 provides better support for Unicode. 407 | 408 | ```javascript 409 | var regex = new RegExp('\u{61}', 'u'); 410 | 411 | console.log(regex.unicode) 412 | console.log("\uD842\uDFD7") 413 | console.log("\uD842\uDFD7".codePointAt()) 414 | ``` 415 | 416 | ## Modules & Module Loaders 417 | Native support for modules. 418 | 419 | ```javascript 420 | no-eval 421 | import defaultMember from "module-name"; 422 | import * as name from "module-name"; 423 | import { member } from "module-name"; 424 | import { member as alias } from "module-name"; 425 | import { member1 , member2 } from "module-name"; 426 | import { member1 , member2 as alias2 , [...] } from "module-name"; 427 | import defaultMember, { member [ , [...] ] } from "module-name"; 428 | import defaultMember, * as name from "module-name"; 429 | import "module-name"; 430 | 431 | ``` 432 | 433 | ```javascript 434 | no-eval 435 | export { name1, name2, …, nameN }; 436 | export { variable1 as name1, variable2 as name2, …, nameN }; 437 | export let name1, name2, …, nameN; // also var 438 | export let name1 = …, name2 = …, …, nameN; // also var, const 439 | 440 | export expression; 441 | export default expression; 442 | export default function (…) { … } // also class, function* 443 | export default function name1(…) { … } // also class, function* 444 | export { name1 as default, … }; 445 | 446 | export * from …; 447 | export { name1, name2, …, nameN } from …; 448 | export { import1 as name1, import2 as name2, …, nameN } from …; 449 | 450 | ``` 451 | 452 | [Import](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import) 453 | [Export](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export) 454 | 455 | 456 | ## Set 457 | Sets as in the mathematical counterpart where all items are unique. 458 | For people who know `SQL` this is equivalent to `distinct`. 459 | 460 | ```javascript 461 | var set = new Set(); 462 | set.add("Potato").add("Tomato").add("Tomato"); 463 | console.log(set.size) 464 | console.log(set.has("Tomato")) 465 | 466 | for(var item of set) { 467 | console.log(item) 468 | } 469 | ``` 470 | 471 | [Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) 472 | 473 | ## WeakSet 474 | The `WeakSet` object lets you store weakly held objects in a collection. 475 | Objects without a reference will be garbage collected. 476 | 477 | ```javascript 478 | var item = { a:"Potato"} 479 | var set = new WeakSet(); 480 | set.add({ a:"Potato"}).add(item).add({ a:"Tomato"}).add({ a:"Tomato"}); 481 | console.log(set.size) 482 | console.log(set.has({a:"Tomato"})) 483 | console.log(set.has(item)) 484 | 485 | for(let item of set) { 486 | console.log(item) 487 | } 488 | ``` 489 | 490 | 491 | [WeakSet](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet) 492 | 493 | 494 | ## Map 495 | Maps, also known as dictionaries. 496 | 497 | 498 | ```javascript 499 | var map = new Map(); 500 | map.set("Potato", 12); 501 | map.set("Tomato", 34); 502 | 503 | console.log(map.get("Potato")) 504 | 505 | 506 | for(let item of map) { 507 | console.log(item) 508 | } 509 | 510 | 511 | for(let item in map) { 512 | console.log(item) 513 | } 514 | ``` 515 | 516 | Other types than strings can be used. 517 | 518 | ```javascript 519 | var map = new Map(); 520 | var key = {a: "a"} 521 | map.set(key, 12); 522 | 523 | 524 | console.log(map.get(key)) 525 | console.log(map.get({a: "a"})) 526 | 527 | 528 | ``` 529 | 530 | 531 | 532 | 533 | [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) 534 | 535 | 536 | ## WeakMap 537 | 538 | Uses objects for keys, and only keeps weak reference to the keys. 539 | 540 | ```javascript 541 | var wm = new WeakMap(); 542 | 543 | var o1 = {} 544 | var o2 = {} 545 | var o3 = {} 546 | 547 | 548 | wm.set(o1, 1); 549 | wm.set(o2, 2); 550 | wm.set(o3, {a: "a"}); 551 | wm.set({}, 4); 552 | 553 | console.log(wm.get(o2)); 554 | console.log(wm.has({})) 555 | 556 | delete o2; 557 | 558 | console.log(wm.get(o3)); 559 | 560 | for(let item in wm) { 561 | console.log(item) 562 | } 563 | 564 | 565 | for(let item of wm) { 566 | console.log(item) 567 | } 568 | ``` 569 | 570 | [WeakMap](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap) 571 | 572 | ## Proxies 573 | Proxies can be used to alter objects' behaviour. They allow us to define traps. 574 | 575 | ```javascript 576 | 577 | var obj = function ProfanityGenerator() { 578 | return { 579 | words: "Horrible words" 580 | } 581 | }() 582 | 583 | var handler = function CensoringHandler() { 584 | return { 585 | get: function (target, key) { 586 | return target[key].replace("Horrible", "Nice"); 587 | }, 588 | } 589 | 590 | }() 591 | 592 | var proxy = new Proxy(obj, handler); 593 | 594 | console.log(proxy.words); 595 | 596 | ``` 597 | 598 | The following traps are available: 599 | 600 | ```javascript 601 | no-eval 602 | var handler = 603 | { 604 | get:..., 605 | set:..., 606 | has:..., 607 | deleteProperty:..., 608 | apply:..., 609 | construct:..., 610 | getOwnPropertyDescriptor:..., 611 | defineProperty:..., 612 | getPrototypeOf:..., 613 | setPrototypeOf:..., 614 | enumerate:..., 615 | ownKeys:..., 616 | preventExtensions:..., 617 | isExtensible:... 618 | } 619 | ``` 620 | 621 | 622 | [Proxies](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Proxy) 623 | 624 | 625 | ## Symbols 626 | Symbols are a new type. Can be used to create anonymous properties. 627 | 628 | ```javascript 629 | var typeSymbol = Symbol("type"); 630 | 631 | class Pet { 632 | 633 | constructor(type) { 634 | 635 | this[typeSymbol] = type; 636 | 637 | } 638 | getType() { 639 | return this[typeSymbol]; 640 | } 641 | 642 | } 643 | 644 | 645 | var a = new Pet("dog"); 646 | console.log(a.getType()); 647 | console.log(Object.getOwnPropertyNames(a)) 648 | 649 | 650 | console.log(Symbol("a") === Symbol("a")) 651 | ``` 652 | 653 | 654 | [More info](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol) 655 | 656 | ## Inheritable Built-ins 657 | 658 | We can now inherit from native classes. 659 | 660 | ```javascript 661 | 662 | class CustomArray extends Array { 663 | 664 | } 665 | 666 | var a = new CustomArray(); 667 | 668 | a[0] = 2 669 | console.log(a[0]) 670 | 671 | ``` 672 | It is not possible to override the getter function without using Proxies of arrays. 673 | 674 | 675 | ## New Library 676 | Various new methods and constants. 677 | 678 | ```javascript 679 | console.log(Number.EPSILON) 680 | console.log(Number.isInteger(Infinity)) 681 | console.log(Number.isNaN("NaN")) 682 | 683 | console.log(Math.acosh(3)) 684 | console.log(Math.hypot(3, 4)) 685 | console.log(Math.imul(Math.pow(2, 32) - 1, Math.pow(2, 32) - 2)) 686 | 687 | console.log("abcde".includes("cd") ) 688 | console.log("abc".repeat(3) ) 689 | 690 | 691 | console.log(Array.of(1, 2, 3) ) 692 | console.log([0, 0, 0].fill(7, 1) ) 693 | console.log([1, 2, 3].find(x => x == 3) ) 694 | console.log([1, 2, 3].findIndex(x => x == 2)) 695 | console.log([1, 2, 3, 4, 5].copyWithin(3, 0)) 696 | console.log(["a", "b", "c"].entries() ) 697 | console.log(["a", "b", "c"].keys() ) 698 | console.log(["a", "b", "c"].values() ) 699 | 700 | console.log(Object.assign({}, { origin: new Point(0,0) })) 701 | 702 | 703 | ``` 704 | 705 | Documentation: [Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number), [Math](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math), [Array.from](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from), [Array.of](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/of), [Array.prototype.copyWithin](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin), [Object.assign](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) 706 | 707 | 708 | ## Binary and Octal 709 | Literals for binary and octal numbering. 710 | 711 | ```javascript 712 | console.log(0b11111) 713 | console.log(0o2342) 714 | 715 | console.log(0xff); // also in es5 716 | 717 | ``` 718 | 719 | ## Promises 720 | The bread and butter for async programing. 721 | 722 | ```javascript 723 | var p1 = new Promise((resolve, reject) => { 724 | setTimeout(() => resolve("1"), 101) 725 | }) 726 | var p2 = new Promise((resolve, reject) => { 727 | setTimeout(() => resolve("2"), 100) 728 | }) 729 | 730 | Promise.race([p1, p2]).then((res) => { 731 | console.log(res) 732 | }) 733 | 734 | Promise.all([p1, p2]).then((res) => { 735 | console.log(res) 736 | }) 737 | 738 | ``` 739 | 740 | ### Quick Promise 741 | Need a quick always resolved promise? 742 | 743 | ```javascript 744 | 745 | var p1 = Promise.resolve("1") 746 | var p2 = Promise.reject("2") 747 | 748 | Promise.race([p1, p2]).then((res) => { 749 | console.log(res) 750 | }) 751 | ``` 752 | 753 | ### Fail fast 754 | If a promise fails, `all` and `race` will reject as well. 755 | 756 | ```javascript 757 | var p1 = new Promise((resolve, reject) => { 758 | setTimeout(() => resolve("1"), 1001) 759 | }) 760 | var p2 = new Promise((resolve, reject) => { 761 | setTimeout(() => reject("2"), 1) 762 | }) 763 | 764 | Promise.race([p1, p2]).then((res) => { 765 | console.log("success" + res) 766 | }, res => { 767 | console.log("error " + res) 768 | }) 769 | 770 | Promise.all([p1, p2]).then((res) => { 771 | console.log("success" + res) 772 | }, res => { 773 | console.log("error " + res) 774 | }) 775 | 776 | 777 | ``` 778 | 779 | [More Info](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) 780 | 781 | 782 | ## Reflect 783 | New type of meta programming with new API for existing and also a few new methods. 784 | 785 | ```javascript 786 | 787 | var z = {w: "Super Hello"} 788 | var y = {x: "hello", __proto__: z}; 789 | 790 | console.log(Reflect.getOwnPropertyDescriptor(y, "x")); 791 | console.log(Reflect.has(y, "w")); 792 | console.log(Reflect.ownKeys(y, "w")); 793 | 794 | console.log(Reflect.has(y, "x")); 795 | console.log(Reflect.deleteProperty(y,"x")) 796 | console.log(Reflect.has(y, "x")); 797 | 798 | ``` 799 | 800 | [More Info](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect) 801 | 802 | ## Tail Call Optimization 803 | ES6 should fix ensure tail calls do not generate stack overflow. (Not all implementations work). 804 | 805 | 806 | ```javascript 807 | 808 | function factorial(n, acc = 1) { 809 | if (n <= 1) return acc; 810 | return factorial(n - 1, n * acc); 811 | } 812 | console.log(factorial(10)) 813 | console.log(factorial(100)) 814 | console.log(factorial(1000)) 815 | console.log(factorial(10000)) 816 | console.log(factorial(100000)) 817 | console.log(factorial(1000000)) 818 | 819 | ``` 820 | 821 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ES6 Features 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/script.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 4 | * This "script" provides functionality to 5 | * turn html "code blocks" into executable blocks while providing 6 | * an index based on headlines. 7 | * 8 | */ 9 | 10 | // ========================================================================= 11 | // Configuration 12 | // ========================================================================= 13 | let config = { 14 | codeBlockSelector: ".lang-javascript,.javascript", 15 | indexSelector: ".content-index", 16 | headlineSelector: "h2" 17 | }; 18 | 19 | 20 | // ========================================================================= 21 | // Helpers 22 | // ========================================================================= 23 | 24 | /** 25 | * Pipes the data through the supplied methods. 26 | */ 27 | function pipe(data, ...methods) { 28 | let result = data; 29 | for (method of methods) { 30 | result = method.bind(this)(result) 31 | } 32 | 33 | return result; 34 | } 35 | 36 | 37 | // ========================================================================= 38 | // Classes 39 | // ========================================================================= 40 | 41 | /** 42 | * CodeConverter class that can convert HTML to executable code with result handling 43 | */ 44 | class CodeConverter { 45 | 46 | constructor(index) { 47 | this.index = index; 48 | 49 | } 50 | 51 | convert(code) { 52 | return pipe.bind(this)(code, 53 | this.removeHtmlEntities, 54 | this.decodeEntities, 55 | this.addResultHandling 56 | ); 57 | } 58 | 59 | addResultHandling(code) { 60 | return code 61 | .replace(/console/, `clearResult("${this.index}"); \nconsole`) 62 | .replace(/console.log\((.*)\).*/g, ` 63 | try {  64 | let _______a = $1; 65 | if(typeof(_______a) === 'object' && _______a != window) { 66 | _______a = JSON.stringify(_______a) 67 | } 68 | addResult('${this.index}', '$1 -> ' + _______a); 69 | } 70 | catch(e) { 71 | addResult('${this.index}', '$1 -> '+ e); 72 | }`) 73 | 74 | } 75 | 76 | decodeEntities(encodedString) { 77 | let textArea = document.createElement('textarea'); 78 | textArea.innerHTML = encodedString; 79 | return textArea.value; 80 | } 81 | 82 | 83 | removeHtmlEntities(text) { 84 | return text.replace(/<(?:.|\/)(?:.|\n)*?>/gm, ''); 85 | } 86 | } 87 | 88 | /** 89 | * CodeBlock class, representing a code block 90 | */ 91 | class CodeBlock { 92 | constructor(element, index) { 93 | this.index = index; 94 | this.codeConverter = new CodeConverter(index) 95 | this.isExecutable = !element.innerHTML.includes("no-eval") 96 | this.element = element 97 | this.addFunctionalityToLangBlock(); 98 | } 99 | 100 | execute() { 101 | try { 102 | this.convertAndExecute(); 103 | } catch (e) { 104 | console.log(e) 105 | addResult(this.index, e) 106 | } 107 | } 108 | 109 | convertAndExecute() { 110 | let code = this.codeConverter.convert(this.element.innerHTML); 111 | eval.apply(window, [code]); 112 | } 113 | 114 | addFunctionalityToLangBlock() { 115 | if (this.isExecutable) { 116 | this.addExecutionButton(); 117 | this.addCodeBlockClass(); 118 | this.addContentEditableAttribute(); 119 | } else { 120 | this.removeNoEval(this.element.innerHTML); 121 | } 122 | } 123 | 124 | addCodeBlockClass() { 125 | $(this.element).addClass("codeblock-" + this.index); 126 | } 127 | 128 | addExecutionButton() { 129 | $(this.element).parent().after(` 130 | 131 |
    132 | `) 133 | } 134 | 135 | addContentEditableAttribute() { 136 | $(this.element).prop('contenteditable', 'true'); 137 | } 138 | 139 | removeNoEval(s) { 140 | this.element.innerHTML = this.element.innerHTML.replace(/no-eval.*\n/, "") 141 | } 142 | 143 | } 144 | 145 | /** 146 | * Page class representing the entire page 147 | */ 148 | class Page { 149 | constructor(config) { 150 | this.config = config; 151 | this.codeBlocks = new Map(); 152 | } 153 | 154 | initialize() { 155 | this.initializeCodeBlocks(); 156 | this.addIndex(); 157 | this.addCodeHighlight(); 158 | } 159 | 160 | initializeCodeBlocks() { 161 | $(this.config.codeBlockSelector).each((i, element) => { 162 | this.codeBlocks.set(i, new CodeBlock(element, i)); 163 | }) 164 | } 165 | 166 | addIndex() { 167 | $(this.config.headlineSelector).each((_, element) => { 168 | $(element).wrap(``) 169 | $(this.config.indexSelector).append(`
  • ${element.innerHTML}
  • `); 170 | }) 171 | } 172 | 173 | addCodeHighlight() { 174 | $('pre code').each(function (i, block) { 175 | hljs.highlightBlock(block); 176 | }); 177 | } 178 | 179 | } 180 | 181 | 182 | // ========================================================================= 183 | // Global Methods 184 | // ========================================================================= 185 | 186 | function addResult(id, res) { 187 | document.getElementById(id).innerHTML += res + "
    "; 188 | } 189 | 190 | function clearResult(id) { 191 | document.getElementById(id).innerHTML = ""; 192 | } 193 | 194 | function executeCode(index) { 195 | let codeBlock = page.codeBlocks.get(parseInt(index)); 196 | if (codeBlock) { 197 | codeBlock.execute(); 198 | } 199 | 200 | } 201 | 202 | // ========================================================================= 203 | // Bootstraping 204 | // ========================================================================= 205 | 206 | var page = new Page(config); 207 | 208 | $(document).ready(function () { 209 | page.initialize(); 210 | }) 211 | -------------------------------------------------------------------------------- /src/style.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: octicons-link; 3 | src: url(data:font/woff;charset=utf-8;base64,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) format('woff'); 4 | } 5 | 6 | body { 7 | -ms-text-size-adjust: 100%; 8 | -webkit-text-size-adjust: 100%; 9 | line-height: 1.5; 10 | color: #333; 11 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; 12 | font-size: 16px; 13 | line-height: 1.5; 14 | word-wrap: break-word; 15 | margin: 0 20px; 16 | } 17 | 18 | a { 19 | background-color: transparent; 20 | -webkit-text-decoration-skip: objects; 21 | } 22 | 23 | a:active, 24 | a:hover { 25 | outline-width: 0; 26 | } 27 | 28 | strong { 29 | font-weight: inherit; 30 | } 31 | 32 | strong { 33 | font-weight: bolder; 34 | } 35 | 36 | h1 { 37 | font-size: 2em; 38 | margin: 0.67em 0; 39 | } 40 | 41 | img { 42 | border-style: none; 43 | } 44 | 45 | svg:not(:root) { 46 | overflow: hidden; 47 | } 48 | 49 | code, 50 | kbd, 51 | pre { 52 | font-family: monospace, monospace; 53 | font-size: 1em; 54 | } 55 | 56 | hr { 57 | box-sizing: content-box; 58 | height: 0; 59 | overflow: visible; 60 | } 61 | 62 | input { 63 | font: inherit; 64 | margin: 0; 65 | } 66 | 67 | input { 68 | overflow: visible; 69 | } 70 | 71 | [type="checkbox"] { 72 | box-sizing: border-box; 73 | padding: 0; 74 | } 75 | 76 | * { 77 | box-sizing: border-box; 78 | } 79 | 80 | input { 81 | font-family: inherit; 82 | font-size: inherit; 83 | line-height: inherit; 84 | } 85 | 86 | a { 87 | color: #4078c0; 88 | text-decoration: none; 89 | } 90 | 91 | a:hover, 92 | a:active { 93 | text-decoration: underline; 94 | } 95 | 96 | strong { 97 | font-weight: 600; 98 | } 99 | 100 | hr { 101 | height: 0; 102 | margin: 15px 0; 103 | overflow: hidden; 104 | background: transparent; 105 | border: 0; 106 | border-bottom: 1px solid #ddd; 107 | } 108 | 109 | hr::before { 110 | display: table; 111 | content: ""; 112 | } 113 | 114 | hr::after { 115 | display: table; 116 | clear: both; 117 | content: ""; 118 | } 119 | 120 | table { 121 | border-spacing: 0; 122 | border-collapse: collapse; 123 | } 124 | 125 | td, 126 | th { 127 | padding: 0; 128 | } 129 | 130 | h1, 131 | h2, 132 | h3, 133 | h4, 134 | h5, 135 | h6 { 136 | margin-top: 0; 137 | margin-bottom: 0; 138 | } 139 | 140 | h1 { 141 | font-size: 32px; 142 | font-weight: 600; 143 | } 144 | 145 | h2 { 146 | font-size: 24px; 147 | font-weight: 600; 148 | } 149 | 150 | h3 { 151 | font-size: 20px; 152 | font-weight: 600; 153 | } 154 | 155 | h4 { 156 | font-size: 16px; 157 | font-weight: 600; 158 | } 159 | 160 | h5 { 161 | font-size: 14px; 162 | font-weight: 600; 163 | } 164 | 165 | h6 { 166 | font-size: 12px; 167 | font-weight: 600; 168 | } 169 | 170 | p { 171 | margin-top: 0; 172 | margin-bottom: 10px; 173 | } 174 | 175 | blockquote { 176 | margin: 0; 177 | } 178 | 179 | ul, 180 | ol { 181 | padding-left: 0; 182 | margin-top: 0; 183 | margin-bottom: 0; 184 | } 185 | 186 | ol ol, 187 | ul ol { 188 | list-style-type: lower-roman; 189 | } 190 | 191 | ul ul ol, 192 | ul ol ol, 193 | ol ul ol, 194 | ol ol ol { 195 | list-style-type: lower-alpha; 196 | } 197 | 198 | dd { 199 | margin-left: 0; 200 | } 201 | 202 | code { 203 | font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; 204 | font-size: 12px; 205 | } 206 | 207 | pre, .results { 208 | margin-top: 0; 209 | margin-bottom: 0; 210 | font: 12px Consolas, "Liberation Mono", Menlo, Courier, monospace; 211 | } 212 | 213 | .octicon { 214 | vertical-align: text-bottom; 215 | } 216 | 217 | input { 218 | -webkit-font-feature-settings: "liga" 0; 219 | font-feature-settings: "liga" 0; 220 | } 221 | 222 | .markdown-body::before { 223 | display: table; 224 | content: ""; 225 | } 226 | 227 | .markdown-body::after { 228 | display: table; 229 | clear: both; 230 | content: ""; 231 | } 232 | 233 | .markdown-body>*:first-child { 234 | margin-top: 0 !important; 235 | } 236 | 237 | .markdown-body>*:last-child { 238 | margin-bottom: 0 !important; 239 | } 240 | 241 | a:not([href]) { 242 | color: inherit; 243 | text-decoration: none; 244 | } 245 | 246 | .anchor { 247 | float: left; 248 | padding-right: 4px; 249 | margin-left: -20px; 250 | line-height: 1; 251 | } 252 | 253 | .anchor:focus { 254 | outline: none; 255 | } 256 | 257 | p, 258 | blockquote, 259 | ul, 260 | ol, 261 | dl, 262 | table, 263 | pre { 264 | margin-top: 0; 265 | margin-bottom: 16px; 266 | } 267 | 268 | hr { 269 | height: 0.25em; 270 | padding: 0; 271 | margin: 24px 0; 272 | background-color: #e7e7e7; 273 | border: 0; 274 | } 275 | 276 | blockquote { 277 | padding: 0 1em; 278 | color: #777; 279 | border-left: 0.25em solid #ddd; 280 | } 281 | 282 | blockquote>:first-child { 283 | margin-top: 0; 284 | } 285 | 286 | blockquote>:last-child { 287 | margin-bottom: 0; 288 | } 289 | 290 | kbd { 291 | display: inline-block; 292 | padding: 3px 5px; 293 | font-size: 11px; 294 | line-height: 10px; 295 | color: #555; 296 | vertical-align: middle; 297 | background-color: #fcfcfc; 298 | border: solid 1px #ccc; 299 | border-bottom-color: #bbb; 300 | border-radius: 3px; 301 | box-shadow: inset 0 -1px 0 #bbb; 302 | } 303 | 304 | h1, 305 | h2, 306 | h3, 307 | h4, 308 | h5, 309 | h6 { 310 | margin-top: 24px; 311 | margin-bottom: 16px; 312 | font-weight: 600; 313 | line-height: 1.25; 314 | } 315 | 316 | h1 .octicon-link, 317 | h2 .octicon-link, 318 | h3 .octicon-link, 319 | h4 .octicon-link, 320 | h5 .octicon-link, 321 | h6 .octicon-link { 322 | color: #000; 323 | vertical-align: middle; 324 | visibility: hidden; 325 | } 326 | 327 | h1:hover .anchor, 328 | h2:hover .anchor, 329 | h3:hover .anchor, 330 | h4:hover .anchor, 331 | h5:hover .anchor, 332 | h6:hover .anchor { 333 | text-decoration: none; 334 | } 335 | 336 | h1:hover .anchor .octicon-link, 337 | h2:hover .anchor .octicon-link, 338 | h3:hover .anchor .octicon-link, 339 | h4:hover .anchor .octicon-link, 340 | h5:hover .anchor .octicon-link, 341 | h6:hover .anchor .octicon-link { 342 | visibility: visible; 343 | } 344 | 345 | h1 { 346 | padding-bottom: 0.3em; 347 | font-size: 2em; 348 | border-bottom: 1px solid #eee; 349 | } 350 | 351 | h2 { 352 | padding-bottom: 0.3em; 353 | font-size: 1.5em; 354 | border-bottom: 1px solid #eee; 355 | } 356 | 357 | h3 { 358 | font-size: 1.25em; 359 | } 360 | 361 | h4 { 362 | font-size: 1em; 363 | } 364 | 365 | h5 { 366 | font-size: 0.875em; 367 | } 368 | 369 | h6 { 370 | font-size: 0.85em; 371 | color: #777; 372 | } 373 | 374 | ul, 375 | ol { 376 | padding-left: 2em; 377 | } 378 | 379 | ul ul, 380 | ul ol, 381 | ol ol, 382 | ol ul { 383 | margin-top: 0; 384 | margin-bottom: 0; 385 | } 386 | 387 | li>p { 388 | margin-top: 16px; 389 | } 390 | 391 | li+li { 392 | margin-top: 0.25em; 393 | } 394 | 395 | dl { 396 | padding: 0; 397 | } 398 | 399 | dl dt { 400 | padding: 0; 401 | margin-top: 16px; 402 | font-size: 1em; 403 | font-style: italic; 404 | font-weight: bold; 405 | } 406 | 407 | dl dd { 408 | padding: 0 16px; 409 | margin-bottom: 16px; 410 | } 411 | 412 | table { 413 | display: block; 414 | width: 100%; 415 | overflow: auto; 416 | } 417 | 418 | table th { 419 | font-weight: bold; 420 | } 421 | 422 | table th, 423 | table td { 424 | padding: 6px 13px; 425 | border: 1px solid #ddd; 426 | } 427 | 428 | table tr { 429 | background-color: #fff; 430 | border-top: 1px solid #ccc; 431 | } 432 | 433 | table tr:nth-child(2n) { 434 | background-color: #f8f8f8; 435 | } 436 | 437 | img { 438 | max-width: 100%; 439 | box-sizing: content-box; 440 | background-color: #fff; 441 | } 442 | 443 | code, .results { 444 | padding: 0; 445 | padding-top: 0.2em; 446 | padding-bottom: 0.2em; 447 | margin: 0; 448 | background-color: rgba(0,0,0,0.04); 449 | border-radius: 3px; 450 | } 451 | 452 | code::before, 453 | code::after { 454 | letter-spacing: -0.2em; 455 | content: "\00a0"; 456 | } 457 | 458 | pre { 459 | word-wrap: normal; 460 | } 461 | 462 | pre>code, { 463 | padding: 0; 464 | margin: 0; 465 | font-size: 100%; 466 | word-break: normal; 467 | white-space: pre; 468 | background: transparent; 469 | border: 0; 470 | } 471 | 472 | .highlight { 473 | margin-bottom: 16px; 474 | } 475 | 476 | .highlight pre { 477 | margin-bottom: 0; 478 | word-break: normal; 479 | } 480 | 481 | .highlight pre,.results, 482 | pre { 483 | padding: 16px; 484 | overflow: auto; 485 | font-size: 85%; 486 | line-height: 1.45; 487 | background-color: #f7f7f7; 488 | border-radius: 3px; 489 | } 490 | 491 | pre code { 492 | display: inline; 493 | max-width: auto; 494 | padding: 0; 495 | margin: 0; 496 | overflow: visible; 497 | line-height: inherit; 498 | word-wrap: normal; 499 | background-color: transparent; 500 | border: 0; 501 | } 502 | 503 | pre code::before, 504 | pre code::after { 505 | content: normal; 506 | } 507 | 508 | .pl-0 { 509 | padding-left: 0 !important; 510 | } 511 | 512 | .pl-1 { 513 | padding-left: 3px !important; 514 | } 515 | 516 | .pl-2 { 517 | padding-left: 6px !important; 518 | } 519 | 520 | .pl-3 { 521 | padding-left: 12px !important; 522 | } 523 | 524 | .pl-4 { 525 | padding-left: 24px !important; 526 | } 527 | 528 | .pl-5 { 529 | padding-left: 36px !important; 530 | } 531 | 532 | .pl-6 { 533 | padding-left: 48px !important; 534 | } 535 | 536 | .full-commit .btn-outline:not(:disabled):hover { 537 | color: #4078c0; 538 | border: 1px solid #4078c0; 539 | } 540 | 541 | kbd { 542 | display: inline-block; 543 | padding: 3px 5px; 544 | font: 11px Consolas, "Liberation Mono", Menlo, Courier, monospace; 545 | line-height: 10px; 546 | color: #555; 547 | vertical-align: middle; 548 | background-color: #fcfcfc; 549 | border: solid 1px #ccc; 550 | border-bottom-color: #bbb; 551 | border-radius: 3px; 552 | box-shadow: inset 0 -1px 0 #bbb; 553 | } 554 | 555 | :checked+.radio-label { 556 | position: relative; 557 | z-index: 1; 558 | border-color: #4078c0; 559 | } 560 | 561 | .task-list-item { 562 | list-style-type: none; 563 | } 564 | 565 | .task-list-item+.task-list-item { 566 | margin-top: 3px; 567 | } 568 | 569 | .task-list-item input { 570 | margin: 0 0.2em 0.25em -1.6em; 571 | vertical-align: middle; 572 | } 573 | 574 | hr { 575 | border-bottom-color: #eee; 576 | } 577 | 578 | .results { 579 | margin-top: 10px; 580 | margin-bottom: 10px; 581 | font-size:12px; 582 | } 583 | 584 | 585 | 586 | /* 587 | 588 | github.com style (c) Vasily Polovnyov 589 | 590 | */ 591 | 592 | .hljs { 593 | display: block; 594 | overflow-x: auto; 595 | padding: 0.5em; 596 | color: #333; 597 | background: #f8f8f8; 598 | } 599 | 600 | .hljs-comment, 601 | .hljs-quote { 602 | color: #998; 603 | font-style: italic; 604 | } 605 | 606 | .hljs-keyword, 607 | .hljs-selector-tag, 608 | .hljs-subst { 609 | color: #333; 610 | font-weight: bold; 611 | } 612 | 613 | .hljs-number, 614 | .hljs-literal, 615 | .hljs-variable, 616 | .hljs-template-variable, 617 | .hljs-tag .hljs-attr { 618 | color: #008080; 619 | } 620 | 621 | .hljs-string, 622 | .hljs-doctag { 623 | color: #d14; 624 | } 625 | 626 | .hljs-title, 627 | .hljs-section, 628 | .hljs-selector-id { 629 | color: #900; 630 | font-weight: bold; 631 | } 632 | 633 | .hljs-subst { 634 | font-weight: normal; 635 | } 636 | 637 | .hljs-type, 638 | .hljs-class .hljs-title { 639 | color: #458; 640 | font-weight: bold; 641 | } 642 | 643 | .hljs-tag, 644 | .hljs-name, 645 | .hljs-attribute { 646 | color: #000080; 647 | font-weight: normal; 648 | } 649 | 650 | .hljs-regexp, 651 | .hljs-link { 652 | color: #009926; 653 | } 654 | 655 | .hljs-symbol, 656 | .hljs-bullet { 657 | color: #990073; 658 | } 659 | 660 | .hljs-built_in, 661 | .hljs-builtin-name { 662 | color: #0086b3; 663 | } 664 | 665 | .hljs-meta { 666 | color: #999; 667 | font-weight: bold; 668 | } 669 | 670 | .hljs-deletion { 671 | background: #fdd; 672 | } 673 | 674 | .hljs-addition { 675 | background: #dfd; 676 | } 677 | 678 | .hljs-emphasis { 679 | font-style: italic; 680 | } 681 | 682 | .hljs-strong { 683 | font-weight: bold; 684 | } 685 | 686 | button { 687 | -moz-box-shadow:inset 0px 1px 0px 0px #ffffff; 688 | -webkit-box-shadow:inset 0px 1px 0px 0px #ffffff; 689 | box-shadow:inset 0px 1px 0px 0px #ffffff; 690 | background:-webkit-gradient(linear, left top, left bottom, color-stop(0.05, #ffffff), color-stop(1, #f6f6f6)); 691 | background:-moz-linear-gradient(top, #ffffff 5%, #f6f6f6 100%); 692 | background:-webkit-linear-gradient(top, #ffffff 5%, #f6f6f6 100%); 693 | background:-o-linear-gradient(top, #ffffff 5%, #f6f6f6 100%); 694 | background:-ms-linear-gradient(top, #ffffff 5%, #f6f6f6 100%); 695 | background:linear-gradient(to bottom, #ffffff 5%, #f6f6f6 100%); 696 | filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#f6f6f6',GradientType=0); 697 | background-color:#ffffff; 698 | border:1px solid #dcdcdc; 699 | display:inline-block; 700 | cursor:pointer; 701 | color:#666666; 702 | font-family:Arial; 703 | font-size:12px; 704 | font-weight:bold; 705 | padding:6px 11px; 706 | text-decoration:none; 707 | } 708 | button:hover { 709 | background:-webkit-gradient(linear, left top, left bottom, color-stop(0.05, #f6f6f6), color-stop(1, #ffffff)); 710 | background:-moz-linear-gradient(top, #f6f6f6 5%, #ffffff 100%); 711 | background:-webkit-linear-gradient(top, #f6f6f6 5%, #ffffff 100%); 712 | background:-o-linear-gradient(top, #f6f6f6 5%, #ffffff 100%); 713 | background:-ms-linear-gradient(top, #f6f6f6 5%, #ffffff 100%); 714 | background:linear-gradient(to bottom, #f6f6f6 5%, #ffffff 100%); 715 | filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f6f6f6', endColorstr='#ffffff',GradientType=0); 716 | background-color:#f6f6f6; 717 | } 718 | button:active { 719 | position:relative; 720 | top:1px; 721 | } 722 | 723 | button { 724 | outline: none; 725 | } 726 | --------------------------------------------------------------------------------