DesmosのChrome拡張を作る
Desmosをコンソールから触る方法が分かったのでChrome拡張にできると嬉しい
作りたいもの
- Desmosの数式などをテキストでimport/exportできるようにする
- Chrome拡張のアイコンをクリックするとテキストボックスとimport/exportのボタンがある
意義
- グラフの保存がローカルでできるようになる
- グラフをgit等でバージョン管理できるようになる
- 色を標準の6色以上設定できるようになる
- 画像を不可逆圧縮なしで挿入可能
- LaTeX入力をお気に入りのエディタで編集できる
- テーブルデータの取り込みができる
consoleからの実行例。
state = Calc.getState()
で現在のグラフの設定を読み込んで、Calc.setState(state)
でグラフを更新できる。
参考:
当方はJS/HTML/Chrome拡張など初心者。とりあえず
- https://qiita.com/sakaimo/items/416f36db1aa982d8d00c
- https://qiita.com/RyBB/items/32b2a7b879f21b3edefc
- https://www.tohoho-web.com/ex/chrome_extension.html
- https://original-game.com/how-to-make-chrome-extensions/
- https://yuki.world/how-to-develop-chrome-extension-basics/
などを参考に色々触ってみた。公式の開発ガイド(英語)は
chrome拡張にはv2とv3があるらしく、新しく作るならv3になるっぽい。
Desmosに関する拡張機能
-
Desmos More Greek Letters
- ギリシャ文字の入力を支援するための拡張
-
Custom colors for desmos
- 使える色を増やしたりするための拡張
-
DesModder for Desmos
- 多機能。動画撮影機能とかもあって嬉しい
Chrome拡張のソースはChrome extension source viewerを使って確認できる。
DesModderは https://github.com/DesModder/DesModder にソースコードが公開されていたが、上記で確認したコードとは異なっていた。tsをjsに変換などしてから拡張機能として登録している…?
https://www.tohoho-web.com/ex/chrome_extension.html を参考にmy-extension-a
を作成
-
popup.js
からdocument.body.style.backgroundColor
を変更できる - popupのボタンをトリガーにコードを実行できる
- console.logでデバッグ用の表示ができる
上記のconsole.log("hoge")
のところでCalc.getState()
したがCalc
が定義されてないと怒られる。
スコープが違うのは当然だと思うが、どのように分離されてるのかまだ分かっていない
https://qiita.com/k7a/items/26d7a22233ecdf48fed8 の
特に「ページ内の変数や関数にアクセスができない」というのがなかなか厄介で、要するにContent Scriptはページ上のスクリプトから隔離されたスコープで実行されているということです。
この特殊な実行環境は公式ドキュメントによるとisolated worldと呼ばれています。
但し、DOMの取得・操作は出来るため、例えばページ内で定義されている関数を実行したい場合など、Webページのスコープ内でスクリプトを実行したい場合は、以下のようにscript要素を挿入してやることで実現できます。
を参考にmy-extension-b
を作成して実行。しかし
myscript.js:3 Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' 'wasm-unsafe-eval'". Either the 'unsafe-inline' keyword, a hash ('sha256-5KUX4DuAakiviv/EBxmQrE/U2E7Uvb+4BTX2tQ24DgU='), or a nonce ('nonce-...') is required to enable inline execution.
のエラーが出てしまった。
記事が古くてv3に対応していないのも影響してそうな気がする。
現時点での理解
- Ctrl+Shift+IのConsoleで実行できたとしても、それをChrome拡張にするのは自明ではない
- 変数のスコープが紛らわしく、Consoleと同じ環境で実行するには
document.body
にinline scriptを入れる必要がある - しかし、inline scriptを許可するのはセキュリティによろしくなく、Chromeが禁止するようになった
- 方法はありそうな気がするが…どうすれば…
よく分からんが https://stackoverflow.com/questions/67439012/chrome-extension-manifest-v3-content-security-policy をベースにしてスコープの問題は解決。
manifest.json
{
"name": "My Extension C",
"description": "My Extension C",
"version": "1.0",
"manifest_version": 3,
"content_scripts": [
{
"matches": [
"https://www.desmos.com/calculator/*"
],
"run_at": "document_end",
"js": [
"inject.js"
]
}
],
"web_accessible_resources": [
{
"resources": [
"myscript.js"
],
"matches": [
"https://*/*"
]
}
]
}
inject.js
function injectCode(src) {
const script = document.createElement('script');
script.src = src;
script.onload = function() {
console.log("script injected");
this.remove();
};
document.documentElement.appendChild(script);
}
injectCode(chrome.runtime.getURL('/myscript.js'));
myscript.js
(async () => {
const sleep = (second) => new Promise(resolve => setTimeout(resolve, second * 1000))
await sleep(3)
state = Calc.getState();
console.log(state);
})()
-
web_accessible_resources
が何かはまだ分かっていない。 - 参考の回答での
"run_at": "document_start"
を"run_at": "document_end"
に置き換えている。ドキュメント読み込み終了時(?)に実行しないとCalc
が未定義になるため。 - 実行前に3秒のスリープを入れている。スリープしない場合、
Calc
が未定義の状態で実行を始めてしまう。 - sleepのコードは https://www.wakuwakubank.com/posts/695-javascript-timer-sleep/ を参考にした。
- 今後はpopup(?)のボタンを呼び出したときにコードを実行することになるので、sleepは不要になるはず。
一旦仕切り直して
を参考に進めるのが良さそう
上記のYukiさんの「【超基礎】Chrome拡張機能の作り方ハンズオン:version 3」がかなり参考になった。
popupのボタンを押してCalc.getState()
するところまではできた。(my-extension-e
)
ただし
-
myscript.js
の変数をcontent.js
に送る方法 - その逆
が分からない
上記のteratailを参考にして少し進んだ。(my-extension-f
)
-
my-extension-e
ではcontent.jsからconsoleにgetStateした結果を表示できない問題があった - これを部分的に解決して、content.js中でgetStateした結果をconsoleに送れた(気がする)。しかし
window.dispatchEvent
やwindow.addEventListener
の使い方が分かっていないために非同期処理や変数のスコープの問題を解決できていない。 -
addEventListener
をボタンを押すたびに実行するのは良くない…?
webで断片的な情報を集めるのに限界を感じたので書籍発注した
式を参照してテキストボックスへのコピーができるようになった〜🎉🎉🎉🎉🎉
元々やりたかった機能は実装できた🎉🎉🎉🎉🎉
あとは色々体裁を整えて完了かな
リポジトリはこちら↓
textareaクリック時にテキスト全体選択もできるようになった
https://into-the-program.com/javascript-input-textarea-focus-select-all-value/ が参考になった
今後はchrome webstoreに申請通すのをやっていく
Desmosとしてはオンラインでグラフを保存して欲しいはずで、テキスト形式でローカルに保存するのは運営側の思想からは外れそう。オンライン保存→共有が便利すぎるので、営業妨害(?)にはならないとは思う。
どこかに確認取らなくて良いのだろうか
広告ブロック拡張が野放しになってるくらいだから開発ルールとしてはあまり気にしなくて良さそう。Desmosが好きなので、運営側に迷惑かけたくない気持ちの方が強い
- https://tech.manafukurou.com/article/chrome-develop-2/
- https://qiita.com/sasao3/items/0606b67da01948ae58b7
などを参考にChrome拡張の申請を進めた。
プライバシーへの取り組みの書き方が以下で良かったのか謎
とりあえず審査待ちになった
欧州経済領域のルールが全然分からない…。
- 市場(?)が金銭のやりとりを指すならトレーダーには該当しなさそう
- 技術的な目的で活動しているならトレーダーには該当しそう
- そもそもChrome Web StoreにDevelopperとして登録しているなら技術的な目的が包含されるのは当然では?
後から変更可能で、トレーダーを選択した場合は住所などを追加で設定する必要があったので、一旦は非トレーダーとして申告した
Chrome Web Storeで公開されてた🥳🥳🥳🥳🥳
目的は全て果たしたのでこれにてスクラップをクローズします。上記のmy-extension-*
は私のprivate repoに置いていますが、公開する意味がなさそうなのでprivateのままにしておきます。コードが気になる方は https://github.com/hyrodium/DesmosTextIO をご覧ください。