中文转换

支持繁简转换、简繁转换、异体字转换和地区习惯用词转换(中国大陆、台湾、香港、日本新字体)

目前为 2021-03-03 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name 中文转换
  3. // @namespace Forbidden Siren
  4. // @version 0.9.12
  5. // @description 支持繁简转换、简繁转换、异体字转换和地区习惯用词转换(中国大陆、台湾、香港、日本新字体)
  6. // @description:zh-TW 支持繁简转换、简繁转换、异体字转换和地区习惯用词转换(中国大陆、台湾、香港、日本新字体)
  7. // @include *
  8. // @match *://*
  9. // @grant GM_getResourceText
  10. // @grant GM_getResourceURL
  11. // @grant GM_registerMenuCommand
  12. // @grant GM_unregisterMenuCommand
  13. // @run-at document-end
  14. //
  15. // @require https://gf.qytechs.cn/scripts/413698-opencc-rust-wasm/code/opencc-rust-wasm.js?version=859508
  16. // @resource opencc_wasm https://cdn.jsdelivr.net/gh/polyproline/opencc-wasm@main/opencc_gc.wasm
  17. // @resource HKVariants https://cdn.jsdelivr.net/npm/opencc-data/data/HKVariants.txt
  18. // @resource HKVariantsRev https://cdn.jsdelivr.net/npm/opencc-data/data/HKVariantsRev.txt
  19. // @resource HKVariantsRevPhrases https://cdn.jsdelivr.net/npm/opencc-data/data/HKVariantsRevPhrases.txt
  20. // @resource JPShinjitaiCharacters https://cdn.jsdelivr.net/npm/opencc-data/data/JPShinjitaiCharacters.txt
  21. // @resource JPShinjitaiPhrases https://cdn.jsdelivr.net/npm/opencc-data/data/JPShinjitaiPhrases.txt
  22. // @resource JPVariants https://cdn.jsdelivr.net/npm/opencc-data/data/JPVariants.txt
  23. // @resource JPVariantsRev https://cdn.jsdelivr.net/npm/opencc-data/data/JPVariantsRev.txt
  24. // @resource STCharacters https://cdn.jsdelivr.net/npm/opencc-data/data/STCharacters.txt
  25. // @resource STPhrases https://cdn.jsdelivr.net/npm/opencc-data/data/STPhrases.txt
  26. // @resource TSCharacters https://cdn.jsdelivr.net/npm/opencc-data/data/TSCharacters.txt
  27. // @resource TSPhrases https://cdn.jsdelivr.net/npm/opencc-data/data/TSPhrases.txt
  28. // @resource TWPhrasesIT https://cdn.jsdelivr.net/npm/opencc-data/data/TWPhrasesIT.txt
  29. // @resource TWPhrasesName https://cdn.jsdelivr.net/npm/opencc-data/data/TWPhrasesName.txt
  30. // @resource TWPhrasesOther https://cdn.jsdelivr.net/npm/opencc-data/data/TWPhrasesOther.txt
  31. // @resource TWPhrasesRev https://cdn.jsdelivr.net/npm/opencc-data/data/TWPhrasesRev.txt
  32. // @resource TWVariants https://cdn.jsdelivr.net/npm/opencc-data/data/TWVariants.txt
  33. // @resource TWVariantsRev https://cdn.jsdelivr.net/npm/opencc-data/data/TWVariantsRev.txt
  34. // @resource TWVariantsRevPhrases https://cdn.jsdelivr.net/npm/opencc-data/data/TWVariantsRevPhrases.txt
  35. // ==/UserScript==
  36. (function () {
  37. "use strict";
  38.  
  39. const ToSimple = [["HKVariantsRevPhrases", "HKVariantsRev"], ["TWPhrasesRev", "TWVariantsRevPhrases", "TWVariantsRev"], ["TSPhrases", "TSCharacters"]];// to Simple Chinese
  40. const ToTraditional = [["TWVariantsRevPhrases", "TWVariantsRev"], ["HKVariantsRevPhrases", "HKVariantsRev"], ["JPShinjitaiPhrases", "JPShinjitaiCharacters", "JPVariantsRev"], ["STPhrases", "STCharacters"]];
  41. const ToTaiwan = [["STPhrases", "STCharacters"], "TWVariants", "TWPhrases"];
  42. const ToHongKong = [["STPhrases", "STCharacters"], "HKVariants"];
  43.  
  44. const NODE_DICT = ToSimple;
  45. const ExcludeTag = new RegExp("SCRIPT|TEXTAREA|META|BASE|NOSCRIPT|OBJECT");
  46. const ExcludeType = new RegExp("text|search|hidden");
  47. const Base64 = new RegExp("(?<=base64,).*");
  48.  
  49. const start = GM_registerMenuCommand("load", function () {
  50. GM_unregisterMenuCommand(start);
  51. const wasm = (function (base64String) {
  52. const rawData = window.atob(base64String);
  53. let outputArray = new Uint8Array(rawData.length);
  54. for (let i = 0; i < rawData.length; ++i) {
  55. outputArray[i] = rawData.charCodeAt(i);
  56. }
  57. return outputArray;
  58. })(Base64.exec(GM_getResourceURL("opencc_wasm"))[0]);
  59. init(wasm).then(() => {
  60. let build = ConverterBuild.new();
  61. NODE_DICT.forEach(item => {
  62. if (Array.isArray(item)) {
  63. item.forEach(function (item) {
  64. build.adddict(GM_getResourceText(item));
  65. });
  66. } else {
  67. console.assert(typeof item == "string");
  68. build.adddict(GM_getResourceText(item));
  69. }
  70. build.group();
  71. });
  72. const converter = build.build();
  73. function translate(pNode) {
  74. var childs;
  75. if (pNode) {
  76. childs = pNode.childNodes;
  77. } else {
  78. childs = document.documentElement.childNodes;
  79. }
  80. for (let i = 0; i < childs.length; i++) {
  81. let child = childs.item(i);
  82. if (child.tagName && ExcludeTag.test(child.tagName)) continue;
  83. if (child.title) {
  84. converter.convert(child.title).then(text => {
  85. if (child.title != text) {
  86. child.title = text;
  87. }
  88. });
  89. }
  90. if (child.alt) {
  91. converter.convert(child.alt).then(text => {
  92. if (child.alt != text) {
  93. child.alt = text;
  94. }
  95. });
  96. }
  97. if (child.tagName == "INPUT" && !ExcludeType.test(child.type)) {
  98. if (child.value) {
  99. converter.convert(child.value).then(text => {
  100. if (child.value != text) {
  101. child.value = text;
  102. }
  103. });
  104. }
  105. if (child.placeholder) {
  106. converter.convert(child.placeholder).then(text => {
  107. if (child.placeholder != text) {
  108. child.placeholder = text;
  109. }
  110. });
  111. }
  112. } else if (child.nodeType == 3) {
  113. if (child.data) {
  114. converter.convert(child.data).then(text => {
  115. if (child.data != text) {
  116. child.data = text;
  117. }
  118. });
  119. }
  120. }
  121. if (child.nodeType == 1) {
  122. translate(child);
  123. }
  124. }
  125. }
  126. translate();
  127. GM_registerMenuCommand("中文转换", translate);
  128. //setTimeout(translate,5*1000);
  129. const id = GM_registerMenuCommand("事件监听", function () {
  130. translate();
  131. GM_unregisterMenuCommand(id);
  132. const MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
  133. let observer = new MutationObserver(function (records) {
  134. records.forEach(function (record) {
  135. switch (record.type) {
  136. case 'childList':
  137. record.addedNodes.forEach(translate)
  138. break;
  139. case 'characterData':
  140. if (record.target.data) {
  141. converter.convert(record.target.data).then(text => {
  142. if (text != record.target.data) {
  143. record.target.data = text;
  144. }
  145. });
  146. }
  147. break;
  148. }
  149. })
  150. });
  151. const option = {
  152. "childList": true,
  153. "subtree": true,
  154. "characterData": true
  155. };
  156. observer.observe(document.body, option);
  157. });
  158. });
  159. });
  160. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址