コンテキストメニューでgoogle翻訳を実行するUserScript

## 概要
ChromeやEdge(Chromiumベース)では右クリックで開くコンテキストメニューに翻訳があり、そこから翻訳することができますが、

同じChromium系ブラウザでもBraveやOperaなど、コンテキストメニューに翻訳が存在しないブラウザがあるので、UserScriptで再現してみました。

## 必要な拡張機能

[Tampermonkey](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo?hl=ja)が必要です。他の同様のUserScript系拡張機能で動くのかどうかは未確認です。
というかコンテキストメニューからの実行をサポートしてるのTampermonkeyだけっぽい。

## スクリプト

**~~丸パk~~...参考**

* [Chromeの翻訳バーっぽいのをSleipnirで使えるようにするスクリプト](https://barrackdo.hatenadiary.org/entry/20110603/1307129666)
* [Javascript: How to auto translate a website?](http://tutorialspots.com/javascript-how-to-auto-translate-a-website-5323.html)

### ページ翻訳を実行するUserScript

```javascript
// ==UserScript==
// @name         ページ翻訳
// @description  表示中のページをGoogle Translate APIで翻訳
// @version      0.1
// @run-at       context-menu
// ==/UserScript==

(function() {
    //すでに翻訳実行済みかどうか確認する
    var skipdiv = document.querySelector(".skiptranslate");

    if(skipdiv == null) {
        //Google Translate API実行のための関数を定義
        var transfunc = function() {
            //ページ言語を設定するためhtmlタグのlang属性を取得、できなければ英語ということにする
            var lang = document.getElementsByTagName("html")[0].lang;
            if(lang.length == 0) {
                lang = "en";
            }

            //Google Translate APIを開始
            new google.translate.TranslateElement({
                pageLanguage: lang,
                includedLanguages: "ja",
                multilanguagePage: true
            }, "google_translate_element");

            setTimeout(function() {
                //1秒後に強制的に日本語を選んで翻訳実行
                var select = document.querySelector("select.goog-te-combo");
                select.value = "ja";
                select.dispatchEvent(new Event("change"));

                setTimeout(function() {
                    //さらに1秒後に翻訳時に出てくるバーを非表示に
                    var bar = document.querySelector(".skiptranslate");
                    bar.style.display = "none";
                    document.body.style.top = 0; //Google Translate APIはバー表示のために勝手にbodyのy位置をずらす模様…
                }, 1000);
            }, 1000);
        };

        //Google Translate APIをインクルード
        var libele = document.createElement("script");
        libele.setAttribute("type", "text/javascript");
        libele.setAttribute("src", "//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit");
        document.body.appendChild(libele);

        //Google Translate APIの言語選択ボックスを置くためのdivブロックを追加(ただし非表示)
        var divele = document.body.insertBefore(document.createElement("div"), document.body.firstChild);
        divele.id = "google_translate_element";
        divele.style.display = "none";

        //Google Translate APIを実行
        var scriptele = document.createElement("script");
        scriptele.setAttribute("type", "text/javascript");
        scriptele.text += "function googleTranslateElementInit(){(" + transfunc.toString() + ")();}";
        document.body.appendChild(scriptele);
    }
})();
```

このUserScriptではgithubなど[CSP](https://developer.mozilla.org/ja/docs/Web/HTTP/CSP)の設定で(script)タグを差し込めないようにされていると翻訳できません。TampermonkeyではCSPを無視する方法は調べた限りないようです(それっぽい項目があるが変えても動かない…)、一応、TampermonkeyではGM_addElementという関数が用意されていてこれだとCSPを無視してタグを差し込めますが、google翻訳API側で差し込んでるタグまでは対応していないので結局動きません。セキュリティなんかどうでもいいからどうしてもCSPを無効化して翻訳したい場合はCSPを無効にする拡張機能があるので導入すると無効化できます。

GM_xmlhttpRequestでスクリプトを読み込んでappendChildを正規表現でGM_addElement(のラッパー関数、引数の形式が違うので)に置換してscriptタグで差し込めば何とかなりそうな気がしないでもないがキリがなさそう…

### Google翻訳のwebページ翻訳を開くUserScript

CSPを無効にしたくない場合はGoogle翻訳のWebページ翻訳を新しいタブで開いて翻訳するUserScriptと併用するといいと思います。こちらはこちらでなぜかDockerHubを翻訳しようとすると問答無用で404エラーを返して翻訳できなかったりします。

```javascript
// ==UserScript==
// @name            Google翻訳で開く
// @description     新しいタブで表示中のページをGoogle翻訳で開いて翻訳
// @version         0.1
// @grant           GM_openInTab
// @run-at          context-menu
// ==/UserScript==

(function() {
    GM_openInTab("https://translate.google.co.jp/translate?hl=ja&sl=auto&tl=ja&u=" + window.location.href, false);
})();
```