From 157186aac40a40f44a766dccbe1171aa0a2e3d03 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Mon, 24 Jul 2023 20:26:52 +0200 Subject: [PATCH 1/1] Reduce reliance on global_filters, to prepare for multiple filtersets. --- ultimate.js | 59 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 24 deletions(-) diff --git a/ultimate.js b/ultimate.js index f70426d..907023a 100644 --- a/ultimate.js +++ b/ultimate.js @@ -1097,16 +1097,16 @@ function open_filter_menu() { menu.style.left = rect.left + 'px'; menu.style.top = (rect.bottom + 10) + 'px'; - add_menu_item(menu, 0, 'match', 'Match (any)'); - add_menu_item(menu, 1, 'player_any', 'Player on field (any)'); - add_menu_item(menu, 2, 'player_all', 'Player on field (all)'); - add_menu_item(menu, 3, 'formation_offense', 'Offense played (any)'); - add_menu_item(menu, 4, 'formation_defense', 'Defense played (any)'); - add_menu_item(menu, 5, 'starting_on', 'Starting on'); - add_menu_item(menu, 6, 'gender_ratio', 'Gender ratio'); + add_menu_item(global_filters, menu, 0, 'match', 'Match (any)'); + add_menu_item(global_filters, menu, 1, 'player_any', 'Player on field (any)'); + add_menu_item(global_filters, menu, 2, 'player_all', 'Player on field (all)'); + add_menu_item(global_filters, menu, 3, 'formation_offense', 'Offense played (any)'); + add_menu_item(global_filters, menu, 4, 'formation_defense', 'Defense played (any)'); + add_menu_item(global_filters, menu, 5, 'starting_on', 'Starting on'); + add_menu_item(global_filters, menu, 6, 'gender_ratio', 'Gender ratio'); } -function add_menu_item(menu, menu_idx, filter_type, title) { +function add_menu_item(filterset, menu, menu_idx, filter_type, title) { let item = document.createElement('div'); item.classList.add('option'); item.appendChild(document.createTextNode(title)); @@ -1118,7 +1118,7 @@ function add_menu_item(menu, menu_idx, filter_type, title) { menu.appendChild(item); - item.addEventListener('click', (e) => { show_submenu(menu_idx, null, filter_type); }); + item.addEventListener('click', (e) => { show_submenu(filterset, menu_idx, null, filter_type); }); } function find_all_ratios(json) @@ -1157,10 +1157,10 @@ function find_all_ratios(json) return ratios; } -function show_submenu(menu_idx, pill, filter_type) { +function show_submenu(filterset, menu_idx, pill, filter_type) { let submenu = document.getElementById('filter-submenu'); let subitems = []; - const filter = find_filter(filter_type); + const filter = find_filter(filterset, filter_type); let choices = []; if (filter_type === 'match') { @@ -1233,7 +1233,7 @@ function show_submenu(menu_idx, pill, filter_type) { if (filter !== null && filter.elements.has(choice.id)) { check.setAttribute('checked', 'checked'); } - check.addEventListener('change', (e) => { checkbox_changed(e, filter_type, choice.id); }); + check.addEventListener('change', (e) => { checkbox_changed(filterset, e, filter_type, choice.id); }); subitem.appendChild(check); subitem.appendChild(document.createTextNode(choice.title)); @@ -1257,8 +1257,8 @@ function show_submenu(menu_idx, pill, filter_type) { } // Find the right filter, if it exists. -function find_filter(filter_type) { - for (let f of global_filters) { +function find_filter(filterset, filter_type) { + for (let f of filterset) { if (f.type === filter_type) { return f; } @@ -1266,8 +1266,19 @@ function find_filter(filter_type) { return null; } -function checkbox_changed(e, filter_type, id) { - let filter = find_filter(filter_type); +// Equivalent to Array.prototype.filter, but in-place. +function inplace_filter(arr, cond) { + let j = 0; + for (let i = 0; i < arr.length; ++i) { + if (cond(arr[i])) { + arr[j++] = arr[i]; + } + } + arr.length = j; +} + +function checkbox_changed(filterset, e, filter_type, id) { + let filter = find_filter(filterset, filter_type); if (e.target.checked) { // See if we must add a new filter to the list. if (filter === null) { @@ -1275,12 +1286,12 @@ function checkbox_changed(e, filter_type, id) { 'type': filter_type, 'elements': new Set([ id ]), }; - filter.pill = make_filter_pill(filter); - global_filters.push(filter); + filter.pill = make_filter_pill(filterset, filter); + filterset.push(filter); document.getElementById('filters').appendChild(filter.pill); } else { filter.elements.add(id); - let new_pill = make_filter_pill(filter); + let new_pill = make_filter_pill(filterset, filter); document.getElementById('filters').replaceChild(new_pill, filter.pill); filter.pill = new_pill; } @@ -1288,9 +1299,9 @@ function checkbox_changed(e, filter_type, id) { filter.elements.delete(id); if (filter.elements.size === 0) { document.getElementById('filters').removeChild(filter.pill); - global_filters = global_filters.filter(f => f !== filter); + inplace_filter(filterset, f => f !== filter); } else { - let new_pill = make_filter_pill(filter); + let new_pill = make_filter_pill(filterset, filter); document.getElementById('filters').replaceChild(new_pill, filter.pill); filter.pill = new_pill; } @@ -1299,7 +1310,7 @@ function checkbox_changed(e, filter_type, id) { process_matches(global_json, global_filters); } -function make_filter_pill(filter) { +function make_filter_pill(filterset, filter) { let pill = document.createElement('div'); pill.classList.add('filter-pill'); let text; @@ -1415,7 +1426,7 @@ function make_filter_pill(filter) { let text_node = document.createElement('span'); text_node.innerText = text; - text_node.addEventListener('click', (e) => show_submenu(null, pill, filter.type)); + text_node.addEventListener('click', (e) => show_submenu(filterset, null, pill, filter.type)); pill.appendChild(text_node); pill.appendChild(document.createTextNode(' ')); @@ -1425,7 +1436,7 @@ function make_filter_pill(filter) { delete_node.addEventListener('click', (e) => { // Delete this filter entirely. document.getElementById('filters').removeChild(pill); - global_filters = global_filters.filter(f => f !== filter); + inplace_filter(filterset, f => f !== filter); process_matches(global_json, global_filters); let add_menu = document.getElementById('filter-add-menu'); -- 2.39.2