KaggleでもMouse Dictionaryを使えるようにする

# Mouse DictionaryとKaggleと私

[Mouse Dictionary](https://qiita.com/wtetsu/items/c43232c6c44918e977c9)を、[Kaggle](https://kaggle.com)rな方々の一部で便利に使っていただいているようでした。

<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">これ入れてから自分比10000万倍くらい kaggle のカーネル読むの捗ってるから、お礼代わりに細やかながら拡散する！！<a href="https://t.co/ccBjjpN7oN">https://t.co/ccBjjpN7oN</a></p>&mdash; かえるるる (@kaeru_nantoka) <a href="https://twitter.com/kaeru_nantoka/status/1037667923014242304?ref_src=twsrc%5Etfw">September 6, 2018</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

一方で、Kaggleのサイトの一部でMouse Dictionaryが反応しないという問題があるようでした(Notebook上の文章とか)

そこで今回は、Mouse DictionaryをKaggleのサイト上コンテンツ全般に対して使用できるようしてみました。


## 結論だけ知りたい

このChrome拡張をインストールしてください。

* [Mouse Dictionary Kaggle support](https://chrome.google.com/webstore/detail/mouse-dictionary-iframe-s/bepofoammpdjhfdibmlghoaljkemineg)


※[Mouse Dictionary本体](https://qiita.com/wtetsu/items/c43232c6c44918e977c9)も必要です


### Mouse Dictionary Kaggle supportのソースコード
https://github.com/wtetsu/mouse-dictionary-enhancer



## 背景を知りたい
### なぜKaggleで使えなかったのか

iframeのせいです。

Kaggleが https://www.kaggle.com/ で、一部コンテンツの中身がiframeになっていて https://www.kaggleusercontent.com/ にあります。

拡張とはいえJavaScriptなので、クロスオリジンなiframe内のコンテンツをMouse Dictionary側に渡すことは、ストレートにはできません。

### 解決案1(採用せず)

もっとも簡単な解決案として、Mouse Dictionary自身が各iframe内にmousemoveなどのイベントを仕込み、そのイベントから取得したコンテンツを都度Mouse Dictionary本体側に渡す、という方法があります。

iframe内JS → Mouse Dictionary拡張のJS → トップレベルドキュメントのJS → Mouse Dictionary小窓の更新

みたいな流れですね。

このようなデータのやり取りは、メッセージ送受信する拡張の仕組みで実現することができます。詳しくはこちらを御覧ください。

Message Passing:
https://developer.chrome.com/extensions/messaging

しかしひとつ問題があります。クロスオリジンなiframe内にイベントを仕込んでメッセージ送受信をするためには、Mouse Dictionaryのパーミッションを追加する必要があるという点です。

これを、

```json
"permissions": ["storage", "unlimitedStorage", "activeTab"],
```

こんな感じにする必要があります。

```json
"permissions": ["storage", "unlimitedStorage", "activeTab", "https://www.kaggleusercontent.com/*"],
```

大多数のユーザにとって関係のないパーミッションを追加するのは、あまりうまい手とはいえません。また、拡張のアップデートの際にパーミッションが追加されていると、ユーザが明示的に許可しないとMouse Dictionaryが使用できなくなってしまいます。セキュリティ面でもユーザ体験面でも、よろしくありません。

また、将来Kaggleのページ構成が変わってしまったときに、Mouse Dictionary本体を追従する必要が出てくるかもしれません。Web上の1サイトに過ぎないKaggleを、Mouse Dictionaryが特別扱いして対応し続けないといけないのも、変な話です。

### 解決案2(採用)

ということで、Mouse Dictionary本体にパーミッションを追加しないで済む、別の案を考える必要がありました。

ここでは、別の拡張(Kaggle support)を、Mouse Dictionaryの追加機能的に提供する仕組みにしてみます。Kaggle利用者だけがこれをインストールすればいいので、Mouse Dictionary側のパーミッションを追加する必要はありません。Mouse Dictionaryのインストールだけで完結しないのは面倒ですが、まあ仕方がありません。

仕組みとしては、iframe内のマウスカーソル下コンテンツ取得は、Kaggle supportにまかせます。Kaggle supportは、Mouse Dictionary側にデータを送信して、小窓内のコンテンツを更新してもらいます。

拡張から拡張へのデータのやりとりには、Cross-extension messagingという仕組みを利用します。

https://developer.chrome.com/extensions/messaging#external

(おおまかな仕組み図)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/106401/1d5dedd0-6fb8-645d-a449-f4c5caca8c22.png)


----

これでKaggleのiframe上でもMouse Dictionaryが反応するようになりました。

Kaggle supportをインストールするときに下記のようなことを訊かれるのは、これがどうしても必要なパーミッションであるためです。上図を見るとご理解いただけるのではないかと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106401/26288ddd-bf27-bbcd-a4c1-1da8b8711193.png)


このやり方であれば、もし仮にKaggleのページ構成が変わってしまっても、Mouse Dictionary本体には影響はなく、Kaggle supportの方だけ変更すれば追従できそうです。

## 謝辞

私はKagglerではないので、Kaggle利用者的にいい感じに動いているかの確認は、かえるるるさんにご協力いただきました。ありがとうございます。
‏