ChatGPT页面翻译按钮

🍓 用ChatGPT一键翻译您正在阅读的网页

当前为 2023-04-16 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name chatgpt-page-translate-button
  3. // @description 🍓 let ChatGPT translate the web page you are reading in one click
  4. // @author mefengl
  5. // @version 0.1.3
  6. // @namespace https://github.com/mefengl
  7. // @require https://cdn.jsdelivr.net/npm/moz-readability@0.2.1/Readability.min.js
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=openai.com
  9. // @license MIT
  10. // @match *://*/*
  11. // @grant GM_setValue
  12. // @grant GM_addValueChangeListener
  13. // @name:en ChatGPT Page Translate Button
  14. // @description:en 🍓 Let ChatGPT translate the web page you are reading in one click
  15. // @name:zh-CN ChatGPT页面翻译按钮
  16. // @description:zh-CN 🍓 用ChatGPT一键翻译您正在阅读的网页
  17. // @name:es Botón de traducción de página ChatGPT
  18. // @description:es 🍓 Deja que ChatGPT traduzca la página web que estás leyendo con un solo clic
  19. // @name:hi ChatGPT पृष्ठ अनुवाद बटन
  20. // @description:hi 🍓 ChatGPT को वेब पृष्ठ का अनुवाद करने दें जिसे आप एक क्लिक में पढ़ रहे हैं
  21. // @name:ar زر ترجمة الصفحة ChatGPT
  22. // @description:ar 🍓 دع ChatGPT يترجم صفحة الويب التي تقرأها بنقرة واحدة
  23. // @name:pt Botão de tradução de página ChatGPT
  24. // @description:pt 🍓 Deixe o ChatGPT traduzir a página da web que você está lendo com um clique
  25. // @name:ru Кнопка перевода страницы ChatGPT
  26. // @description:ru 🍓 Позвольте ChatGPT перевести веб-страницу, которую вы читаете, одним щелчком мыши
  27. // @name:ja ChatGPTページ翻訳ボタン
  28. // @description:ja 🍓 ChatGPTが読んでいるWebページをワンクリックで翻訳させる
  29. // @name:de ChatGPT Seitenübersetzungs-Schaltfläche
  30. // @description:de 🍓 Lassen Sie ChatGPT die Webseite, die Sie gerade lesen, mit einem Klick übersetzen
  31. // @name:fr Bouton de traduction de page ChatGPT
  32. // @description:fr 🍓 Laissez ChatGPT traduire la page Web que vous lisez en un clic
  33. // ==/UserScript==
  34. (() => {
  35. var __async = (__this, __arguments, generator) => {
  36. return new Promise((resolve, reject) => {
  37. var fulfilled = (value) => {
  38. try {
  39. step(generator.next(value));
  40. } catch (e) {
  41. reject(e);
  42. }
  43. };
  44. var rejected = (value) => {
  45. try {
  46. step(generator.throw(value));
  47. } catch (e) {
  48. reject(e);
  49. }
  50. };
  51. var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
  52. step((generator = generator.apply(__this, __arguments)).next());
  53. });
  54. };
  55.  
  56. // ../../packages/chatkit/dist/index.mjs
  57. function getTextarea() {
  58. const form = document.querySelector("form");
  59. if (!form)
  60. return;
  61. const textareas = form.querySelectorAll("textarea");
  62. const result = textareas[0];
  63. return result;
  64. }
  65. function getSubmitButton() {
  66. const textarea = getTextarea();
  67. if (!textarea)
  68. return;
  69. return textarea.nextElementSibling;
  70. }
  71. function getRegenerateButton() {
  72. const form = document.querySelector("form");
  73. if (!form)
  74. return;
  75. const buttons = form.querySelectorAll("button");
  76. const result = Array.from(buttons).find((button) => {
  77. var _a;
  78. return (_a = button.textContent) == null ? void 0 : _a.trim().toLowerCase().includes("regenerate");
  79. });
  80. return result;
  81. }
  82. function getStopGeneratingButton() {
  83. const form = document.querySelector("form");
  84. if (!form)
  85. return;
  86. const buttons = form.querySelectorAll("button");
  87. const result = Array.from(buttons).find((button) => {
  88. var _a;
  89. return (_a = button.textContent) == null ? void 0 : _a.trim().toLowerCase().includes("stop generating");
  90. });
  91. return result;
  92. }
  93. function getLastResponseElement() {
  94. const responseElements = document.querySelectorAll(".group.w-full");
  95. return responseElements[responseElements.length - 1];
  96. }
  97. function getLastResponse() {
  98. const lastResponseElement = getLastResponseElement();
  99. if (!lastResponseElement)
  100. return;
  101. const lastResponse = lastResponseElement.textContent;
  102. return lastResponse;
  103. }
  104. function getTextareaValue() {
  105. var _a;
  106. return ((_a = getTextarea()) == null ? void 0 : _a.value) || "";
  107. }
  108. function setTextarea(message) {
  109. const textarea = getTextarea();
  110. if (!textarea)
  111. return;
  112. textarea.value = message;
  113. textarea.dispatchEvent(new Event("input"));
  114. }
  115. function send(message) {
  116. setTextarea(message);
  117. const textarea = getTextarea();
  118. if (!textarea)
  119. return;
  120. textarea.dispatchEvent(new KeyboardEvent("keydown", { key: "Enter", bubbles: true }));
  121. }
  122. function regenerate() {
  123. const regenerateButton = getRegenerateButton();
  124. if (!regenerateButton)
  125. return;
  126. regenerateButton.click();
  127. }
  128. function onSend(callback) {
  129. const textarea = getTextarea();
  130. if (!textarea)
  131. return;
  132. textarea.addEventListener("keydown", function(event) {
  133. if (event.key === "Enter" && !event.shiftKey) {
  134. callback();
  135. }
  136. });
  137. const sendButton = getSubmitButton();
  138. if (!sendButton)
  139. return;
  140. sendButton.addEventListener("mousedown", callback);
  141. }
  142. function isGenerating() {
  143. var _a, _b;
  144. return ((_b = (_a = getSubmitButton()) == null ? void 0 : _a.firstElementChild) == null ? void 0 : _b.childElementCount) === 3;
  145. }
  146. function waitForIdle() {
  147. return new Promise((resolve) => {
  148. const interval = setInterval(() => {
  149. if (!isGenerating()) {
  150. clearInterval(interval);
  151. resolve();
  152. }
  153. }, 1e3);
  154. });
  155. }
  156. function setListener(key = "prompt_texts") {
  157. let last_trigger_time = +/* @__PURE__ */ new Date();
  158. if (location.href.includes("chat.openai")) {
  159. GM_addValueChangeListener(key, (name, old_value, new_value) => __async(this, null, function* () {
  160. if (+/* @__PURE__ */ new Date() - last_trigger_time < 500) {
  161. return;
  162. }
  163. last_trigger_time = +/* @__PURE__ */ new Date();
  164. setTimeout(() => __async(this, null, function* () {
  165. const prompt_texts = new_value;
  166. if (prompt_texts.length > 0) {
  167. let firstTime = true;
  168. while (prompt_texts.length > 0) {
  169. if (!firstTime) {
  170. yield new Promise((resolve) => setTimeout(resolve, 2e3));
  171. }
  172. if (!firstTime && chatgpt.isGenerating()) {
  173. continue;
  174. }
  175. firstTime = false;
  176. const prompt_text = prompt_texts.shift() || "";
  177. chatgpt.send(prompt_text);
  178. }
  179. }
  180. }), 0);
  181. GM_setValue(key, []);
  182. }));
  183. }
  184. }
  185. var chatgpt = {
  186. getTextarea,
  187. getSubmitButton,
  188. getRegenerateButton,
  189. getStopGeneratingButton,
  190. getLastResponseElement,
  191. getLastResponse,
  192. getTextareaValue,
  193. setTextarea,
  194. send,
  195. regenerate,
  196. onSend,
  197. isGenerating,
  198. waitForIdle,
  199. setListener
  200. };
  201. var chatgpt_default = chatgpt;
  202.  
  203. // src/createButton/index.ts
  204. function createButton(callback) {
  205. if (window.location.href.includes("chat.openai")) {
  206. return;
  207. }
  208. const hideRight = document.title.match(/[\u4e00-\u9fa5]/) ? "-130px" : "-120px";
  209. const button = document.createElement("button");
  210. button.innerHTML = "\u7F51\u9875\u7FFB\u8BD1";
  211. button.style.position = "fixed";
  212. button.style.width = "140px";
  213. button.style.top = "120px";
  214. button.style.right = hideRight;
  215. button.style.zIndex = "999999";
  216. button.style.backgroundColor = "#4285f4";
  217. button.style.color = "#fff";
  218. button.style.opacity = "0.8";
  219. button.style.border = "none";
  220. button.style.borderRadius = "4px";
  221. button.style.padding = "10px 16px";
  222. button.style.fontSize = "18px";
  223. button.style.cursor = "pointer";
  224. button.style.transition = "right 0.3s";
  225. document.body.appendChild(button);
  226. button.addEventListener("mouseenter", () => {
  227. button.style.right = "-10px";
  228. });
  229. button.addEventListener("mouseleave", () => {
  230. button.style.right = hideRight;
  231. });
  232. document.addEventListener("fullscreenchange", () => {
  233. if (document.fullscreenElement) {
  234. button.style.display = "none";
  235. } else {
  236. button.style.display = "block";
  237. }
  238. });
  239. button.addEventListener("click", callback);
  240. }
  241. var createButton_default = createButton;
  242.  
  243. // src/SimpleArticleSegmentation/index.ts
  244. var MIN_PARAGRAPH_LENGTH = 1600;
  245. var MAX_PARAGRAPH_LENGTH = 1800;
  246. var SimpleArticleSegmentation = class {
  247. constructor(text) {
  248. this.text = text;
  249. }
  250. segment() {
  251. const paragraphs = [];
  252. const sentences = this.text.split(new RegExp("(?<=[.!?])\\s+"));
  253. let paragraph = "";
  254. for (const sentence of sentences) {
  255. if (paragraph.length + sentence.length + 1 <= MAX_PARAGRAPH_LENGTH) {
  256. paragraph += (paragraph.length > 0 ? " " : "") + sentence;
  257. } else {
  258. if (paragraph.length >= MIN_PARAGRAPH_LENGTH) {
  259. paragraphs.push(paragraph);
  260. paragraph = sentence;
  261. } else {
  262. paragraph += " " + sentence;
  263. }
  264. }
  265. }
  266. if (paragraph.length >= MIN_PARAGRAPH_LENGTH) {
  267. paragraphs.push(paragraph);
  268. }
  269. return paragraphs;
  270. }
  271. };
  272. var SimpleArticleSegmentation_default = SimpleArticleSegmentation;
  273.  
  274. // src/getParagraphs/index.ts
  275. function getParagraphs() {
  276. try {
  277. let docClone = document.cloneNode(true);
  278. let article = new Readability(docClone).parse();
  279. if (article && article.textContent) {
  280. const segmenter = new SimpleArticleSegmentation_default(article.textContent);
  281. const paragraphs = segmenter.segment();
  282. return paragraphs;
  283. } else {
  284. console.warn("Readability.js could not extract any text content from this page.");
  285. return [];
  286. }
  287. } catch (error) {
  288. console.error("An error occurred while using Readability.js:", error);
  289. return [];
  290. }
  291. }
  292. var getParagraphs_default = getParagraphs;
  293.  
  294. // src/index.ts
  295. function initialize() {
  296. return __async(this, null, function* () {
  297. yield new Promise((resolve) => window.addEventListener("load", resolve));
  298. yield new Promise((resolve) => setTimeout(resolve, 1e3));
  299. });
  300. }
  301. function main() {
  302. return __async(this, null, function* () {
  303. yield initialize();
  304. const key = "prompt_texts";
  305. chatgpt_default.setListener(key);
  306. const translateWeb = () => __async(this, null, function* () {
  307. const paragraphs = getParagraphs_default();
  308. const prompt_texts = paragraphs.map((paragraph) => {
  309. return `${paragraph}
  310. translate above paragraph to Chinese with compact and intuitive format:`;
  311. });
  312. GM_setValue(key, prompt_texts);
  313. });
  314. createButton_default(translateWeb);
  315. });
  316. }
  317. (function() {
  318. main();
  319. })();
  320. })();
  321.  

QingJ © 2025

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