Chrome拡張シリーズ。
今回は車輪の再開発モノです、いやオベンキョーと呼ぶべきか。
世の中から非常に評価されている拡張機能の一つにオートページモノがあります。
AutoPatchworkとかGoogle Auto Next Pageさんが有名。
グーグルやアマゾンの検索画面って沢山ヒットして、目的に辿りつくまで数ページめくることになったりするじゃないですか、で、それがメンドクサイと。
オートページは、後ろのページの内容を読み込んで、どんどん画面下に追加していってくれる的な動きをします。永久スクロールみたいな使用感です。
すげえなぁ、カッコいいよなぁ。
というワケで真似してみることに。今回はグーグル検索ページで実行してみます。
動作は...
・グーグルの検索ページの下部。
これの中から例えば「2」に設置してあるURLを取得する。
・Ajax(別のサイトからデータを取り寄せる機能)で、上で取得したURLを指定して「2」のページの中身をHTMLでもらう。
・帰って来たデータはページ丸ごとの長大なテキストファイルなので、そこから検索結果の部分だけトリミングする。オーヤダヤダ
・元のページの検索結果の最後にトリミングしたモノを追加する。
こんな感じ。
機能をトリガーするタイミングは、ページのプロパティを読み取れば調整できる、近いことを以前やった気がする。でも今回は面倒だからそこまでやらない。
では、詳細。
現在開いているグーグル検索ページの次のページのリンク取得
この沢山あるtdがそれぞれ1,2,3…などのボタンを表しています。
こういうしっかりしたページの要素取得って面倒、階層深くて。HTML界隈の人達も大変ですね。
次「Ajax」
あんまり使わないので、ちょっとビビッてましたが、すごくあっさりと動きました。
ただdataTypeにhtmlを指定するとクロームに怒られるんですが...一応止まらず動作しています。中身を見るのが怖いけど、console.log()してみると。
これですよ。PCがフリーズしなくて良かったですがしばらく固まりました。
次は、この文字列の中から個別の検索結果の切り取りをしないといけません。
あーユウウツ。
検索結果の部分だけトリミング
ここでだいぶ手こずりました。
さきほどの、わけのわからない文章の海に検索かけて、にらめっこして、個別の検索結果の起点となる文字列を判別。
<ここから検索結果その1が始まります>とか書いてありゃいいんですがねぇ。
実際はこれを採用 <div class="srg"><div class="g">
それからそれを閉じるタグ。
これを採用 </span></div></div></div></div><!--n--></div>
indexOf(開始タグ)で、上の文字列が文章の海の中のどこに存在するのか、トリミングの開始地点を特定します。おなじく終了地点を特定。
splice(開始地点、終了地点)を使えば、トリミングッド。検索結果が1つバラせました。
試しにページに埋め込んでみたところ動作確認が出来ましたので、もう止めようかと思いました 笑。
さて、ここからが悩みどころ。
上のindexOfは最初に見つけたものしかもって来てくれません。どうしたら効率良く、全ての検索結果の開始地点と終了地点を取得できるものかと。
正規表現で/gでマッチさせれば複数マッチできる、ということで試しましたが、なんと/gはマッチした位置が取得できないという仕様、なんででしょうね。
/gを使わずマッチさせればちゃんとindexを取得できる、でもその後はどうやって中断した地点から検索をかける?indexOfと一緒やんけ!深みにハマりました。
だから正規表現嫌い。
力技なら、文章の海から結果をトリミングしてリストに保存し、更にその結果以降の海を保存し、それをもう一度トリミングし...を繰り返せば達成できますが、いかにもブサイク。
結局、連続マッチさせつつlastIndexが調べられる正規表現オブジェクトを使う。
var regexp = /<\/span><\/div><\/div><\/div><\/div><!--n--><\/div>/g
↑これを regexp.exec(文章の海)すると最初にマッチした場所で止まり、regexp.lastIndexで位置を取り出せます。続けて.execするとさきほどの場所から先を検索してくれます。マッチしなくなるまでループさせ、最後のlastIndexを保存。
文章の海をよく見りゃ、検索結果は1つ1つトリミングしてリストに格納する必要はなさそう。検索結果同士の間に無駄なタグがないので、最初の検索結果の開始地点と、最後の検索結果の終了地点がわかれば、それをズボーンと切ってそのまま埋め込めそうです。
元のページの検索結果の最後にトリミングしたモノを追加する
document.getElement~でそれらしい箱を選んで調べ、埋め込むのに良い位置を探す。
createElementしてトリミング結果を代入、それを選んだ位置にappendChild。どや?
はい、上手くできました。
縦長になるのでスクショにおさまらなくて残念ですが、グーグルの検索結果って1ページに9件なんですが、18件表示されています。
というわけで私のブラウザ、グーグル検索では自動で18件表示してくれるようになりました。
でも人気の拡張機能はこれグーグル以外のサイトでも出来るようにしてんだよな。
どうやって次のページのリンク取得してるの? 次のページのリンクはここにまとめて置く、とかいう業界のルールでもあります? 埋め込む位置はbodyの下の方って、適当に?
よくわかんねぇ...。でも人のコードは読みたくねぇ。おしまい。