<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans-CN">
	<id>https://mcbbs.wiki/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AHanziConverterShell.js</id>
	<title>MediaWiki:HanziConverterShell.js - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="https://mcbbs.wiki/index.php?action=history&amp;feed=atom&amp;title=MediaWiki%3AHanziConverterShell.js"/>
	<link rel="alternate" type="text/html" href="https://mcbbs.wiki/index.php?title=MediaWiki:HanziConverterShell.js&amp;action=history"/>
	<updated>2026-05-14T15:17:24Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.40.3</generator>
	<entry>
		<id>https://mcbbs.wiki/index.php?title=MediaWiki:HanziConverterShell.js&amp;diff=29089&amp;oldid=prev</id>
		<title>Salt lovely：​分离外壳部分</title>
		<link rel="alternate" type="text/html" href="https://mcbbs.wiki/index.php?title=MediaWiki:HanziConverterShell.js&amp;diff=29089&amp;oldid=prev"/>
		<updated>2021-04-15T07:39:51Z</updated>

		<summary type="html">&lt;p&gt;分离外壳部分&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;// 外壳部分, 需要依靠核心部分来运行, 估计不支持IE&lt;br /&gt;
// 编译自TypeScript&lt;br /&gt;
var __awaiter = (this &amp;amp;&amp;amp; this.__awaiter) || function (thisArg, _arguments, P, generator) {&lt;br /&gt;
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }&lt;br /&gt;
    return new (P || (P = Promise))(function (resolve, reject) {&lt;br /&gt;
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }&lt;br /&gt;
        function rejected(value) { try { step(generator[&amp;quot;throw&amp;quot;](value)); } catch (e) { reject(e); } }&lt;br /&gt;
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }&lt;br /&gt;
        step((generator = generator.apply(thisArg, _arguments || [])).next());&lt;br /&gt;
    });&lt;br /&gt;
};&lt;br /&gt;
(function () {&lt;br /&gt;
    let prefix = &amp;#039;[SaltHanziConverter]&amp;#039;;&lt;br /&gt;
    let techprefix = &amp;#039;SaltHanziConverter-&amp;#039;;&lt;br /&gt;
    let ver = &amp;#039;0.1.0&amp;#039;;&lt;br /&gt;
    let type = readWithDefault(&amp;#039;HanziConverterType&amp;#039;, -1); // 默认-1 即不转换&lt;br /&gt;
    const ignoreElements = [&amp;#039;TEXTAREA&amp;#039;, &amp;#039;STYLE&amp;#039;, &amp;#039;SCRIPT&amp;#039;, &amp;#039;INPUT&amp;#039;];&lt;br /&gt;
    const scanAttributes = [&amp;#039;title&amp;#039;, &amp;#039;placeholder&amp;#039;];&lt;br /&gt;
    const log = console.log, time = console.time, timeEnd = console.timeEnd;&lt;br /&gt;
    /**开关功能 */&lt;br /&gt;
    function userSwitch() {&lt;br /&gt;
        // 三种模式：强制简体/强制繁体/不作转换 分别对应 0/1/-1 汉/漢/无&lt;br /&gt;
        // 添加切换按钮&lt;br /&gt;
        let frag = document.createDocumentFragment(), div = document.createElement(&amp;#039;div&amp;#039;);&lt;br /&gt;
        div.id = &amp;#039;HanziConverterTypeSwitch&amp;#039;;&lt;br /&gt;
        let t1 = document.createElement(&amp;#039;span&amp;#039;), t2 = document.createElement(&amp;#039;span&amp;#039;), t3 = document.createElement(&amp;#039;span&amp;#039;);&lt;br /&gt;
        t1.textContent = &amp;#039;汉&amp;#039;;&lt;br /&gt;
        t3.textContent = &amp;#039;|&amp;#039;;&lt;br /&gt;
        t2.textContent = &amp;#039;漢&amp;#039;;&lt;br /&gt;
        t1.className = &amp;#039;s&amp;#039;;&lt;br /&gt;
        t3.className = &amp;#039;d&amp;#039;;&lt;br /&gt;
        t2.className = &amp;#039;t&amp;#039;;&lt;br /&gt;
        div.appendChild(t1);&lt;br /&gt;
        div.appendChild(t3);&lt;br /&gt;
        div.appendChild(t2);&lt;br /&gt;
        div.onclick = function () {&lt;br /&gt;
            type++;&lt;br /&gt;
            if (type &amp;gt; 1 || type &amp;lt; -1)&lt;br /&gt;
                type = -1;&lt;br /&gt;
            write(&amp;#039;HanziConverterType&amp;#039;, type);&lt;br /&gt;
            styleChange();&lt;br /&gt;
            checkAndConvert();&lt;br /&gt;
            checkAttributeAndConvert();&lt;br /&gt;
        };&lt;br /&gt;
        styleChange();&lt;br /&gt;
        frag.appendChild(div);&lt;br /&gt;
        function styleChange() {&lt;br /&gt;
            switch (type) {&lt;br /&gt;
                case 1:&lt;br /&gt;
                    div.className = &amp;#039;simplified&amp;#039;;&lt;br /&gt;
                    div.title = &amp;#039;文字转为简体&amp;#039;;&lt;br /&gt;
                    break;&lt;br /&gt;
                case 0:&lt;br /&gt;
                    div.className = &amp;#039;traditional&amp;#039;;&lt;br /&gt;
                    div.title = &amp;#039;文字转为繁体&amp;#039;;&lt;br /&gt;
                    break;&lt;br /&gt;
                default:&lt;br /&gt;
                    div.className = &amp;#039;none&amp;#039;;&lt;br /&gt;
                    div.title = &amp;#039;不作繁简转化&amp;#039;;&lt;br /&gt;
                    break;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        // 适配网页&lt;br /&gt;
        document.body.appendChild(frag);&lt;br /&gt;
    }&lt;br /&gt;
    /**主过程 */&lt;br /&gt;
    function main() {&lt;br /&gt;
        userSwitch();&lt;br /&gt;
        checkAndConvert();&lt;br /&gt;
        checkAttributeAndConvert();&lt;br /&gt;
        // MW会不停地翻新某个script导致监视器被不停触发...&lt;br /&gt;
        // 因此需要节流&lt;br /&gt;
        setTimeout(() =&amp;gt; {&lt;br /&gt;
            let observer = new MutationObserver(function (records) {&lt;br /&gt;
                // for of比map性能更好&lt;br /&gt;
                for (let record of records)&lt;br /&gt;
                    for (let node of record.addedNodes)&lt;br /&gt;
                        checkAndConvert(node);&lt;br /&gt;
            });&lt;br /&gt;
            observer.observe(document.body, {&lt;br /&gt;
                subtree: true,&lt;br /&gt;
                attributes: false,&lt;br /&gt;
                childList: true,&lt;br /&gt;
                characterData: false&lt;br /&gt;
            });&lt;br /&gt;
            let attrObserver = new MutationObserver(function (records) {&lt;br /&gt;
                var _a;&lt;br /&gt;
                // for of比map性能更好&lt;br /&gt;
                for (let record of records)&lt;br /&gt;
                    if (scanAttributes.indexOf((_a = record.attributeName) !== null &amp;amp;&amp;amp; _a !== void 0 ? _a : &amp;#039;&amp;#039;) != -1 &amp;amp;&amp;amp; record.target instanceof HTMLElement)&lt;br /&gt;
                        checkAttributeAndConvert(record.target);&lt;br /&gt;
            });&lt;br /&gt;
            attrObserver.observe(document.body, {&lt;br /&gt;
                subtree: true,&lt;br /&gt;
                attributes: true,&lt;br /&gt;
                childList: false,&lt;br /&gt;
                characterData: false&lt;br /&gt;
            });&lt;br /&gt;
        }, 1500);&lt;br /&gt;
        setTimeout(() =&amp;gt; {&lt;br /&gt;
            checkAndConvert();&lt;br /&gt;
            checkAttributeAndConvert();&lt;br /&gt;
        }, 1500);&lt;br /&gt;
        // 整活&lt;br /&gt;
        log(window.HanziConverterFunction(prefix + &amp;#039; 一只忧郁的台湾乌龟&amp;#039;, type));&lt;br /&gt;
    }&lt;br /&gt;
    /** */&lt;br /&gt;
    function docReady(callback) {&lt;br /&gt;
        if (document.readyState == &amp;#039;loading&amp;#039;)&lt;br /&gt;
            document.addEventListener(&amp;#039;DOMContentLoaded&amp;#039;, () =&amp;gt; {&lt;br /&gt;
                callback();&lt;br /&gt;
            });&lt;br /&gt;
        else&lt;br /&gt;
            callback();&lt;br /&gt;
    }&lt;br /&gt;
    /**主要功能 */&lt;br /&gt;
    function checkAndConvert(target = document.body) {&lt;br /&gt;
        return __awaiter(this, void 0, void 0, function* () {&lt;br /&gt;
            if (type != 0 &amp;amp;&amp;amp; type != 1)&lt;br /&gt;
                return;&lt;br /&gt;
            // time(prefix + &amp;#039; Text&amp;#039;)&lt;br /&gt;
            let nodes = findAllTextNodes(target);&lt;br /&gt;
            for (let i = 0; i &amp;lt; nodes.length; i++) {&lt;br /&gt;
                let node = nodes[i];&lt;br /&gt;
                if (typeof node.textContent == &amp;#039;string&amp;#039;) {&lt;br /&gt;
                    let _temp = window.HanziConverterFunction(node.textContent, type);&lt;br /&gt;
                    if (node.textContent != _temp) // 防止过于频繁的写入&lt;br /&gt;
                        node.textContent = _temp;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            // timeEnd(prefix + &amp;#039; Text&amp;#039;) // WikiText近48w字节的页面也能在350ms内搞定, 而且全程异步不影响操作&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
    /**替换属性中的汉字 */&lt;br /&gt;
    function checkAttributeAndConvert(parentElement = document.body) {&lt;br /&gt;
        return __awaiter(this, void 0, void 0, function* () {&lt;br /&gt;
            if (type != 0 &amp;amp;&amp;amp; type != 1)&lt;br /&gt;
                return;&lt;br /&gt;
            // time(prefix + &amp;#039; Attr&amp;#039;)&lt;br /&gt;
            for (let _temp of scanAttributes)&lt;br /&gt;
                convertAttribute(_temp, parentElement);&lt;br /&gt;
            // timeEnd(prefix + &amp;#039; Attr&amp;#039;) // 耗时很短, 不过为了应付意外情况, 还是选择了异步&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
    /**查找所有的文字节点 */&lt;br /&gt;
    function findAllTextNodes(parent) {&lt;br /&gt;
        var _a, _b, _c;&lt;br /&gt;
        let nodes = [];&lt;br /&gt;
        if (parent.hasChildNodes()) {&lt;br /&gt;
            let children = Array.from(parent.childNodes);&lt;br /&gt;
            for (let n of children) {&lt;br /&gt;
                if (((_a = n.parentElement) === null || _a === void 0 ? void 0 : _a.id) == &amp;#039;HanziConverterTypeSwitch&amp;#039;)&lt;br /&gt;
                    continue;&lt;br /&gt;
                if (ignoreElements.indexOf((_c = (_b = n.parentElement) === null || _b === void 0 ? void 0 : _b.tagName.toUpperCase()) !== null &amp;amp;&amp;amp; _c !== void 0 ? _c : &amp;#039;&amp;#039;) != -1)&lt;br /&gt;
                    continue;&lt;br /&gt;
                if (n.nodeType == 3)&lt;br /&gt;
                    nodes.push(n);&lt;br /&gt;
                else&lt;br /&gt;
                    nodes.push(...findAllTextNodes(n));&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        return nodes;&lt;br /&gt;
    }&lt;br /&gt;
    /**替换范围内所有元素的属性 */&lt;br /&gt;
    function convertAttribute(attr, parentElement) {&lt;br /&gt;
        var _a;&lt;br /&gt;
        let nodes = parentElement.querySelectorAll(&amp;#039;*[&amp;#039; + attr + &amp;#039;]&amp;#039;), _temp = &amp;#039;&amp;#039;;&lt;br /&gt;
        for (let i = 0; i &amp;lt; nodes.length; i++) {&lt;br /&gt;
            let n = nodes[i];&lt;br /&gt;
            if (n instanceof HTMLElement &amp;amp;&amp;amp; (_temp = (_a = n.getAttribute(attr)) !== null &amp;amp;&amp;amp; _a !== void 0 ? _a : &amp;#039;&amp;#039;).length &amp;gt; 0) {&lt;br /&gt;
                let _temp_ = window.HanziConverterFunction(_temp, type);&lt;br /&gt;
                if (_temp_ != _temp)&lt;br /&gt;
                    n.setAttribute(attr, _temp_);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    /**&lt;br /&gt;
     * 根据key存入本地存储&lt;br /&gt;
     * @param key 键值&lt;br /&gt;
     * @param value 要存放的值&lt;br /&gt;
     */&lt;br /&gt;
    function write(key, value) {&lt;br /&gt;
        if (value) {&lt;br /&gt;
            value = JSON.stringify(value);&lt;br /&gt;
        }&lt;br /&gt;
        localStorage.setItem(techprefix + key, value);&lt;br /&gt;
    }&lt;br /&gt;
    /**&lt;br /&gt;
     * 根据key读取本地数据&lt;br /&gt;
     * @param key 键值&lt;br /&gt;
     */&lt;br /&gt;
    function readWithDefault(key, defaultValue) {&lt;br /&gt;
        let value = localStorage.getItem(techprefix + key);&lt;br /&gt;
        if (value &amp;amp;&amp;amp; value != &amp;quot;undefined&amp;quot; &amp;amp;&amp;amp; value != &amp;quot;null&amp;quot;) {&lt;br /&gt;
            let temp = JSON.parse(value);&lt;br /&gt;
            if (typeof defaultValue == &amp;#039;boolean&amp;#039; &amp;amp;&amp;amp; typeof temp == &amp;#039;string&amp;#039;) { // 防坑措施&lt;br /&gt;
                // @ts-ignore&lt;br /&gt;
                if (temp == &amp;#039;true&amp;#039;) {&lt;br /&gt;
                    temp = true;&lt;br /&gt;
                }&lt;br /&gt;
                else {&lt;br /&gt;
                    temp = false;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            return temp;&lt;br /&gt;
        }&lt;br /&gt;
        write(key, defaultValue);&lt;br /&gt;
        return defaultValue;&lt;br /&gt;
    }&lt;br /&gt;
    docReady(main);&lt;br /&gt;
})();&lt;/div&gt;</summary>
		<author><name>Salt lovely</name></author>
	</entry>
</feed>