UNPKG

3.46 kBJavaScriptView Raw
1/*global micromustache,examples*/
2
3/* eslint-disable @typescript-eslint/restrict-plus-operands */
4/* eslint-disable @typescript-eslint/no-unsafe-call */
5/* eslint-disable @typescript-eslint/no-unsafe-member-access */
6/* eslint-disable @typescript-eslint/no-unsafe-assignment */
7/* eslint-disable @typescript-eslint/no-unsafe-return */
8
9const id = (id) => document.getElementById(id)
10const createEl = (tagName) => document.createElement(tagName)
11const text = (el, contents) => (el.innerText = contents)
12const 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}
22const setVal = (el, value) => (el.value = value)
23const on = (el, eventName, handler) => el.addEventListener(eventName, handler)
24const onInput = (el, handler) => on(el, 'input', handler)
25const fire = (el, eventName) => el.dispatchEvent(new Event(eventName))
26const ready = (fn) =>
27 ['complete', 'interactive'].includes(document.readyState)
28 ? fn()
29 : on(document, 'DOMContentLoaded', fn)
30
31const exampleSelector = id('example-selector')
32const template = id('template')
33const optionsToggle = id('options-toggle')
34const options = id('options')
35const templateError = id('template-error')
36const scope = id('scope')
37const scopeError = id('scope-error')
38const result = id('result')
39const resultError = id('result-error')
40
41// Runs a function showing its results or errors in appropriate DOM elements
42function 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
57function render() {
58 console.log('Render', getVal(id('validateVarNames')))
59 // Handle the template errors
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 // Handle the scope errors
71 const scopeObj = runFn(scope, scopeError, () => JSON.parse(getVal(scope)))
72
73 if (!renderer || !scopeObj) {
74 return text(result, '')
75 }
76
77 // If all is well try to generate the results handling the errors
78 text(
79 result,
80 runFn(result, resultError, () => renderer.render(scopeObj))
81 )
82}
83
84ready(() => {
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})