@@ -115,87 +115,145 @@ function frameworkDir(keyed) {
115115function createArrowMainSource ( keyed , mode ) {
116116 const title = keyed ? 'ArrowJS (keyed)' : 'ArrowJS (non-keyed)'
117117 const importPath = mode === 'local' ? './arrow.js' : '@arrow-js/core'
118- const rows = `() => {
119- const items = data.items
120- const rows = new Array(items.length)
121- for (let i = 0; i < items.length; i++) {
122- rows[i] = getRowView(items[i])
123- }
124- return rows
125- }`
118+ const rows = `() => (data.version, views)`
126119 return `import { reactive, html } from '${ importPath } ';
127120let data = reactive({
128- items: [],
129- selected: undefined,
121+ version: 0,
130122});
123+ let ids = [];
124+ let labels = [];
125+ let views = [];
131126
132127let rowId = 1;
133- const rowViews = new WeakMap() ;
128+ let selectedIndex = -1 ;
134129const 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"];
135130const colours = ["red", "yellow", "blue", "green", "pink", "brown", "purple", "brown", "white", "black", "orange"];
136131const nouns = ["table", "chair", "house", "bbq", "desk", "car", "pony", "cookie", "sandwich", "burger", "pizza", "mouse", "keyboard"];
137- const add = () => data.items.push(...buildData(1000)),
132+ const labelPool = [];
133+ for (let i = 0; i < adjectives.length; i++) {
134+ const prefix = adjectives[i] + " ";
135+ for (let j = 0; j < colours.length; j++) {
136+ const stem = prefix + colours[j] + " ";
137+ for (let k = 0; k < nouns.length; k++) {
138+ labelPool.push(stem + nouns[k]);
139+ }
140+ }
141+ }
142+ const labelPoolSize = labelPool.length;
143+ const add = () => {
144+ appendData(1000);
145+ data.version++;
146+ },
138147 clear = () => {
139- data.items.length = 0;
140- data.selected = undefined;
148+ selectedIndex = -1;
149+ ids.length = 0;
150+ labels.length = 0;
151+ views.length = 0;
152+ data.version++;
141153 },
142154 partialUpdate = () => {
143- const items = data.items;
144- for (let i = 0; i < items.length; i += 10) {
145- items [i].label += ' !!!' ;
155+ for (let i = 0; i < ids.length; i += 10) {
156+ labels[i] += ' !!!';
157+ views [i] = createRowView(ids[i], labels[i]) ;
146158 }
159+ data.version++;
147160 },
148161 run = () => {
149- data.items = buildData(1000);
150- data.selected = undefined;
162+ selectedIndex = -1;
163+ buildData(1000, ids, labels, views);
164+ data.version++;
151165 },
152166 runLots = () => {
153- data.items = buildData(10000);
154- data.selected = undefined;
167+ selectedIndex = -1;
168+ buildData(10000, ids, labels, views);
169+ data.version++;
155170 },
156171 swapRows = () => {
157- const items = data.items;
158- if (items.length > 998) {
159- const item = items[1];
160- items[1] = items[998];
161- items[998] = item;
172+ if (ids.length > 998) {
173+ const id = ids[1];
174+ ids[1] = ids[998];
175+ ids[998] = id;
176+ const label = labels[1];
177+ labels[1] = labels[998];
178+ labels[998] = label;
179+ const view = views[1];
180+ views[1] = views[998];
181+ views[998] = view;
182+ if (selectedIndex === 1) selectedIndex = 998;
183+ else if (selectedIndex === 998) selectedIndex = 1;
184+ data.version++;
162185 }
163186 };
164187
165- function getRowView(row) {
166- let view = rowViews.get(row);
167- if (view) return view;
168- const id = row.id;
169- view = html\`<tr class="\${() => data.selected === id ? 'danger' : ''}" data-id="\${id}"><td class="col-md-1">\${id}</td><td class="col-md-4"><a data-action="select">\${() => row.label}</a></td><td class="col-md-1"><a data-action="remove"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span></a></td><td class="col-md-6"></td></tr>\`${ keyed ? `.key(id)` : '' } ;
170- rowViews.set(row, view);
171- return view;
188+ function createRowView(id, label, selected) {
189+ return html\`<tr class="\${selected ? 'danger' : false}"><td class="col-md-1">\${id}</td><td class="col-md-4"><a>\${label}</a></td><td class="col-md-1"><a><span class="glyphicon glyphicon-remove" aria-hidden="true"></span></a></td><td class="col-md-6"></td></tr>\`${ keyed ? `.key(id)` : '' } ;
172190}
173191
174192function handleRowClick(event) {
175- const target = event.target instanceof Element
176- ? event.target.closest('[data-action] ')
193+ const cell = event.target instanceof Element
194+ ? event.target.closest('td ')
177195 : null;
178- if (!target) return;
179- const action = target.getAttribute('data-action');
180- const id = Number(target.closest('tr')?.getAttribute('data-id'));
181- if (!id) return;
182- if (action === 'select') {
183- data.selected = id;
196+ if (!cell) return;
197+ const index = cell.cellIndex;
198+ if (index !== 1 && index !== 2) return;
199+ const row = cell.parentElement;
200+ if (!(row instanceof HTMLTableRowElement)) return;
201+ const idx = row.sectionRowIndex;
202+ if (idx < 0 || idx >= ids.length) return;
203+ if (index === 1) {
204+ if (selectedIndex === idx) return;
205+ const previousIndex = selectedIndex;
206+ selectedIndex = idx;
207+ if (previousIndex > -1) {
208+ views[previousIndex] = createRowView(ids[previousIndex], labels[previousIndex], false);
209+ }
210+ views[idx] = createRowView(ids[idx], labels[idx], true);
211+ data.version++;
184212 return;
185213 }
186- if (action === 'remove') {
187- const idx = data.items.findIndex((row) => row.id === id);
188- if (idx > -1) data.items.splice(idx, 1);
214+ if (index === 2) {
215+ if (idx === selectedIndex) {
216+ selectedIndex = -1;
217+ } else if (selectedIndex > idx) selectedIndex--;
218+ ids.splice(idx, 1);
219+ labels.splice(idx, 1);
220+ views.splice(idx, 1);
221+ data.version++;
189222 }
190223}
191224
192- function _random(max) { return Math.round(Math.random() * 1000) % max; };
225+ function buildData(count, ids, labels, views, start = 0) {
226+ const pool = labelPool;
227+ const size = labelPoolSize;
228+ const createView = createRowView;
229+ const end = start + count;
230+ let nextId = rowId;
231+ ids.length = end;
232+ labels.length = end;
233+ views.length = end;
234+ for (var i = start; i < end; i++) {
235+ const id = nextId++;
236+ const label = pool[(Math.random() * size) | 0];
237+ ids[i] = id;
238+ labels[i] = label;
239+ views[i] = createView(id, label, false);
240+ }
241+ rowId = nextId;
242+ }
193243
194- function buildData(count = 1000) {
195- const data = new Array(count);
196- for (var i = 0; i < count; i++)
197- data[i] = { id: rowId++, label: adjectives[_random(adjectives.length)] + " " + colours[_random(colours.length)] + " " + nouns[_random(nouns.length)] };
198- return data;
244+ function appendData(count) {
245+ const pool = labelPool;
246+ const size = labelPoolSize;
247+ const createView = createRowView;
248+ let nextId = rowId;
249+ for (let i = 0; i < count; i++) {
250+ const id = nextId++;
251+ const label = pool[(Math.random() * size) | 0];
252+ ids.push(id);
253+ labels.push(label);
254+ views.push(createView(id, label, false));
255+ }
256+ rowId = nextId;
199257}
200258html\`<div class="container">
201259 <div class="jumbotron">
0 commit comments