gallery/script/gallery.js

197 lines
4.3 KiB
JavaScript
Raw Normal View History

2020-08-03 17:11:15 -04:00
(function() {
'use strict';
2020-08-04 13:14:12 -04:00
let reqBoxes;
let excBoxes;
let allBoxes;
let tags;
let itemsByYear;
2020-08-03 17:11:15 -04:00
2021-03-12 23:29:57 -05:00
let showSingles = false;
2020-08-03 17:11:15 -04:00
function fillSets() {
let checkedValues = boxes =>
new Set(boxes.filter(b => b.checked).map(b => b.value));
return [checkedValues(reqBoxes), checkedValues(excBoxes)];
}
2020-08-03 20:20:57 -04:00
function updateItems() {
2020-08-03 17:11:15 -04:00
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);
2020-08-03 17:11:15 -04:00
item.hidden = hidden;
hide &&= hidden;
}
document.getElementById(`marker-${year}`).hidden = hide;
2020-08-03 17:11:15 -04:00
}
}
2020-08-03 20:20:57 -04:00
function update() {
updateItems();
history.pushState(null, "", makeFragment());
}
2020-08-03 17:11:15 -04:00
function converseId(id) {
if (id.match(/^require/)) {
return id.replace('require', 'exclude');
} else {
return id.replace('exclude', 'require');
}
}
2021-03-12 23:30:07 -05:00
function toggle(checkbox) {
2020-08-03 17:11:15 -04:00
if (checkbox.checked)
document.getElementById(converseId(checkbox.id)).checked = false;
update();
}
function clearForm() {
allBoxes.forEach(b => b.checked = b.defaultChecked);
2020-08-03 17:11:15 -04:00
}
function clear(e) {
clearForm();
update();
if (e) e.preventDefault();
}
function toggleSingles(e) {
showSingles = !showSingles;
2022-12-29 21:19:33 -05:00
for (let li of document.querySelectorAll('.filterlist li')) {
let count = +li.querySelector('label').dataset.count;
if (count <= 1) {
li.hidden = !showSingles;
}
}
2020-08-03 17:11:15 -04:00
if (e) e.preventDefault();
}
2020-08-03 20:20:57 -04:00
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(';');
}
}
2020-08-16 05:29:56 -04:00
function useFragment() {
2020-09-22 13:12:18 -04:00
let frag = decodeURIComponent(location.hash).replace(/^#/, '');
2022-01-05 10:10:19 -05:00
let details = document.getElementById('filters-details');
2020-08-03 20:20:57 -04:00
2022-01-05 10:10:19 -05:00
if (!frag) {
2020-08-03 20:20:57 -04:00
clearForm();
2022-01-05 10:10:19 -05:00
} else if (frag == 'all') {
allBoxes.forEach(b => b.checked = false);
details.open = false;
} else {
2020-08-03 20:20:57 -04:00
let set = new Set(frag.split(';'));
2022-01-01 18:04:31 -05:00
let re = /^(require|exclude)_|hide_filters/;
2022-01-05 10:10:19 -05:00
if (Array.from(set).every(x => re.test(x))) {
allBoxes.forEach(b => b.checked = set.has(b.id));
2022-06-08 08:37:02 -04:00
details.open = !frag.match(/hide_filters|example\b/);
}
2020-08-03 20:20:57 -04:00
}
updateItems();
}
2022-11-12 06:13:44 -05:00
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');
}
2023-06-21 13:58:01 -04:00
function sortFiltersAlpha(e) {
2022-11-12 06:13:44 -05:00
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)));
2023-06-21 13:58:01 -04:00
e.preventDefault();
2022-11-12 06:13:44 -05:00
}
2023-06-21 13:58:01 -04:00
function sortFiltersUses(e) {
2022-11-12 06:13:44 -05:00
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));
2023-06-21 13:58:01 -04:00
e.preventDefault();
2022-11-12 06:13:44 -05:00
}
2020-08-03 17:11:15 -04:00
function setup() {
2020-08-16 05:31:07 -04:00
function inputs(id) {
let iter = document.getElementById(id).getElementsByTagName('input');
return Array.from(iter);
}
let items = Array.from(document.getElementsByClassName('post'));
2023-06-21 13:58:01 -04:00
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);
}
2020-08-16 05:31:07 -04:00
reqBoxes = inputs('require');
excBoxes = inputs('exclude');
2020-08-04 13:14:12 -04:00
allBoxes = [...reqBoxes, ...excBoxes];
tags = new Map(items.map(item => [item, item.dataset.tags.split(';')]));
2020-08-03 17:11:15 -04:00
allBoxes.forEach(b => b.addEventListener('change', () => toggle(b)));
2022-11-12 06:13:44 -05:00
function addClick(id, f) {
document.getElementById(id).addEventListener('click', f);
}
addClick('clear', clear);
addClick('sortalpha', sortFiltersAlpha);
addClick('sortuses', sortFiltersUses);
addClick('singles', toggleSingles);
2020-08-03 17:11:15 -04:00
2020-08-16 05:29:56 -04:00
window.addEventListener('popstate', useFragment);
2020-08-04 13:14:12 -04:00
2020-08-16 05:29:56 -04:00
useFragment();
2020-08-03 17:11:15 -04:00
}
2020-08-04 13:14:12 -04:00
window.addEventListener('DOMContentLoaded', setup);
2020-08-03 17:11:15 -04:00
})();