subscldr.jsが動かなくなったのを直してみた

Firefox3.6にしてからかどうかは定かではないのですが(他に原因は思いつきませんが)、自分の環境ではsubscldr.jsが動かなくなっていました。

liberator.echoを入れまくってデバッグしたところ、XHRで取得したDocumentに対するXPathがなぜかマッチしないことが原因なようでした。XHTML用のNSResolverを作り、XPath式にxhtml prefixをつけてやると動くようになりました。

どうして元々のコードでマッチしなくなったのかは分かりません。他の方がsubscldr.jsが動かなくなったという話も見かけないので、何か自分の環境がおかしいのかもしれません。

(追記)liblyのXPath機能を使う他のプラグインは問題なく動いているので、Livedoorが渡してくるコンテンツが変わったのかもしれません。以前と比較するのが難しいですが。

とりあえずパッチ

私はCodeReposのアカウントは持っていないので、もしこれが他の方にも役に立つ修正だったらご自由に取り込んでください。

@@ -195,11 +195,11 @@ liberator.plugins.subscldr = (function() {
        feedlinks: []
     };
 
-    $LXs('id("feed_candidates")/li', htmldoc).forEach( function(item) {
-      var feedlink = $LX('./a[@class="feedlink"]', item);
-      var title = $LX('./a[@class="subscribe_list"]', item);
-      var users = $LX('./span[@class="subscriber_count"]/a', item);
-      var yet = $LX('./input[@name="feedlink"]', item);
+    $LXs('id("feed_candidates")/xhtml:li', htmldoc).forEach( function(item) {
+      var feedlink = $LX('./xhtml:a[@class="feedlink"]', item);
+      var title = $LX('./xhtml:a[@class="subscribe_list"]', item);
+      var users = $LX('./xhtml:span[@class="subscriber_count"]/xhtml:a', item);
+      var yet = $LX('./xhtml:input[@name="feedlink"]', item);
       liberator.log("input:" + feedlink.href);
       subscribeInfo.feedlinks.push([feedlink.href, (yet != null), (title ? title.textContent : '' ) + ' / ' + (users ? users.textContent :  '0 user')]);
     });
@@ -235,8 +235,27 @@ liberator.plugins.subscldr = (function() {
   }
 
   // For convenience
-  function $LXs(a,b) libly.$U.getNodesFromXPath(a,b);
-  function $LX(a,b)  libly.$U.getFirstNodeFromXPath(a,b);
+  //function $LXs(a,b) libly.$U.getNodesFromXPath(a,b);
+  //function $LX(a,b)  libly.$U.getFirstNodeFromXPath(a,b);
+
+  function nsResolver(prefix) {
+    var ns = { 'xhtml': 'http://www.w3.org/1999/xhtml' };
+    return ns[prefix] || null;
+  }
+
+  function $LXs(a, b) {
+    var ret = [];
+    var res = (b.ownerDocument || b).evaluate(a, b, nsResolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+    for (var i = 0; i < res.snapshotLength; i++) {
+      ret.push(res.snapshotItem(i));
+    }
+    return ret;
+  }
+
+  function $LX(a, b) {
+    var res = (b.ownerDocument || b).evaluate(a, b, nsResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
+    return res.singleNodeValue || null;
+  }
 
   // }}}
   return PUBLICS;