Created
June 8, 2010 18:09
-
-
Save edvakf/430414 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name oAutoPagerize | |
// @namespace http://ss-o.net/ | |
// @description loading next page and inserting into current page. oAutoPagerize supports for Opera 9.5+, GreaseKit(Safari/WebKit) | |
// @version 1.5.2 | |
// @include http://* | |
// @include https://* | |
// @exclude https://mail.google.com/* | |
// @exclude http://b.hatena.ne.jp/* | |
// ==/UserScript== | |
// | |
// author: os0x( http://d.hatena.ne.jp/os0x/ ) | |
// | |
// this script based on | |
// AutoPagerize_opera ( http://d.hatena.ne.jp/gnarl/20070603/1180820465 id:gnarl) and | |
// AutoPagerize ( http://userscripts.org/scripts/show/8551 id:swdyh) and | |
// GoogleAutoPager ( http://la.ma.la/blog/diary_200506231749.htm ) and | |
// estseek autopager ( http://la.ma.la/blog/diary_200601100209.htm ). | |
// thanks to ma.la. | |
// | |
// Released under the GPLv3 | |
// http://www.gnu.org/copyleft/gpl.html | |
// | |
// UPDATE INFO (Only Japanese) http://d.hatena.ne.jp/os0x/searchdiary?word=%2a%5boAutoPagerize%5d | |
// | |
(function _oAutoPagerize(window,loaded){ | |
var oAutoPagerize = _oAutoPagerize; | |
var Set = window.AutoPagerizeSettings || { | |
TOP_SITEINFO:[] | |
,BOTTOM_SITEINFO:[] | |
}; | |
var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml'; | |
var SITEINFO_SERVER = Set.SITEINFO_SERVER ? | |
Set.SITEINFO_SERVER.replace('%url',encodeURIComponent(location.href)) : | |
'http://ss-o.net/json/wedataAutoPagerizeSITEINFO.js'; | |
Set.DISABLE_SITE = Set.DISABLE_SITE || []; | |
if (window.AutoPagerizeWedataSiteinfo) { | |
var SITEINFO = window.AutoPagerizeWedataSiteinfo; | |
} else if (window.name !== 'oAutoPagerizeRequest') { | |
if (Set.DISABLE_IFRAME && window.parent !== window) return; | |
insertSITEINFO(); | |
} | |
var isSafari3 = window.getMatchedCSSRules && !window.postMessage; | |
window.AutoPagerizeSettings = null; | |
window.AutoPagerizeWedataSiteinfo = null; | |
// disable site set | |
var disable = Set.DISABLE_SITE.concat([ | |
'pagead\\d\\.googlesyndication\\.com/pagead/ads' | |
//,'' | |
]); | |
var naviType = Set.naviType || 'number'; // 'link' or 'number'; | |
var DebugMode = Set.DebugMode || false; | |
var URL = 'http://d.hatena.ne.jp/os0x/searchdiary?word=%2a%5boAutoPagerize%5d'; | |
var UPDATE_URL = window.opera ? 'http://ss-o.net/userjs/0AutoPagerize.SITEINFO.js' : 'http://ss-o.net/userjs/0AutoPagerize.SITEINFO.user.js'; | |
var VERSION = '1.5.2'; | |
var AUTO_START = Set.AUTO_START !== false; | |
//var CACHE_EXPIRE = 24 * 60 * 60 * 1000; | |
var BASE_REMAIN_HEIGHT = Set.BASE_REMAIN_HEIGHT || 400; | |
var FORCE_TARGET_WINDOW = Set.FORCE_TARGET_WINDOW !== false; | |
var TARGET_WINDOW_NAME = Set.TARGET_WINDOW_NAME || '_blank'; | |
var DISABLE_IFRAME = Set.DISABLE_IFRAME || false; | |
var HISTORY_MODE_FAST = Set.HISTORY_MODE_FAST || false; | |
var COLOR = { | |
on : '#00ff00', | |
off : '#cccccc', | |
loading : '#00ffff', | |
terminated : '#0000ff', | |
error : '#ff00ff' | |
}; | |
var ICON_SIZE = Set.ICON_SIZE || 10; | |
if (Set.COLOR) (function(c){ | |
for (var i in c) { | |
COLOR[i] = c[i]; | |
} | |
})(Set.COLOR); | |
var MICROFORMATs = [ | |
{ | |
url : '^https?://.' | |
,nextLink : '//a[@rel="next"] | //link[@rel="next"]' | |
,insertBefore : '//*[contains(concat(" ",@class," "), " autopagerize_insert_before ")]' | |
,pageElement : '//*[contains(concat(" ",@class," "), " autopagerize_page_element ")]' | |
} | |
,{ | |
url : '^https?://.' | |
,nextLink : '//link[@rel="next"] | //a[contains(concat(" ",@rel," "), " next ")] | //a[contains(concat(" ",@class," "), " next ")]' | |
,pageElement : '//*[contains(concat(" ",@class," "), " hfeed ") or contains(concat(" ",@class," "), " xfolkentry ")]' | |
} | |
]; | |
var useIframe = false; | |
var locationHref = location.href; | |
// check disable site | |
if (disable.some(function(ads) { | |
return new RegExp(ads).test(locationHref); | |
})) return; | |
var TOP_SITEINFO = Set.TOP_SITEINFO.concat([ | |
/* | |
{ | |
url: 'https?://(?:explore\\.)?twitter\\.com/' | |
,nextLink: '//div[@class="pagination"]/a[last()]' | |
,incremental: { | |
nextMatch: '\\?page=(\\d+)' | |
,nextLink: '?page=#' | |
,step: 1 | |
} | |
,pageElement: '//table[@class="doing"]' | |
,exampleUrl: 'http://twitter.com/os0x' | |
}, | |
*/ | |
{ | |
url: '^http://m\\.twitter\\.com/' | |
,nextLink: '//a[@accesskey="6"]' | |
,pageElement: '//ul/li' | |
,exampleUrl: 'http://m.twitter.com/os0x' | |
} | |
,{ | |
url: '^http://eow\\.alc\\.co\\.jp/[^/]+' | |
,nextLink: 'id("AutoPagerizeNextLink")' | |
,pageElement: 'id("resultsList")/ul' | |
,exampleUrl: 'http://eow.alc.co.jp/%E3%81%82%E3%82%8C/UTF-8/ http://eow.alc.co.jp/are' | |
} | |
,{ | |
url: '^http://matome\\.naver\\.jp/odai/' | |
,nextLink: '//a[@class="next"]' | |
,pageElement: 'id("itemDetail")/li' | |
,exampleUrl: 'http://matome.naver.jp/odai/2127476492987286301' | |
} | |
]); | |
var BOTTOM_SITEINFO = Set.BOTTOM_SITEINFO.concat([ | |
/* template | |
,{ | |
url: '' | |
,nextLink: '' | |
//,insertBefore: '' | |
,pageElement: '' | |
,exampleUrl: '' | |
} | |
*/ | |
]); | |
if (window != window.parent) { //if frame | |
if (window.opera && window.name == 'oAutoPagerizeRequest' && window.parent.AutoPagerize && window.parent.AutoPagerize.AutoPagerObject) { | |
try { | |
var node = document.body || document.getElementsByTagName('head')[0]; | |
if (node) { | |
var style = document.createElementNS(HTML_NAMESPACE, 'style'); | |
style.type = 'text/css'; | |
style.textContent = 'body{display:none ! important;}'; | |
node.appendChild(style); | |
} else { | |
document.write('<style type="text/css">body{display:none ! important;}</style>'); | |
} | |
window.opera.addEventListener( 'BeforeEventListener', function (e) { | |
if (e.event.type != 'DOMContentLoaded') e.preventDefault(); | |
}, false ); | |
document.addEventListener('DOMContentLoaded',function(){ | |
var _AutoPager = window.parent.AutoPagerize.AutoPagerObject; | |
_AutoPager._frameLoad.call(_AutoPager); | |
setTimeout(function(){ | |
_AutoPager.removeIframe(); | |
},100); | |
},false); | |
} catch (e) { | |
log(e); | |
} | |
return; | |
} | |
if (DISABLE_IFRAME) | |
return; | |
} | |
var miscellaneous = []; | |
if (/^http:\/\/(www|images)\.google\.(?:[^.]+\.)?[^.\/]+\/images\?./.test(locationHref)) { | |
miscellaneous.push(function(utils){ | |
//via http://furyu.tea-nifty.com/annex/2008/04/autopagerizeaut_c163.html | |
var info, href = location.href.replace(/^http:\/\/www/,'http://images') + '&gbv=1'; | |
SITEINFO.some(function(site){ | |
var r = new RegExp(site.url); | |
var m = !r.test('http://a') && r.test(href); | |
if (m) { | |
info = site; | |
site.url = 'http://..'; | |
return r; | |
} | |
}); | |
if (!info) return; | |
var a = utils.getFirstElementByXPath(info.nextLink); | |
if (a) { | |
a.href = a.href.replace(/(\?)gbv=2&|&gbv=2(&?)/,'$1$2') + '&gbv=1'; | |
} | |
setTimeout(function(){ | |
new Image().src = 'http://www.google.com/images?gbv=2&hl=ja&q=AutoPagerize?update='+(new Date()).getTime(); | |
// for delete cookie(PREF= .. GBV=1 ..) | |
},100); | |
}); | |
} else if ( | |
/^http:\/\/\w+\.google\.(?:[^.]+\.)?[^.\/]+/.test(locationHref) && (/^\/videosearch\?/.test(location.pathname) || /tbs=vid(%3A|:)1/.test(location.search)) | |
) { | |
useIframe = true; | |
} else if (location.host === 'eow.alc.co.jp') { | |
var alc = function(doc){ | |
var a,r = doc.evaluate('id("paging")/a[last()]',doc,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null); | |
if (r.singleNodeValue) a = r.singleNodeValue; | |
else return; | |
a.id = 'AutoPagerizeNextLink'; | |
a.href = a.href.replace(/javascript:goPage\("(\d+)"\)/,'./?pg=$1'); | |
}; | |
miscellaneous.push(function(){ | |
alc(document); | |
setTimeout(function(){if (window.AutoPagerize) AutoPagerize.addDocumentFilter(alc);},500); | |
}); | |
} else if (location.host==='matome.naver.jp') { | |
miscellaneous.push(function(utils){ | |
var info, href = location.href; | |
TOP_SITEINFO.concat(SITEINFO, BOTTOM_SITEINFO).some(function(site){ | |
var r = new RegExp(site.url); | |
var m = !r.test('http://a') && r.test(href); | |
if (m) { | |
info = site; | |
return true; | |
} | |
}); | |
if (!info) return; | |
var X = utils.getFirstElementByXPath; | |
var naver = function(doc){ | |
var next = X(info.nextLink, doc); | |
try{ | |
var nextpage = next.getAttribute('onclick').match(/goPage\(\s*(\d+)\s*\)/)[1]; | |
var form=document.getElementsByName('missionViewForm')[0]; | |
var param=[].slice.call(form).map(function(i){return i.name+'='+(i.name==='page'?nextpage:i.value);}).join('&'); | |
next.href = location.pathname+'?'+param; | |
}catch(e){// last page | |
next.removeAttribute('href'); | |
} | |
}; | |
naver(document); | |
setTimeout(function(){if (window.AutoPagerize) AutoPagerize.addDocumentFilter(naver);},500); | |
}); | |
} | |
if (HISTORY_MODE_FAST && window.opera) { | |
opera.addEventListener('AfterEvent.GM_AutoPagerizeNextPageLoaded', function(){ | |
if (window.AutoPagerize) | |
window.opera.setOverrideHistoryNavigationMode('fast'); | |
opera.removeEventListener('AfterEvent.GM_AutoPagerizeNextPageLoaded',arguments.callee,false); | |
}, false); | |
} | |
var autopager = function() { | |
if (!SITEINFO) return; | |
miscellaneous.forEach(function(f){f({getFirstElementByXPath:getFirstElementByXPath});}); | |
log('oAutoPagerize loading'); | |
if (!document.body) return; | |
var docRoot = /BackCompat/.test(document.compatMode) ? document.body : document.documentElement; | |
var AutoPager = function() {this.initialize.apply(this, arguments);}; | |
AutoPager.prototype = { | |
initialize:function(info){ | |
log('new AutoPager('+info+')'); | |
this.pageNum = 1; | |
this.info = info; | |
this.state = AUTO_START; | |
var self = this; | |
var url = this.requestURL = this.getNextURL(info.nextLink, document); | |
if (info.insertBefore) { | |
this.insertPoint = getFirstElementByXPath(info.insertBefore); | |
} | |
if (!this.insertPoint) { | |
var lastPageElement = getElementsByXPath(info.pageElement).pop() || {}; | |
this.insertPoint = lastPageElement.nextSibling || lastPageElement.parentNode.appendChild(document.createTextNode(' ')); | |
} | |
log('this.insertPoint.parentNode:'+this.insertPoint); | |
if (!url || !this.insertPoint) return; | |
this.loadedURLs = {}; | |
this.loadedURLs[location.href] = true; | |
this.toggle = function() {self.stateToggle();}; | |
this.scroll = function() {self.onScroll();}; | |
window.addEventListener('scroll', this.scroll, false); | |
this.initHelp(); | |
var scrollHeight = docRoot.scrollHeight; | |
var bottom = getElementPosition(this.insertPoint).top || this.getPageElementsBottom() || (Math.round(scrollHeight * 0.8)); | |
this.remainHeight = scrollHeight - bottom + BASE_REMAIN_HEIGHT; | |
// append space to show scrollbar surely. | |
var pageHeight = window.opera ? document.documentElement.clientHeight : document.body.offsetHeight; | |
if (window.innerHeight >= pageHeight) { | |
document.body.appendChild(document.createElementNS(HTML_NAMESPACE, 'div')).setAttribute('style','position:absolute;bottom:-1px;height:1px;width:1px;'); | |
} | |
} | |
,getPageElementsBottom:function() { | |
try { | |
var elem = getElementsByXPath(this.info.pageElement).pop(); | |
return getElementBottom(elem); | |
} catch(e) {} | |
} | |
,initHelp:function() { | |
var icon = document.createElementNS(HTML_NAMESPACE, 'div'); | |
icon.setAttribute('id', 'autopagerize_icon'); | |
var css = [ | |
'#autopagerize_help {' | |
,'margin:0 0 0 15px;' | |
,'padding:0 5px;' | |
,'font-size:10px;' | |
,'background:#ffffff;' | |
,'border:none;' | |
,'color:#000000;' | |
,'text-align:left;' | |
,'font-weight:normal;' | |
,'line-height:120%;' | |
,'font-family:verdana;' | |
,'display:none;' | |
,'}' | |
,'#autopagerize_help p{' | |
,'margin:0;' | |
,'padding:0 0 3px;' | |
,'line-height:1.2;' | |
,'}' | |
,'#autopagerize_help .toggle{' | |
,'float:right;padding:8px;' | |
,'}' | |
,'#autopagerize_help .autopagerize_status {' | |
,'min-width:' + (140 + ICON_SIZE) + 'px;margin:0;padding:3px 0;list-style:none;text-align:left;' | |
,'}' | |
,'#autopagerize_help .autopagerize_status li{' | |
,'margin:3px 0;padding:0;border:none;' | |
,'}' | |
,'#autopagerize_help .autopagerize_status li span{' | |
,'display:inline-block;' | |
,'vertical-align:middle;' | |
,'margin:0 3px 0 0;' | |
,'}' | |
,'#autopagerize_help .autopagerize_status li span.autopagerize_icons{' | |
,'width:12px;' | |
,'height:12px;' | |
,'}' | |
,'#autopagerize_icon {' | |
,'font-size:12px;' | |
,'position:fixed;' | |
,'top:3px;' | |
,'right:3px;' | |
,'background:',(this.state ? COLOR['on'] : COLOR['off']),';' | |
,'color:#fff;' | |
,'width:',ICON_SIZE,'px;' | |
,'height:',ICON_SIZE,'px;' | |
,'z-index:4294967295;' | |
,'opacity:0.8;' | |
,'overflow:hidden;' | |
,'margin:0;' | |
,'padding:0;' | |
,'}' | |
,'#autopagerize_icon:hover {' | |
,'overflow:visible;' | |
,'width:auto;' | |
,'height:auto;' | |
,'border:1px solid #cccccc;' | |
,'}' | |
,'#autopagerize_icon:hover #autopagerize_help {' | |
,'display:block;' | |
,'}' | |
].join(''); | |
addCSS(css); | |
document.body.appendChild(icon); | |
this.icon = icon; | |
var helpDiv = document.createElementNS(HTML_NAMESPACE, 'div'); | |
helpDiv.setAttribute('id', 'autopagerize_help'); | |
var toggleDiv = document.createElementNS(HTML_NAMESPACE, 'div'); | |
toggleDiv.className = 'toggle'; | |
var a = document.createElementNS(HTML_NAMESPACE, 'a'); | |
a.className = 'autopagerize_link'; | |
a.textContent = 'on/off'; | |
a.href = 'javascript:void 0'; | |
var self = this; | |
a.addEventListener('click', function() {self.stateToggle();}, false); | |
toggleDiv.appendChild(a); | |
var ul = document.createElementNS(HTML_NAMESPACE, 'ul'); | |
ul.className = 'autopagerize_status'; | |
for (var i in COLOR) { | |
var li = document.createElementNS(HTML_NAMESPACE, 'li'); | |
var span = document.createElementNS(HTML_NAMESPACE, 'span'); | |
var text = document.createElementNS(HTML_NAMESPACE, 'span'); | |
span.className = 'autopagerize_icons'; | |
span.style.background = COLOR[i]; | |
text.textContent = i; | |
li.appendChild(span); | |
li.appendChild(text); | |
ul.appendChild(li); | |
} | |
helpDiv.appendChild(toggleDiv); | |
helpDiv.appendChild(ul); | |
var versionDiv = document.createElementNS(HTML_NAMESPACE,'div'); | |
var range = document.createRange(); | |
range.selectNodeContents(document.body); | |
var df = range.createContextualFragment([ | |
'<p><a href="' + URL + '">oAutoPagerize</a> ver. ' + VERSION + '</p>' | |
,'<p><a href="' + UPDATE_URL + '">UPDATE SITEINFO</a></p>' | |
].join('\n')); | |
versionDiv.appendChild(df); | |
helpDiv.appendChild(versionDiv); | |
icon.appendChild(helpDiv); | |
this.helpLayer = helpDiv; | |
} | |
,onScroll:function() { | |
if (!this.wait && !this.checkRemain()) { | |
this.wait = true; | |
var self = this; | |
setTimeout(function(){ | |
self.checkRemain(); | |
self.wait = false; | |
},500); | |
} | |
} | |
,checkRemain:function() { | |
var remain = docRoot.scrollHeight - window.innerHeight - window.pageYOffset; | |
if (this.state && remain < this.remainHeight) { | |
this.request(); | |
return true; | |
} | |
return false; | |
} | |
,stateToggle:function() { | |
if (this.state) { | |
this.disable(); | |
} else { | |
this.enable(); | |
} | |
} | |
,enable:function() { | |
this.state = true; | |
this.icon.style.background = COLOR['on']; | |
this.icon.style.opacity = 0.8; | |
} | |
,disable:function() { | |
this.state = false; | |
this.icon.style.background = COLOR['off']; | |
this.icon.style.opacity = 0.5; | |
} | |
,request:function() { | |
if (!this.requestURL || this.lastRequestURL == this.requestURL) return; | |
if (this.requestURL.indexOf('http') != 0) { | |
this.requestURL = pathToURL(this.requestURL); | |
} | |
this.lastRequestURL = this.requestURL; | |
this.showLoading(true); | |
if (useIframe || window.opera && !window.localStorage && ( !window.postMessage || 'utf-8' != document.characterSet ) ) { | |
this.frameRequest(); | |
} else { | |
this.httpRequest(); | |
} | |
} | |
,httpRequest:function() { | |
var self = this; | |
try { | |
var x = new XMLHttpRequest(); | |
x.open('GET',this.requestURL,true); | |
x.onload = function() { | |
self.requestLoad.call(self, x); | |
}; | |
x.onerror = function(){ | |
if (window.opera) { | |
self.frameRequest(); | |
} else { | |
self.error(x); | |
} | |
}; | |
log('XMLHttpRequest: url='+this.requestURL); | |
x.overrideMimeType('text/html; charset=' + document.characterSet); | |
x.send(null); | |
} catch (e) { | |
if (window.opera) { | |
self.frameRequest(); | |
} else { | |
log('message: '+e.message); | |
this.error(); | |
return; | |
} | |
} | |
} | |
,frameRequest:function() { | |
var iframe = document.createElementNS(HTML_NAMESPACE, 'iframe'); | |
var self = this; | |
this.removeIframe = function(){ | |
document.body.removeChild(iframe); | |
}; | |
this._frameLoad = function(){ | |
self.frameLoad.call(self,iframe); | |
}; | |
iframe.width = iframe.height = 1; | |
iframe.style.visibility = 'hidden'; | |
iframe.name = 'oAutoPagerizeRequest'; | |
iframe.src = this.requestURL; | |
document.body.appendChild(iframe); | |
} | |
,showLoading:function(sw) { | |
if (sw) { | |
this.icon.style.background = COLOR['loading']; | |
} else { | |
this.icon.style.background = COLOR['on']; | |
} | |
} | |
,frameLoad:function(frame) { | |
var htmlDoc = frame.contentDocument || frame.contentWindow.document; | |
this.loaded(htmlDoc); | |
} | |
,requestLoad:function(res) { | |
log('requestLoad\n'+'status: '+res.statusText); | |
var t = res.responseText; | |
var htmlDoc = createHTMLDocumentByString(t); | |
this.createHTMLDocumentMode = true; | |
this.loaded(htmlDoc); | |
} | |
,loaded:function(htmlDoc) { | |
AutoPager.documentFilters.forEach(function(i) { | |
i(htmlDoc, this.requestURL, this.info); | |
}, this); | |
log('response document: '+htmlDoc); | |
try { | |
var pages = getElementsByXPath(this.info.pageElement, htmlDoc); | |
var url = this.getNextURL(this.info.nextLink, htmlDoc); | |
if (!!this.info.incremental) { | |
var exp = new RegExp(this.info.incremental.nextMatch,'i'); | |
var _m = this.info.incremental.nextLink; | |
var step = this.info.incremental.step || 1; | |
url = this.requestURL.replace(exp,function(m0,m1){ | |
var n = parseInt(m1,10) + step; | |
return _m.split('#').join(n); | |
}); | |
} | |
} catch(e) { | |
log('error at AutoPager:requestLoad() : '+e); | |
log('code: '+e.code); | |
this.error(); | |
return; | |
} | |
if (!pages.length) { | |
log('requestLoad abort: pages:'+pages); | |
this.terminate(); | |
return; | |
} | |
if (this.loadedURLs[this.requestURL]) { | |
log('requestLoad abort: already loadpage:' + this.requestURL); | |
this.terminate(); | |
return; | |
} | |
pages.forEach(function(page, i) { | |
pages[i] = document.importNode(page, true); | |
}); | |
this.loadedURLs[this.requestURL] = true; | |
this.addPage(htmlDoc, pages); | |
AutoPager.filters.forEach(function(i) { | |
i(pages); | |
}); | |
this.requestURL = url; | |
this.showLoading(false); | |
if (!url) { | |
log('requestLoad abort: next URL is empty'); | |
this.terminate(); | |
} | |
var ev = document.createEvent('Event'); | |
ev.initEvent('GM_AutoPagerizeNextPageLoaded', true, false); | |
document.dispatchEvent(ev); | |
} | |
,addPage:function(htmlDoc, pages) { | |
var insertParentNode = this.insertPoint.parentNode; | |
var root,node; | |
if (/^tbody$/i.test(insertParentNode.localName)) { | |
var colNodes = getElementsByXPath('child::tr[1]/child::*[self::td or self::th]',insertParentNode); | |
var colums = 0; | |
for (var i = 0, l = colNodes.length;i<l;i++) { | |
var col = colNodes[i].getAttribute('colspan'); | |
colums += parseInt(col,10) || 1; | |
} | |
node = document.createElementNS(HTML_NAMESPACE, 'td'); | |
root = document.createElementNS(HTML_NAMESPACE, 'tr'); | |
node.setAttribute('colspan',colums); | |
root.appendChild(node); | |
} else { | |
root = node = document.createElementNS(HTML_NAMESPACE, 'div'); | |
} | |
node.className = 'autopagerize_page_separator_blocks'; | |
var tmpl = { | |
number:'<hr style="clear:both;" class="autopagerize_page_separator"/><p class="autopagerize_page_info">page: <a class="autopagerize_link" href="%s">%n</a></p>' | |
,link:'<hr style="clear:both;" class="autopagerize_page_separator"/><p class="autopagerize_page_info">AutoPagerized: <a class="autopagerize_link" href="%s">%s</a></p>' | |
}; | |
var range = document.createRange(); | |
range.selectNodeContents(document.body); | |
var df = range.createContextualFragment((tmpl[naviType]||tmpl['number']).replace(/%s/g, this.requestURL).replace(/%n/g,++this.pageNum)); | |
node.appendChild(df); | |
insertParentNode.insertBefore(root, this.insertPoint); | |
var self = this; | |
if (!this.nodeInsert) (function(){ | |
if (window.opera) { | |
var dummy = document.createEvent('MutationEvents'); | |
dummy.initMutationEvent('hogehoge', true, false, insertParentNode, null, null, null, null); | |
if (!dummy.relatedNode) { // MutationEventsがキチンと動かないブラウザの救済処置 | |
self.nodeInsert = function(node) { | |
var insertNode = insertParentNode.insertBefore(node, self.insertPoint); | |
var ev = document.createEvent('Event'); | |
ev.initEvent('AutoPagerize_DOMNodeInserted', true, false); | |
ev.relatedNode = insertParentNode; | |
ev.newValue = self.requestURL; | |
insertNode.dispatchEvent(ev); | |
}; | |
return; | |
} | |
} | |
self.nodeInsert = function(node) { | |
var insertNode = insertParentNode.insertBefore(node, self.insertPoint); | |
var ev = document.createEvent('MutationEvents'); | |
ev.initMutationEvent('AutoPagerize_DOMNodeInserted', true, false, insertParentNode, null, self.requestURL, null, null); | |
insertNode.dispatchEvent(ev); | |
}; | |
})(); | |
pages.forEach(this.nodeInsert); | |
} | |
,getNextURL:function(xpath, doc) { | |
var next = getFirstElementByXPath(xpath, doc); | |
if (next) { | |
return next.getAttribute('href') || next.getAttribute('action') || next.getAttribute('value'); | |
} | |
} | |
,terminate:function() { | |
log('terminating'); | |
this.icon.style.background = COLOR['terminated']; | |
window.removeEventListener('scroll', this.scroll, true); | |
var self = this; | |
setTimeout(function() { | |
self.icon.parentNode.removeChild(self.icon); | |
}, 1500); | |
} | |
,error:function() { | |
this.icon.style.background = COLOR['error']; | |
window.removeEventListener('scroll', this.scroll, true); | |
} | |
}; | |
AutoPager.documentFilters = []; | |
AutoPager.filters = []; | |
if (FORCE_TARGET_WINDOW) { | |
var setTargetBlank = function(doc) { | |
var anchers = getElementsByXPath('descendant-or-self::a[@href and not(contains(@class, "autopagerize_link") or starts-with(@href, "javascript:") or starts-with(@href, "#"))]', doc); | |
anchers.forEach(function(i) { | |
i.target = TARGET_WINDOW_NAME; | |
}); | |
}; | |
AutoPager.documentFilters.push(setTargetBlank); | |
} | |
var launchAutoPager = function(list) { | |
log('launchAutoPager(...)'); | |
var s = (new Date).getTime(); | |
list.some(function(info) { | |
try { | |
var exp = new RegExp(info.url); | |
if (ap) { | |
} else if ( ! exp.test(locationHref) ) { | |
} else if (!getFirstElementByXPath(info.nextLink)) { | |
// ignore microformats case. | |
if (!exp.test('http://a')) { | |
debug('nextLink not found.', info); | |
} | |
} else if (!getFirstElementByXPath(info.pageElement)) { | |
if (!exp.test('http://a')) { | |
debug('pageElement not found.', info); | |
} | |
} else { | |
ap = new AutoPager(info); | |
window.AutoPagerize.AutoPagerObject = ap; | |
return true; | |
} | |
} catch(e) { | |
log('error at launchAutoPager() : ' + e); | |
} | |
}); | |
log('launchAutoPager... fin:'+((new Date).getTime()-s)); | |
MICROFORMATs.forEach(function(format){ | |
if (!ap && getFirstElementByXPath(format.nextLink) && getFirstElementByXPath(format.pageElement)) { | |
ap = new AutoPager(format); | |
window.AutoPagerize.AutoPagerObject = ap; | |
} | |
}); | |
}; | |
// initialize | |
if (!window.AutoPagerize) { | |
window.AutoPagerize = { | |
addFilter:function(f) { | |
AutoPager.filters.push(f); | |
} | |
,addDocumentFilter:function(f) { | |
AutoPager.documentFilters.push(f); | |
} | |
}; | |
} | |
var ev = document.createEvent('Event'); | |
ev.initEvent('GM_AutoPagerizeLoaded', true, false); | |
document.dispatchEvent(ev); | |
var ap = null; | |
launchAutoPager(TOP_SITEINFO.concat(SITEINFO,BOTTOM_SITEINFO)); | |
// utility functions. | |
window.AutoPagerize.getElementsByXPath = getElementsByXPath; | |
window.AutoPagerize.getFirstElementByXPath = getFirstElementByXPath; | |
function createHTMLDocumentByString(str) { | |
if (document.documentElement.nodeName != 'HTML') { | |
return new DOMParser().parseFromString(str, 'application/xhtml+xml'); | |
} | |
var html = String(str);// Thx! jAutoPagerize#HTMLResource.createDocumentFromString http://svn.coderepos.org/share/lang/javascript/userscripts/jautopagerize.user.js | |
html = html.replace(/<script(?:[ \t\r\n][^>]*)?>[\S\s]*?<\/script[ \t\r\n]*>|<\/?(?:i?frame|html|script|object)(?:[ \t\r\n][^<>]*)?>/gi, ' '); | |
if (isSafari3) return createDocumentFromString(html); | |
return createDocumentFromString(html); | |
} | |
function createDocumentFromString(str) { | |
getXPathResult.forceRelative = true; | |
var d = document.createElement('div'); | |
d.appendChild(createDocumentFragmentByString(str)); | |
return d; | |
} | |
// via http://github.com/hatena/hatena-bookmark-xul/blob/master/chrome/content/common/05-HTMLDocumentCreator.js | |
function createDocumentFromString(source){ | |
var doc; | |
if (document.implementation.createHTMLDocument) { | |
doc = document.implementation.createHTMLDocument('title'); | |
} else { | |
doc = document.cloneNode(false); | |
if (doc) { | |
doc.appendChild(doc.importNode(document.documentElement, false)); | |
} else { | |
doc = document.implementation.createDocument(null, 'title', null); | |
} | |
} | |
var range = document.createRange(); | |
range.selectNodeContents(document.documentElement); | |
var fragment = range.createContextualFragment(source); | |
var headChildNames = {title: true, meta: true, link: true, script: true, style: true, /*object: true,*/ base: true/*, isindex: true,*/}; | |
var child, head = doc.getElementsByTagName('head')[0] || doc.createElement('head'), | |
body = doc.getElementsByTagName('body')[0] || doc.createElement('body'); | |
while ((child = fragment.firstChild)) { | |
if ( | |
(child.nodeType === doc.ELEMENT_NODE && !(child.nodeName.toLowerCase() in headChildNames)) || | |
(child.nodeType === doc.TEXT_NODE &&/\S/.test(child.nodeValue)) | |
) | |
break; | |
head.appendChild(child); | |
} | |
body.appendChild(fragment); | |
doc.documentElement.appendChild(head); | |
doc.documentElement.appendChild(body); | |
return doc; | |
} | |
function debug(message, siteinfo) { | |
if (!DebugMode) return; | |
var params = (function(site){ | |
var p = []; | |
for (var k in site) { | |
if (k == 'data') { | |
var data = site[k]; | |
for (var j in data) { | |
p.push(j+':'+data[j]); | |
} | |
} else { | |
p.push(k+':'+site[k]); | |
} | |
} | |
return p.join(','); | |
})(siteinfo); | |
log(message,params); | |
} | |
function log() { | |
if (!DebugMode) return; | |
if (window.console) { | |
console.log(Array.prototype.slice.call(arguments)); | |
} else if (window.opera && window.opera.postError) { | |
window.opera.postError(arguments); | |
} | |
} | |
function getElementPosition(elem) { | |
var offsetTrail = elem; | |
var offsetLeft = 0; | |
var offsetTop = 0; | |
while (offsetTrail) { | |
offsetLeft += offsetTrail.offsetLeft; | |
offsetTop += offsetTrail.offsetTop; | |
offsetTrail = offsetTrail.offsetParent; | |
} | |
offsetTop = offsetTop || null; | |
offsetLeft = offsetLeft || null; | |
return {left: offsetLeft, top: offsetTop}; | |
} | |
function getElementBottom(elem) { | |
var c_style = document.defaultView.getComputedStyle(elem, ''); | |
var height = 0; | |
var prop = [ | |
'height', 'borderTopWidth', 'borderBottomWidth', | |
'paddingTop', 'paddingBottom', | |
'marginTop', 'marginBottom']; | |
prop.forEach(function(i) { | |
var h = parseInt(c_style[i]); | |
if (typeof h == 'number') { | |
height += h; | |
} | |
}); | |
var top = getElementPosition(elem).top; | |
return top ? (top + height) : null; | |
} | |
function pathToURL(path) { | |
var link = document.createElement('a'); | |
link.href = path; | |
return link.href; | |
} | |
function getElementsByXPath(xpath, node) { | |
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) { | |
if (getXPathResult.forceRelative) { | |
xpath = xpath.replace(/id\(\s*(["'])([^"']+)\1\s*\)/g, './/*[@id="$2"]'); | |
xpath = xpath.indexOf('(//') == 0 | |
? '(.//' + xpath.substring(3) | |
: (xpath[0] == '/' ? '.' : './') + xpath; | |
} | |
var node = node || document; | |
var doc = node.ownerDocument || node; | |
var resolver = doc.createNSResolver(node.documentElement || node); | |
// Use |node.lookupNamespaceURI('')| for Opera 9.5 | |
var isXHTML = document.documentElement.tagName !== 'HTML'; | |
var defaultNS = node.lookupNamespaceURI(window.opera ? '' : null); | |
if (isXHTML) { | |
var 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) { | |
var tokenPattern = /([A-Za-z_\u00c0-\ufffd][\w\-.\u00b7-\ufffd]*|\*)\s*(::?|\()?|(".*?"|'.*?'|\d+(?:\.\d*)?|\.(?:\.|\d+)?|[\)\]])|(\/\/?|!=|[<>]=?|[\(\[|,=+-])|([@$])/g; | |
var 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 addCSS (css){ | |
var style = document.createElementNS(HTML_NAMESPACE, 'style'); | |
style.id = 'autopagerize_style'; | |
style.type = 'text/css'; | |
var root = document.getElementsByTagName('head')[0] || document.body; | |
root.appendChild(style); | |
addCSS = function(_css){ | |
style.appendChild(document.createTextNode(_css+'\n')); | |
}; | |
addCSS(css); | |
} | |
}; | |
function insertSITEINFO(){ | |
var sc = document.createElementNS(HTML_NAMESPACE, 'script'); | |
sc.type = 'text/javascript'; | |
window.AutoPagerizeCallbackSiteinfo = function(res){ | |
window.AutoPagerizeCallbackSiteinfo = null; | |
SITEINFO = res; | |
var ev = document.createEvent('Event'); | |
ev.initEvent('AutoPagerize_SiteinfoLoaded', true, false); | |
document.dispatchEvent(ev); | |
sc.parentNode.removeChild(sc); | |
}; | |
sc.src = SITEINFO_SERVER; | |
if (window.opera && (document.readyState === 'loading' || document.readyState === 'interactive')) { | |
document.addEventListener('DOMContentLoaded',insert,false); | |
} else { | |
insert(); | |
} | |
function insert(){ | |
document.body.appendChild(sc); | |
} | |
} | |
if (window.opera && (document.readyState === 'loading' || document.readyState === 'interactive')) { | |
document.addEventListener('DOMContentLoaded', autopager, false); | |
} else { | |
autopager(); | |
} | |
document.addEventListener('AutoPagerize_SiteinfoLoaded', autopager, false); | |
})(window); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment