eludicon

去年作ろうとして iframe の仕様のせいで諦めてたやつですが、いい感じに完成しました

せっかくなので苦労の流れでも書いてみます
ながーーくなるのでダウンロードしたいだけの人は こちら



まずは最初に

この拡張機能の機能は

右クリックしてその要素を非表示か削除する

これだけです


Chrome の拡張機能では右クリックメニューを作っても、クリックしたのがどこか教えてくれません
なので、自分で右クリックした場所をページ側で保存しておいて、右クリックされたことを拡張機能側からページ側へ伝えて、ページ側で保存しておいた要素を非表示にします

これだけで 基本の要素は非表示にできます

ホントはこれで終わりだったはずなんです……



フレームが入ってくるとうまく行かなくなります
この拡張機能の主な使いみちは邪魔な広告消しになりそうなのでフレームが扱えないのは致命的です

さて、フレームの問題点ですが

フレームを右クリックしても、イベントはトップフレームで受け取れないです
対象になる要素が存在するフレームの window 内でだけイベントが起きます

右クリックイベントだけじゃなくて mousedown など多くのイベントでそうなってます

拡張機能なのでタブ内の全部のフレームで同じスクリプトを実行できるのですけど、できたからといって親フレームのこの iframe が自分っていう情報を伝えられないですから、それで解決はできません

それでも、全部のフレームで実行すればフレームの中での右クリックでも、右クリックした要素だけを消すことはできるようになりました



どうにかしてフレーム自体を消したいので、マウスカーソルを監視して iframe の上に来たらそのフレームを覚えておくようにします
クリックしたりアクティブにしたら、フレームの方にイベントが行くようになるのですが、マウスが上を通るだけだとトップフレームで受け取れます

これで右クリックメニューが選ばれたら最後にマウスが乗ったフレームを消せば OK
……なはずでした

ほとんどの場合はうまく動いていたのですが、右クリックメニューを押した瞬間のマウスの位置が別のフレームの上だとそっちが消えていました
広告だと並んでることが多いので、サイトによっては頻繁に右クリックしたのと違うのが消されそうでこれもちょっとどうにかしないとです

原因は 右クリックメニューを選んだというメッセージを受け取るより先に mouseover イベントが起きて、最後にマウスが乗ったフレームが書き換わってしまっていること
トップフレームで右クリックイベントを受け取れないので、メッセージを受け取る前の状態で固定できません



この辺りでやっぱり無理な機能なのかなー
とか思ってましたが、拡張機能の機能でフレームの場合は右クリックした URL が取得できるのを発見!

URL なので一意とは行かないのですけど、最近マウスが乗った3つ4つの要素を保存しておいて、その中から URL が一致するものを見つけて削除すれば 全く同じ広告が横に並んでない限り大丈夫なはず!

これで終わりか……と思ったらまたも問題発生しました
よくわからないけど動くページと動かないページがある…

原因が分かりづらかったですが、URL が一致しないと消さないようにしたので URL が合わない場合に消えません
URL が合わない場合というのはこんな時に起きます

フレームA → フレームB → フレームC

こんな フレームA の中に iframe でフレームB、フレームB の中に iframe でフレームC という構造です
フレームC を右クリックしたら取得する URL はフレームC のです
トップフレームのフレームA から見るとフレームC はフレームB が間にあるので、保存してあるリストにマッチすることはないです


原因がわかったところで、もう最近のフレームを保存するのはやめて、全部のフレームから URL にマッチするフレームを消すことにしました
一回目はフレームB が消えて、もう一回やるとフレームA が消えますが仕方ないので妥協です


さーてこれでかんせーい……?


えーと、うごかないね



ここでまた時間を取られましたが、拡張機能の全部のフレームで実行は本当に全部のフレームではなかったのです
広告ではそこそこ見るもので、src なしの iframe をつくってそこに DOM を作ります
その src なし iframe の中で src ありの iframe を作ります

フレームB が src なしで、フレームA から JavaScript で作られたものだった場合です
この場合は、フレームB ではスクリプトが実行されません


じゃあ無理?? って思ったのですが、 src なしで JavaScript で DOM を作ってる以上、クロスドメイン制限に引っかからずに親フレームからフレームの中を JavaScript で操作できます

つまり src がないものは、手動で親フレームの JavaScript から調べればどうにかできます

フレームC を消そうとしたときには、フレームA とフレームC でしかスクリプトが実行されませんが、フレームA でフレームB の中のフレーム一覧もチェックするようにします

とりあえずこれで完成  なはず
いろいろ試してみた分には問題なく消せました


右クリックした要素を消すなんてすっごく簡単そうですがやってみると大変な目にあいました
フレームって複雑ですねー



あとはいつもの拡張機能ならではのデバッグのやりづらさが面倒でした
ブレイクポイントを埋め込むスクリプトにつけて一時停止すると、最初に実行されたフレームでだけ停止して他のフレームでストップしてくれなかったです
「止めたいフレームだったら」の if 文を書いてそこにブレイクポイント仕込むという変な方法で対処しましたけど、やっぱり拡張機能だとデバッグまわりがあまりしっかりしてないです
原因はフレームごとに並列実行してるからなのかなー

ダウンロード

ダウンロードはここから!

elud.crx

インストール方法
→ Chromeにcrxファイルのインストール

無効化される場合 
→ Chromeで無効化されたcrxファイルを動かす