Greasy Fork is available in English.

Magic Twitter translate with DeepL

Adds external translation with DeepL

Verze ze dne 09. 03. 2021. Zobrazit nejnovější verzi.

  1. // ==UserScript==
  2. // @name Magic Twitter translate with DeepL
  3. // @namespace https://github.com/magicoflolis
  4. // @version 0.5
  5. // @description Adds external translation with DeepL
  6. // @author Magic of Lolis
  7. // @match https://twitter.com/*
  8. // @grant none
  9. // @require https://code.jquery.com/jquery-3.5.1.min.js
  10. // ==/UserScript==
  11.  
  12. ( () => {
  13. 'use strict';
  14.  
  15. let injected = null,
  16. injectInterval = null,
  17. waitForHeadNodeInterval = null;
  18. function isHTML(str) {
  19. let doc = new DOMParser().parseFromString(str, "text/html");
  20. return Array.from(doc.body.childNodes).some(node => node.nodeType === 1);
  21. }
  22.  
  23. function injectDeeplTranslationButton() {
  24. let translateButton = $("div[lang]").eq(0).siblings().eq(0).children("span"),
  25. deeplbtn = $("div[lang]").eq(0).siblings().eq(1).children("span"),
  26. translateBio = $('div[data-testid="UserDescription"]').eq(0).siblings().eq(0).children("span"),
  27. deeplBio = $('div[data-testid="UserDescription"]').eq(0).siblings().eq(1).children("span"),
  28. deepbtn = () => {
  29. let tweetContainer = translateButton.parent().siblings(),
  30. tweetLang = tweetContainer.attr("lang"),
  31. tweetContent = "",
  32. deeplButton = translateButton.parent().clone().appendTo(translateButton.parent().parent());
  33. tweetContainer.children("span").each((index,item) => {
  34. let tweetPart = $(item).html().trim();
  35. if(tweetPart && tweetPart != "" && !isHTML(tweetPart)) {
  36. tweetContent += " " + tweetPart;
  37. }
  38. });
  39. deeplButton.children("span").html("Translate with DeepL");
  40. deeplButton.hover(function() {
  41. $(this).css("text-decoration", "underline");
  42. }, function() {
  43. $(this).css("text-decoration", "none");
  44. });
  45. deeplButton.on("click", () => {
  46. window.open(`https://www.deepl.com/translator#${tweetLang}/en/${tweetContent}`,'_blank');
  47. })
  48. },
  49. biobtn = () => {
  50. let bioContainer = translateBio.parent().siblings(),
  51. bioLang = bioContainer.attr("lang"),
  52. bioContent = "",
  53. deeplButton = translateBio.parent().clone().appendTo(translateBio.parent().parent());
  54. bioContainer.children("span").each((index,item) => {
  55. let bioPart = $(item).html().trim();
  56. if(bioPart && bioPart != "" && !isHTML(bioPart)) {
  57. bioContent += " " + bioPart;
  58. }
  59. });
  60. deeplButton.children("span").html("Translate with DeepL");
  61. deeplButton.hover(function() {
  62. $(this).css("text-decoration", "underline");
  63. }, function() {
  64. $(this).css("text-decoration", "none");
  65. });
  66. deeplButton.on("click", () => {
  67. window.open(`https://www.deepl.com/translator#${bioLang}/en/${bioContent}`,'_blank');
  68. })
  69. };
  70. (deeplbtn.length != 1 && translateButton.length > 0) ? deepbtn() : false;
  71. (deeplBio.length != 1 && translateBio.length > 0) ? biobtn() : false;
  72. injected = true;
  73. clearInterval(injectInterval);
  74. injectInterval = null;
  75. }
  76.  
  77. function addObserverIfHeadNodeAvailable() {
  78. const target = $("head > title")[0],
  79. MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver,
  80. observer = new MutationObserver((mutations) => {
  81. mutations.forEach( () => {
  82. injected = null;
  83. injectInterval = setInterval(injectDeeplTranslationButton, 100);
  84. });
  85. });
  86. if(!target) {
  87. return;
  88. }
  89. clearInterval(waitForHeadNodeInterval);
  90. observer.observe(target, { subtree: true, characterData: true, childList: true });
  91. }
  92. waitForHeadNodeInterval = setInterval(addObserverIfHeadNodeAvailable, 100);
  93. })();