Greasy Fork

Greasy Fork is available in English.

简繁转换(中国大陆、台湾、香港、日本新字体)

调用 opencc-rust-wasm 转换中文

当前为 2022-06-21 提交的版本,查看 最新版本

// ==UserScript==
// @name	简繁转换(中国大陆、台湾、香港、日本新字体)
// @namespace	Forbidden Siren
// @version	  0.9.13
// @description 调用 opencc-rust-wasm 转换中文
// @include	*
// @grant	GM_getResourceText
// @grant	GM_getResourceURL
// @grant	GM_registerMenuCommand
// @grant	GM_unregisterMenuCommand
// @license MIT
// @run-at document-start
// @require  http://greasyfork.icu/scripts/413698-opencc-rust-wasm/code/opencc-rust-wasm.js?version=859508
// @resource opencc_wasm https://cdn.jsdelivr.net/gh/polyproline/opencc-wasm@main/opencc_gc.wasm
// @resource  HKVariants	https://cdn.jsdelivr.net/npm/opencc-data/data/HKVariants.txt
// @resource  HKVariantsRev	https://cdn.jsdelivr.net/npm/opencc-data/data/HKVariantsRev.txt
// @resource  HKVariantsRevPhrases	https://cdn.jsdelivr.net/npm/opencc-data/data/HKVariantsRevPhrases.txt
// @resource  JPShinjitaiCharacters	https://cdn.jsdelivr.net/npm/opencc-data/data/JPShinjitaiCharacters.txt
// @resource  JPShinjitaiPhrases	https://cdn.jsdelivr.net/npm/opencc-data/data/JPShinjitaiPhrases.txt
// @resource  JPVariants	https://cdn.jsdelivr.net/npm/opencc-data/data/JPVariants.txt
// @resource  JPVariantsRev	https://cdn.jsdelivr.net/npm/opencc-data/data/JPVariantsRev.txt
// @resource  STCharacters	https://cdn.jsdelivr.net/npm/opencc-data/data/STCharacters.txt
// @resource  STPhrases	https://cdn.jsdelivr.net/npm/opencc-data/data/STPhrases.txt
// @resource  TSCharacters	https://cdn.jsdelivr.net/npm/opencc-data/data/TSCharacters.txt
// @resource  TSPhrases	https://cdn.jsdelivr.net/npm/opencc-data/data/TSPhrases.txt
// @resource  TWPhrasesIT	https://cdn.jsdelivr.net/npm/opencc-data/data/TWPhrasesIT.txt
// @resource  TWPhrasesName	https://cdn.jsdelivr.net/npm/opencc-data/data/TWPhrasesName.txt
// @resource  TWPhrasesOther	https://cdn.jsdelivr.net/npm/opencc-data/data/TWPhrasesOther.txt
// @resource  TWPhrasesRev	https://cdn.jsdelivr.net/npm/opencc-data/data/TWPhrasesRev.txt
// @resource  TWVariants	https://cdn.jsdelivr.net/npm/opencc-data/data/TWVariants.txt
// @resource  TWVariantsRev	https://cdn.jsdelivr.net/npm/opencc-data/data/TWVariantsRev.txt
// @resource  TWVariantsRevPhrases	https://cdn.jsdelivr.net/npm/opencc-data/data/TWVariantsRevPhrases.txt
// ==/UserScript==
(function () {
	"use strict";

	const ToSimple = [["HKVariantsRevPhrases", "HKVariantsRev"], ["TWPhrasesRev", "TWVariantsRevPhrases", "TWVariantsRev"], ["TSPhrases", "TSCharacters"]];// to Simple Chinese
	const ToTraditional = [["TWVariantsRevPhrases", "TWVariantsRev"], ["HKVariantsRevPhrases", "HKVariantsRev"], ["JPShinjitaiPhrases", "JPShinjitaiCharacters", "JPVariantsRev"], ["STPhrases", "STCharacters"]];
	const ToTaiwan = [["STPhrases", "STCharacters"], "TWVariants", "TWPhrases"];
	const ToHongKong = [["STPhrases", "STCharacters"], "HKVariants"];

	const NODE_DICT = ToSimple;
	const ExcludeTag = new RegExp("SCRIPT|TEXTAREA|META|BASE|NOSCRIPT|OBJECT");
	const ExcludeType = new RegExp("text|search|hidden");
	const Base64 = new RegExp("(?<=base64,).*");

	const start = GM_registerMenuCommand("load", function () {
		GM_unregisterMenuCommand(start);
		const wasm = (async () => {
			const url = GM_getResourceURL("opencc_wasm");
			let arr;
			if (url.startsWith('data:')) {
				const base64String = Base64.exec(url)[0];
				const rawData = window.atob(base64String);
				arr = new Uint8Array(rawData);
			} else {
				const req = await fetch(url);
				const buf = await req.arrayBuffer();
				arr = new Uint8Array(buf);
			}
			return arr;
		})();
		init(wasm).then(() => {
			let build = ConverterBuild.new();
			NODE_DICT.forEach(item => {
				if (Array.isArray(item)) {
					item.forEach(function (item) {
						build.adddict(GM_getResourceText(item));
					});
				} else {
					console.assert(typeof item == "string");
					build.adddict(GM_getResourceText(item));
				}
				build.group();
			});
			const converter = build.build();
			function translate(pNode) {
				var childs = pNode.childNodes;
				for (let i = 0; i < childs.length; i++) {
					let child = childs.item(i);
					if (child.tagName && ExcludeTag.test(child.tagName)) continue;
					if (child.title) {
						converter.convert(child.title).then(text => {
							if (child.title != text) {
								child.title = text;
							}
						});
					}
					if (child.alt) {
						converter.convert(child.alt).then(text => {
							if (child.alt != text) {
								child.alt = text;
							}
						});
					}
					if (child.tagName == "INPUT" && !ExcludeType.test(child.type)) {
						if (child.value) {
							converter.convert(child.value).then(text => {
								if (child.value != text) {
									child.value = text;
								}
							});
						}
						if (child.placeholder) {
							converter.convert(child.placeholder).then(text => {
								if (child.placeholder != text) {
									child.placeholder = text;
								}
							});
						}
					} else if (child.nodeType == 3) {
						if (child.data) {
							converter.convert(child.data).then(text => {
								if (child.data != text) {
									child.data = text;
								}
							});
						}
					}
					if (child.nodeType == 1) {
						translate(child);
					}
				}
			}
			const translate_no = () => { translate(document.body) };
			translate(document.documentElement);
			GM_registerMenuCommand("中文转换", translate_no);
			//setTimeout(translate,5*1000);
			{
				const MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
				let observer = new MutationObserver(function (records) {
					records.forEach(function (record) {
						switch (record.type) {
							case 'childList':
								record.addedNodes.forEach(translate)
								break;
							case 'characterData':
								if (record.target.data) {
									converter.convert(record.target.data).then(text => {
										if (text != record.target.data) {
											record.target.data = text;
										}
									});
								}
								break;
						}
					})
				});
				const option = {
					"childList": true,
					"subtree": true,
					"characterData": true
				};
				let id = GM_registerMenuCommand("事件监听", listen_event);
				function listen_event() {
					GM_unregisterMenuCommand(id);
					translate_no();
					observer.observe(document.body, option);
					id = GM_registerMenuCommand("取消监听", unlisten_event);
				}
				function unlisten_event() {
					GM_unregisterMenuCommand(id);
					observer.disconnect();
					id = GM_registerMenuCommand("事件监听", listen_event);
				}
			}
		});
	});
})();