aboutsummaryrefslogtreecommitdiffstats
path: root/nextlink.js
diff options
context:
space:
mode:
authorsuVene2008-12-15 20:39:55 +0000
committersuVene2008-12-15 20:39:55 +0000
commit80edc5946395edba6f21410a2937a4b80475606f (patch)
tree21181b32ade085e69c757e64ab974c1a85ac3d5d /nextlink.js
parentc01b41bc966cec5cf63114305c26dedb5e454f68 (diff)
downloadvimperator-plugins-80edc5946395edba6f21410a2937a4b80475606f.tar.bz2
ざっくりとインデントを下げた。プラス、pageElement が取れなかった場合、@class="autopagerize_page_element" を検索するようにした。(本家仕様)
git-svn-id: http://svn.coderepos.org/share/lang/javascript/vimperator-plugins/trunk@26828 d0d07461-0603-4401-acd4-de1884942a52
Diffstat (limited to 'nextlink.js')
-rw-r--r--nextlink.js858
1 files changed, 431 insertions, 427 deletions
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 =
-<VimperatorPlugin>
- <name>nextlink</name>
- <description>mapping "[[", "]]" by AutoPagerize XPath.</description>
- <description lang="ja">AutoPagerize 用の XPath より "[[", "]]" をマッピングします。</description>
- <author mail="suvene@zeromemory.info" homepage="http://zeromemory.sblo.jp/">suVene</author>
- <version>0.2.4</version>
- <minVersion>1.2</minVersion>
- <maxVersion>2.0pre</maxVersion>
- <detail><![CDATA[
-== NEEDS LIBLARY ==
-- _libly.js(ver.0.1.9)
- @see http://coderepos.org/share/browser/lang/javascript/vimperator-plugins/trunk/_libly.js
-
-== Option ==
->||
- let g:nextlink_followlink = "true"
-||<
-と設定することにより、"[[", "]]" の動作は、カレントのタブに新しくページを読み込むようになります。
-
-== Command ==
-:nextlink:
- autocmd によって呼び出されます。
-
- ]]></detail>
-</VimperatorPlugin>;
-//}}}
-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 =
- <style type="text/css"><![CDATA[
- .vimperator-nextlink-page {
- background-color: #555;
- color: #fff;
- opacity: .85;
- padding: 10px;
- margin-top: 5px;
- margin-bottom: 5px;
- height: 1em;
- font-weight: bold;
- text-align: left;
- -moz-border-radius: 5px;
- }
- .vimperator-nextlink-page a:link {
- color: #EF6D29;
- }
- .vimperator-nextlink-page a:visited {
- color: #A50000;
- }
- ]]></style>;
- //}}}
-
- 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: <a href="' + reqUrl + '">' + cache.curPage + '</a>';
- 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 =
+<VimperatorPlugin>
+ <name>nextlink</name>
+ <description>mapping "[[", "]]" by AutoPagerize XPath.</description>
+ <description lang="ja">AutoPagerize 用の XPath より "[[", "]]" をマッピングします。</description>
+ <author mail="suvene@zeromemory.info" homepage="http://zeromemory.sblo.jp/">suVene</author>
+ <version>0.2.5</version>
+ <minVersion>1.2</minVersion>
+ <maxVersion>2.0pre</maxVersion>
+ <detail><![CDATA[
+== NEEDS LIBLARY ==
+- _libly.js(ver.0.1.9)
+ @see http://coderepos.org/share/browser/lang/javascript/vimperator-plugins/trunk/_libly.js
+
+== Option ==
+>||
+ let g:nextlink_followlink = "true"
+||<
+と設定することにより、"[[", "]]" の動作は、カレントのタブに新しくページを読み込むようになります。
+
+== Command ==
+:nextlink:
+ autocmd によって呼び出されます。
+
+ ]]></detail>
+</VimperatorPlugin>;
+//}}}
+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 =
+ <style type="text/css"><![CDATA[
+ .vimperator-nextlink-page {
+ background-color: #555;
+ color: #fff;
+ opacity: .85;
+ padding: 10px;
+ margin-top: 5px;
+ margin-bottom: 5px;
+ height: 1em;
+ font-weight: bold;
+ text-align: left;
+ -moz-border-radius: 5px;
+ }
+ .vimperator-nextlink-page a:link {
+ color: #EF6D29;
+ }
+ .vimperator-nextlink-page a:visited {
+ color: #A50000;
+ }
+ ]]></style>;
+//}}}
+
+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: <a href="' + reqUrl + '">' + cache.curPage + '</a>';
+ 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:
+