(function() { 'use strict'; let reqBoxes; let excBoxes; let allBoxes; let tags; let itemsByYear; let showSingles = false; function fillSets() { let checkedValues = boxes => new Set(boxes.filter(b => b.checked).map(b => b.value)); return [checkedValues(reqBoxes), checkedValues(excBoxes)]; } function updateItems() { let [reqTags, excTags] = fillSets(); let anyReq = reqTags.size > 0; for (let [year, items] of itemsByYear) { let hide = true; for (let item of items) { let req = tags.get(item).some(x => reqTags.has(x)); let exc = tags.get(item).some(x => excTags.has(x)); let hidden = exc || (anyReq && !req); item.hidden = hidden; hide &&= hidden; } document.getElementById(`marker-${year}`).hidden = hide; } } function update() { updateItems(); history.pushState(null, "", makeFragment()); } function converseId(id) { if (id.match(/^require/)) { return id.replace('require', 'exclude'); } else { return id.replace('exclude', 'require'); } } function toggle(checkbox) { if (checkbox.checked) document.getElementById(converseId(checkbox.id)).checked = false; update(); } function clearForm() { allBoxes.forEach(b => b.checked = b.defaultChecked); } function clear(e) { clearForm(); update(); if (e) e.preventDefault(); } function toggleSingles(e) { showSingles = !showSingles; for (let li of document.querySelectorAll('.filterlist li')) { let count = +li.querySelector('label').dataset.count; if (count <= 1) { li.hidden = !showSingles; } } if (e) e.preventDefault(); } function makeFragment() { let ids = allBoxes.filter(b => b.checked).map(b => b.id); if (ids.length == 0) { return '#all'; } else if (allBoxes.every(b => b.checked == b.defaultChecked)) { return '#'; } else { return '#' + ids.join(';'); } } function useFragment() { let frag = decodeURIComponent(location.hash).replace(/^#/, ''); let details = document.getElementById('filters-details'); if (!frag) { clearForm(); } else if (frag == 'all') { allBoxes.forEach(b => b.checked = false); details.open = false; } else { let set = new Set(frag.split(';')); let re = /^(require|exclude)_|hide_filters/; if (Array.from(set).every(x => re.test(x))) { allBoxes.forEach(b => b.checked = set.has(b.id)); details.open = !frag.match(/hide_filters|example\b/); } } updateItems(); } function sortFilters(cmp) { function sort1(id) { let elt = document.getElementById(id); let children = [...elt.childNodes]; children.sort(cmp); for (let c of children) { elt.removeChild(c); elt.appendChild(c); } } sort1('require'); sort1('exclude'); } function sortFiltersAlpha() { function getName(x) { if (x.nodeType == Node.ELEMENT_NODE) { return x.getElementsByTagName('input')[0].value; } else { return ''; } } sortFilters((a, b) => getName(a).localeCompare(getName(b))); } function sortFiltersUses() { function getUses(x) { if (x.nodeType == Node.ELEMENT_NODE) { return parseInt(x.getElementsByTagName('label')[0].dataset.count); } else { return 0; } } sortFilters((a, b) => getUses(b) - getUses(a)); } function setup() { function inputs(id) { let iter = document.getElementById(id).getElementsByTagName('input'); return Array.from(iter); } let items = Array.from(document.getElementsByClassName('post')); itemsByYear = new Map; for (let item of items) { let year = item.dataset.year; if (!itemsByYear.has(year)) itemsByYear.set(year, new Set); itemsByYear.get(year).add(item); } reqBoxes = inputs('require'); excBoxes = inputs('exclude'); allBoxes = [...reqBoxes, ...excBoxes]; tags = new Map(items.map(item => [item, item.dataset.tags.split(';')])); allBoxes.forEach(b => b.addEventListener('change', () => toggle(b))); function addClick(id, f) { document.getElementById(id).addEventListener('click', f); } addClick('clear', clear); addClick('sortalpha', sortFiltersAlpha); addClick('sortuses', sortFiltersUses); addClick('singles', toggleSingles); window.addEventListener('popstate', useFragment); useFragment(); } window.addEventListener('DOMContentLoaded', setup); })();