User:胡葡萄/PageCollapser.js
外观
< User:胡葡萄
注意:保存之后,你必须清除浏览器缓存才能看到做出的更改。Google Chrome、Firefox、Microsoft Edge及Safari:按住⇧ Shift键并单击工具栏的“刷新”按钮。参阅Help:绕过浏览器缓存以获取更多帮助。
/**
* 頁面摺疊器 v0.2 by User:逆襲的天邪鬼
*
* 自己拿着開心去吧。記住不要用IE678那種老掉牙的瀏覽器。
*
* 功能:
* 1. 將長長的討論頁或條目等頁面摺疊起來。
* 2. 將「互煮」的討論審查掉。(可能會造成不良影響,慎用)
*
* 待添加功能:
* 1. 使用交互式頁面設定「黑名單」,並通過LocalStorage存起來
* 2. 不要摺疊封禁申訴、頁面底部導航等模板
* 3. 不摺疊已存檔或已結束的話題等(因為已經被摺疊了)
* 4. 針對DYK、VIP等特殊頁面進行特殊處理(例如給出處理結果等)
*
* 已知bug:
* 1. DYK頁面無法摺疊(因為DYK頁面結構特殊,而且該頁面不能直接摺疊否則會Orz)
* 2. 被框住的內容無法摺疊,例如[[User talk:和平奮鬥救地球]](問題出在第244行$content.children().each……)
*/
$(function() {
'use strict';
/**
* 說明:由於沒設計交互式對話框,需要按照下面的內容進行設置。
*
* 設置時,可以在自己的common.js頁面中加入:
* window.talkCollapser = {
* collapse: true,
* blacktitle: [
* 'A',
* '.*B'
* ],
* ...
* }
*
* 可摺疊標題的樣式由 .collapsable 類定義。自己去CSS頁設置就行。
* 該程式支持標題「黑名單」功能,上榜的討論將會被直接隱藏。但程式不支持簡繁轉換,並且因為是RegExp的test,所以表達式不要寫得太簡單以免誤傷。
*/
var defaultConfig = {
collapse: false,
arrow: { // 展開/摺疊箭頭
color: '#777',
open: '▾[已摺疊]',
close: '▴'
},
duration: 'fast', // 動畫效果持續時間
hide: {
article: true, // 是否在普通條目中和論述類頁面中摺疊
talk: true, // 是否在討論頁面(包括討論頁、互助客棧等)中摺疊
vote: true, // 是否在投票頁(包括DYK、存廢討論等)中摺疊
request: true, // 是否在請求頁(包括VIP、RFCU等)中摺疊
user: false // 是否在User命名空間中摺疊
},
noh3: true, // 鑑於有人會在討論頁中開小標題,該選項可以將其從目錄中移除。僅用於討論頁。
censor: { // 對黑名單的審查
showTag: true, // 為true時標出「已隱藏」,為false時直接隱藏,不留痕跡
tagTitle: '[該討論已被隱藏]',
tagDesc: '該討論已被隱藏,原標題為:$1',
},
blacktitle: [ // 黑名單
]
};
var userconfig = window.talkCollapser;
if (typeof userconfig !== 'object') {
userconfig = {};
}
var config = $.extend(true, defaultConfig, userconfig);
var visible = {};
var isNoToc = (document.getElementById('toc') === null);
var titleLevel = 'h2';
var hideH3 = config.noh3;
var needCollapse = false;
config.noh3 = false;
var projects = {
talk: {
'互助客栈': 'h2',
'知识问答': 'h2'
},
vote: {
'新条目推荐/候选': 'h3', // TODO: 單獨處理
'優良條目評選': 'h3',
'特色条目评选': 'h3',
'同行评审': 'h3',
'頁面存廢討論/記錄': 'h2',
'頁面存廢討論/疑似侵權': 'h3',
'檔案存廢討論': 'h2'
},
request: {
'合并请求': 'h3',
'请求保护页面': 'h3',
'当前的破坏': 'h3',
'用戶查核請求': 'h3'
}
};
switch (mw.config.get('wgCanonicalNamespace')) {
case 'Talk':
case 'User_talk':
case 'File_talk':
case 'MediaWiki_talk':
case 'Template_talk':
case 'Help_talk':
case 'Category_talk':
case 'Portal_talk':
case 'Draft_talk':
case 'Module_talk':
case 'Project_talk':
needCollapse = config.hide.talk;
config.noh3 = hideH3;
break;
case '':
case 'Draft':
case 'Help':
needCollapse = config.hide.article;
break;
case 'User':
needCollapse = (!isNoToc) && config.hide.user;
break;
case 'Project':
var title = mw.config.get('wgTitle');
var t;
needCollapse = !isNoToc;
for (t in projects.talk) {
if (title.startsWith(t)) {
needCollapse = config.hide.talk;
titleLevel = projects.talk[t];
config.noh3 = hideH3;
break;
}
}
for (t in projects.vote) {
if (title.startsWith(t)) {
needCollapse = config.hide.vote;
titleLevel = projects.vote[t];
break;
}
}
for (t in projects.request) {
if (title.startsWith(t)) {
needCollapse = config.hide.request;
titleLevel = projects.request[t];
break;
}
}
break;
default:
needCollapse = false;
break;
}
if (needCollapse && mw.config.get('wgAction') === 'view') {
// 折叠讨论串
var $content = $('#mw-content-text');
var firstTopic = true;
var $lastTitle = null, $discuss = null;
// 找到第一个h2
var childrenCount = $content.children().length;
// 處理黑名單
var blacklist = [];
for (var i=0; i<config.blacktitle.length; i++) {
blacklist.push(new RegExp(config.blacktitle[i]));
}
// 摺疊或移除討論
var makeBox = function () {
if ($lastTitle === null) {
return;
}
var titleId = $lastTitle.attr('data-id');
var titleName = $lastTitle.children().first().text();
var badTitle = false;
// 判斷是否為黑名單標題
for (var i=0; i<blacklist.length; i++) {
if (blacklist[i].test(titleName)) {
badTitle = true;
break;
}
}
var $tocTitle = $("a[href='#" + titleId + "']", '#toc');
if (config.noh3) {
$('ul', $tocTitle.parent()).remove();
}
// 處理符合黑名單的討論
if (badTitle) {
if (config.censor.showTag) {
var $censor = $('<table class="plainlinks ombox ombox-notice" style=""><tbody><tr><td class="mbox-image"><a href="/wiki/File:Information_icon4.svg" class="image"><img alt="Information icon4.svg" src="//upload.wikimedia.org/wikipedia/commons/thumb/1/1d/Information_icon4.svg/40px-Information_icon4.svg.png" width="40" height="40" srcset="//upload.wikimedia.org/wikipedia/commons/thumb/1/1d/Information_icon4.svg/60px-Information_icon4.svg.png 1.5x, //upload.wikimedia.org/wikipedia/commons/thumb/1/1d/Information_icon4.svg/80px-Information_icon4.svg.png 2x" data-file-width="620" data-file-height="620"></a></td><td class="mbox-text" style="">{{{text}}}</td></tr></tbody></table>');
$('.mbox-text', $censor).text(config.censor.tagDesc.replace('$1', titleName));
$discuss.prepend($censor);
$lastTitle.children().first().text(config.censor.tagTitle);
$('.toctext', $tocTitle).text(config.censor.tagTitle);
// 有些用戶喜歡開小標題,一塊兒隱藏
$('ul', $tocTitle.parent()).remove();
// 經過審查之後可以按照正常討論進行處理了
badTitle = false;
} else {
$tocTitle.parent().remove();
}
}
// 摺疊討論內容
if (!badTitle) {
if ($discuss === null) {
$discuss = $('<div id="discuss_' + titleId + '"></div>');
}
visible[titleId] = !config.collapse;
var arrow = config.collapse ? config.arrow.open : config.arrow.close;
$lastTitle
.addClass('collapsable')
.css('cursor', 'pointer')
.prepend('<span style="color:' + config.arrow.color + ';" id="status_' + titleId + '">' + arrow + '</span> ')
.after($discuss);
if (config.collapse) {
$discuss.slideUp(config.duration);
}
} else {
// 用戶要求直接隱藏黑名單裏的討論
$lastTitle.remove();
$discuss.remove();
}
$discuss = null;
};
$content.children().each(function (index, element) {
if (element.tagName === titleLevel.toUpperCase()) {
if ($discuss !== null) {
makeBox();
}
firstTopic = false;
var titleElement = element.children[0];
if (titleElement.className.indexOf('plainlinks') >= 0) {
titleElement = titleElement.children[0];
}
var titleId = titleElement.id;
$lastTitle = $(element);
$lastTitle.attr('data-id', titleId);
$discuss = $('<div id="discuss_' + titleId + '"></div>');
} else if ((titleLevel === 'h2' && element.tagName === 'H1') ||
(titleLevel === 'h3' && (element.tagName === 'H1' || element.tagName === 'H2')) ||
(element.tagName === 'DIV' && element.id === 'toc')) {
// 官大一級壓死人
if ($discuss !== null) {
makeBox();
}
$lastTitle = null;
$discuss = null;
} else if ((!firstTopic) && $discuss) {
$discuss.append(element);
}
if (index === childrenCount - 1) {
makeBox();
$(titleLevel, '#mw-content-text').click(function (e) {
var id = $(this).attr('data-id');
// 點擊標題上的連結時不要摺疊(例如Wikiplus)
if ((!id) || e.target.tagName === 'A') {
return true;
}
if (visible[id] !== null) {
if (visible[id]) {
visible[id] = null;
$(document.getElementById('discuss_' + id)).slideUp(config.duration, function() {
visible[id] = false;
document.getElementById('status_' + id).innerHTML = config.arrow.open;
});
} else {
visible[id] = null;
$(document.getElementById('discuss_' + id)).slideDown(config.duration, function() {
visible[id] = true;
document.getElementById('status_' + id).innerHTML = config.arrow.close;
});
}
}
});
}
});
}
});