User:Wengier/wordcount.js
外观
注意:保存之后,你必须清除浏览器缓存才能看到做出的更改。Google Chrome、Firefox、Microsoft Edge及Safari:按住⇧ Shift键并单击工具栏的“刷新”按钮。参阅Help:绕过浏览器缓存以获取更多帮助。
function getWordCount(html) {
var str = html.innerHTML.replace(/(<([^>]+)>)/ig,"").trim();
var wordCount = 0;
var arr = str.match(/[\u3040-\u309F]|[\u30A0-\u30FF]|[\u4E00-\u9FFF\uF900-\uFAFF\u3400-\u4DBF]|\S+/g);
if (arr) {
wordCount = arr.length;
}
return wordCount;
}
function getContentDiv() {
var contentDiv;
if (mw.config.get('wgAction') == 'edit') {
contentDiv = document.getElementById('wikiPreview');
}
else {
contentDiv = document.getElementById('mw-content-text');
}
return contentDiv;
}
function isValidListNode(node) {
if (node.parentElement.id == "word-count-stats") {
return false;
}
if (node.className.indexOf("toclevel-") > -1 ||
node.parentElement.parentElement.id == "toc") {
return false;
}
if (node.parentElement.parentElement.parentElement.className == "catlinks") {
return false;
}
var bodyContent = getContentDiv();
var curNode = node.parentElement.parentElement;
while (curNode && (curNode != bodyContent)) {
if (curNode.className.indexOf("infobox") > -1) {
return false;
}
else if (curNode.className.indexOf("metadata") > -1) {
return false;
}
else if (curNode.className.indexOf("navbox") > -1) {
return false;
}
else {
curNode = curNode.parentElement;
}
}
return true;
}
function isValidParagraphNode(node) {
if (node.parentNode.className.indexOf("mw-parser-output") > -1 ||
node.parentNode.parentNode.className.indexOf("mw-parser-output") > -1 ||
node.parentNode.nodeName == "BLOCKQUOTE") {
return true;
}
else {
return false;
}
}
function isValidReferenceNode(node) {
var bodyContent = getContentDiv();
var curNode = node.parentElement;
while (curNode && (curNode != bodyContent)) {
if (curNode.classList.contains("references") ||
curNode.classList.contains("reflist") ||
curNode.classList.contains("refbegin")) {
return true;
}
curNode = curNode.parentElement;
}
return false;
}
function toggleWordCount() {
if (mw.config.get('wgAction') == 'edit') {
var wikiPreview = document.getElementById('wikiPreview');
var wikiPreviewStyle = window.getComputedStyle(wikiPreview);
if (wikiPreviewStyle.display === 'none') {
alert("You need to preview the text for the word count script to work in edit mode.");
return;
}
}
var bodyContent = getContentDiv();
var output = document.getElementById("word-count-stats");
if (output) {
var oldStyle = output.className;
var i = 0;
// Cleanup background color
var pList = bodyContent.getElementsByTagName("p");
if (pList) {
for (i=0; i < pList.length; i++){
if (isValidParagraphNode(pList[i])) {
pList[i].style.cssText = oldStyle;
}
}
}
var listTypes = ["li", "dd"];
for (var j = 0; j < listTypes.length; j++) {
var liList = bodyContent.getElementsByTagName(listTypes[j]);
if (liList) {
for (i=0; i < liList.length; i++) {
liList[i].style.cssText = oldStyle;
}
}
}
var hList = bodyContent.getElementsByClassName("mw-heading");
if (hList) {
for (i=0; i < hList.length; i++) {
hList[i].style.cssText = oldStyle;
}
}
// Remove nodes
output.parentNode.removeChild(output);
var header = document.getElementById("word-count-header");
header.parentNode.removeChild(header);
var footer = document.getElementById("word-count-footer");
footer.parentNode.removeChild(footer);
}
else {
getStatistics(bodyContent);
}
}
//
// Main counting function
//
function getStatistics(bodyContent) {
// Statistics
var output = document.createElement("ul");
output.id = "word-count-stats";
var lead_value = document.createElement("li");
lead_value.id = "lead-stat";
output.appendChild(lead_value);
output.className = bodyContent.getElementsByTagName("p").item(0).style.cssText;
var main_body_value = document.createElement("li");
main_body_value.id = "main-body-stat";
output.appendChild(main_body_value);
var subtotal_value = document.createElement("li");
subtotal_value.id = "subtotal-stat";
output.appendChild(subtotal_value);
var ref_value = document.createElement("li");
ref_value.id = "ref-stat";
output.appendChild(ref_value);
bodyContent.insertBefore(output, bodyContent.firstChild);
// Header
var header = document.createElement("span");
header.id = "word-count-header";
header.innerHTML = "<b>条目字数统计:</b>";
bodyContent.insertBefore(header,output);
var footer = document.createElement("span");
footer.id = "word-count-footer";
footer.innerHTML = "<b>总字数:</b><p/>";
bodyContent.insertBefore(footer,output.nextSibling);
// Create counters
var main_body_count = 0;
var lead_count = 0;
var ref_count = 0;
var i = 0, sec = 0, sectop = 0;
// Count within headings
var hList = bodyContent.getElementsByClassName("mw-heading");
if (hList && hList.length) {
const rect = hList[0].getBoundingClientRect();
sec = 1;
sectop = rect.top;
}
// Count within paragraphs
var pList = bodyContent.getElementsByTagName("p");
if (pList) {
for (i=0; i < pList.length; i++) {
var para = pList[i];
if (isValidParagraphNode(para)) {
var paraCount = getWordCount(para);
const rect = para.getBoundingClientRect();
if (paraCount > 0) {
const rect = para.getBoundingClientRect();
if (sec && rect.top < sectop) {
lead_count += paraCount;
para.style.cssText = "background-color:lightgreen";
} else {
main_body_count += paraCount;
para.style.cssText = "background-color:yellow";
}
}
}
}
}
// Count within lists
var listTypes = ["li", "dd"];
for (var j = 0; j < listTypes.length; j++) {
var liList = bodyContent.getElementsByTagName(listTypes[j]);
if (liList) {
for (i=0; i < liList.length; i++) {
var li = liList[i];
if (isValidReferenceNode(li)) {
ref_count += getWordCount(li);
li.style.cssText = "background-color:cyan";
}
else if (isValidListNode(li)) {
main_body_count += getWordCount(li);
li.style.cssText = "background-color:yellow";
}
}
}
}
if (hList) {
for (i=0; i < hList.length; i++) {
var h = hList[i];
if (h.id == "Contents") {
continue;
}
main_body_count += getWordCount(h);
h.style.cssText = "background-color:yellow";
}
}
lead_value.innerHTML = "序言章节: " + lead_count + "个字";
main_body_value.innerHTML = "正文内容: " + main_body_count + "个字";
subtotal_value.innerHTML = "字数总计: " + (main_body_count + lead_count) + "个字";
ref_value.innerHTML = "参考文献: " + ref_count + "个字";
footer.innerHTML = "<b>条目总字数: " + (main_body_count + lead_count + ref_count) + "</b><p/>";
}
jQuery(function () {
mw.loader.using( ['mediawiki.util'], function () {
if($.inArray(mw.config.get('wgAction'), ['edit', 'view' , 'submit' , 'historysubmit' , 'purge']) !== -1) {
$( mw.util.addPortletLink('p-tb', '#', '字数统计', 't-word-count', '计算条目字数') )
.click( toggleWordCount );
}
});
});
//</nowiki>