(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 = false); } function clear(e) { clearForm(); update(); if (e) e.preventDefault(); } function toggleSingles(e) { showSingles = !showSingles; for (let li of document.querySelectorAll('#filters 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(/^#/, ''); if (frag == 'all' || !frag) { clearForm(); } else { let set = new Set(frag.split(';')); if (new Array(...set).every(x => /^(require|exclude)_/.test(x))) { allBoxes.forEach(b => b.checked = set.has(b.id)); let details = document.getElementById('filters-details'); details.open = !set.has('hide_filters'); } } updateItems(); } 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))); document.getElementById('clear').addEventListener('click', clear); document.getElementById('singles').addEventListener('click', toggleSingles); window.addEventListener('popstate', useFragment); useFragment(); } window.addEventListener('DOMContentLoaded', setup); })();