Operaでdocument.evaluateするとき名前空間がnullだとエラーになるんだったら名前空間を動的に取得するのはやめる
自己引用。
そういうわけで自分の用途では、一度 html で XPath 結果を取ってみて、空集合なら上の resolver を使うようにした。
document.evaluateと名前空間がわからない - by edvakf in hatena
これだと、名前空間がごちゃ混ぜになっている文書では正常に全ての要素を評価することができない。
どうせ HTML (名前空間無し) な要素か XHTML な要素しか取得しないんだから、こんな感じでやることにした。
function getElementsByXPath(exp) { /* exp == '//a[@href]|//input[not(@type="hidden")]|//textarea|//select|//img[@onclick]|//button' */ var exp2=exp.replace(/\/\//g,'//xhtml:'); exp = exp+'|'+exp2; function resolv(prefix){ if(prefix=='xhtml') return 'http://www.w3.org/1999/xhtml'; } var result = document.evaluate(exp, document, resolv, 7, null); var nodearray = []; for (var i = 0,len=result.snapshotLength; i < len; i++) { nodearray[nodearray.length] = result.snapshotItem(i); } return nodearray; }
と、こんなことを Vimperator の hints.js を読んでいて思いついた。hints.js ではこんな感じで XPath を作ってる。
const DEFAULT_HINTTAGS = "//*[@onclick or @onmouseover or @onmousedown or @onmouseup or @oncommand or @class='lk' or @class='s'] | " + "//input[not(@type='hidden')] | //a | //area | //iframe | //textarea | //button | //select | " + "//xhtml:*[@onclick or @onmouseover or @onmousedown or @onmouseup or @oncommand or @class='lk' or @class='s'] | " + "//xhtml:input[not(@type='hidden')] | //xhtml:a | //xhtml:area | //xhtml:iframe | //xhtml:textarea | //xhtml:button | //xhtml:select";
2回XPathを評価するよりは堅牢になったと思う。
ちなみに、今のバージョンの Hit-a-Hint では getElementsByXPath ではなく nodesOfXpath という名前になっている。特に意味はない。命名はいつも適当な方なので。
もひとつちなみに、今のバージョンでは resolv 関数がグローバル変数になってる気がする。だめだこりゃ。
あまり沢山の人に影響を与える変更ではないので Generator のほうには反映していない。
僕がいつも使っている m.twitter.com に oAutoPagerize 1.1.3を入れたときの不具合が消えるのがナイス。
更新するまでにはこれも取り込むことにしよう。
こんな些細な変更でいけるんだね。