Adobe LiveDocs Incremental Search

Greasemonkey: Javadoc Incremental Search User Scriptのパッチという形で書いた。

Index: javadoc_isearch.user.js
===================================================================
--- javadoc_isearch.user.js	(リビジョン 27)
+++ javadoc_isearch.user.js	(作業コピー)
@@ -3,6 +3,7 @@
 // @namespace     http://kengo.z1.bbzone.net/
 // @description   Incremental search for Javadoc Class names.
 // @include       */allclasses-frame.html 
+// @include       http://*.adobe.com/*/all-classes.html
 // ==/UserScript==
 //
 // version 0.5
@@ -18,8 +19,14 @@
 const SEARCH_ACCESS_KEY = "s";
 const ERASE_ACCESS_KEY = "a";
 
-const XPATH_HEADING = "//font[@class='FrameHeadingFont']/b";
-const XPATH_CONTAINER = "//font[@class='FrameItemFont']";
+const XPATH_HEADING = {
+    JAVA_DOC : "//font[@class='FrameHeadingFont']/b",
+    ADOBE_DOC: "//h3[1]"
+};
+const XPATH_CONTAINER = {
+    JAVA_DOC : "//font[@class='FrameItemFont']",
+    ADOBE_DOC: "//h3[1]/following-sibling::table[1]/descendant::td",
+};
 const XPATH_MENU_LINK = "//li/a";
 
 const ICON_ERASE = "data:image/gif;base64,R0lGODlhDQANAJEDAM%2FPz%2F%2F%2F%2F93d3UpihSH5BAEAAAMALAAAAAANAA0AAAIwnCegcpcg4nIw2sRGDZYnBAWiIHJQRZbec5XXEqnrmXIupMWdZGCXlAGhJg0h7lAAADs%3D";
@@ -593,9 +600,20 @@
 }
 
 View.prototype.initContainer = function() {
-    var xpathResult = selectAnyType(XPATH_CONTAINER);
+    var xpathResult = selectAnyType(XPATH_CONTAINER.JAVA_DOC);
     var node = xpathResult.iterateNext();
     if (node == null) {
+        (function() {
+            for (var a = [], c, i = 0, e = $X(XPATH_CONTAINER.ADOBE_DOC); c = e[i++]; a.push(c.innerHTML));
+            for (var table = e[0].parentNode.parentNode, rows = table.rows; rows.length; table.deleteRow(0));
+            var cell = table.insertRow(0).insertCell(0);
+            cell.style.whiteSpace = "pre";
+            cell.innerHTML = a.join('\u000a');
+        })();
+        xpathResult = selectAnyType(XPATH_CONTAINER.ADOBE_DOC);
+        node = xpathResult.iterateNext();
+    }
+    if (node == null) {
         return false;
     }
     this.container = new Container(node);
@@ -605,8 +623,13 @@
 }
 
 View.prototype._getHeadingNode = function() {
-    var xpathResult = selectAnyType(XPATH_HEADING);
-    return xpathResult.iterateNext();
+    var xpathResult = selectAnyType(XPATH_HEADING.JAVA_DOC);
+    var node = xpathResult.iterateNext();
+    if (node == null) {
+        xpathResult = selectAnyType(XPATH_HEADING.ADOBE_DOC);
+        node = xpathResult.iterateNext();
+    }
+    return node;
 }
 
 View.prototype._createSearchField = function() {
@@ -908,6 +931,22 @@
 /*
  * utils
  */
+const ns_xhtml = 'http://www.w3.org/1999/xhtml';
+function $X(xpath, context, ns) {
+    if (!context) context = document;
+    var expr = document.createExpression(xpath, function() document.contentType === 'text/html' ? '' : ns || ns_xhtml);
+    var result = expr.evaluate(context, XPathResult.ANY_TYPE, null);
+    switch (result.resultType) {
+    case XPathResult.STRING_TYPE : return result.stringValue;
+    case XPathResult.NUMBER_TYPE : return result.numberValue;
+    case XPathResult.BOOLEAN_TYPE: return result.booleanValue;
+    case XPathResult.UNORDERED_NODE_ITERATOR_TYPE:
+        result = expr.evaluate(context, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+        for (var a = [], i = 0, l = result.snapshotLength; i < l; a.push(result.snapshotItem(i++)));
+        return a;
+    }
+}
+
 function selectAnyType(xpath) {
     return document.evaluate(xpath, document, null, 
                              XPathResult.ANY_TYPE, null);