Created
October 19, 2008 18:42
-
-
Save os0x/17904 to your computer and use it in GitHub Desktop.
XPath Anchor. This script is unsafe!
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 XPath Anchor | |
// @namespace http://ss-o.net/ | |
// @description XPath Anchor. This script is unsafe! | |
// @include http://* | |
// ==/UserScript== | |
(function (unsafeWindow) { | |
var __hash = document.location.hash; | |
log(unsafeWindow.document.location.watch); | |
if (document.location.__defineGetter__) { | |
document.location.__defineGetter__("hash", function() { | |
return __hash; | |
}); | |
document.location.__defineSetter__("hash", function(hash) { | |
__hash = '#' + hash; | |
hashlink(); | |
}); | |
window.location.__defineGetter__("hash", function() { | |
return __hash; | |
}); | |
window.location.__defineSetter__("hash", function(hash) { | |
__hash = '#' + hash; | |
hashlink(); | |
}); | |
} else if (unsafeWindow.document.location.watch) { | |
unsafeWindow.document.location.watch('hash',function (id,oldhash,newhash) { | |
__hash = '#' + newhash; | |
log(newhash,hashlink+''); | |
setTimeout(hashlink,100); | |
return newhash; | |
}); | |
unsafeWindow.location.watch('hash',function (id,oldhash,newhash) { | |
__hash = '#' + newhash; | |
log(newhash,hashlink+''); | |
setTimeout(hashlink,100); | |
return newhash; | |
}); | |
} | |
hashlink(); | |
function hashlink(){ | |
var Smooth = true; | |
log(__hash+''); | |
var hash = /^#(?:(XPath|TEXT)=(.+)|(.+))/.exec(__hash+''); | |
log(hash); | |
if (!hash) | |
return; | |
var type = hash[1]; | |
var path = hash[2]; | |
log(type,path); | |
if (hash[3]) { | |
type = 'TEXT'; | |
path = hash[3]; | |
} | |
if (path.indexOf('%') >= 0) { | |
path = decodeURIComponent(path); | |
} | |
var xpath = ({XPath:path,TEXT:'//*[contains(text(), "' + path + '")]'})[type]; | |
log(xpath); | |
if (!xpath) return; | |
var nodetype = document.body.nodeType; | |
var pageY = window.pageYOffset; | |
$X(xpath).some(function(target){ | |
if (target.nodeType != nodetype || !target.getBoundingClientRect) return; | |
var pos = target.getBoundingClientRect(); | |
if (pos.top == 0) return; | |
if (Smooth) | |
TweenFnc({scroll:function(v){window.scrollTo(pos.left,v);}},{scroll:{to:pos.top+pageY,from:pageY},time:0.3}); | |
else | |
window.scrollTo(pos.left,pos.top); | |
return true; | |
}); | |
} | |
function log () { | |
if (this.console) { | |
this.unsafeWindow.console.log(arguments); | |
} else if (window.opera) { | |
opera.postError(arguments); | |
} | |
} | |
// simple version of $X | |
// $X(exp); | |
// $X(exp, context); | |
// @source http://gist.github.com/3242.txt | |
function $X (exp, context) { | |
context || (context = document); | |
var expr = (context.ownerDocument || context).createExpression(exp, function (prefix) { | |
return document.createNSResolver(context.documentElement || context).lookupNamespaceURI(prefix) || | |
context.namespaceURI || document.documentElement.namespaceURI || ""; | |
}); | |
var result = expr.evaluate(context, XPathResult.ANY_TYPE, null); | |
switch (result.resultType) { | |
case XPathResult.STRING_TYPE : return result.stringValue; | |
case XPathResult.NUMBER_TYPE : return result.numberValue; | |
case XPathResult.BOOLEAN_TYPE: return result.booleanValue; | |
case XPathResult.UNORDERED_NODE_ITERATOR_TYPE: | |
// not ensure the order. | |
var ret = [], i = null; | |
while (i = result.iterateNext()) ret.push(i); | |
return ret; | |
} | |
return null; | |
} | |
/* | |
// Tweener Like snippet | |
new TweenFnc(div.style,{time:1, onComplete:function(){},left:{to:0,from:100,tmpl:"+$#px"}}); | |
*/ | |
function TweenFnc(item, opt) { | |
var self = this, TIME = 10, time = opt.time * 1000, TM_EXP = /(\+)?\$([\#\d])/g, count = Math.ceil(time / TIME), sets = [], easing = opt.transition || function(t, b, c, d){return c*t/d + b;}, _T = {time:1,onComplete:1,transition:1,delay:1}; | |
for (var k in opt) if (!_T[k]) { | |
var set = opt[k], from = set.from || parseFloat(item[k]) || 0, values = [], tmpl = set.tmpl || '$#'; | |
for (var i = 1; i <= count; ++i) { | |
var val = easing(i * TIME, from, set.to - from , time); | |
values.push(tmpl.replace(TM_EXP, function(m, p, m1){return p && val < 0 ? 0 : (m1 == '#' ? val : val.toFixed(m1));} )); | |
} | |
sets.push({key:k, values:values, tmpl:tmpl}); | |
} | |
var L = sets.length; | |
var run = function(i){ | |
for (var k = 0; k < L; ++k) item[sets[k].key](sets[k].values[i]); | |
if (--count > 0) setTimeout(function(){run.call(self, ++i);},TIME); | |
else if (typeof opt.onComplete == 'function') opt.onComplete(); | |
}; | |
(typeof opt.delay == "number") ? setTimeout(function(){run(0);},opt.delay*1000) : run(0); | |
} | |
})(this.unsafeWindow||window); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment