注意:在您儲存之後您必須清除瀏覽器快取才可看到最新的變動。
?_=1
來訪問最新頁面。
'use strict';
// 獲取鏈接地址可用的名字空間ID。
let wgFormattedNamespaces = mw.config.get('wgFormattedNamespaces');
let wgNamespaceIds = mw.config.get('wgNamespaceIds');
let validNamespaceIds = [ 'User', 'User_talk', 'Special' ].map(ns => wgNamespaceIds[ns.toLowerCase()]);
// 定義允許出現在簽名中的鏈接域名。
let validServers = [
'http://zh.moegirl.tw',
'http://mzh.moegirl.tw',
'http://commons.moegirl.tw',
'http://common.moegirl.tw',
'http://library.moegirl.tw'
];
// URI對象構造器。
function URI(uri) {
this.success = true;
if (!uri)
{
this.success = false; // 構造失敗。
return;
}
let regExp = /^(([^:]+):\/\/([^\/:]+)(:([^\/]+))?)?([^?#]+)(\?([^#]+))?(#(.+))?$/;
let matchObj = regExp.exec(uri);
if (!matchObj)
{
this.success = false; // 構造失敗。
return;
}
this.rawURI = uri;
this.scheme = matchObj[2];
this.host = matchObj[3];
this.port = matchObj[5];
this.path = matchObj[6] ? decodeURI(matchObj[6]) : undefined;
this.query = matchObj[8] ? decodeURI(matchObj[8]) : undefined;
this.fragment = matchObj[10] ? decodeURI(matchObj[10]) : undefined;
if (this.scheme && this.scheme !== '') this.server = this.scheme + '://' + this.host + (this.port && this.port !== '' ? ':' + this.port : '');
if (this.path && this.path !== '') this.pathSegments = this.path.substring(1).match(/(?<=^|\/)[^\/]*/g); else this.pathSegments = [];
this.queryParameter = {};
if (this.query && this.query !== '')
this.query.split('&').filter(param => param !== '').forEach(pair => {
if (this.success === false) return;
let pos = pair.indexOf('=');
if (pos <= 0)
{
this.success = false;
this.queryParameter = {};
}
else
{
this.queryParameter[pair.substring(0, pos)] = pair.substring(pos + 1);
}
});
if (this.success === false) return;
this.isRelative = this.server == null;
this.isAbsolute = !this.isRelative;
}
function markPrefixToken(element, markProvider) {
let children = $(element).children(':not(pre, code, a, table.navbox, span.discussiontoken)');
if (children.length > 0)
children.each((_, e) => markPrefixToken(e, markProvider));
$(element).contents().filter(function() {
return this.nodeType === Node.TEXT_NODE;
}).replaceWith(markProvider);
}
function markSignatureToken(element) {
$(element).find('a').each((_, a) => {
let href = new URI($(a).attr('href')); // 構造URI對象。
if (href.success === false) { /*alert("不符合的a元素。\n" + $(a)[0].innerHTML);*/ return; }; // 構造失敗,排除不存在鏈接地址的元素。
if (href.server && $.inArray(href.server, validServers) < 0) { /*alert("不符合的鏈接地址域名:" + href.host +"\n" + decodeURI(href.rawURI));*/ return; } // 排除不符合的鏈接地址。
let pathSegments = $(a).hasClass('new') ? new URI('/' + (href.queryParameter.title || '')).pathSegments : href.pathSegments;
if (pathSegments.length === 0) return; // 鏈接地址不能為首頁。
let rootPageNameWithNamespace = pathSegments[0];
let namespaceSeparator = rootPageNameWithNamespace.indexOf(':');
if (namespaceSeparator <= 0) return; // 鏈接地址必須包含用戶頁、用戶討論頁或貢獻頁,即包含名字空間。
let namespace, namespaceId, rootPageName = undefined;
namespace = rootPageNameWithNamespace.substring(0, namespaceSeparator);
rootPageName = rootPageNameWithNamespace.substring(namespaceSeparator + 1);
if (rootPageName.length === 0) return; // 鏈接地址的根目錄名稱為空。
let isNamespaceValid = false;
for (var wgNamespace in wgNamespaceIds)
{
namespaceId = wgNamespaceIds[wgNamespace];
if ($.inArray(namespaceId, validNamespaceIds) < 0) continue; // 排除不可用的名字空間ID。
if (namespace.toLowerCase() === wgNamespace.toLowerCase())
{ // 名字空間匹配。
isNamespaceValid = true;
break;
}
}
if (!isNamespaceValid) return; // 未定義的名字空間,將視作位於(主)名字空間根頁面名稱的一部分,不可用。
// 獲取用戶名。
let userName = undefined;
let tokenType = undefined;
switch(wgFormattedNamespaces[namespaceId])
{ // 精準檢查鏈接地址。
case 'User':
case 'User talk':
userName = rootPageName; // 找到用戶。
if (pathSegments.length > 1) tokenType = 'subpage'; else tokenType = 'userpage';
break;
case 'Special':
switch(rootPageName)
{
case 'Contributions':
case '用戶貢獻':
case '用戶貢獻':
// 獲取用戶名。
if (pathSegments.length > 2) return; // 過多的路徑層級,用戶名包含非法字符。
userName = pathSegments[1]; // 找到用戶。
tokenType = 'contributions';
break;
default: return; // 不可是除用戶貢獻外的其他頁面。
}
break;
}
// 可以再增加檢測用戶名是否存在。
//alert(userName);
$(a).wrap($('<span/>').addClass('discussiontoken discussiontoken-' + tokenType)); //將找到的關鍵字替換,加上高亮。
});
markPrefixToken(element, function() {
return this.nodeValue.replace(/@|[-—]+/g, match =>
$('<span/>').addClass('discussiontoken ' + (match[0] === '@' ? 'discussiontoken-replyto' : 'discussiontoken-signaturestart')).text(match[0])
.get(0).outerHTML
);
});
}
//alert("執行MarkSignatures.js。");
$(function() {
let wgNamespaceNumber = mw.config.get('wgNamespaceNumber');
if (wgNamespaceNumber < 0 || wgNamespaceNumber % 2 === 0) return; // 判斷當前頁面的名字空間是否為討論名字空間。
alert('共有 ' + $('#mw-content-text .mw-parser-output').children('h2').length + ' 個章節。');
$('#mw-content-text .mw-parser-output').children('h2').each((sectIndex, h2) =>
markSignatureToken($(h2).nextUntil('h2').wrapAll($('<div/>')))
);
// 添加定製CSS的鏈接。
if ($('#discussiontoken').length === 0) {
$('head').append($('<link />').attr({
id: 'discussiontoken',
rel: 'stylesheet',
type: 'text/css',
href: '/index.php?title=User:サンムル/js/MarkSignatures.css&action=raw&ctype=text/css'
}));
}
});