'; }).join("") + ''; Array.prototype.forEach.call(byId("filters").querySelectorAll(".option"), function (button) { button.addEventListener("click", function () { var arr = states[button.dataset.field]; var option = button.dataset.option; var index = arr.indexOf(option); if (index === -1) arr.push(option); else arr.splice(index, 1); pager.page = 1; render(); }); }); } function filtered() { var queryInput = byId("q"); var sortInput = byId("sort"); var q = text(queryInput && queryInput.value).toLowerCase(); var result = items.filter(function (item) { for (var fieldName in states) { if (states[fieldName].length && !states[fieldName].some(function (option) { return optionMatches(item, fieldName, option); })) return false; } if (q) { var haystack = [item.name, item.englishName, firstId(item), item.trait, item.talentDescription].join(" ").toLowerCase(); if (haystack.indexOf(q) === -1) return false; } return true; }); result = result.slice().sort(function (a, b) { var sort = sortInput ? sortInput.value : "id_asc"; if (sort === "id_asc") return firstId(a).localeCompare(firstId(b)); if (sort === "id_desc") return firstId(b).localeCompare(firstId(a)); if (sort === "name_asc") return a.name.localeCompare(b.name, "zh"); if (sort === "name_desc") return b.name.localeCompare(a.name, "zh"); return 0; }); return result; } function renderGrid(rows) { byId("grid").innerHTML = rows.map(function (item) { return '' + '' + esc(item.name) + '' + '' + esc(item.name) + ''; }).join(""); } function renderPager(total) { var maxPage = Math.max(1, Math.ceil(total / pager.pageSize)); if (pager.page > maxPage) pager.page = maxPage; var pages = []; function button(page, label, disabled) { pages.push(''); } button(Math.max(1, pager.page - 1), "‹", pager.page <= 1); var candidates = [1, maxPage, pager.page - 2, pager.page - 1, pager.page, pager.page + 1, pager.page + 2] .filter(function (page, index, arr) { return page >= 1 && page <= maxPage && arr.indexOf(page) === index; }) .sort(function (a, b) { return a - b; }); candidates.forEach(function (page, index) { if (index && page - candidates[index - 1] > 1) pages.push("..."); button(page); }); button(Math.min(maxPage, pager.page + 1), "›", pager.page >= maxPage); pages.push(''); byId("pager").innerHTML = pages.join(""); Array.prototype.forEach.call(byId("pager").querySelectorAll("button[data-page]"), function (btn) { btn.addEventListener("click", function () { pager.page = Number(btn.dataset.page); render(); }); }); byId("pageSize").addEventListener("change", function (event) { pager.pageSize = Number(event.target.value); pager.page = 1; render(); }); } function render() { renderFilters(); var result = filtered(); byId("count").textContent = result.length; var start = (pager.page - 1) * pager.pageSize; renderGrid(result.slice(start, start + pager.pageSize)); renderPager(result.length); } function applyCategories(batch) { batch.forEach(function (page) { var item = items.find(function (candidate) { return candidate.pageTitle === page.title || candidate.name === page.title; }); if (!item) return; var categories = (page.categories || []).map(function (cat) { return cat.title || ""; }); var entity = categories.find(function (title) { return title.indexOf("分类:实体类型为") === 0 && title.lastIndexOf("的装置") === title.length - 3; }); item.entityType = entity ? entity.replace("分类:实体类型为", "").replace("的装置", "") : "默认"; item.flags.rewritableTile = categories.indexOf("分类:可重写地块的装置") !== -1; item.flags.unknownMechanism = categories.indexOf("分类:暂未探明机制的装置") !== -1; }); } function fetchCategories(offset) { var batch = items.slice(offset, offset + 50); if (!batch.length || !window.mw || !mw.util || !window.fetch) return; var titles = batch.map(function (item) { return item.pageTitle; }).join("|"); var url = mw.util.wikiScript("api") + "?action=query&format=json&formatversion=2&prop=categories&cllimit=max&titles=" + encodeURIComponent(titles); fetch(url, { credentials: "same-origin" }) .then(function (response) { return response.json(); }) .then(function (data) { applyCategories((data.query && data.query.pages) || []); render(); fetchCategories(offset + 50); }); } root.innerHTML = '
筛选
' + items.length + '
'; byId("q").addEventListener("input", function () { pager.page = 1; render(); }); byId("sort").addEventListener("change", function () { pager.page = 1; render(); }); byId("collapse").addEventListener("click", function () { byId("filters").classList.toggle("hidden"); var collapsed = byId("filters").classList.contains("hidden"); byId("collapse").textContent = collapsed ? "⌄" : "⌃"; byId("collapse").setAttribute("aria-label", collapsed ? "展开筛选" : "收起筛选"); }); render(); fetchCategories(0); })();