|
1 |
| -import { bind, wire } from "hyperhtml"; |
| 1 | +import { bind, wire } from '../node_modules/hyperhtml/esm/index.js'; |
2 | 2 |
|
3 |
| -import { startMeasure, stopMeasure } from "./utils"; |
4 |
| -import { Store } from "./store"; |
| 3 | +let did = 1; |
| 4 | +const buildData = (count) => { |
| 5 | + const adjectives = ["pretty", "large", "big", "small", "tall", "short", "long", "handsome", "plain", "quaint", "clean", "elegant", "easy", "angry", "crazy", "helpful", "mushy", "odd", "unsightly", "adorable", "important", "inexpensive", "cheap", "expensive", "fancy"]; |
| 6 | + const colours = ["red", "yellow", "blue", "green", "pink", "brown", "purple", "brown", "white", "black", "orange"]; |
| 7 | + const nouns = ["table", "chair", "house", "bbq", "desk", "car", "pony", "cookie", "sandwich", "burger", "pizza", "mouse", "keyboard"]; |
| 8 | + const data = []; |
| 9 | + for (let i = 0; i < count; i++) { |
| 10 | + data.push({ |
| 11 | + id: did++, |
| 12 | + label: adjectives[_random(adjectives.length)] + " " + colours[_random(colours.length)] + " " + nouns[_random(nouns.length)] |
| 13 | + }); |
| 14 | + } |
| 15 | + return data; |
| 16 | +}; |
5 | 17 |
|
6 |
| -const rows = new WeakMap; |
7 |
| -const store = new Store(); |
8 |
| -const render = bind(document.querySelector("#main")); |
9 |
| -app(render); |
| 18 | +const _random = max => Math.round(Math.random() * 1000) % max; |
10 | 19 |
|
11 |
| -// |
| 20 | +const scope = { |
| 21 | + add() { |
| 22 | + scope.data = scope.data.concat(buildData(1000)); |
| 23 | + update(scope); |
| 24 | + }, |
| 25 | + run() { |
| 26 | + scope.data = buildData(1000); |
| 27 | + update(scope); |
| 28 | + }, |
| 29 | + runLots() { |
| 30 | + scope.data = buildData(10000); |
| 31 | + update(scope); |
| 32 | + }, |
| 33 | + clear() { |
| 34 | + scope.data = []; |
| 35 | + update(scope); |
| 36 | + }, |
| 37 | + update() { |
| 38 | + const {data} = scope; |
| 39 | + for (let i = 0, {length} = data; i < length; i += 10) |
| 40 | + data[i].label += ' !!!'; |
| 41 | + update(scope); |
| 42 | + }, |
| 43 | + swapRows() { |
| 44 | + const {data} = scope; |
| 45 | + if (data.length > 998) { |
| 46 | + const tmp = data[1]; |
| 47 | + data[1] = data[998]; |
| 48 | + data[998] = tmp; |
| 49 | + } |
| 50 | + update(scope); |
| 51 | + }, |
| 52 | + interact(event) { |
| 53 | + event.preventDefault(); |
| 54 | + const a = event.target.closest('a'); |
| 55 | + const id = parseInt(a.closest('tr').id, 10); |
| 56 | + scope[a.dataset.action](id); |
| 57 | + }, |
| 58 | + delete(id) { |
| 59 | + const {data} = scope; |
| 60 | + const idx = data.findIndex(d => d.id === id); |
| 61 | + data.splice(idx, 1); |
| 62 | + update(scope); |
| 63 | + }, |
| 64 | + select(id) { |
| 65 | + scope.selected = id; |
| 66 | + update(scope); |
| 67 | + }, |
| 68 | + selected: -1, |
| 69 | + data: [], |
| 70 | +}; |
12 | 71 |
|
13 |
| -function app(render) { |
| 72 | +const render = bind(document.getElementById('main')); |
| 73 | +update(scope); |
| 74 | + |
| 75 | +function update({data, selected, run, runLots, add, update, clear, swapRows, interact}) { |
14 | 76 | render`
|
15 |
| - <div class="container"> |
16 |
| - <div class="jumbotron"> |
17 |
| - <div class="row"> |
18 |
| - <div class="col-md-6"> |
19 |
| - <h1>hyper(HTML) v2.4.0</h1> |
20 |
| - </div> |
| 77 | + <div class="container"> |
| 78 | + <div class="jumbotron"> |
| 79 | + <div class="row"> |
| 80 | + <div class="col-md-6"> |
| 81 | + <h1>lighterhtml</h1> |
| 82 | + </div> |
21 | 83 | <div class="col-md-6">
|
22 | 84 | <div class="row">
|
23 | 85 | <div class="col-sm-6 smallpad">
|
24 |
| - <button type="button" class="btn btn-primary btn-block" id="run" onclick=${run}>Create 1,000 rows</button> |
| 86 | + <button type="button" class="btn btn-primary btn-block" |
| 87 | + id="run" onclick=${run}>Create 1,000 rows</button> |
25 | 88 | </div>
|
26 | 89 | <div class="col-sm-6 smallpad">
|
27 |
| - <button type="button" class="btn btn-primary btn-block" id="runlots" onclick=${runLots}>Create 10,000 rows</button> |
| 90 | + <button type="button" class="btn btn-primary btn-block" |
| 91 | + id="runlots" onclick=${runLots}>Create 10,000 rows</button> |
28 | 92 | </div>
|
29 | 93 | <div class="col-sm-6 smallpad">
|
30 |
| - <button type="button" class="btn btn-primary btn-block" id="add" onclick=${add}>Append 1,000 rows</button> |
| 94 | + <button type="button" class="btn btn-primary btn-block" |
| 95 | + id="add" onclick=${add}>Append 1,000 rows</button> |
31 | 96 | </div>
|
32 | 97 | <div class="col-sm-6 smallpad">
|
33 |
| - <button type="button" class="btn btn-primary btn-block" id="update" onclick=${update}>Update every 10th row</button> |
| 98 | + <button type="button" class="btn btn-primary btn-block" |
| 99 | + id="update" onclick=${update}>Update every 10th row</button> |
34 | 100 | </div>
|
35 | 101 | <div class="col-sm-6 smallpad">
|
36 |
| - <button type="button" class="btn btn-primary btn-block" id="clear" onclick=${clear}>Clear</button> |
| 102 | + <button type="button" class="btn btn-primary btn-block" |
| 103 | + id="clear" onclick=${clear}>Clear</button> |
37 | 104 | </div>
|
38 | 105 | <div class="col-sm-6 smallpad">
|
39 |
| - <button type="button" class="btn btn-primary btn-block" id="swaprows" onclick=${swapRows}>Swap Rows</button> |
| 106 | + <button type="button" class="btn btn-primary btn-block" |
| 107 | + id="swaprows" onclick=${swapRows}>Swap Rows</button> |
40 | 108 | </div>
|
41 | 109 | </div>
|
42 | 110 | </div>
|
43 | 111 | </div>
|
44 |
| - </div> |
45 |
| - <table class="table table-hover table-striped test-data"> |
46 |
| - <tbody> |
47 |
| - ${store.data.map(row)} |
48 |
| - </tbody> |
49 |
| - </table> |
50 |
| - <span class="preloadicon glyphicon glyphicon-remove" aria-hidden="true"></span> |
51 |
| - </div>`; |
52 |
| - |
53 |
| - stopMeasure(); |
54 |
| -} |
55 |
| - |
56 |
| -function run() { |
57 |
| - startMeasure("run"); |
58 |
| - store.run(); |
59 |
| - app(render); |
60 |
| -} |
61 |
| - |
62 |
| -function runLots() { |
63 |
| - startMeasure("runLots"); |
64 |
| - store.runLots(); |
65 |
| - app(render); |
66 |
| -} |
67 |
| - |
68 |
| -function add() { |
69 |
| - startMeasure("add"); |
70 |
| - store.add(); |
71 |
| - app(render); |
72 |
| -} |
73 |
| - |
74 |
| -function update() { |
75 |
| - startMeasure("update"); |
76 |
| - store.update(); |
77 |
| - app(render); |
78 |
| -} |
79 |
| - |
80 |
| -function clear() { |
81 |
| - startMeasure("clear"); |
82 |
| - store.clear(); |
83 |
| - app(render); |
84 |
| -} |
85 |
| - |
86 |
| -function swapRows() { |
87 |
| - startMeasure("swapRows"); |
88 |
| - store.swapRows(); |
89 |
| - app(render); |
90 |
| -} |
91 |
| - |
92 |
| -function remove(id) { |
93 |
| - startMeasure("delete"); |
94 |
| - store.delete(id); |
95 |
| - app(render); |
96 |
| -} |
97 |
| - |
98 |
| -function select(id) { |
99 |
| - startMeasure("select"); |
100 |
| - store.select(id); |
101 |
| - app(render); |
102 |
| -} |
103 |
| - |
104 |
| -function row(state) { |
105 |
| - const view = rows.get(state) || createRow(state); |
106 |
| - return view.render` |
107 |
| - <tr class=${view.class(store.selected)}> |
108 |
| - <td class="col-md-1">${state.id}</td> |
109 |
| - <td class="col-md-4"> |
110 |
| - <a onclick=${view.onselect}>${state.label}</a> |
111 |
| - </td> |
112 |
| - <td class="col-md-1"> |
113 |
| - <a onclick=${view.onremove}> |
114 |
| - <span class="glyphicon glyphicon-remove" aria-hidden="true"></span> |
115 |
| - </a> |
116 |
| - </td> |
117 |
| - <td class="col-md-6"></td> |
118 |
| - </tr> |
119 |
| - `; |
120 |
| -} |
121 |
| - |
122 |
| -function createRow(state) { |
123 |
| - const row = { |
124 |
| - render: wire(state), |
125 |
| - class(selected) { |
126 |
| - return state.id === selected ? 'danger' : ''; |
127 |
| - }, |
128 |
| - onremove() { |
129 |
| - remove(state.id); |
130 |
| - }, |
131 |
| - onselect() { |
132 |
| - select(state.id); |
133 |
| - } |
134 |
| - }; |
135 |
| - rows.set(state, row); |
136 |
| - return row; |
| 112 | + </div> |
| 113 | + <table onclick=${interact} class="table table-hover table-striped test-data"> |
| 114 | + <tbody>${ |
| 115 | + data.map(item => { |
| 116 | + const {id, label} = item; |
| 117 | + return wire(item)` |
| 118 | + <tr id=${id} class=${id === selected ? 'danger' : ''}> |
| 119 | + <td class="col-md-1">${id}</td> |
| 120 | + <td class="col-md-4"> |
| 121 | + <a data-action='select'>${label}</a> |
| 122 | + </td> |
| 123 | + <td class="col-md-1"> |
| 124 | + <a data-action='delete'> |
| 125 | + <span class="glyphicon glyphicon-remove" aria-hidden="true"></span> |
| 126 | + </a> |
| 127 | + </td> |
| 128 | + <td class="col-md-6"></td> |
| 129 | + </tr>`; |
| 130 | + }) |
| 131 | + }</tbody> |
| 132 | + </table> |
| 133 | + <span class="preloadicon glyphicon glyphicon-remove" aria-hidden="true"></span> |
| 134 | + </div>`; |
137 | 135 | }
|
0 commit comments