注意:在您儲存之後您必須清除瀏覽器快取才可看到最新的變動。
?_=1來訪問最新頁面。
/**
* @description 遞歸查找分類內的所有子分類
*
* @todo 列出分類內的頁面數
*/
// <pre>
// eslint-disable-next-line
var _addText = '{{Documentation|content=本小工具用於快速遞歸查詢某分類下的所有子分類。\n\n使用方式:在[[Special:MyPage/common.js|個人js頁]]添加如下代碼\n<pre class="prettyprint lang-javascript" style="margin-top:0">mw.loader.load("/index.php?title=User:BearBin/js/Cat-in-Tree.js&action=raw&ctype=text/javascript");</pre>}}';
"use strict";
$(() => (async () => {
if (mw.config.get("wgNamespaceNumber") === 14) {
await mw.loader.using(["mediawiki.api", "mediawiki.notification", "oojs-ui"]);
const api = new mw.Api();
const PAGENAME = mw.config.get("wgPageName");
let treeList = []; // 用於記錄單次從頂至底查找的內容,檢測分類嵌套。
let level = 0;
let maxLevel = 0;
$("head").append(`<style>
#cit-level-select {
display: inline-block;
width: 8em;
}
#cit-divider {
margin: 1em 0;
}
</style>`);
const CiTSearch = new OO.ui.ButtonWidget({
label: "遞歸列出子分類",
flags: "progressive",
icon: "search",
id: "cit-search",
});
$("#mw-content-text").append(
'<hr id="cit-divider" />',
CiTSearch.$element,
);
$("#cit-search").after('<div id="cit-list"></div>');
const CiTMuilticol = new OO.ui.ButtonWidget({
label: "分列顯示",
flags: "progressive",
id: "cit-multicol",
});
CiTMuilticol.$element.insertAfter(CiTSearch.$element).hide();
// 遞歸查詢並列出頁面列表
async function getSubCat(cmtitle, $node) {
let cmcontinue = "";
const catList = [];
if(level === 1) {
treeList = []; // 每次回到頂部刷新記錄列表
}
while (cmcontinue !== false) {
const subCats = await api.get({
action: "query",
list: "categorymembers",
cmtype: "subcat",
cmlimit: "max",
cmtitle,
cmcontinue,
});
cmcontinue = subCats.continue ? subCats.continue.cmcontinue : false;
for (const item of subCats.query.categorymembers) {
/*
if(treeList.includes(item.title)) {
throw `${cmtitle}處出現嵌套分類。`;
}*/
catList.push(item.title);
treeList.push(item.title);
}
}
if(catList.length > 0) {
const ul = $("<ul></ul>");
$node.append(ul);
for(const cat of catList) {
console.log(level);
level++;
maxLevel = Math.max(maxLevel, level);
const catitem = $(`<li class="cit-level-${level}"><a href="/${cat}">${cat.replace("Category:", "")}</a></li>`);
ul.append(catitem);
await getSubCat(cat, catitem);
level--;
}
}
}
// 搜索
CiTSearch.on("click", async () => {
// 移除上次搜索的內容(如果有)
level = 0;
maxLevel = 0;
$("#cit-level-select").remove();
$("#cit-list").html("");
// 進入加載狀態,顯示分列按鈕
$("#cit-search a").addClass("oo-ui-pendingElement-pending");
CiTMuilticol.$element.show();
try {
await getSubCat(PAGENAME, $("#cit-list"));
} catch(e) {
OO.ui.alert(e, {
title: "遇到錯誤",
size: "small",
});
}
$("#cit-search a").removeClass("oo-ui-pendingElement-pending"); // 查詢完成
mw.notify("查詢完畢");
// 用戶選擇顯示層級。
// 非常笨的實現方法,歡迎提出好建議
const options = [{data: "all", label: "顯示所有"}];
for (let i = 1; i <= maxLevel; i++) {
options.push({data: i, label: `顯示${i}級`});
}
const CitLevelSelect = new OO.ui.DropdownInputWidget({
options,
id: "cit-level-select",
});
CitLevelSelect.$element.insertAfter(CiTMuilticol.$element);
CitLevelSelect.on("change", () => {
const showLevel = CitLevelSelect.getValue();
if(showLevel === "all") {
for (let i = 1; i <= maxLevel; i++) {
$(`.cit-level-${i}`).show();
}
} else {
for (let i = 1; i <= Number(showLevel); i++) {
$(`.cit-level-${i}`).show();
}
$(`.cit-level-${Number(showLevel)+1}`).hide();
}
});
});
// 分列顯示按鈕
let multiList = false;
CiTMuilticol.on("click", () => {
if(multiList){
$("#cit-list").removeClass("mw-category");
$("#cit-multicol .oo-ui-labelElement-label").text("分列顯示");
} else {
$("#cit-list").addClass("mw-category");
$("#cit-multicol .oo-ui-labelElement-label").text("關閉分列顯示");
}
multiList = !multiList;
});
}
})());
// </pre>