--- autopagerize.user.js.original	2008-09-05 19:44:45.781250000 +0900
+++ autopagerize.user.js	2008-12-11 20:08:58.531250000 +0900
@@ -15,16 +15,18 @@
 // estseek autopager(http://la.ma.la/blog/diary_200601100209.htm).
 // thanks to ma.la.
 //
 // Released under the GPL license
 // http://www.gnu.org/copyleft/gpl.html
 //
 
 var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml'
+var XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace'
+var XMLNS_NAMESPACE = 'http://www.w3.org/2000/xmlns/'
 var URL = 'http://userscripts.org/scripts/show/8551'
 var VERSION = '0.0.31'
 var DEBUG = false
 var AUTO_START = true
 var CACHE_EXPIRE = 24 * 60 * 60 * 1000
 var BASE_REMAIN_HEIGHT = 400
 var FORCE_TARGET_WINDOW = true
 var USE_COUNTER = true
@@ -63,17 +65,17 @@ var MICROFORMAT = {
     pageElement:  '//*[contains(@class, "autopagerize_page_element")]',
 }
 
 var AutoPager = function(info) {
     this.pageNum = 1
     this.info = info
     this.state = AUTO_START ? 'enable' : 'disable'
     var self = this
-    var url = this.getNextURL(info.nextLink, document)
+    var url = this.getNextURL(info.nextLink, document, location.href)
 
     if ( !url ) {
         debug("getNextURL returns null.", info.nextLink)
         return
     }
     if (info.insertBefore) {
         this.insertPoint = getFirstElementByXPath(info.insertBefore)
     }
@@ -248,17 +250,17 @@ AutoPager.prototype.requestLoad = functi
 
     var t = res.responseText
     var htmlDoc = createHTMLDocumentByString(t)
     AutoPager.documentFilters.forEach(function(i) {
         i(htmlDoc, this.requestURL, this.info)
     }, this)
     try {
         var page = getElementsByXPath(this.info.pageElement, htmlDoc)
-        var url = this.getNextURL(this.info.nextLink, htmlDoc)
+        var url = this.getNextURL(this.info.nextLink, htmlDoc, this.requestURL)
     }
     catch(e){
         log(e)
         this.error()
         return
     }
 
     if (!page || page.length < 1 ) {
@@ -339,22 +341,22 @@ AutoPager.prototype.initIcon = function(
         if (this.state != 'enable') {
             background = COLOR['off']
         }
     }
     document.body.appendChild(div)
     this.icon = div
 }
 
-AutoPager.prototype.getNextURL = function(xpath, doc) {
+AutoPager.prototype.getNextURL = function(xpath, doc, baseURL) {
     var next = getFirstElementByXPath(xpath, doc)
     if (next) {
         var url = next.href || next.action || next.value
         if (!url.match(/^http:/)) {
-            url = pathToURL(url)
+            url = pathToURL(baseURL, url)
         }
         return url
     }
 }
 
 AutoPager.prototype.canHandleCrossDomainRequest = function(url) {
     if ( !supportsFinalUrl() ) {
         if (!isSameDomain(this.requestURL)) {
@@ -687,46 +689,91 @@ SITEINFO_IMPORT_URLS.forEach(function(i)
         launchAutoPager(cacheInfo[i].info)
     }
 })
 launchAutoPager([MICROFORMAT])
 return
 
 // utility functions.
 function createHTMLDocumentByString(str) {
-    var html = str.replace(/<!DOCTYPE.*?>/, '').replace(/<html.*?>/, '').replace(/<\/html>.*/, '')
-    var htmlDoc  = document.implementation.createDocument(null, 'html', null)
+    var html = str.replace(/<\?xml.*?\?>/, '').replace(/<!DOCTYPE.*?>/, '').replace(/<html.*?>/, '').replace(/<\/html>.*/, '')
+    // Use |document.lookupNamespaceURI('')| for Opera 9.5
+    var defaultNS = document.lookupNamespaceURI(null)
+    var htmlDoc   = document.implementation.createDocument(defaultNS, 'html', null)
+    if (defaultNS) {
+        htmlDoc.documentElement.setAttributeNS(XMLNS_NAMESPACE, 'xmlns', defaultNS)
+    }
     var fragment = createDocumentFragmentByString(html)
     try {
         fragment = htmlDoc.adoptNode(fragment)
     } catch(e) {
         fragment = htmlDoc.importNode(fragment, true)
     }
     htmlDoc.documentElement.appendChild(fragment)
-   return htmlDoc
+    return htmlDoc
 }
 
 function getElementsByXPath(xpath, node) {
-    var node = node || document
-    var doc = node.ownerDocument ? node.ownerDocument : node
-    var nodesSnapshot = doc.evaluate(xpath, node, null,
-        XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)
+    var nodesSnapshot = getXPathResult(xpath, node,
+        XPathResult.ORDERED_NODE_SNAPSHOT_TYPE)
     var data = []
     for (var i = 0; i < nodesSnapshot.snapshotLength; i++) {
         data.push(nodesSnapshot.snapshotItem(i))
     }
     return data
 }
 
 function getFirstElementByXPath(xpath, node) {
+    var result = getXPathResult(xpath, node,
+        XPathResult.FIRST_ORDERED_NODE_TYPE)
+    return result.singleNodeValue
+}
+
+function getXPathResult(xpath, node, resultType) {
     var node = node || document
-    var doc = node.ownerDocument ? node.ownerDocument : node
-    var result = doc.evaluate(xpath, node, null,
-        XPathResult.FIRST_ORDERED_NODE_TYPE, null)
-    return result.singleNodeValue ? result.singleNodeValue : null
+    var doc = node.ownerDocument || node
+    var resolver = doc.createNSResolver(node.documentElement || node)
+    // Use |node.lookupNamespaceURI('')| for Opera 9.5
+    var defaultNS = node.lookupNamespaceURI(null)
+    if (defaultNS) {
+        const defaultPrefix = '__default__'
+        xpath = addDefaultPrefix(xpath, defaultPrefix)
+        var defaultResolver = resolver
+        resolver = function (prefix) {
+            return (prefix == defaultPrefix)
+                ? defaultNS : defaultResolver.lookupNamespaceURI(prefix)
+        }
+    }
+    return doc.evaluate(xpath, node, resolver, resultType, null)
+}
+
+function addDefaultPrefix(xpath, prefix) {
+    const tokenPattern = /([A-Za-z_\u00c0-\ufffd][\w\-.\u00b7-\ufffd]*|\*)\s*(::?|\()?|(".*?"|'.*?'|\d+(?:\.\d*)?|\.(?:\.|\d+)?|[\)\]])|(\/\/?|!=|[<>]=?|[\(\[|,=+-])|([@$])/g
+    const TERM = 1, OPERATOR = 2, MODIFIER = 3
+    var tokenType = OPERATOR
+    prefix += ':'
+    function replacer(token, identifier, suffix, term, operator, modifier) {
+        if (suffix) {
+            tokenType =
+                (suffix == ':' || (suffix == '::' &&
+                 (identifier == 'attribute' || identifier == 'namespace')))
+                ? MODIFIER : OPERATOR
+        }
+        else if (identifier) {
+            if (tokenType == OPERATOR && identifier != '*') {
+                token = prefix + token
+            }
+            tokenType = (tokenType == TERM) ? OPERATOR : TERM
+        }
+        else {
+            tokenType = term ? TERM : operator ? OPERATOR : MODIFIER
+        }
+        return token
+    }
+    return xpath.replace(tokenPattern, replacer)
 }
 
 function createDocumentFragmentByString(str) {
     var range = document.createRange()
     range.setStartAfter(document.body)
     return range.createContextualFragment(str)
 }
 
@@ -775,18 +822,19 @@ function getElementBottom(elem) {
     return top ? (top + height) : null
 }
 
 function getScrollHeight() {
     return Math.max(document.documentElement.scrollHeight,
                                 document.body.scrollHeight)
 }
 
-function pathToURL(path) {
-    var link = document.createElement('a')
+function pathToURL(baseURL, path) {
+    var link = document.createElementNS(HTML_NAMESPACE, 'a')
+    link.setAttributeNS(XML_NAMESPACE, 'xml:base', baseURL)
     link.href = path
     return link.href
 }
 
 function isSameDomain(url) {
     return location.host == url.split('/')[2]
 }
 
