注意:在您儲存之後您必須清除瀏覽器快取才可看到最新的變動。
?_=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' })); } });