MCBBS Wiki欢迎您共同参与编辑!在参与编辑之前请先阅读Wiki方针。
如果在编辑的过程中遇到了什么问题,可以去讨论板提问。
为了您能够无阻碍地参与编辑 未验证/绑定过邮箱的用户,请尽快绑定/验证。
MCBBS Wiki GitHub群组已上线!
您可以在回声洞中发表吐槽!
服务器状态监控。点击进入
本站由MCBBS用户自行搭建,与MCBBS及东银河系漫游指南(北京)科技有限公司没有从属关系。点此了解 MCBBS Wiki 不是什么>>
MediaWiki:HanziConverter.js:修订间差异
跳到导航
跳到搜索
Salt lovely(留言 | 贡献) (繁简转换脚本,外壳部分) |
Sheep-realms(留言 | 贡献) 无编辑摘要 |
||
(未显示1个用户的4个中间版本) | |||
第1行: | 第1行: | ||
"use strict"; |
"use strict"; |
||
// 加载核心以及补充包、CSS |
// 加载核心以及补充包、CSS |
||
mw.loader.load("//mcbbs |
mw.loader.load("//mcbbs.wiki/index.php?title=MediaWiki:HanziConverterCore.js&action=raw&ctype=text/javascript", "text/javascript"); |
||
mw.loader.load("//mcbbs |
mw.loader.load("//mcbbs.wiki/index.php?title=MediaWiki:HanziConverterPlus.js&action=raw&ctype=text/javascript", "text/javascript"); |
||
mw.loader.load("//mcbbs |
mw.loader.load("//mcbbs.wiki/index.php?title=MediaWiki:HanziConverterCSS.css&action=raw&ctype=text/css", "text/css"); |
||
mw.loader.load("//mcbbs.wiki/index.php?title=MediaWiki:HanziConverterShell.js&action=raw&ctype=text/javascript", "text/javascript"); |
|||
// 外壳部分, 需要依靠核心部分来运行, 估计不支持IE |
|||
// 编译自TypeScript |
|||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { |
|||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } |
|||
return new (P || (P = Promise))(function (resolve, reject) { |
|||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } |
|||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } |
|||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } |
|||
step((generator = generator.apply(thisArg, _arguments || [])).next()); |
|||
}); |
|||
}; |
|||
(function () { |
|||
let prefix = '[SaltHanziConverter]'; |
|||
let techprefix = 'SaltHanziConverter-'; |
|||
let ver = '0.1.0'; |
|||
let type = -1; // 默认-1 即不转换 |
|||
const ignoreElements = ['TEXTAREA', 'STYLE', 'SCRIPT', 'INPUT']; |
|||
const scanAttributes = ['title', 'placeholder']; |
|||
const log = console.log, time = console.time, timeEnd = console.timeEnd, HanziConverter = window.HanziConverterFunction; |
|||
/**开关功能 */ |
|||
function userSwitch() { |
|||
// 三种模式:强制简体/强制繁体/不作转换 分别对应 0/1/-1 汉/漢/无 |
|||
type = format2Integer(readWithDefault('HanziConverterType', -1)); |
|||
function format2Integer(n) { |
|||
if (typeof n === 'number' && n % 1 === 0) |
|||
return n; |
|||
n = parseInt(n + ''); |
|||
if (isNaN(n)) |
|||
n = 0; |
|||
return n; |
|||
} |
|||
// 添加切换按钮 |
|||
let frag = document.createDocumentFragment(), div = document.createElement('div'); |
|||
div.id = 'HanziConverterTypeSwitch'; |
|||
let t1 = document.createElement('span'), t2 = document.createElement('span'), t3 = document.createElement('span'); |
|||
t1.textContent = '汉'; |
|||
t3.textContent = '|'; |
|||
t2.textContent = '漢'; |
|||
t1.className = 's'; |
|||
t3.className = 'd'; |
|||
t2.className = 't'; |
|||
div.appendChild(t1); |
|||
div.appendChild(t3); |
|||
div.appendChild(t2); |
|||
div.onclick = function () { |
|||
type++; |
|||
if (type > 1 || type < -1) |
|||
type = -1; |
|||
write('HanziConverterType', type); |
|||
styleChange(); |
|||
checkAndConvert(); |
|||
checkAttributeAndConvert(); |
|||
}; |
|||
styleChange(); |
|||
frag.appendChild(div); |
|||
function styleChange() { |
|||
switch (type) { |
|||
case 1: |
|||
div.className = 'simplified'; |
|||
div.title = '文字转为简体'; |
|||
break; |
|||
case 0: |
|||
div.className = 'traditional'; |
|||
div.title = '文字转为繁体'; |
|||
break; |
|||
default: |
|||
div.className = 'none'; |
|||
div.title = '不作繁简转化'; |
|||
break; |
|||
} |
|||
} |
|||
// 适配网页 |
|||
let css = `#HanziConverterTypeSwitch{position:fixed;top:0.25rem;left:1rem;padding:0.25rem 0.5rem;background-color:#fff;opacity:0.5;transition:0.2s ease;z-index:999999;cursor:pointer;user-select:none;font-size:1.2rem;font-family:"STKaiti", "KaiTi", "MicrosoftYaHei";color:#222;text-align:center}#HanziConverterTypeSwitch.none{background-color:#ccc;color:#666}#HanziConverterTypeSwitch.simplified .s{outline:1px solid #222;font-weight:bold}#HanziConverterTypeSwitch.traditional .t{outline:1px solid #222;font-weight:bold}#HanziConverterTypeSwitch::after{content:attr(title);position:absolute;top:0.25rem;left:50%;width:8.4rem;opacity:0;pointer-events:none;transition:0.3s ease}#HanziConverterTypeSwitch:hover{box-shadow:2px 3px 5px 0 #222;opacity:1}#HanziConverterTypeSwitch:hover::after{left:100%;opacity:1}#HanziConverterTypeSwitch:active{box-shadow:1px 2px 2px 0 #222;background-color:#ddd} |
|||
`; |
|||
let s = document.createElement('style'); |
|||
s.textContent = css; |
|||
document.head.appendChild(s); |
|||
document.body.appendChild(frag); |
|||
} |
|||
/**主过程 */ |
|||
function main() { |
|||
userSwitch(); |
|||
checkAndConvert(); |
|||
checkAttributeAndConvert(); |
|||
// MW会不停地翻新某个script导致监视器被不停触发... |
|||
// 因此需要节流 |
|||
setTimeout(() => { |
|||
let observer = new MutationObserver(function (records) { |
|||
// for of比map性能更好 |
|||
for (let record of records) |
|||
for (let node of record.addedNodes) |
|||
checkAndConvert(node); |
|||
}); |
|||
observer.observe(document.body, { |
|||
subtree: true, |
|||
attributes: false, |
|||
childList: true, |
|||
characterData: false |
|||
}); |
|||
let attrObserver = new MutationObserver(function (records) { |
|||
var _a; |
|||
// for of比map性能更好 |
|||
for (let record of records) |
|||
if (scanAttributes.indexOf((_a = record.attributeName) !== null && _a !== void 0 ? _a : '') != -1 && record.target instanceof HTMLElement) |
|||
checkAttributeAndConvert(record.target); |
|||
}); |
|||
attrObserver.observe(document.body, { |
|||
subtree: true, |
|||
attributes: true, |
|||
childList: false, |
|||
characterData: false |
|||
}); |
|||
}, 1500); |
|||
setTimeout(() => { |
|||
checkAndConvert(); |
|||
checkAttributeAndConvert(); |
|||
}, 1500); |
|||
// 整活 |
|||
log(HanziConverter(prefix + ' 一只忧郁的台湾乌龟', type)); |
|||
} |
|||
/** */ |
|||
function docReady(callback) { |
|||
if (document.readyState == 'loading') |
|||
document.addEventListener('DOMContentLoaded', () => { |
|||
callback(); |
|||
}); |
|||
else |
|||
callback(); |
|||
} |
|||
/**主要功能 */ |
|||
function checkAndConvert(target = document.body) { |
|||
return __awaiter(this, void 0, void 0, function* () { |
|||
if (type != 0 && type != 1) |
|||
return; |
|||
// time(prefix + ' Text') |
|||
let nodes = findAllTextNodes(target); |
|||
for (let i = 0; i < nodes.length; i++) { |
|||
let node = nodes[i]; |
|||
if (typeof node.textContent == 'string') { |
|||
let _temp = HanziConverter(node.textContent, type); |
|||
if (node.textContent != _temp) // 防止过于频繁的写入 |
|||
node.textContent = _temp; |
|||
} |
|||
} |
|||
// timeEnd(prefix + ' Text') // WikiText近48w字节的页面也能在350ms内搞定, 而且全程异步不影响操作 |
|||
}); |
|||
} |
|||
/**替换属性中的汉字 */ |
|||
function checkAttributeAndConvert(parentElement = document.body) { |
|||
return __awaiter(this, void 0, void 0, function* () { |
|||
if (type != 0 && type != 1) |
|||
return; |
|||
// time(prefix + ' Attr') |
|||
for (let _temp of scanAttributes) |
|||
convertAttribute(_temp, parentElement); |
|||
// timeEnd(prefix + ' Attr') // 耗时很短, 不过为了应付意外情况, 还是选择了异步 |
|||
}); |
|||
} |
|||
/**查找所有的文字节点 */ |
|||
function findAllTextNodes(parent) { |
|||
var _a, _b, _c; |
|||
let nodes = []; |
|||
if (parent.hasChildNodes()) { |
|||
let children = Array.from(parent.childNodes); |
|||
for (let n of children) { |
|||
if (((_a = n.parentElement) === null || _a === void 0 ? void 0 : _a.id) == 'HanziConverterTypeSwitch') |
|||
continue; |
|||
if (ignoreElements.indexOf((_c = (_b = n.parentElement) === null || _b === void 0 ? void 0 : _b.tagName.toUpperCase()) !== null && _c !== void 0 ? _c : '') != -1) |
|||
continue; |
|||
if (n.nodeType == 3) |
|||
nodes.push(n); |
|||
else |
|||
nodes.push(...findAllTextNodes(n)); |
|||
} |
|||
} |
|||
return nodes; |
|||
} |
|||
/**替换范围内所有元素的属性 */ |
|||
function convertAttribute(attr, parentElement) { |
|||
var _a; |
|||
let nodes = parentElement.querySelectorAll('*[' + attr + ']'), _temp = ''; |
|||
for (let i = 0; i < nodes.length; i++) { |
|||
let n = nodes[i]; |
|||
if (n instanceof HTMLElement && (_temp = (_a = n.getAttribute(attr)) !== null && _a !== void 0 ? _a : '').length > 0) { |
|||
let _temp_ = HanziConverter(_temp, type); |
|||
if (_temp_ != _temp) |
|||
n.setAttribute(attr, _temp_); |
|||
} |
|||
} |
|||
} |
|||
/** |
|||
* 根据key存入本地存储 |
|||
* @param key 键值 |
|||
* @param value 要存放的值 |
|||
*/ |
|||
function write(key, value) { |
|||
if (value) { |
|||
value = JSON.stringify(value); |
|||
} |
|||
localStorage.setItem(techprefix + key, value); |
|||
} |
|||
/** |
|||
* 根据key读取本地数据 |
|||
* @param key 键值 |
|||
*/ |
|||
function readWithDefault(key, defaultValue) { |
|||
let value = localStorage.getItem(techprefix + key); |
|||
if (value && value != "undefined" && value != "null") { |
|||
let temp = JSON.parse(value); |
|||
if (typeof defaultValue == 'boolean' && typeof temp == 'string') { // 防坑措施 |
|||
// @ts-ignore |
|||
if (temp == 'true') { |
|||
temp = true; |
|||
} |
|||
else { |
|||
temp = false; |
|||
} |
|||
} |
|||
return temp; |
|||
} |
|||
write(key, defaultValue); |
|||
return defaultValue; |
|||
} |
|||
/** |
|||
* 节流函数,必定执行最后一次操作 |
|||
* @param threshold 阈值 |
|||
* @param handler 要执行的函数 |
|||
* @param _arguments 要执行的函数的参数 |
|||
*/ |
|||
let throttled = function (handler, threshold = 500, ..._arguments) { |
|||
let throttledTimer, throttledLastTrigger, timerTriggered = true; |
|||
return function () { |
|||
let now = new Date().getTime(), timePast = now - (throttledLastTrigger !== null && throttledLastTrigger !== void 0 ? throttledLastTrigger : 0); |
|||
if (timePast < threshold) { |
|||
if (timerTriggered) { |
|||
timerTriggered = false; |
|||
throttledTimer = setTimeout(() => { |
|||
// log('TimeoutRunHandler ' + timerTriggered) |
|||
timerTriggered = true; |
|||
throttledLastTrigger = new Date().getTime(); |
|||
handler(..._arguments); |
|||
}, threshold - timePast); |
|||
} |
|||
} |
|||
else { |
|||
if (!timerTriggered) { |
|||
clearTimeout(throttledTimer); |
|||
// log('ClearTimeout ' + timerTriggered) |
|||
} |
|||
// log('RunHandler ' + timerTriggered) |
|||
timerTriggered = false; |
|||
throttledLastTrigger = now; |
|||
handler(..._arguments); |
|||
timerTriggered = true; |
|||
} |
|||
}; |
|||
}; |
|||
// /** |
|||
// * assert: 断言 |
|||
// * @param condition 为假时报错 |
|||
// * @param msg 报错语句,默认为“发生错误” |
|||
// * */ |
|||
// function assert(condition: any, msg?: string): asserts condition { |
|||
// if (!condition) throw new Error(prefix + ': ' + (msg ?? '发生错误')) |
|||
// } |
|||
// /**version: 显示版本*/ |
|||
// function version() { |
|||
// log(prefix + ' ' + ver) |
|||
// } |
|||
docReady(main); |
|||
})(); |
2022年7月30日 (六) 12:31的最新版本
"use strict";
// 加载核心以及补充包、CSS
mw.loader.load("//mcbbs.wiki/index.php?title=MediaWiki:HanziConverterCore.js&action=raw&ctype=text/javascript", "text/javascript");
mw.loader.load("//mcbbs.wiki/index.php?title=MediaWiki:HanziConverterPlus.js&action=raw&ctype=text/javascript", "text/javascript");
mw.loader.load("//mcbbs.wiki/index.php?title=MediaWiki:HanziConverterCSS.css&action=raw&ctype=text/css", "text/css");
mw.loader.load("//mcbbs.wiki/index.php?title=MediaWiki:HanziConverterShell.js&action=raw&ctype=text/javascript", "text/javascript");