Blueskyの外国語を自動的に翻訳

Blueskyの日本語文字が含まれてないポストを自動で翻訳(英語・ドイツ語・ポルトガル語のみ)

  1. // ==UserScript==
  2. // @name Blueskyの外国語を自動的に翻訳
  3. // @namespace @lamrongol
  4. // @version 0.1.8
  5. // @description Blueskyの日本語文字が含まれてないポストを自動で翻訳(英語・ドイツ語・ポルトガル語のみ)
  6. // @author Lamron🍞
  7. // @match https://bsky.app/*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=bsky.app
  9. // @require https://ajax.googleapis.com/ajax/libs/jquery/3.7.0/jquery.min.js
  10. // @license MIT
  11. // @grant none
  12. // ==/UserScript==
  13.  
  14. (function() {
  15. 'use strict';
  16.  
  17. // setting
  18. //const sourceLang = "en";
  19. const targetLang = "ja";
  20.  
  21. const jaRe = /[\p{Script_Extensions=Hiragana}\p{Script_Extensions=Katakana}\p{Script_Extensions=Han}]/u
  22. const geRe = /[äöüÄÖÜß]/u
  23. const ptRe = /[áéíóúâêôãõç]/u//ref https://amadora.co.uk/aprender/alfabeto/
  24.  
  25. const postTextCSS = ".css-175oi2r > .css-175oi2r.r-1awozwy.r-18u37iz.r-1w6e6rj > .css-146c3p1";
  26. //const quotePostTextCSS;
  27. const marker = "translated";
  28.  
  29. const observeTarget = "#root";
  30. const observeOption = {
  31. childList: true,
  32. subtree: true,
  33. }
  34.  
  35. async function sleep(ms) {
  36. return new Promise(resolve => setTimeout(resolve, ms));
  37. }
  38.  
  39. let translateObserver = new MutationObserver(function (MutationRecords, MutationObserver) {
  40. translateObserver.disconnect();
  41. const elms = $(postTextCSS).not(`.${marker}`);
  42. for(let i = elms.length-1; i > -1; i--){
  43. const elem = elms[i];
  44. $(elem).addClass(marker);
  45. const originalText = elem.textContent;
  46. if(jaRe.test(originalText)) continue;
  47.  
  48. let sourceLang = "en";
  49. if(geRe.test(originalText)) sourceLang = "de";
  50. else if(ptRe.test(originalText)) sourceLang = "pt";
  51.  
  52. const base_url = `https://translate.googleapis.com/translate_a/single?client=gtx&sl=${sourceLang}&tl=${targetLang}&dt=t&q=`;
  53.  
  54. const encodeText = encodeURIComponent(originalText);
  55. const url = base_url + encodeText;
  56. $.ajaxSetup({async: false});
  57. $.getJSON(url, function(data) {
  58. let text = "";
  59. data[0].forEach(function(element){
  60. text += `<p>${escapeHtml(element[0])}</p>`;
  61. });
  62. const parent = $(elem).parent();
  63. const translatedDiv = document.createElement("div");
  64. translatedDiv.classList.add("translatedText");
  65. parent.after(translatedDiv);
  66.  
  67. translatedDiv.innerHTML = "<hr>"+text;
  68. });
  69. $.ajaxSetup({async: true});
  70. sleep(2000);//awaitを付けるとエラー これだとsleepできてないが問題なく使える?
  71. }
  72.  
  73. translateObserver.observe($(observeTarget).get(0), observeOption);
  74. });
  75. translateObserver.observe($(observeTarget).get(0), observeOption);
  76.  
  77. function escapeHtml(str) {
  78. var patterns = {
  79. '<' : '&lt;',
  80. '>' : '&gt;',
  81. '&' : '&amp;',
  82. '"' : '&quot;',
  83. '\'' : '&#x27;',
  84. '`' : '&#x60;'
  85. };
  86. return str.replace(/[<>&"'`]/g, function(match) {
  87. return patterns[match];
  88. });
  89. };
  90. })();

QingJ © 2025

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