├── .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 | Evaluate
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,d09GRgABAAAAAAZwABAAAAAACFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABEU0lHAAAGaAAAAAgAAAAIAAAAAUdTVUIAAAZcAAAACgAAAAoAAQAAT1MvMgAAAyQAAABJAAAAYFYEU3RjbWFwAAADcAAAAEUAAACAAJThvmN2dCAAAATkAAAABAAAAAQAAAAAZnBnbQAAA7gAAACyAAABCUM+8IhnYXNwAAAGTAAAABAAAAAQABoAI2dseWYAAAFsAAABPAAAAZwcEq9taGVhZAAAAsgAAAA0AAAANgh4a91oaGVhAAADCAAAABoAAAAkCA8DRGhtdHgAAAL8AAAADAAAAAwGAACfbG9jYQAAAsAAAAAIAAAACABiATBtYXhwAAACqAAAABgAAAAgAA8ASm5hbWUAAAToAAABQgAAAlXu73sOcG9zdAAABiwAAAAeAAAAME3QpOBwcmVwAAAEbAAAAHYAAAB/aFGpk3jaTY6xa8JAGMW/O62BDi0tJLYQincXEypYIiGJjSgHniQ6umTsUEyLm5BV6NDBP8Tpts6F0v+k/0an2i+itHDw3v2+9+DBKTzsJNnWJNTgHEy4BgG3EMI9DCEDOGEXzDADU5hBKMIgNPZqoD3SilVaXZCER3/I7AtxEJLtzzuZfI+VVkprxTlXShWKb3TBecG11rwoNlmmn1P2WYcJczl32etSpKnziC7lQyWe1smVPy/Lt7Kc+0vWY/gAgIIEqAN9we0pwKXreiMasxvabDQMM4riO+qxM2ogwDGOZTXxwxDiycQIcoYFBLj5K3EIaSctAq2kTYiw+ymhce7vwM9jSqO8JyVd5RH9gyTt2+J/yUmYlIR0s04n6+7Vm1ozezUeLEaUjhaDSuXHwVRgvLJn1tQ7xiuVv/ocTRF42mNgZGBgYGbwZOBiAAFGJBIMAAizAFoAAABiAGIAznjaY2BkYGAA4in8zwXi+W2+MjCzMIDApSwvXzC97Z4Ig8N/BxYGZgcgl52BCSQKAA3jCV8CAABfAAAAAAQAAEB42mNgZGBg4f3vACQZQABIMjKgAmYAKEgBXgAAeNpjYGY6wTiBgZWBg2kmUxoDA4MPhGZMYzBi1AHygVLYQUCaawqDA4PChxhmh/8ODDEsvAwHgMKMIDnGL0x7gJQCAwMAJd4MFwAAAHjaY2BgYGaA4DAGRgYQkAHyGMF8NgYrIM3JIAGVYYDT+AEjAwuDFpBmA9KMDEwMCh9i/v8H8sH0/4dQc1iAmAkALaUKLgAAAHjaTY9LDsIgEIbtgqHUPpDi3gPoBVyRTmTddOmqTXThEXqrob2gQ1FjwpDvfwCBdmdXC5AVKFu3e5MfNFJ29KTQT48Ob9/lqYwOGZxeUelN2U2R6+cArgtCJpauW7UQBqnFkUsjAY/kOU1cP+DAgvxwn1chZDwUbd6CFimGXwzwF6tPbFIcjEl+vvmM/byA48e6tWrKArm4ZJlCbdsrxksL1AwWn/yBSJKpYbq8AXaaTb8AAHja28jAwOC00ZrBeQNDQOWO//sdBBgYGRiYWYAEELEwMTE4uzo5Zzo5b2BxdnFOcALxNjA6b2ByTswC8jYwg0VlNuoCTWAMqNzMzsoK1rEhNqByEyerg5PMJlYuVueETKcd/89uBpnpvIEVomeHLoMsAAe1Id4AAAAAAAB42oWQT07CQBTGv0JBhagk7HQzKxca2sJCE1hDt4QF+9JOS0nbaaYDCQfwCJ7Au3AHj+LO13FMmm6cl7785vven0kBjHCBhfpYuNa5Ph1c0e2Xu3jEvWG7UdPDLZ4N92nOm+EBXuAbHmIMSRMs+4aUEd4Nd3CHD8NdvOLTsA2GL8M9PODbcL+hD7C1xoaHeLJSEao0FEW14ckxC+TU8TxvsY6X0eLPmRhry2WVioLpkrbp84LLQPGI7c6sOiUzpWIWS5GzlSgUzzLBSikOPFTOXqly7rqx0Z1Q5BAIoZBSFihQYQOOBEdkCOgXTOHA07HAGjGWiIjaPZNW13/+lm6S9FT7rLHFJ6fQbkATOG1j2OFMucKJJsxIVfQORl+9Jyda6Sl1dUYhSCm1dyClfoeDve4qMYdLEbfqHf3O/AdDumsjAAB42mNgYoAAZQYjBmyAGYQZmdhL8zLdDEydARfoAqIAAAABAAMABwAKABMAB///AA8AAQAAAAAAAAAAAAAAAAABAAAAAA==) 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 | Evaluate
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 |
--------------------------------------------------------------------------------