Twitter translate with DeepL

Adds external translation to Twitter.

Pada tanggal 10 Maret 2021. Lihat %(latest_version_link).

// ==UserScript==
// @name         Twitter translate with DeepL
// @description  Adds external translation to Twitter.
// @author       Magic of Lolis
// @version      0.71
// @namespace    https://github.com/magicoflolis
// @require      https://code.jquery.com/jquery-3.6.0.slim.min.js
// @match        https://twitter.com/*
// @match        https://mobile.twitter.com/*
// @grant        none
// @run-at       document-end
// ==/UserScript==

( () => {
    'use strict';
    const debug = "[Magic Translate]";
    // let config = {
    //     /** @type {'deepl'|'hide'|'ignore'} */
    //     translator: ('deepl'),
    //   }
    function isHTML(str) {
        let doc = new DOMParser().parseFromString(str, "text/html");
        return Array.from(doc.body.childNodes).some(node => node.nodeType === 1);
    }

    function injectDeeplTranslationButton() {
        const translateTweet = $("div[lang]").eq(0).siblings().eq(0).children("span"),
            translateBio = $('div[data-testid="UserDescription"]').eq(0).siblings().eq(0).children("span"),
            trBtn = $('[dir="ltr"]').eq(0),
            dlTweet = $("div[lang]").eq(0).siblings().eq(1),
            dlBio = $('div[data-testid="UserDescription"]').eq(0).siblings().eq(1);
        let tweetbtn = () => {
                const tweetContainer = translateTweet.parent().siblings(),
                    tweetLang = tweetContainer.attr("lang"),
                    deeplButton = translateTweet.parent().clone().appendTo(translateTweet.parent().parent());
                let content = "";
                tweetContainer.children("span").each((index,item) => {
                    let tweetPart = $(item).html().trim();
                    if(tweetPart && tweetPart != "" && !isHTML(tweetPart)) {
                        content += " " + tweetPart;
                    }
                });
                deeplButton.children("span").html("Translate with DeepL");
                deeplButton.hover(function() {
                    $(this).css("text-decoration", "underline");
                }, function() {
                    $(this).css("text-decoration", "none");
                });
                deeplButton.on("click", () => {
                    window.open(`https://www.deepl.com/translator#${tweetLang}/en/${content}`,'_blank');
                })
            },
            biobtn = () => {
                const bioContainer = translateBio.parent().siblings(),
                deeplButton = translateBio.parent().clone().appendTo(translateBio.parent().parent());
                let content = "";
                bioContainer.children("span").each((index,item) => {
                    let bioPart = $(item).html().trim();
                    if(bioPart && bioPart != "" && !isHTML(bioPart)) {
                        content += " " + bioPart;
                    }
                });
                deeplButton.children("span").html("Translate with DeepL");
                deeplButton.hover(function() {
                    $(this).css("text-decoration", "underline");
                }, function() {
                    $(this).css("text-decoration", "none");
                });
                deeplButton.on("click", () => {
                    window.open(`https://www.deepl.com/translator#auto/en/${content}`,'_blank');
                })
            };
            (translateBio.length && !dlBio.length) ? biobtn() : false;
            (trBtn.length && !dlTweet.length) ? tweetbtn() : false;
    }

    function start() {
        const init = { subtree: true, characterData: true, childList: true },
        target = document.getElementById('react-root');
        if (!target) {
            console.log(`${debug} can't find ${target}`)
            return
        }
        const callback = (_mutations, observer) => {
            observer.disconnect()
            injectDeeplTranslationButton()
            observer.observe(target, init)
        }
        new MutationObserver(callback)
            .observe(target, init)
    }
    start()
})();