// ==UserScript==
// @name AutoPagerize
// @namespace http://swdyh.yu.to/
// @description loading next page and inserting into current page.
// @include http://*
// @include https://*
// @exclude https://mail.google.com/*
// @exclude http://b.hatena.ne.jp/*
// @exclude http://www.facebook.com/plugins/like.php*
// @exclude http://api.tweetmeme.com/button.js*
// ==/UserScript==
//
// auther: swdyh http://d.hatena.ne.jp/swdyh/
// version: 0.0.60 2011-10-02T17:40:35+09:00
//
// this script based on
// 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 GPL license
// http://www.gnu.org/copyleft/gpl.html
//
if (isGreasemonkey()) {
var ep = getPref('exclude_patterns')
if (ep && isExclude(ep)) {
// FIXME
// return
}
}
else {
gmCompatible()
}
var URL = 'http://autopagerize.net/'
var VERSION = '0.0.60'
var DEBUG = false
var AUTO_START = true
var CACHE_EXPIRE = 24 * 60 * 60 * 1000
var BASE_REMAIN_HEIGHT = 400
var FORCE_TARGET_WINDOW = getPref('force_target_window', true)
var XHR_TIMEOUT = 30 * 1000
var SITEINFO_IMPORT_URLS = [
'http://wedata.net/databases/AutoPagerize/items.json',
]
var COLOR = {
on: '#0f0',
off: '#ccc',
loading: '#0ff',
terminated: '#00f',
error: '#f0f'
}
var SITEINFO = [
/* sample
{
url: 'http://(.*).google.+/(search).+',
nextLink: 'id("navbar")//td[last()]/a',
pageElement: '//div[@id="res"]/div',
exampleUrl: 'http://www.google.com/search?q=nsIObserver',
},
*/
/* template
{
url: '',
nextLink: '',
pageElement: '',
exampleUrl: '',
},
*/
]
var MICROFORMAT = {
url: '.*',
nextLink: '//a[@rel="next"] | //link[@rel="next"]',
insertBefore: '//*[contains(@class, "autopagerize_insert_before")]',
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, location.href)
if ( !url ) {
debug("getNextURL returns null.", info.nextLink)
return
}
if (info.insertBefore) {
this.insertPoint = getFirstElementByXPath(info.insertBefore)
}
if (!this.insertPoint) {
var lastPageElement = getElementsByXPath(info.pageElement).pop()
if (lastPageElement) {
this.insertPoint = lastPageElement.nextSibling ||
lastPageElement.parentNode.appendChild(document.createTextNode(' '))
}
}
if (!this.insertPoint) {
debug("insertPoint not found.", lastPageElement, info.pageElement)
return
}
this.requestURL = url
this.loadedURLs = {}
this.loadedURLs[location.href] = true
var toggle = function() {self.stateToggle()}
this.toggle = toggle
GM_registerMenuCommand('AutoPagerize - on/off', toggle)
this.scroll= function() { self.onScroll() }
window.addEventListener("scroll", this.scroll, false)
if (isFirefoxExtension()) {
var div = document.createElement("div")
div.setAttribute('id', 'autopagerize_icon')
div.style.display = 'none'
document.body.appendChild(div)
this.icon = div
}
else if (isChromeExtension() || isSafariExtension() || isJetpack()) {
var frame = document.createElement('iframe')
frame.style.display = 'none'
frame.style.position = 'fixed'
frame.style.bottom = '0px'
frame.style.left = '0px'
frame.style.height = '25px'
frame.style.border = '0px'
frame.style.opacity = '0.8'
frame.style.zIndex = '1000'
frame.width = '100%'
frame.scrolling = 'no'
this.messageFrame = frame
var u = settings['extension_path'] ?
settings['extension_path'] + 'loading.html' :
'http://autopagerize.net/files/loading.html'
this.messageFrame.src = u
document.body.appendChild(frame)
if (isSafariExtension()) {
safari.self.tab.dispatchMessage('launched', {url: location.href })
}
else if (isChromeExtension()) {
chrome.extension.connect({name: "launched"}).postMessage()
}
if (isJetpack()) {
postMessage({name: 'launched', data: location.href })
}
}
else {
this.initIcon()
this.initHelp()
GM_addStyle('@media print{#autopagerize_icon, #autopagerize_help {display: none !important;}}')
this.icon.addEventListener("mouseover", function() {
self.viewHelp()
}, true)
}
var scrollHeight = getScrollHeight()
var bottom = getElementPosition(this.insertPoint).top ||
this.getPageElementsBottom() ||
(Math.round(scrollHeight * 0.8))
this.remainHeight = scrollHeight - bottom + BASE_REMAIN_HEIGHT
this.onScroll()
var that = this
document.addEventListener('AutoPagerizeToggleRequest', function() {
that.toggle()
}, false)
document.addEventListener('AutoPagerizeUpdateIconRequest', function() {
that.updateIcon()
}, false)
that.updateIcon()
}
AutoPager.prototype.getPageElementsBottom = function() {
try {
var elem = getElementsByXPath(this.info.pageElement).pop()
return getElementBottom(elem)
}
catch(e) {}
}
AutoPager.prototype.initHelp = function() {
var helpDiv = document.createElement('div')
helpDiv.setAttribute('id', 'autopagerize_help')
helpDiv.setAttribute('style', 'padding:5px;position:fixed;' +
'top:-200px;right:3px;font-size:10px;' +
'background:#fff;color:#000;border:1px solid #ccc;' +
'z-index:256;text-align:left;font-weight:normal;' +
'line-height:120%;font-family:verdana;')
var toggleDiv = document.createElement('div')
toggleDiv.setAttribute('style', 'margin:0 0 0 50px;')
var a = document.createElement('a')
a.setAttribute('class', 'autopagerize_link')
a.innerHTML = 'on/off'
a.href = 'javascript:void(0)'
var self = this
var toggle = function() {
self.stateToggle()
helpDiv.style.top = '-200px'
}
a.addEventListener('click', toggle, false)
toggleDiv.appendChild(a)
var s = '<div style="width:100px; float:left;">'
for (var i in COLOR) {
s += '<div style="float:left;width:1em;height:1em;' +
'margin:0 3px;background-color:' + COLOR[i] + ';' +
'"></div><div style="margin:0 3px">' + i + '</div>'
}
s += '</div>'
var colorDiv = document.createElement('div')
colorDiv.innerHTML = s
helpDiv.appendChild(colorDiv)
helpDiv.appendChild(toggleDiv)
var versionDiv = document.createElement('div')
versionDiv.setAttribute('style', 'clear:both;')
versionDiv.innerHTML = '<a href="' + URL +
'">AutoPagerize</a> ver ' + VERSION
helpDiv.appendChild(versionDiv)
document.body.appendChild(helpDiv)
var proc = function(e) {
var c_style = document.defaultView.getComputedStyle(helpDiv, '')
var s = ['top', 'left', 'height', 'width'].map(function(i) {
return parseInt(c_style.getPropertyValue(i)) })
if (e.clientX < s[1] || e.clientX > (s[1] + s[3] + 11) ||
e.clientY < s[0] || e.clientY > (s[0] + s[2] + 11)) {
helpDiv.style.top = '-200px'
}
}
helpDiv.addEventListener('mouseout', proc, false)
this.helpLayer = helpDiv
GM_addStyle('#autopagerize_help a { color: #0f0; text-decoration: underline;}')
}
AutoPager.prototype.viewHelp = function() {
this.helpLayer.style.top = '3px'
}
AutoPager.prototype.onScroll = function() {
var scrollHeight = Math.max(document.documentElement.scrollHeight,
document.body.scrollHeight)
var remain = scrollHeight - window.innerHeight - window.scrollY
if (this.state == 'enable' && remain < this.remainHeight) {
this.request()
}
}
AutoPager.prototype.stateToggle = function() {
if (this.state == 'enable') {
this.disable()
}
else {
this.enable()
}
}
AutoPager.prototype.enable = function() {
this.state = 'enable'
this.updateIcon()
}
AutoPager.prototype.disable = function() {
this.state = 'disable'
this.updateIcon()
}
AutoPager.prototype.updateIcon = function(state) {
var st = state || this.state
var rename = {'enable': 'on', 'disable': 'off' }
if (rename[st]) {
st = rename[st]
}
var color = COLOR[st]
if (color) {
if (isFirefoxExtension()) {
chlorine.pageAction.update(color, location.href)
}
else if (isChromeExtension()) {
chrome.extension.connect({name: "pageActionChannel"}).postMessage(color)
}
else if (isSafariExtension() || isJetpack()) {
}
else {
this.icon.style.background = color
}
}
}
AutoPager.prototype.request = function() {
if (!this.requestURL || this.lastRequestURL == this.requestURL) {
return
}
this.lastRequestURL = this.requestURL
var self = this
var mime = 'text/html; charset=' + document.characterSet
var headers = {}
if (isSameDomain(this.requestURL)) {
headers.Cookie = document.cookie
}
else {
this.error()
return
}
var opt = {
method: 'get',
url: this.requestURL,
headers: headers,
overrideMimeType: mime,
onerror: function(res) {
self.error()
},
onload: function(res) {
if (res.finalUrl && location.host == res.finalUrl.split('/')[2]) {
self.requestLoad.apply(self, [res])
}
else {
self.error()
}
}
}
AutoPager.requestFilters.forEach(function(i) { i(opt) }, this)
if (opt.stop) {
this.requestURL = opt.url
}
else {
this.showLoading(true)
GM_xmlhttpRequest(opt)
}
}
AutoPager.prototype.showLoading = function(sw) {
if (sw) {
this.updateIcon('loading')
if (this.messageFrame && settings['display_message_bar']) {
this.messageFrame.style.display = 'block'
}
}
else {
this.updateIcon('enable')
if (this.messageFrame) {
this.messageFrame.style.display = 'none'
}
}
}
AutoPager.prototype.requestLoad = function(res) {
AutoPager.responseFilters.forEach(function(i) {
i(res, this.requestURL)
}, this)
var htmlDoc = createHTMLDocumentByString(res.responseText)
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, this.requestURL)
}
catch(e){
log(e)
this.error()
return
}
if (!page || page.length < 1 ) {
debug('pageElement not found.' , this.info.pageElement)
this.terminate()
return
}
if (this.loadedURLs[this.requestURL]) {
debug('page is already loaded.', this.requestURL, this.info.nextLink)
this.terminate()
return
}
this.loadedURLs[this.requestURL] = true
page = this.addPage(htmlDoc, page)
AutoPager.filters.forEach(function(i) {
i(page)
})
this.requestURL = url
this.showLoading(false)
this.onScroll()
if (!url) {
debug('nextLink not found.', this.info.nextLink, htmlDoc)
this.terminate()
}
var ev = document.createEvent('Event')
ev.initEvent('GM_AutoPagerizeNextPageLoaded', true, false)
document.dispatchEvent(ev)
}
AutoPager.prototype.addPage = function(htmlDoc, page) {
var HTML_NS = 'http://www.w3.org/1999/xhtml'
var hr = document.createElementNS(HTML_NS, 'hr')
var p = document.createElementNS(HTML_NS, 'p')
hr.setAttribute('class', 'autopagerize_page_separator')
p.setAttribute('class', 'autopagerize_page_info')
var self = this
if (page[0] && page[0].tagName == 'TR') {
var insertParent = this.insertPoint.parentNode
var colNodes = getElementsByXPath('child::tr[1]/child::*[self::td or self::th]', insertParent)
var colums = 0
for (var i = 0, l = colNodes.length; i < l; i++) {
var col = colNodes[i].getAttribute('colspan')
colums += parseInt(col, 10) || 1
}
var td = document.createElement('td')
// td.appendChild(hr)
td.appendChild(p)
var tr = document.createElement('tr')
td.setAttribute('colspan', colums)
tr.appendChild(td)
insertParent.insertBefore(tr, this.insertPoint)
}
else {
this.insertPoint.parentNode.insertBefore(hr, this.insertPoint)
this.insertPoint.parentNode.insertBefore(p, this.insertPoint)
}
p.innerHTML = 'page: <a class="autopagerize_link" href="' +
this.requestURL.replace(/&/g, '&') + '">' + (++this.pageNum) + '</a>'
return page.map(function(i) {
var pe = document.importNode(i, true)
self.insertPoint.parentNode.insertBefore(pe, self.insertPoint)
var ev = document.createEvent('MutationEvent')
ev.initMutationEvent('AutoPagerize_DOMNodeInserted', true, false,
self.insertPoint.parentNode, null,
self.requestURL, null, null)
pe.dispatchEvent(ev)
return pe
})
}
AutoPager.prototype.initIcon = function() {
var div = document.createElement("div")
div.setAttribute('id', 'autopagerize_icon')
with (div.style) {
fontSize = '12px'
position = 'fixed'
top = '3px'
right = '3px'
background = COLOR['on']
color = '#fff'
width = '10px'
height = '10px'
zIndex = '255'
if (this.state != 'enable') {
background = COLOR['off']
}
}
document.body.appendChild(div)
this.icon = div
}
AutoPager.prototype.getNextURL = function(xpath, doc, url) {
var nextLink = getFirstElementByXPath(xpath, doc)
if (nextLink) {
var nextValue = nextLink.getAttribute('href') ||
nextLink.getAttribute('action') || nextLink.value
if (nextValue.match(/^http(s)?:/)) {
return nextValue
}
else {
var base = getFirstElementByXPath('//base[@href]', doc)
return resolvePath(nextValue, (base ? base.href : url))
}
}
}
AutoPager.prototype.terminate = function() {
window.removeEventListener('scroll', this.scroll, false)
this.updateIcon('terminated')
var self = this
setTimeout(function() {
if (self.icon) {
self.icon.parentNode.removeChild(self.icon)
}
if (isSafariExtension()) {
var mf = self.messageFrame
mf.parentNode.removeChild(mf)
}
}, 1500)
}
AutoPager.prototype.error = function() {
this.updateIcon('error')
window.removeEventListener('scroll', this.scroll, false)
if (isSafariExtension() || isChromeExtension() || isJetpack()) {
var mf = this.messageFrame
var u = settings['extension_path'] ?
settings['extension_path'] + 'error.html' :
'http://autopagerize.net/files/error.html'
mf.src = u
mf.style.display = 'block'
setTimeout(function() {
mf.parentNode.removeChild(mf)
}, 3000)
}
}
AutoPager.documentFilters = []
AutoPager.requestFilters = []
AutoPager.responseFilters = []
AutoPager.filters = []
var parseInfo = function(str) {
var lines = str.split(/\r\n|\r|\n/)
var re = /(^[^:]*?):(.*)$/
var strip = function(str) {
return str.replace(/^\s*/, '').replace(/\s*$/, '')
}
var info = {}
for (var i = 0; i < lines.length; i++) {
if (lines[i].match(re)) {
info[RegExp.$1] = strip(RegExp.$2)
}
}
var isValid = function(info) {
var infoProp = ['url', 'nextLink', 'pageElement']
for (var i = 0; i < infoProp.length; i++) {
if (!info[infoProp[i]]) {
return false
}
}
return true
}
return isValid(info) ? info : null
}
var launchAutoPager = function(list) {
if (list.length == 0) {
return
}
for (var i = 0; i < list.length; i++) {
try {
if (ap) {
return
}
else if (!location.href.match(list[i].url)) {
}
else if (!getFirstElementByXPath(list[i].nextLink)) {
// FIXME microformats case detection.
// limiting greater than 12 to filter microformats like SITEINFOs.
if (list[i].url.length > 12 ) {
debug("nextLink not found.", list[i].nextLink)
}
}
else if (!getFirstElementByXPath(list[i].pageElement)) {
if (list[i].url.length > 12 ) {
debug("pageElement not found.", list[i].pageElement)
}
}
else {
ap = new AutoPager(list[i])
return
}
}
catch(e) {
log(e)
continue
}
}
}
var clearCache = function() {
GM_setValue('cacheInfo', '')
}
var getCache = function() {
try {
return JSON.parse(GM_getValue('cacheInfo')) || {}
}
catch(e) {
return {}
}
}
var getCacheCallback = function(res, url) {
if (res.status != 200) {
return getCacheErrorCallback(url)
}
var info
try {
info = JSON.parse(res.responseText).map(function(i) { return i.data })
}
catch(e) {
info = []
}
if (info.length > 0) {
info = info.filter(function(i) { return ('url' in i) })
info.sort(function(a, b) { return (b.url.length - a.url.length) })
var r_keys = ['url', 'nextLink', 'insertBefore', 'pageElement']
info = info.map(function(i) {
var item = {}
r_keys.forEach(function(key) {
if (i[key]) {
item[key] = i[key]
}
})
return item
})
cacheInfo[url] = {
url: url,
expire: new Date(new Date().getTime() + CACHE_EXPIRE),
info: info
}
GM_setValue('cacheInfo', JSON.stringify(cacheInfo))
launchAutoPager(info)
}
else {
getCacheErrorCallback(url)
}
}
var getCacheErrorCallback = function(url) {
var expire = new Date(new Date().getTime() + CACHE_EXPIRE)
if (cacheInfo[url]) {
cacheInfo[url].expire = expire
launchAutoPager(cacheInfo[url].info)
}
else {
cacheInfo[url] = {
url: url,
expire: expire,
info: []
}
}
GM_setValue('cacheInfo', cacheInfo.toSource())
}
var linkFilter = function(doc, url) {
var base = getFirstElementByXPath('//base[@href]', doc)
var baseUrl = base ? base.href : url
var isSameBase = isSameBaseUrl(location.href, baseUrl)
if (!FORCE_TARGET_WINDOW && isSameBase) {
return
}
var anchors = getElementsByXPath('descendant-or-self::a[@href]', doc)
anchors.forEach(function(i) {
var attrHref = i.getAttribute('href')
if (FORCE_TARGET_WINDOW && !attrHref.match(/^#|^javascript:/) &&
i.className.indexOf('autopagerize_link') < 0) {
i.target = '_blank'
}
if (!isSameBase && !attrHref.match(/^#|^\w+:/)) {
i.href = resolvePath(i.getAttribute('href'), baseUrl)
}
})
if (!isSameBase) {
var images = getElementsByXPath('descendant-or-self::img', doc)
images.forEach(function(i) {
i.src = resolvePath(i.getAttribute('src'), baseUrl)
})
}
}
AutoPager.documentFilters.push(linkFilter)
fixResolvePath()
if (typeof(window.AutoPagerize) == 'undefined') {
window.AutoPagerize = {}
window.AutoPagerize.addFilter = function(f) {
AutoPager.filters.push(f)
}
window.AutoPagerize.addDocumentFilter = function(f) {
AutoPager.documentFilters.push(f)
}
window.AutoPagerize.addResponseFilter = function(f) {
AutoPager.responseFilters.push(f)
}
window.AutoPagerize.addRequestFilter = function(f) {
AutoPager.requestFilters.push(f)
}
window.AutoPagerize.launchAutoPager = launchAutoPager
var ev = document.createEvent('Event')
ev.initEvent('GM_AutoPagerizeLoaded', true, false)
document.dispatchEvent(ev)
}
var settings = {}
var ap = null
if (isChromeExtension()) {
var port = chrome.extension.connect({name: "settingsChannel"})
port.postMessage()
port.onMessage.addListener(function(res) {
settings = res
if (res['exclude_patterns'] && isExclude(res['exclude_patterns'])) {
return
}
launchAutoPager(SITEINFO)
var port_ = chrome.extension.connect({name: "siteinfoChannel"})
port_.postMessage({ url: location.href })
port_.onMessage.addListener(function(res) {
launchAutoPager(res)
chrome.extension.onConnect.addListener(function(port) {
if (port.name == "toggleRequestChannel") {
port.onMessage.addListener(function(msg) {
if (ap) {
ap.toggle()
}
})
}
})
})
})
}
else if (isSafariExtension()) {
var re_exclude = /^(about:|safari-extension:)/
if (!location.href.match(re_exclude)) {
safari.self.addEventListener('message', function(event) {
if (event.name === 'settings') {
settings = event.message
safari.self.tab.dispatchMessage('siteinfoChannel', {url: location.href })
}
else if (event.name === 'siteinfoChannel') {
if (!settings['exclude_patterns'] || !isExclude(settings['exclude_patterns'])) {
launchAutoPager(SITEINFO)
launchAutoPager([MICROFORMAT])
launchAutoPager(event.message)
}
}
else if (event.name === 'toggleRequestChannel') {
if (ap) {
ap.toggle()
}
}
else if (event.name === 'updateSettings') {
settings = event.message
}
}, false)
safari.self.tab.dispatchMessage('settings')
}
}
else if (isJetpack()) {
postMessage({ name: 'settings' })
onMessage = function(message) {
if (message.name == 'siteinfo') {
// launchAutoPager(SITEINFO)
launchAutoPager(message.data)
}
else if (message.name == 'settings') {
settings = message.data
if (settings['exclude_patterns'] && isExclude(settings['exclude_patterns'])) {
// return
}
else {
postMessage({ name: 'siteinfo', url: location.href })
launchAutoPager([MICROFORMAT])
}
}
}
}
else {
launchAutoPager(SITEINFO)
GM_registerMenuCommand('AutoPagerize - clear cache', clearCache)
var cacheInfo = getCache()
var xhrStates = {}
SITEINFO_IMPORT_URLS.forEach(function(i) {
if (!cacheInfo[i] || new Date(cacheInfo[i].expire) < new Date()) {
var opt = {
method: 'get',
url: i,
onload: function(res) {
xhrStates[i] = 'loaded'
getCacheCallback(res, i)
},
onerror: function(res){
xhrStates[i] = 'error'
getCacheErrorCallback(i)
},
}
xhrStates[i] = 'start'
GM_xmlhttpRequest(opt)
setTimeout(function() {
if (xhrStates[i] == 'start') {
getCacheErrorCallback(i)
}
}, XHR_TIMEOUT)
}
else {
launchAutoPager(cacheInfo[i].info)
}
})
launchAutoPager([MICROFORMAT])
}
// new google search sucks!
if (location.href.match('^http://[^.]+\.google\.(?:[^.]{2,3}\.)?[^./]{2,3}/.*(&fp=)')) {
var to = location.href.replace(/&fp=.*/, '')
// console.log([location.href, to])
location.href = to
}
// utility functions.
function createHTMLDocumentByString(str) {
if (document.documentElement.nodeName != 'HTML') {
return new DOMParser().parseFromString(str, 'application/xhtml+xml')
}
var html = strip_html_tag(str)
var htmlDoc
try {
// We have to handle exceptions since Opera 9.6 throws
// a NOT_SUPPORTED_ERR exception for |document.cloneNode(false)|
// against the DOM 3 Core spec.
htmlDoc = document.cloneNode(false)
htmlDoc.appendChild(htmlDoc.importNode(document.documentElement, false))
}
catch(e) {
htmlDoc = document.implementation.createDocument(null, 'html', null)
}
var fragment = createDocumentFragmentByString(html)
try {
fragment = htmlDoc.adoptNode(fragment)
}
catch(e) {
fragment = htmlDoc.importNode(fragment, true)
}
htmlDoc.documentElement.appendChild(fragment)
return htmlDoc
}
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) {
var node = node || document
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)
}
function log(message) {
if (typeof console == 'object') {
console.log(message)
}
else {
GM_log(message)
}
}
function debug() {
if ( typeof DEBUG != 'undefined' && DEBUG ) {
console.log.apply(console, 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 getScrollHeight() {
return Math.max(document.documentElement.scrollHeight,
document.body.scrollHeight)
}
function isSameDomain(url) {
if (url.match(/^\w+:/)) {
var url_s = url.split(/[\/\?]/)
return url_s[0] == location.protocol && location.host == url_s[2]
}
else {
return true
}
}
function isSameBaseUrl(urlA, urlB) {
return (urlA.replace(/[^/]+$/, '') == urlB.replace(/[^/]+$/, ''))
}
function resolvePath(path, base) {
if (path.match(/^https?:\/\//)) {
return path
}
if (path.match(/^\?/)) {
return base.replace(/\?.+$/, '') + path;
}
if (path.match(/^[^\/]/)) {
return base.replace(/[^/]+$/, '') + path
}
else {
return base.replace(/([^/]+:\/\/[^/]+)\/.*/, '\$1') + path
}
}
function fixResolvePath() {
if (resolvePath('', 'http://resolve.test/') == 'http://resolve.test/') {
return
}
// A workaround for WebKit and Mozilla 1.9.2a1pre,
// which don't support XML Base in HTML.
// https://bugs.webkit.org/show_bug.cgi?id=17423
// https://bugzilla.mozilla.org/show_bug.cgi?id=505783
var XML_NS = 'http://www.w3.org/XML/1998/namespace'
var baseElement = document.createElementNS(null, 'base')
var pathElement = document.createElementNS(null, 'path')
baseElement.appendChild(pathElement)
resolvePath = function resolvePath_workaround(path, base) {
baseElement.setAttributeNS(XML_NS, 'xml:base', base)
pathElement.setAttributeNS(XML_NS, 'xml:base', path)
return pathElement.baseURI
}
}
function strip_html_tag(str) {
var chunks = str.split(/(<html(?:[ \t\r\n][^>]*)?>)/)
if (chunks.length >= 3) {
chunks.splice(0, 2)
}
str = chunks.join('')
chunks = str.split(/(<\/html[ \t\r\n]*>)/)
if (chunks.length >= 3) {
chunks.splice(chunks.length - 2)
}
return chunks.join('')
}
function getPref(key, defaultValue) {
var value = GM_getValue(key)
return (typeof value == 'undefined') ? defaultValue : value
}
function wildcard2regep(str) {
return '^' + str.replace(/([-()\[\]{}+?.$\^|,:#<!\\])/g, '\\$1').replace(/\x08/g, '\\x08').replace(/\*/g, '.*')
}
function isExclude(patterns) {
var rr = /^\/(.+)\/$/
var eps = (patterns || '').split(/[\r\n ]+/)
for (var i = 0; i < eps.length; i++) {
var reg = null
if (rr.test(eps[i])) {
reg = eps[i].match(rr)[1]
}
else {
reg = wildcard2regep(eps[i])
}
if (location.href.match(reg)) {
return true
}
}
return false
}
// obsolete
function isFirefoxExtension() {
return (typeof chlorine == 'object')
}
function isChromeExtension() {
return (typeof chrome == 'object') &&
(typeof chrome.extension == 'object')
}
function isSafariExtension() {
return (typeof safari == 'object') &&
(typeof safari.extension == 'object')
}
function isGreasemonkey() {
return (typeof GM_log == 'function')
}
function isJetpack() {
// isFirefoxExtension is obsolete
return (!isGreasemonkey() && !isSafariExtension() &&
!isChromeExtension() && !isFirefoxExtension())
}
function gmCompatible() {
GM_registerMenuCommand = function() {}
GM_setValue = function() {}
GM_getValue = function() {}
GM_addStyle = function() {}
uneval = function() {}
fixResolvePath = function() {}
resolvePath = function (path, base) { return path }
if (isChromeExtension() || isSafariExtension()) {
createHTMLDocumentByString = function(str) {
if (document.documentElement.nodeName != 'HTML') {
return new DOMParser().parseFromString(str, 'application/xhtml+xml')
}
// FIXME
var html = str.replace(/<script(?:[ \t\r\n][^>]*)?>[\S\s]*?<\/script[ \t\r\n]*>|<\/?(?:i?frame|html|script|object)(?:[ \t\r\n][^<>]*)?>/gi, ' ')
var htmlDoc = document.implementation.createHTMLDocument ?
document.implementation.createHTMLDocument('apfc') :
document.implementation.createDocument(null, 'html', null)
var range = document.createRange()
range.selectNodeContents(document.documentElement)
htmlDoc.documentElement.appendChild(range.createContextualFragment(html))
return htmlDoc
}
}
return true
}
Mozilla add on,User script,Grease Monkey Script, greasemonkey userscripts, updater userscripts mafia wars userscripts mafia wars autoplayer userscripts mafia wars wall userscripts scripts userscripts travian greasemonkey greasemonkey download greasemonkey facebook greasemonkey tutorial greasemonkey youtube greasemonkey travian greasemonkey chrome greasemonkey mafia wars greasemonkey mafia wars autoplayer
Sunday, October 2, 2011
AutoPagerize
Subscribe to:
Post Comments (Atom)
0 comments:
Post a Comment