XPathとappendChildとreplaceChildを使って効率よく広告を消す

今回はSYSLABO LOADERを使いやすく改造していく。その過程で得たtipsを紹介するエントリー。
http://syslabo3.orz.hm/up144/でどれでもいいのでファイルを選んでクリックしてパスワード入力のページに飛んでください。

なにをするのか


デフォルトの状態。ファイル詳細部分とパスワード入力部分だけを残して、他の邪魔なものを消したい。


最終的にこうしたい。

仕組み

  1. XPathで3つのノードを捕獲する。「ファイル詳細」、「パスワード入力」、「引越し先」。
  2. ここがミソ。「ファイル詳細」の中に「パスワード入力」を含ませる。
  3. ひとつにまとめたものを「引越し先」に置換する。

ソースコード

var g = document.evaluate('//div[../@id="content"][child::table/@class="file"] | id("download") | id("content")', document, null, 7, null);
g.snapshotItem(1).appendChild(g.snapshotItem(2));
g.snapshotItem(0).parentNode.replaceChild(g.snapshotItem(1), g.snapshotItem(0));
  • XPathのsnapshotはツリーの順番で作られるのでsnapshotItem(0):引越し先、snapshotItem(1):ファイル詳細、snapshotItem(2):パスワード入力となる。
  • XPathの条件はそれぞれ一意になるようにすること。

感想

今までの広告削除ネタは広告に照準を合わせたものばかりだったが、今回のように必要なものだけを操作するほうが効率が良い場合がほとんど。
必要なものをひとつにまとめる箇所でDOM Rangeを使おうと考えたが選択の範囲が一続きである必要がある(たぶん)ので、点在する複数のノードを取り扱う場合はXPathで一斉捕獲してappendChildが最適だとおもう。

関連

今回の元になったエントリー。

操作したいノードが一続きになっていれば、DOM Rangeも有効。対象のノードが点在している場合は今回のようにappendChildを使うべき。


おまけ

パスワード入力のページが対象のgreasemonkey。対ファイル一覧ページとサイドバーの広告削除は割愛。

//パスワード入力ページが対象
if (/download/.test(location.href)){
  //オリジナルのファイル名でダウンロードする用(&mod系のバグ対策)
  if(!/attach|attatch/.test(location.href)) location.replace(location+'/attach');
  //パスワード入力欄とダウンロードボタンを拡大
  GM_addStyle('#download_pass {font-size: 25pt;width: 180px; }');
  GM_addStyle('#download_submit {width: 100px; }');

  var g = document.evaluate('//div[../@id="content"][child::table/@class="file"] | id("download") | id("content")', document, null, 7, null);
  g.snapshotItem(1).appendChild(g.snapshotItem(2));
  g.snapshotItem(0).parentNode.replaceChild(g.snapshotItem(1), g.snapshotItem(0));
}