常に最新ツイートがトップに来るようなChrome ExtensionをTypescriptで作る(執筆中)
イラっとしますね(唐突)
Twitterは無駄に流れてくるタイムラインを眺めるのが楽しいのになんでデフォルトが「ホーム」なんでしょうか。
Twitter立ち上げるたびに最新ツイートに変更しています。
DBじゃなくてCookieで持っているんですかね。
むっちゃイライラするので、自動的に最新ツイートが投稿順に流れるようにするChrome Extensionを作りましょう。
これでひな型を作ります。
Would you like more UI Features?
と聞かれるので、ここだけ注意してください。まあ全部とりあえずぶち込んでおけばいいって考えてもいいですが(私は遊びだったので全部ぶち込みました)
Content Scripts
にチェックを入れてください。
windows 10
なので yarn
を入れる必要があったりするのですが、そこはよしなに入れていきましょう。
エラーが出たら入れて、を繰り返したら特に問題なく完了しました。
とりあえずぶち込んだら、
$ yarn install
します。場合によっては npm install
でもいいんじゃないでしょうか(試していないですが…)。
そこまで時間がかからず入れ終わるはずなので
$ yarn run dev:chrome
実行!!
あとは dist/chrome
をChrome拡張としてChromeにぶち込みます。
chrome://extensions/
にアクセスして
上記画像の「パッケージ化されていない拡張機能を読み込む」から dist
以下の chrome
を読み込みます。
開発ツールからコンソールを見ると成功していればなんか出ていると思います。
app\scripts\contentscript.ts
の console.log
に対応しています。
私はけっこうここではまったんですけど、 app\scripts\contentscript.ts
を編集しても chrome://extensions/
の該当Extensionのくるっと回っている矢印で更新しないと反映されません。
なんというトラップ
さてここから app\scripts\contentscript.ts
を編集していきましょう。
潜影蛇手
window.addEventListener("load", Main); function Main():void { let event = document.createEvent( 'MouseEvents' ); setTimeout(() => { const top_tweet_label = document.querySelector('[aria-label="トップツイートがオフになります"]'); const home_tweet_label = document.querySelector('[aria-label="トップツイートがオンになります"]'); let timeline_change_star = home_tweet_label === null ? top_tweet_label : home_tweet_label; event.initEvent("click", true, true); if(timeline_change_star !== null){ timeline_change_star.dispatchEvent(event); setTimeout(() => { let button_change_timeline_change = document.querySelector('[role="menu"] [role="menuitem"]'); event.initEvent("click", true, true); if(button_change_timeline_change !== null){ button_change_timeline_change.dispatchEvent(event); } }, 500); } }, 4000);
(この段階では画面をロードした瞬間に「ホーム」と「最新ツイート」を切り替えます。) 動いているGif
解説というよりはまりどころ
- 画面ロード時と全体が表示されるタイミングが違う
=> よくあることなんですかね…。とりあえず window.addEventListener("load", Main);
ってしたらよしなに読み込んでくれると思ったのですが、実際はちょっとずらしているっぽいです。 React
の動作なのかな。
とりあえず setTimeout
で4秒後に実行にします。
だいたい3.5秒くらいで(私の環境では)ロードされました。
これはネットワークなどによって異なるため、ほんまは繰り返して成功したタイミングで!!とかやりたかったんですけど、無限ループでブラウザ落ちて(正確には閉じることすらできなくなった)だめだったので、暫定対応です。
- TypeScriptの画面ロード完了後に読み込まれるメソッドは?
window.addEventListener("load", Main);
いつも jQuery
使っていたので知らなかったです。
- タイムラインを並び順を変更するボタンをどうやって取得する?
Class
は難読化のためか、まったく規則性がなくて使えない。 id
もけっこう上にしかついていなくて、取得できない。
諦めかけていたのですが、「トップツイートがオフになります」「トップツイートがオンになります」これだけは不変であるようでした。これを取得することに
- 3を決めたがいいがどうやって取得する?
document.querySelector('[aria-label="トップツイートがオフになります"]');
いつも jQuery
使っていたので querySelector
初めて使いました(笑)
- マウスイベントをどうやって発火させる?(そもそもマウスイベントでやるべきなのか、まだ検討中です)
ここも地味にはまりました。検索かけても取得する方法で発火させる方法は全然出てこない。
document.createEvent( 'MouseEvents' );
マウスイベントを作った?上で event.initEvent("click", true, true);
クリックイベントを登録?して(すみません、残り二つの引数の意味わかっていないです。最初動かなくて適当に入れたら動きました…)、
timeline_change_star.dispatchEvent(event);
実際に発火させます。
- タイムラインを切り変えるためのボタンはどう押す?
これも地味にはまりました。 id
も class
もあてにならないので。
document.querySelector('[role="menu"] [role="menuitem"]');
こんな実装に…。
initEvent
二回する意味ある?
今検討中です。
リポジトリも置いておきますが上記ファイル以外は何の意味もないファイルです。