From 80edc5946395edba6f21410a2937a4b80475606f Mon Sep 17 00:00:00 2001 From: suVene Date: Mon, 15 Dec 2008 20:39:55 +0000 Subject: ざっくりとインデントを下げた。プラス、pageElement が取れなかった場合、@class="autopagerize_page_element" を検索するようにした。(本家仕様) git-svn-id: http://svn.coderepos.org/share/lang/javascript/vimperator-plugins/trunk@26828 d0d07461-0603-4401-acd4-de1884942a52 --- nextlink.js | 858 ++++++++++++++++++++++++++++++------------------------------ 1 file changed, 431 insertions(+), 427 deletions(-) (limited to 'nextlink.js') diff --git a/nextlink.js b/nextlink.js index d2ed69e..01e0119 100644 --- a/nextlink.js +++ b/nextlink.js @@ -1,427 +1,431 @@ -// PLUGIN_INFO//{{{ -var PLUGIN_INFO = - - nextlink - mapping "[[", "]]" by AutoPagerize XPath. - AutoPagerize 用の XPath より "[[", "]]" をマッピングします。 - suVene - 0.2.4 - 1.2 - 2.0pre - || - let g:nextlink_followlink = "true" -||< -と設定することにより、"[[", "]]" の動作は、カレントのタブに新しくページを読み込むようになります。 - -== Command == -:nextlink: - autocmd によって呼び出されます。 - - ]]> -; -//}}} -liberator.plugins.nextlink = (function() { - // initialize //{{{ - if (!liberator.plugins.libly) { - liberator.log('nextlink: needs _libly.js'); - return; - } - - var libly = liberator.plugins.libly; - var $U = libly.$U; - var logger = $U.getLogger('nextlink'); - - var isFollowLink = typeof liberator.globalVariables.nextlink_followlink == 'undefined' ? - false : $U.eval(liberator.globalVariables.nextlink_followlink); - var pageNaviCss = - ; - //}}} - - var NextLink = function() {//{{{ - this.initialize.apply(this, arguments); - }; - NextLink.prototype = { - initialize: function(pager) { - - this.WEDATA_AUTOPAGERIZE = 'http://wedata.net/databases/AutoPagerize/items.json'; - this.initialized = false; - this.isCurOriginalMap = true; - this.siteinfo = []; - this.cache = {}; // {url: {xpath: xpath, next: element, prev: url}} or null - this.pager = pager; - this.browserModes = config.browserModes || [modes.NORMAL, modes.VISUAL]; - this.is2_0later = config.autocommands.some(function ([k, v]) k == 'DOMLoad'); // toriaezu - - var req = new libly.Request(this.WEDATA_AUTOPAGERIZE); - req.addEventListener('onSuccess', $U.bind(this, - function(res) { - var json = $U.evalJson(res.responseText); - if (!json) return; - this.siteinfo = json.map(function(item) item.data) - .sort(function(a, b) b.url.length - a.url.length); // sort url.length desc - this.initialized = true; - } - )); - req.get(); - // for debug - /* - this.initialized = true; - this.siteinfo = [ - { - url: '^https?://(?:192\\.168(?:\\.\\d+){2}|localhost)(?::\\d+)?/', - nextLink: 'id("next")', - pageElement: '//*' - } - ]; - */ - - commands.addUserCommand(['nextlink'], 'map ]] by AutoPagerize XPath.', - $U.bind(this, function(args) { this.handler(args); }), null, true - ); - var loadEvent = autocommands['DOMLoad'] || 'PageLoad'; // for 1.2 - liberator.execute(':autocmd! ' + (this.is2_0later ? 'DOMLoad' : 'PageLoad') + ' .* :nextlink onLoad'); - liberator.execute(':autocmd! LocationChange .* :nextlink onLocationChange'); - }, - handler: function(args) { - event = args.string || args; - this[event](buffer.URL); - commandline.echo(''); - }, - onLoad: function(url) { - if (!this.initialized) return; - if (this.cache[url] && - this.cache[url].hasOwnProperty('xpath')) { - this.cache[url].doc = window.content.document; - this.onLocationChange(url, true); - return; - } - - for (let i = 0, len = this.siteinfo.length; i < len; i++) { - if (url.match(this.siteinfo[i].url) && this.siteinfo[i].url != '^https?://.') { - window.content.addEventListener('unload', $U.bind(this, - function() { this.cache[url] = null; }), false); - this.setCache(url, - ['doc', 'xpath', 'siteinfo'], - [window.content.document, this.siteinfo[i].nextLink, this.siteinfo[i]] - ); - this.onLocationChange(url, true); - return; - } - } - this.setCache(url, ['doc', 'xpath', 'prev', 'next'], [null, null, null, null]); - }, - onLocationChange: function(url, isCallerLoaded) { - - if (!this.initialized || - !this.cache[url] || - !this.cache[url].hasOwnProperty('xpath')) return; - - if (this.cache[url]['xpath'] == null) { - this.restorOrginalMap(); - return; - } - - this.pager.onLocationChange(this, url, isCallerLoaded); - this.customizeMap(this, url); - this.isCurOriginalMap = false; - }, - customizeMap: function(context, url) { - - var cache = this.cache[url]; - var prev = cache.prev; - var next = cache.next; - - if (!prev) - this.removeMap('[['); - - if (!next) - this.removeMap(']]'); - - this.pager.customizeMap(context, url, prev, next); - }, - restorOrginalMap: function() { - - if (this.isCurOriginalMap) return; - this.removeMap('[['); - this.removeMap(']]'); - this.isCurOriginalMap = true; - }, - setCache: function(key, subKeys, values) { - if (!this.cache[key]) this.cache[key] = {}; - values = [].concat(values); - [].concat(subKeys).forEach($U.bind(this, function(subKey, i) { - this.cache[key][subKey] = values[i]; - })); - }, - removeMap: function(cmd) { - try { - if (mappings.hasMap(this.browserModes, cmd)) { - mappings.remove(this.browserModes, cmd); - } - return true; - } catch (e) { - return false; - } - } - };//}}} - - var Autopager = function() {};//{{{ - Autopager.prototype = { - onLocationChange: function(context, url, isCallerLoaded) { - - var cache = context.cache[url]; - var doc = cache.doc; - var elems = cache.next; - var elem; - - if (isCallerLoaded) { - let insertPoint, lastPageElement; - - if (cache.insertBefore) - insertPoint = $U.getNodesFromXPath(cache.siteinfo.insertBefore, doc); - - if (!insertPoint) - lastPageElement = $U.getNodesFromXPath(cache.siteinfo.pageElement, doc).pop(); - if (lastPageElement) - insertPoint = lastPageElement.nextSibling || - lastPageElement.parentNode.appendChild(doc.createTextNode(' ')); - - if (context.is2_0later) { - let css = $U.xmlToDom(pageNaviCss, doc); - let node = doc.importNode(css, true); - doc.body.insertBefore(node, doc.body.firstChild); - //doc.body.appendChild(css); - } - - $U.getNodesFromXPath(cache.xpath, doc, function(item) elem = item, this); - - context.setCache(url, - ['prev', 'next', 'curPage', 'insertPoint', 'terminate', 'lastReqUrl', 'loadedURLs', 'mark'], - [[], [elem], 1, insertPoint, 0, null, {}, []] - ); - } - }, - customizeMap: function(context, url, prev, next) { - - var cache = context.cache[url]; - var doc = cache.doc; - - mappings.addUserMap(context.browserModes, ['[['], 'customize by nextlink.js', - $U.bind(this, function(count) { - if (cache.curPage == 1) { - return; - } else if (--cache.curPage == 1) { - window.content.scrollTo(0, 0); - } else { - this.focusPagenavi(context, url, cache.curPage); - } - }), - { flags: Mappings.flags.COUNT }); - - mappings.addUserMap(context.browserModes, [']]'], 'customize by nextlink.js', - $U.bind(this, function(count) { - var reqUrl, lastReqUrl; - reqUrl = $U.pathToURL(cache.next[cache.curPage - 1], doc); - lastReqUrl = cache.lastReqUrl; - - if (cache.isLoading) { - logger.echo('loading now...'); - return; - } - - if (!reqUrl || cache.curPage == cache.terminate) { - logger.echo('end of pages.'); - return; - } - if (cache.loadedURLs[reqUrl]) { - this.focusPagenavi(context, url, ++cache.curPage); - return; - } - context.setCache(url, ['lastReqUrl', 'isLoading'], [reqUrl, true]); - var req = new libly.Request( - reqUrl, null, - { asynchronous: true, encoding: doc.characterSet, - context: context, url: url } - ); - req.addEventListener('onSuccess', $U.bind(this, this.onSuccess)); - req.addEventListener('onFailure', $U.bind(this, this.onFailure)); - req.addEventListener('onException', $U.bind(this, this.onFailure)); - req.get(); - }), - { flags: Mappings.flags.COUNT } - ); - }, - onSuccess: function(res) { - - var context = res.req.options.context; - var url = res.req.options.url; - var cache = context.cache[url]; - var doc = cache.doc; - var page = res.getHTMLDocument(cache.siteinfo.pageElement); - var htmlDoc = res.doc; - var prev = cache.next[cache.curPage]; - var next = $U.getNodesFromXPath(cache.xpath, htmlDoc); - - cache.isLoading = false; - cache.loadedURLs[res.req.url] = true; - - if (!page || page.length < 1) { - context.setCache(url, 'terminate', cache.curPage); - return; - } - - cache.curPage++; - if (next && next.length) { - cache.prev.push(prev); - cache.next.push(next[0]); - } else { - context.setCache(url, 'terminate', cache.curPage); - } - - this.addPage(context, htmlDoc, url, page, res.req.url); - this.focusPagenavi(context, url, cache.curPage); - }, - addPage: function(context, doc, url, page, reqUrl) { - - var cache = context.cache[url]; - var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml'; - //var hr = doc.createElementNS(HTML_NAMESPACE, 'hr'); - var p = doc.createElementNS(HTML_NAMESPACE, 'p'); - var tagName; - - if (page[0] && page[0].tagName) - tagName = page[0].tagName.toLowerCase(); - - if (tagName == 'tr') { - let insertParent = cache.insertPoint.parentNode; - let colNodes = getElementsByXPath('child::tr[1]/child::*[self::td or self::th]', insertParent); - - let colums = 0; - for (let i = 0, l = colNodes.length; i < l; i++) { - let col = colNodes[i].getAttribute('colspan'); - colums += parseInt(col, 10) || 1; - } - let td = doc.createElement('td'); - // td.appendChild(hr); - td.appendChild(p); - let tr = doc.createElement('tr'); - td.setAttribute('colspan', colums); - tr.appendChild(td); - insertParent.insertBefore(tr, cache.insertPoint); - } else if (tagName == 'li') { - let li = doc.createElementNS(HTML_NAMESPACE, 'li'); - cache.insertPoint.parentNode.insertBefore(li, cache.insertPoint); - li.appendChild(p); - } else { - //cache.insertPoint.parentNode.insertBefore(hr, cache.insertPoint); - cache.insertPoint.parentNode.insertBefore(p, cache.insertPoint); - } - - p.id = 'vimperator-nextlink-' + cache.curPage; - p.innerHTML = 'page: ' + cache.curPage + ''; - p.className = 'vimperator-nextlink-page'; - cache.mark.push(p); - - return page.map(function(elem) { - var pe = doc.importNode(elem, true); - cache.insertPoint.parentNode.insertBefore(pe, cache.insertPoint); - return pe; - }); - }, - onFailure: function(res) { - logger.log('onFailure'); - var context = res.req.options.context; - var url = res.req.options.url; - var cache = context.cache[url]; - cache.isLoading = false; - logger.echoerr('nextlink: loading failed. ' + '[' + res.status + ']' + res.statusText + ' > ' + res.req.url); - res.req.options.context.setCache(res.req.options.url, 'terminate', cache.curPage); - }, - focusPagenavi: function(context, url, page) { - var elem, p; - try { - elem = context.cache[url].mark[page - 2]; - p = $U.getElementPosition(elem); - window.content.scrollTo(0, p.top); - } catch (e) { - logger.log('focusPagenavi: err ' + page + ' ' + e); - } - } - };//}}} - - var FollowLink = function() {};//{{{ - FollowLink.prototype = { - onLocationChange: function(context, url, isCallerLoaded) { - - var cache = context.cache[url]; - var doc = cache.doc; - var elem; - - //var matches = buffer.evaluateXPath(this.cache[url]); - //for each (let match in matches) elem = match; - $U.getNodesFromXPath(cache.xpath, doc, function(item) elem = item, this); - - var nextURL = $U.pathToURL(elem, doc); - var xpath = ['a', 'link'].map(function(e) - '//' + e + '[translate(normalize-space(@rel), "PREV", "prev")="prev"]') - .join(' | '); - var prev = $U.getNodesFromXPath(xpath, doc); - if (prev.length) - context.setCache(url, 'prev', prev[0]); - context.setCache(nextURL, 'prev', url); - context.setCache(url, 'next', elem); - }, - customizeMap: function(context, url, prev, next) { - - var cache = context.cache[url]; - var doc = cache.doc; - - if (prev) - mappings.addUserMap(context.browserModes, ['[['], 'customize by nextlink.js', - function(count) { - if (prev.href) { - buffer.followLink(prev, liberator.CURRENT_TAB); - } else { - liberator.open(prev, liberator.CURRENT_TAB); - } - }, - { flags: Mappings.flags.COUNT }); - - if (next) - mappings.addUserMap(context.browserModes, [']]'], 'customize by nextlink.js', - function(count) { buffer.followLink(next, liberator.CURRENT_TAB); }, - { flags: Mappings.flags.COUNT }); - } - };//}}} - - var instance = new NextLink((isFollowLink ? new FollowLink() : new Autopager())); - return instance; - -})(); -// vim: set fdm=marker sw=4 ts=4 sts=0 et: - +// PLUGIN_INFO//{{{ +var PLUGIN_INFO = + + nextlink + mapping "[[", "]]" by AutoPagerize XPath. + AutoPagerize 用の XPath より "[[", "]]" をマッピングします。 + suVene + 0.2.5 + 1.2 + 2.0pre + || + let g:nextlink_followlink = "true" +||< +と設定することにより、"[[", "]]" の動作は、カレントのタブに新しくページを読み込むようになります。 + +== Command == +:nextlink: + autocmd によって呼び出されます。 + + ]]> +; +//}}} +liberator.plugins.nextlink = (function() { + +// initialize //{{{ +if (!liberator.plugins.libly) { + liberator.log('nextlink: needs _libly.js'); + return; +} + +var libly = liberator.plugins.libly; +var $U = libly.$U; +var logger = $U.getLogger('nextlink'); + +var isFollowLink = typeof liberator.globalVariables.nextlink_followlink == 'undefined' ? + false : $U.eval(liberator.globalVariables.nextlink_followlink); +var pageNaviCss = + ; +//}}} + +var NextLink = function() {//{{{ + this.initialize.apply(this, arguments); +}; +NextLink.prototype = { + initialize: function(pager) { + + this.WEDATA_AUTOPAGERIZE = 'http://wedata.net/databases/AutoPagerize/items.json'; + this.initialized = false; + this.isCurOriginalMap = true; + this.siteinfo = []; + this.cache = {}; // {url: {xpath: xpath, next: element, prev: url}} or null + this.pager = pager; + this.browserModes = config.browserModes || [modes.NORMAL, modes.VISUAL]; + this.is2_0later = config.autocommands.some(function ([k, v]) k == 'DOMLoad'); // toriaezu + + var req = new libly.Request(this.WEDATA_AUTOPAGERIZE); + req.addEventListener('onSuccess', $U.bind(this, + function(res) { + var json = $U.evalJson(res.responseText); + if (!json) return; + this.siteinfo = json.map(function(item) item.data) + .sort(function(a, b) b.url.length - a.url.length); // sort url.length desc + this.initialized = true; + } + )); + req.get(); + // for debug + /* + this.initialized = true; + this.siteinfo = [ + { + url: '^https?://(?:192\\.168(?:\\.\\d+){2}|localhost)(?::\\d+)?/', + nextLink: 'id("next")', + pageElement: '//*' + } + ]; + */ + + commands.addUserCommand(['nextlink'], 'map ]] by AutoPagerize XPath.', + $U.bind(this, function(args) { this.handler(args); }), null, true + ); + var loadEvent = autocommands['DOMLoad'] || 'PageLoad'; // for 1.2 + liberator.execute(':autocmd! ' + (this.is2_0later ? 'DOMLoad' : 'PageLoad') + ' .* :nextlink onLoad'); + liberator.execute(':autocmd! LocationChange .* :nextlink onLocationChange'); + }, + handler: function(args) { + event = args.string || args; + this[event](buffer.URL); + commandline.echo(''); + }, + onLoad: function(url) { + if (!this.initialized) return; + if (this.cache[url] && + this.cache[url].hasOwnProperty('xpath')) { + this.cache[url].doc = window.content.document; + this.onLocationChange(url, true); + return; + } + + for (let i = 0, len = this.siteinfo.length; i < len; i++) { + if (url.match(this.siteinfo[i].url) && this.siteinfo[i].url != '^https?://.') { + window.content.addEventListener('unload', $U.bind(this, + function() { this.cache[url] = null; }), false); + this.setCache(url, + ['doc', 'xpath', 'siteinfo'], + [window.content.document, this.siteinfo[i].nextLink, this.siteinfo[i]] + ); + this.onLocationChange(url, true); + return; + } + } + this.setCache(url, ['doc', 'xpath', 'prev', 'next'], [null, null, null, null]); + }, + onLocationChange: function(url, isCallerLoaded) { + + if (!this.initialized || + !this.cache[url] || + !this.cache[url].hasOwnProperty('xpath')) return; + + if (this.cache[url]['xpath'] == null) { + this.restorOrginalMap(); + return; + } + + this.pager.onLocationChange(this, url, isCallerLoaded); + this.customizeMap(this, url); + this.isCurOriginalMap = false; + }, + customizeMap: function(context, url) { + + var cache = this.cache[url]; + var prev = cache.prev; + var next = cache.next; + + if (!prev) + this.removeMap('[['); + + if (!next) + this.removeMap(']]'); + + this.pager.customizeMap(context, url, prev, next); + }, + restorOrginalMap: function() { + + if (this.isCurOriginalMap) return; + this.removeMap('[['); + this.removeMap(']]'); + this.isCurOriginalMap = true; + }, + setCache: function(key, subKeys, values) { + if (!this.cache[key]) this.cache[key] = {}; + values = [].concat(values); + [].concat(subKeys).forEach($U.bind(this, function(subKey, i) { + this.cache[key][subKey] = values[i]; + })); + }, + removeMap: function(cmd) { + try { + if (mappings.hasMap(this.browserModes, cmd)) { + mappings.remove(this.browserModes, cmd); + } + return true; + } catch (e) { + return false; + } + } +};//}}} + +var Autopager = function() {};//{{{ +Autopager.prototype = { + onLocationChange: function(context, url, isCallerLoaded) { + + var cache = context.cache[url]; + var doc = cache.doc; + var elems = cache.next; + var elem; + + if (isCallerLoaded) { + let insertPoint, lastPageElement; + + if (cache.insertBefore) + insertPoint = $U.getNodesFromXPath(cache.siteinfo.insertBefore, doc); + + if (!insertPoint) + lastPageElement = $U.getNodesFromXPath(cache.siteinfo.pageElement, doc).pop(); + if (lastPageElement) + insertPoint = lastPageElement.nextSibling || + lastPageElement.parentNode.appendChild(doc.createTextNode(' ')); + + if (context.is2_0later) { + let css = $U.xmlToDom(pageNaviCss, doc); + let node = doc.importNode(css, true); + doc.body.insertBefore(node, doc.body.firstChild); + //doc.body.appendChild(css); + } + + $U.getNodesFromXPath(cache.xpath, doc, function(item) elem = item, this); + + context.setCache(url, + ['prev', 'next', 'curPage', 'insertPoint', 'terminate', 'lastReqUrl', 'loadedURLs', 'mark'], + [[], [elem], 1, insertPoint, 0, null, {}, []] + ); + } + }, + customizeMap: function(context, url, prev, next) { + + var cache = context.cache[url]; + var doc = cache.doc; + + mappings.addUserMap(context.browserModes, ['[['], 'customize by nextlink.js', + $U.bind(this, function(count) { + if (cache.curPage == 1) { + return; + } else if (--cache.curPage == 1) { + window.content.scrollTo(0, 0); + } else { + this.focusPagenavi(context, url, cache.curPage); + } + }), + { flags: Mappings.flags.COUNT }); + + mappings.addUserMap(context.browserModes, [']]'], 'customize by nextlink.js', + $U.bind(this, function(count) { + var reqUrl, lastReqUrl; + reqUrl = $U.pathToURL(cache.next[cache.curPage - 1], doc); + lastReqUrl = cache.lastReqUrl; + + if (cache.isLoading) { + logger.echo('loading now...'); + return; + } + + if (!reqUrl || cache.curPage == cache.terminate) { + logger.echo('end of pages.'); + return; + } + if (cache.loadedURLs[reqUrl]) { + this.focusPagenavi(context, url, ++cache.curPage); + return; + } + context.setCache(url, ['lastReqUrl', 'isLoading'], [reqUrl, true]); + var req = new libly.Request( + reqUrl, null, + { asynchronous: true, encoding: doc.characterSet, + context: context, url: url } + ); + req.addEventListener('onSuccess', $U.bind(this, this.onSuccess)); + req.addEventListener('onFailure', $U.bind(this, this.onFailure)); + req.addEventListener('onException', $U.bind(this, this.onFailure)); + req.get(); + }), + { flags: Mappings.flags.COUNT } + ); + }, + onSuccess: function(res) { + + var context = res.req.options.context; + var url = res.req.options.url; + var cache = context.cache[url]; + var doc = cache.doc; + var page = res.getHTMLDocument(cache.siteinfo.pageElement); + var htmlDoc = res.doc; + var prev = cache.next[cache.curPage]; + var next = $U.getNodesFromXPath(cache.xpath, htmlDoc); + + cache.isLoading = false; + cache.loadedURLs[res.req.url] = true; + + if (!page || page.length < 1) + page = res.getHTMLDocument('//*[contains(@class, "autopagerize_page_element")]'); + + if (!page || page.length < 1) { + context.setCache(url, 'terminate', cache.curPage); + return; + } + + cache.curPage++; + if (next && next.length) { + cache.prev.push(prev); + cache.next.push(next[0]); + } else { + context.setCache(url, 'terminate', cache.curPage); + } + + this.addPage(context, htmlDoc, url, page, res.req.url); + this.focusPagenavi(context, url, cache.curPage); + }, + addPage: function(context, doc, url, page, reqUrl) { + + var cache = context.cache[url]; + var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml'; + //var hr = doc.createElementNS(HTML_NAMESPACE, 'hr'); + var p = doc.createElementNS(HTML_NAMESPACE, 'p'); + var tagName; + + if (page[0] && page[0].tagName) + tagName = page[0].tagName.toLowerCase(); + + if (tagName == 'tr') { + let insertParent = cache.insertPoint.parentNode; + let colNodes = getElementsByXPath('child::tr[1]/child::*[self::td or self::th]', insertParent); + + let colums = 0; + for (let i = 0, l = colNodes.length; i < l; i++) { + let col = colNodes[i].getAttribute('colspan'); + colums += parseInt(col, 10) || 1; + } + let td = doc.createElement('td'); + // td.appendChild(hr); + td.appendChild(p); + let tr = doc.createElement('tr'); + td.setAttribute('colspan', colums); + tr.appendChild(td); + insertParent.insertBefore(tr, cache.insertPoint); + } else if (tagName == 'li') { + let li = doc.createElementNS(HTML_NAMESPACE, 'li'); + cache.insertPoint.parentNode.insertBefore(li, cache.insertPoint); + li.appendChild(p); + } else { + //cache.insertPoint.parentNode.insertBefore(hr, cache.insertPoint); + cache.insertPoint.parentNode.insertBefore(p, cache.insertPoint); + } + + p.id = 'vimperator-nextlink-' + cache.curPage; + p.innerHTML = 'page: ' + cache.curPage + ''; + p.className = 'vimperator-nextlink-page'; + cache.mark.push(p); + + return page.map(function(elem) { + var pe = doc.importNode(elem, true); + cache.insertPoint.parentNode.insertBefore(pe, cache.insertPoint); + return pe; + }); + }, + onFailure: function(res) { + logger.log('onFailure'); + var context = res.req.options.context; + var url = res.req.options.url; + var cache = context.cache[url]; + cache.isLoading = false; + logger.echoerr('nextlink: loading failed. ' + '[' + res.status + ']' + res.statusText + ' > ' + res.req.url); + res.req.options.context.setCache(res.req.options.url, 'terminate', cache.curPage); + }, + focusPagenavi: function(context, url, page) { + var elem, p; + try { + elem = context.cache[url].mark[page - 2]; + p = $U.getElementPosition(elem); + window.content.scrollTo(0, p.top); + } catch (e) { + logger.log('focusPagenavi: err ' + page + ' ' + e); + } + } +};//}}} + +var FollowLink = function() {};//{{{ +FollowLink.prototype = { + onLocationChange: function(context, url, isCallerLoaded) { + + var cache = context.cache[url]; + var doc = cache.doc; + var elem; + + //var matches = buffer.evaluateXPath(this.cache[url]); + //for each (let match in matches) elem = match; + $U.getNodesFromXPath(cache.xpath, doc, function(item) elem = item, this); + + var nextURL = $U.pathToURL(elem, doc); + var xpath = ['a', 'link'].map(function(e) + '//' + e + '[translate(normalize-space(@rel), "PREV", "prev")="prev"]') + .join(' | '); + var prev = $U.getNodesFromXPath(xpath, doc); + if (prev.length) + context.setCache(url, 'prev', prev[0]); + context.setCache(nextURL, 'prev', url); + context.setCache(url, 'next', elem); + }, + customizeMap: function(context, url, prev, next) { + + var cache = context.cache[url]; + var doc = cache.doc; + + if (prev) + mappings.addUserMap(context.browserModes, ['[['], 'customize by nextlink.js', + function(count) { + if (prev.href) { + buffer.followLink(prev, liberator.CURRENT_TAB); + } else { + liberator.open(prev, liberator.CURRENT_TAB); + } + }, + { flags: Mappings.flags.COUNT }); + + if (next) + mappings.addUserMap(context.browserModes, [']]'], 'customize by nextlink.js', + function(count) { buffer.followLink(next, liberator.CURRENT_TAB); }, + { flags: Mappings.flags.COUNT }); + } +};//}}} + +var instance = new NextLink((isFollowLink ? new FollowLink() : new Autopager())); +return instance; + +})(); +// vim: set fdm=marker sw=4 ts=4 sts=0 et: + -- cgit v1.2.3