【Chrome拡張機能】Google Translation Supporter を公開した。
グーグル翻訳機能をアシストする拡張機能を作った
翻訳に関しては優秀なサイトもアプリもあるので、もう困る時代じゃないと思っています。スマホカメラかざすだけでまるっと翻訳しますし、全然作成する気もなかったんですが、チラっと耳にした話、それぞれのサービスにアレコレ不満があるそうな。
特殊な使い方やヘビーユーズする人の中にはブラウザの拡張機能が良い、っていう人がいるんですね、ちょっとした手間がネックとか、そういう事情ってあるよね
(スマホカメラなんかかざしてられっか!みたいな)。
Chrome拡張機能のストアで有名な機能のレビューを見てみると、なるほど、APIを使っている機能は回数制限があったり、認証が切れたり。グーグル本家などはブラウザに機能写したからそっち使え、と拡張機能自体を公開停止にしたり、キレている人がいらっしゃる。
まぁそうだよなぁ、API使うなら誰がその登録をするのよ?ユーザーがしようがデベロッパー側がしようが何かしらの制限はかかるよね。なんとかならんもんか、と考えて作成しました。
なんと却下されずに無事公開
APIを使う発想はそもそも無いので、まず思ったのが「作業しているタブ内にグーグル翻訳のサイトを表示すれば良いだけじゃね?」です。バカな発想ですが、iFrameを使えばどうか → はい無理、iFrame自体が嫌われ者でグーグルサービスが利用を許可していない。
まぁ仕方ない、私もiFrame嫌いですから。
じゃ、拡張機能でグーグル翻訳のサイトをタブで開かせて、非表示とかに出来ません? → 非表示状態では機能を使えません
笑 そういうのあるのね。
じゃタブが表示されてても別に良いんで、拡張機能の通信機能を使って機能を使わせてもらえません?アナログにちゃんとテキスト入力してボタンクリックとかをプログラムで書きますから →
だから「画面非表示状態」では機能を使えません サイトをちゃんと「表示」して使って。
これは困りました。現在のブラウザでは今開いているタブを監視しているようで、その他のタブで音楽を流しっぱなしとかに出来なかったりしますよね。それを回避する拡張機能を見たことがある 笑
あとは、ブラウザ設定のバックグラウンドタブ設定でゴニョゴニョできそうですが、ブラウザ依存は信頼出来ない、もうちょっと確実な方法が欲しい。
とはいえ、これくらい作業した時点で、グーグル翻訳サイトのテキストエリアに .innerText()とかで入力してゴニョゴニョすればちゃんとサイトは翻訳をかけてくれることがわかった、入力を検知して勝手に翻訳してくれます。
結果もちゃんと取得出来ます。が、ここであるある問題に直面。
それは、DOM取得の方法、今時のグーグルはネーミングが完全に自動生成のようで、HTML要素の特定や取得が不確かになってしまう(ま、どのサイトでもそうですが)
この点はサイトのアップデートや地域、設定言語によって違いがあるとお手上げです。これをなんとかしないと公開できませんね。
まぁ、それは見なかったことにして。
さて、ここでタブ式にしてしまうと、そのタブを一瞬にせよ開かないと機能が動かない。これは痛いです、作業しているタブから飛ぶなど言語道断。そこで別ウィンドウ式にしました。
動線としては:
拡張機能を開くと → 別ウィンドウでグーグル翻訳のサイトが開く、同時に作業しているタブにコントロール用の操作パネルが埋め込まれる、これはドラッグしたりサイズ調整ができるので、画面の好きな位置におく → 作業タブで文字を操作パネルに渡して機能をトリガーさせると → 拡張機能の通信機能でバックグラウンドスクリプトに文字データを渡す → バックグラウンドスクリプトでグーグル翻訳ウィンドウにテキスト入力する → 翻訳サイトから結果をDOM取得してバックグラウンドスクリプトに返す → バックグラウンドスクリプトから作業タブへ結果を返す → 翻訳結果がパネルに表示される
こんな感じです。
グーグル翻訳を使う際には一瞬でもグーグル翻訳ウィンドウを前面に表示しないと動いてくれませんが、そこはウィンドウを小さくして邪魔にならない位置に配置すればそれほど気にならない。翻訳が終わればすぐに背面に戻りますので、一瞬ピコっと画面に出るロード中!みたいなもんです(あまりにウィンドウが小さいと表示されてると見なされない可能性があってビクビクした)
翻訳結果が出るまで体感で1秒くらいですかねぇ、グーグル翻訳本家がそんなもんなので、拡張機能通信には何も時間が取られていないイメージ。
うん、悪くないぞ。
翻訳結果をDOM取得する所はちょっと手こずりました。
元のサイトは「リアルタイムで翻訳結果」を出す、ということは非同期なわけです、
プログラムで外から翻訳完了のタイミングを待つのは無理じゃない?
そこはDOMの変化を検知して取得です。ということで mutation observer を使いました。
これが結構ネックで昔から頭を悩まされる機能です。うまく指定しているつもりでも発火しまくるので、その制御が難しい。
今回でも数回翻訳していると、前のデータがなぜか返ってきたり非常に不安定だった。
この泥臭い拡張機能の良いことは、あくまでグーグル翻訳サイトを開いて使っているので、利用制限がかからないところ(たぶん)。あと、設定面や機能もそっち任せな所で、言語設定なんかはサイトのウィンドウを開いてアレコレして作業中は最小まで縮めて配置する。
これでこちらが設定機能やそれらUIを用意する手間がなくなりました、通信と表示を担当しているだけです。
あとの作業は一応バリデーションとか? でも出口はグーグル翻訳を使うわけだからな。文字数制限くらいはしても良いかも。あとは機能の簡易トリガーとかコピペ機能。
で、結局公開して大丈夫なの?ということですが、うーむ。
まずDOMの取得がネック、サイトに手を加えられたらたちまち動作しません。
そもそもクラス名なんかが自動生成に見えるので、どれくらいの頻度で変更されるのか、地域や言語で違うんじゃない?ならどうすんの?
対応としては
・ユーザーがDOM要素(入力テキストエリアと結果テキストエリア)の指定・保存が出来るようにする。
まぁ別にこれくらいしてはしてもらっても良い気がするけど...
あるいは
・「グーグル翻訳の入力テキストエリア&翻訳結果テキストエリア、国別 json」みたいなAPIサーバーを作る、んで拡張機能で fetch 出来るようにしておく。
イヤ、そういうの好きなんですけどね。誰が最初にデータ用意してくれんのって話。
もう一つ大きなネックは、グーグルドキュメントで使おうとしたら、普通のサイトなら使えるコピペ類の機能がダメだったんですよねぇ、これは痛い。
グーグルドキュメント自体がアプリなので、一般的なサイトで使えるメソッドが通らなかったりします。普通ならハイライトした文字を取得するのにgetSelection() とかでガサっとコピー出来ますが、それが無理。Ctrl + C を検知も無理、onKeyPress みたいなキーボード操作がそもそも検知できません。
これでは、ユーザーが操作パネルにコピペする手間が残るなぁ、なんとかならんかね。
クリップボード許可もらうとか? getSelection() が使えないのはかなり痛い。
※まぁもう公開してしまったし、様子をみます。
最近拡張機能をアップデートするときにはPaypalの寄付ボタンを設置するようにしました。この収益化はどうだろうか?普通に機能制限つけて解除したければプレミアム版をストアで購入させるのが王道でしょうが、面倒。