|
|
| 第4行: |
第4行: |
| mw.loader.load("//mcbbs-wiki.cn/index.php?title=MediaWiki:HanziConverterPlus.js&action=raw&ctype=text/javascript", "text/javascript"); | | mw.loader.load("//mcbbs-wiki.cn/index.php?title=MediaWiki:HanziConverterPlus.js&action=raw&ctype=text/javascript", "text/javascript"); |
| mw.loader.load("//mcbbs-wiki.cn/index.php?title=MediaWiki:HanziConverterCSS.css&action=raw&ctype=text/css", "text/css"); | | mw.loader.load("//mcbbs-wiki.cn/index.php?title=MediaWiki:HanziConverterCSS.css&action=raw&ctype=text/css", "text/css"); |
| // 外壳部分, 需要依靠核心部分来运行, 估计不支持IE
| | mw.loader.load("//mcbbs-wiki.cn/index.php?title=MediaWiki:HanziConverterShell.js&action=raw&ctype=text/javascript", "text/javascript"); |
| // 编译自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;
| |
| /**开关功能 */
| |
| 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;
| |
| }
| |
| }
| |
| // 适配网页
| |
| 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(window.HanziConverterFunction(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 = window.HanziConverterFunction(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_ = window.HanziConverterFunction(_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;
| |
| }
| |
| docReady(main);
| |
| })();
| |