1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 | const id = (id) => document.getElementById(id)
|
10 | const createEl = (tagName) => document.createElement(tagName)
|
11 | const text = (el, contents) => (el.innerText = contents)
|
12 | const getVal = (el) => {
|
13 | switch (el.type) {
|
14 | case 'checkbox':
|
15 | return el.checked
|
16 | case 'number':
|
17 | return el.valueAsNumber
|
18 | default:
|
19 | return el.value
|
20 | }
|
21 | }
|
22 | const setVal = (el, value) => (el.value = value)
|
23 | const on = (el, eventName, handler) => el.addEventListener(eventName, handler)
|
24 | const onInput = (el, handler) => on(el, 'input', handler)
|
25 | const fire = (el, eventName) => el.dispatchEvent(new Event(eventName))
|
26 | const ready = (fn) =>
|
27 | ['complete', 'interactive'].includes(document.readyState)
|
28 | ? fn()
|
29 | : on(document, 'DOMContentLoaded', fn)
|
30 |
|
31 | const exampleSelector = id('example-selector')
|
32 | const template = id('template')
|
33 | const optionsToggle = id('options-toggle')
|
34 | const options = id('options')
|
35 | const templateError = id('template-error')
|
36 | const scope = id('scope')
|
37 | const scopeError = id('scope-error')
|
38 | const result = id('result')
|
39 | const resultError = id('result-error')
|
40 |
|
41 |
|
42 | function runFn(successEl, errorEl, fn) {
|
43 | if (typeof fn !== 'function') {
|
44 | throw new TypeError(`Expected a function. Got ${fn}`)
|
45 | }
|
46 | try {
|
47 | const result = fn()
|
48 | successEl.classList.remove('error')
|
49 | text(errorEl, '')
|
50 | return result
|
51 | } catch (err) {
|
52 | successEl.classList.add('error')
|
53 | text(errorEl, '⛔ ' + err)
|
54 | }
|
55 | }
|
56 |
|
57 | function render() {
|
58 | console.log('Render', getVal(id('validateVarNames')))
|
59 |
|
60 | const renderer = runFn(template, templateError, () =>
|
61 | micromustache.compile(getVal(template), {
|
62 | depth: getVal(id('depth')),
|
63 | explicit: getVal(id('explicit')),
|
64 | maxVarNameLength: getVal(id('maxVarNameLength')),
|
65 | propsExist: getVal(id('propsExist')),
|
66 | tags: [getVal(id('tag0')), getVal(id('tag1'))],
|
67 | validateVarNames: getVal(id('validateVarNames')),
|
68 | })
|
69 | )
|
70 |
|
71 | const scopeObj = runFn(scope, scopeError, () => JSON.parse(getVal(scope)))
|
72 |
|
73 | if (!renderer || !scopeObj) {
|
74 | return text(result, '')
|
75 | }
|
76 |
|
77 |
|
78 | text(
|
79 | result,
|
80 | runFn(result, resultError, () => renderer.render(scopeObj))
|
81 | )
|
82 | }
|
83 |
|
84 | ready(() => {
|
85 | examples.forEach((example, i) => {
|
86 | const option = createEl('option')
|
87 | text(option, example.name)
|
88 | setVal(option, i)
|
89 | exampleSelector.appendChild(option)
|
90 | })
|
91 |
|
92 | onInput(optionsToggle, () => (options.hidden = !optionsToggle.checked))
|
93 | onInput(scope, render)
|
94 | onInput(template, render)
|
95 | onInput(id('depth'), render)
|
96 | onInput(id('explicit'), render)
|
97 | onInput(id('maxVarNameLength'), render)
|
98 | onInput(id('propsExist'), render)
|
99 | onInput(id('tag0'), render)
|
100 | onInput(id('tag1'), render)
|
101 | onInput(id('validateVarNames'), render)
|
102 |
|
103 | onInput(exampleSelector, () => {
|
104 | const example = examples[getVal(exampleSelector)]
|
105 | setVal(template, example.template)
|
106 | setVal(scope, JSON.stringify(example.scope, null, 2))
|
107 | render()
|
108 | })
|
109 | fire(exampleSelector, 'input')
|
110 | })
|