DOM Rangeを使って複数のノードを上の階層に上書きする
前回に引き続き http://upload0.dyndns.org/up/2/_/ を使い易いように改造する。
どのファイルでもいいので適当にクリックして、個別のページにいったら『ダウンロード』をクリックしてパスワードを求められるページに進む。
パスワード入力欄とボタンの部分だけ欲しい。
前回と同じように広告バナーを消すには、上の階層に移動するのが良さそう。複数のノードを扱うにはDOM Rangeが便利らしいのでそれを使ってみる。
ソースコード
var d = document.evaluate('//label[@for="download_pass"]', document, null, 7, null); var range = document.createRange(); range.setStart(d.snapshotItem(0), 0); range.setEnd(d.snapshotItem(0).nextSibling.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling, 0); var df = range.extractContents(); d.snapshotItem(0).parentNode.parentNode.replaceChild(df, d.snapshotItem(0).parentNode);
xpath一本釣り。まず基点となるlabelをxpathで補足する。次にRangeを組み立てていく。setStartとsetEndの第二引数のoffsetは今回必要がないので0。nextSiblingが並んでいるのはlabel→\n→input→\n→input→\n→inputという具合にDOMツリーを辿るため。formタグの外に置いたらpostできないので上げすぎに注意。
今回のミソはrange.extractContents()の部分。RengeはdocumentFragmentに変換しないとDOMツリー(?)に挿入することができないので、extractContents()かcloneContents()を使ってdocumentFragmentに変換する。
追記 こっちのほうがいいかな。xpathサビキ釣り。
//注意点は出力される順番を把握しておくこと。 //xpathはツリーの上から順に走査されるので今回の場合、 //divがsnapshotItem(0)、labelがsnapshotItem(1)、inputがsnapshotItem(2)となる。 var d = document.evaluate('//label[@for="download_pass"] | //input[@class="submit"] | //div[@class="input_download_pass"] ', document, null, 7, null); var range = document.createRange(); range.setStart(d.snapshotItem(1), 0); range.setEnd(d.snapshotItem(2), 0); var df = range.extractContents(); d.snapshotItem(0).parentNode.replaceChild(df, d.snapshotItem(0));
まとめ
// ==UserScript== // @name mod_index-uploader // @namespace http://d.hatena.ne.jp/Cherenkov/ // @include http://upload0.dyndns.org/up/2/_/* // ==/UserScript== //キーワードにヒットしたらハイライト var k = document.evaluate('//td[@class="name"]', document, null, 7, null); for(i=0;i<k.snapshotLength;i++){ //if(/hoge|fuga|kame|hige|cut/ig.test(k.snapshotItem(i).textContent)){ これ間違い if(/hoge|fuga|kame|hige|cut/i.test(k.snapshotItem(i).textContent)){ k.snapshotItem(i).style.backgroundColor = 'yellow'; } } //個別のファイルのページ if(/jump/.test(location.href)) { var c = document.evaluate('//a[@class="download"]', document, null, 7, null); //if(c) location.href = c.snapshotItem(0).href; //コメントアウトをはずせば自動でパスワード入力のページへ c.snapshotItem(0).parentNode.offsetParent.replaceChild(c.snapshotItem(0), c.snapshotItem(0).parentNode.parentNode.parentNode); GM_addStyle('.download { font-size:30pt }'); } //パスワード入力のページ if(/download/.test(location.href)) { var d = document.evaluate('//label[@for="download_pass"]', document, null, 7, null); var range = document.createRange(); range.setStart(d.snapshotItem(0), 0); range.setEnd(d.snapshotItem(0).nextSibling.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling, 0); var df = range.extractContents(); d.snapshotItem(0).parentNode.parentNode.replaceChild(df, d.snapshotItem(0).parentNode); document.getElementById('download_pass').focus(); GM_addStyle('#download_pass { font-size:30pt }'); }