By alien_scum
Has 15 other scripts.
// ==UserScript==
// @name Script Updater
// @namespace userscripts.org/alien_scum
// @description checks all your scripts for updates on user script.org
// @include *
// ==/UserScript==
function getValue(query) {
return eval(GM_getValue('cache','({})'))[query];
}
function setValue(query,value) {
var values=eval(GM_getValue('cache','({})'));
values[query]=value;
GM_setValue('cache', uneval(values));
}
function $x(xpath) {
//xpath=xpath.replace(/((^|\|)\s*)([^/|]+)/g,'$2//$3').replace(/([^.])\.(\w*)/g,'$1[@class="$2"]').replace(/#(\w*)/g,'[@id="$1"]').replace(/\/\[/g,'/*[');
var got=document.evaluate(xpath,document,null,null,null), result=[];
while(next=got.iterateNext()) result.push(next);
if (x=result[0]) for(var i in x.wrappedJSObject) if(typeof result[i] =='undefined')
if(typeof x[i]=='function') result[i]=Function('a','b','c','this.forEach(res=function (n) {if(n.'+i+') return n.'+i+'(a,b,c);return res})');
else {result[i]=x[i]; result.watch(i,function(p,o,n){this.forEach(function (e){e[p]=n})});}
result.addEventListener=function(t,f,b){this.forEach(function(n){n.addEventListener(t,f,b)})};
return result;
}
function xhr(uri,f,a,b,c) {GM_xmlhttpRequest({method: 'get',headers: {'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey'},url: uri,onload:function(res){f(res.responseText,a,b,c)}});}
function iframe(src,show) {var f=document.createElement('iframe');f.style.display=show?'inline':'none';f.src=src;return f;}
function hash(s){
s=s.replace(/&/g,'&').replace(/&\w*;/g,'').replace(/[^\w(){}=.-+]/g,'');
var h=0;
for (i=0;i<s.length;i++) h=(h<<3)^(h>>29)^s.charCodeAt(i);
return h
}
function wait(c,f){
if (c()) f()
else window.setTimeout(function (){wait(c,f)},1000,false);
}
function upref(num) {return 'http://userscripts.org/scripts/source/'+num+'.user.js'}
function ckref(num) {return upref(num)+'?source'}
function cE(tag,content){
var res=document.createElement(tag);
if(content) res.innerHTML=content;
return res;
}
function checkable() {
try {
// avoid a flood of dialogs e.g. when opening a browser with multiple tabs set to homepage
// and a script with * includes or opening a tabgrop
var DoS_PREVENTION_TIME = 2 * 60 * 1000;
var isSomeoneChecking = getValue('CHECKING', null);
var now = new Date().getTime();
setValue('CHECKING', now.toString());
if (isSomeoneChecking && (now - isSomeoneChecking) < DoS_PREVENTION_TIME) return false;
// check daily
var ONE_DAY = 24 * 60 * 60 * 1000;
var lastChecked = getValue('LAST_CHECKED', null);
if (lastChecked && (now - lastChecked) < ONE_DAY) return false;
setValue('LAST_CHECKED',now);
return true
} catch (ex) {return false}
}
profile=getValue('profile');
if (!profile) {
setValue('profile',true);
GM_openInTab('about:cache#scriptupdater') //get profile directory from cache page
} else {
if(location.href=='about:cache#scriptupdater') {
profile=document.getElementsByTagName('tt')[7].innerHTML.replace(/\\/g,'/').replace(/^\s*/g,'').replace(/ /g,'%20').replace(/cache$/i,'').replace(/<wbr>/g,'')
if (/\w:\//.test(profile)){
if(/\/local%20settings/i.test(profile))
profile='file:///'+profile.replace(/\/local%20settings/i,'');
else if (/\/AppData\/Local/.test(profe))
profile='file:///'+profile.replace(/\/AppData\/Local/i,'\/AppData\/Roaming');
else
profile='file:///'+profile.replace(/((\/[^/]*){2})\/[^/]*/i,'$1');
}
else
profile='file://'+profile.replace(/Caches(\/Firefox)/i,"Application%20Support$1");
setValue('profile',profile);
location.replace(profile+'bookmarks.html#scriptupdater'); //we need a file:/// page to get acsess to the scripts
}
if(location.href==profile+'bookmarks.html#scriptupdater'){
document.body.innerHTML='';
document.title='Update userscripts';
GM_addStyle('#header td:hover {background:#EEEEEE}'+
'#header {cursor:pointer}');
mes=document.body.appendChild(document.createElement('h2'));
mes.innerHTML='finding scripts...';
f=document.body.appendChild(iframe(profile+'gm_scripts/config.xml'));
window.setTimeout(function (){// waits for iframe to load
d=f.contentDocument.documentElement;
t=document.body.appendChild(document.createElement('table')).appendChild(document.createElement('tbody'));
lnks=[];
tr=t.appendChild(cE('tr'));
tr.id='header';
tr.appendChild(cE('td','Name'));
tr.appendChild(cE('td','Filename'));
tr.appendChild(cE('td','State'));
tr.appendChild(cE('td','Hash')).style.display='none';
cnt=0;
scripts={};
for (var i=0;n=d.childNodes[i];i++) if(n.nodeType!=3){
tr=t.appendChild(cE('tr'));
cnt++;
tr.appendChild(cE('td',name=n.getAttribute('name')));
tr.appendChild(cE('td',filename=n.getAttribute('filename')));
if(n.getAttribute('enabled')=='false'){
tr.style.background='#EEEEEE';
tr.appendChild(cE('td','disabled'));
cnt--;
} else xhr('http://userscripts.org/scripts/search?q='+name,function(res,p,s,ns){
if (s.length>47) s=s.slice(0,47)+'...';
var xs = s.replace(/\&/g, '&').replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1');
reg=new RegExp('<a[^>]*href[^>\\d]*/show/(\\d+)[^>]*>[\s\r\n]*'+xs+'[\s\r\n]*<\\\/a>','ig');
var r=null,rs=[];
while(e=reg.exec(res)) rs.push(e);
if (rs.length>1) rs.forEach(function(n){xhr(ckref(n[1]),function(res,ns,n){
var m=res.match(/@namespace\s*(.*)/)
if (!m&&!ns||m&&m[1]==ns) {
r=n;
rs.splice(rs.indexOf(n),1);
}
},ns,n);});
else r=rs[0];
wait(function (){return r||(rs.length==0)},function (){
p.innerHTML=r?r[1]:'Not on us.o';
if (r) {
scripts[s]={name:s,num:r[1],hash:p.nextSibling.innerHTML};
xhr(ckref(r[1]),function(res){if(!(c=hash(res)==p.nextSibling.innerHTML)) p.innerHTML='<a href="'+upref(p.innerHTML)+'">Update</a>';p.nextSibling.innerHTML+='<br>'+hash(res);p.parentNode.style.background=c?'#CCFFCC':'#FFAA44'});
}else p.parentNode.style.background='#FFCCCC';
cnt--;
});
},tr.appendChild(cE('td')),name,n.getAttribute('namespace'));
tr.appendChild(cE('td')).appendChild(iframe(profile+'gm_scripts/'+filename)).parentNode.style.display='none';
}
mes.innerHTML='looking on us.o for updates...';
window.setTimeout(function (){//waits for iframe to load
for (var i=1;n=t.childNodes[i];i++)
n.childNodes[3].innerHTML=hash(n.childNodes[3].childNodes[0].contentDocument.documentElement.innerHTML.match(/<pre>([\s\S]*)<\/pre>/)[1]);
wait(function(){return cnt==0},function (){
mes.innerHTML='Updates Found';
f.parentNode.removeChild(f);
setValue('scripts',scripts);
[].forEach.call(t.childNodes[0].childNodes,function (td,i) {
td.addEventListener('click',function(){
nodes=[];
while(t.childNodes[1]) nodes.push(t.removeChild(t.childNodes[1]));
nodes.sort(function(a,b){return a.childNodes[i].innerHTML.toLowerCase()<b.childNodes[i].innerHTML.toLowerCase()?1:-1;})
while(script = nodes.pop()) t.appendChild(script);
},false);
});
});
},100,false);
},30,false);
}
if(/userscripts.org/.test(location.href)){
$x('//a[contains(@href,".user.js")]').addEventListener('click',function(){num=this.href.match(/\d+/);xhr(ckref(num),function(res){
scripts=getValue('scripts');
name=res.match(/@name\s*(.*)/)[1];
scripts[name]={name:name,num:num,hash:hash(res)};
setValue('scripts',scripts);
})});
}
if(!/#scriptupdater/.test(location.href) && checkable()) {
scripts=getValue('scripts');
for(s in scripts){
xhr(ckref(scripts[s].num),function(res,s){
script=scripts[s];
if (hash(res)!=script.hash) {
scpts=getValue('scripts');
scpts[s].hash=hash(res);
setValue('scripts',scpts);
if(confirm('Update found for: \n'+script.name+'\n'+res.match(/@description\s*(.*)/)[1]))
GM_openInTab(upref(script.num))
}
},s);
}
}
}