User:WhoSaidThat/RevisionData.js

// Usage - var rdObj = new RevisionsData( 'Some Page' ); // the ready and error functions are executed in the context of the newly created RevisionData object // limit restricts the number of revisions to load, loading starts for the most recent revisions // and the summaries are load a batch of listSize at a time (note that if listSize not a multiple of limit the limit may be breached)

// this object only fetches revision summaries when first created // that content text of each revisions needs to be loaded with calls to the objects loadRevision method // due to browser localStorage size constraints the ability of this object to store a client side cache of assembled revisions data is not very useful

//

function RevisionsData(page, whenReady, onerror, limit, listSize){

this.baseURL='/w/api.php?action=';

this.dataLimit=limit?limit:1400; //number of revisions summaries this.dataSize=listSize?listSize:'max' //number of revisions summaries per call

this.onListingLoaded=whenReady; this.onError=(onerror) ? (onerror) : ( function(jqXHR, textStatus, errorThrown){ /*alert('Uncaught RD error' +textStatus);*/ } ); this.errors=[];

this.page=page.replace(/_/g,' '); this.revisions=[];

this.afterLoadingContent=[];

this.loadCount=0; this.loadThrottle=5; this.loadWaiting=false; this.pendingLoads=[];

this.cacheText=false; this.cacheListing=false;

this.storagePrefix='rev'; this.storagePrefixLisiting='list';

this.loadInfo = function{

var url=this.baseURL+'query&titles='+ this.page +'&prop=info&format=json'; var action=function(data) { var ids=''; var pageFound=false; for(var i in data.query.pages){ ids+=i+' '+data.query.pages[i].title+' '; if( data.query.pages[i].title == this.page ){ pageFound=data.query.pages[i].title; this.pageId=data.query.pages[i].pageid; this.finalRevId=data.query.pages[i].lastrevid; this.nextRevId=this.finalRevId; }			}

if(!pageFound && this.msg) alert(ids+'\n'+this.page); else{ if(this.msg) alert('page found '+pageFound); }

this.loadListing; };

$.ajax({'url':url, 'context':this,'dataType':'json','success':action ,				'error':function(jqXHR, textStatus, errorThrown){					this.lastError={'requestObject':jqXHR,'message':textStatus,'errorObject':errorThrown};					this.onError(jqXHR, textStatus, errorThrown);				}});

}

this.checkForNewRevisions= function{

var url=this.baseURL+'query&titles='+ this.page +'&prop=revisions'; url += '&rvlimit=1&rvprop=timestamp&format=json';

var action=function(data){

if(data.query.pages[this.pageId].revisions[0].timestamp!=this.revisions[0].timestamp){

var action= function(data){ this.newerVersion=data.query.pages[this.pageId].revisions[0]; }

var url=this.baseURL+'query&titles='+ this.page +'&prop=revisions'; url += '&rvlimit=1&rvprop=timestamp|user|comment|ids|size|content&format=json';

$.ajax({'url':url, 'context':this,'dataType':'json','success':action ,				'error':function(jqXHR, textStatus, errorThrown){					this.lastError={'requestObject':jqXHR,'message':textStatus,'errorObject':errorThrown};					this.onError(jqXHR, textStatus, errorThrown);				}});

}		}

$.ajax({'url':url, 'context':this,'dataType':'json','success':action ,				'error':function(jqXHR, textStatus, errorThrown){					this.lastError={'requestObject':jqXHR,'message':textStatus,'errorObject':errorThrown};					this.onError(jqXHR, textStatus, errorThrown);				}}); }

this.loadListing=function{

if(this.cacheListing){

var key=this.storagePrefixLisiting+this.page.replace(/ /g,'_'); if(localStorage.getItem(key)){ this.revisions=JSON.parse(localStorage.getItem(key)); alert('load cached listing'); return; }else{ if(this.msg) alert('no cache found for '+key); }

}

if(this.nextRevId){

var url=this.baseURL+'query&titles='+ this.page +'&prop=revisions'; url += '&rvdir=older&rvlimit=max&rvprop=timestamp|user|comment|ids|size|tags|flags&rvstartid='; url += this.nextRevId +'&format=json';

var action= function(data) {

if( !data.query.pages[this.pageId]) alert('error not found '+this.pageId);

var nrevs=data.query.pages[this.pageId].revisions;

if((new Date(nrevs[0].timestamp))<=(new Date(nrevs[nrevs.length-1].timestamp))){ if(this.msg) alert('wrong order'); this.nextRevId=false; this.nextRevisionI=this.revisions.length-1;

this.loadRevision(0,function{						this.revObj.onListingLoaded(true);					},function{						this.revObj.onListingLoaded(false);					}); this.loadListing; return false; }

/*alert(this.revisions.length+' got listing chunk '+nrevs.length+' '+nrevs[nrevs.length-1].parentid); if( this.revisions.length>1 && (new Date(nrevs[0].timestamp)) < (new Date( this.revisions[this.revisions.length-1].timestamp )) && (new Date(nrevs[0].timestamp))>(new Date(nrevs[nrevs.length-1].timestamp))) alert('ok newT '+nrevs[0].timestamp+'- '+nrevs[nrevs.length-1].timestamp+' lastT'+this.revisions[this.revisions.length-1].timestamp);*/

this.revisions= this.revisions.concat( data.query.pages[this.pageId].revisions );

if(this.revisions[this.revisions.length-1].parentid && this.revisions.length<this.dataLimit){ this.nextRevId=this.revisions[this.revisions.length-1].parentid; }else{

if(this.cacheListing){ var key=this.storagePrefixLisiting+this.page.replace(/ /g,'_'); localStorage.setItem(key,JSON.stringify(this.revisions)); }					this.loadRevision(0,function{						this.revObj.onListingLoaded(true);					},function{						this.revObj.onListingLoaded(false);					});

this.nextRevId=false; this.nextRevisionI=this.revisions.length-1; }

this.loadListing; };

$.ajax({'url':url, 'context':this,'dataType':'json','success':action ,				'error':function(jqXHR, textStatus, errorThrown){					this.lastError={'requestObject':jqXHR,'message':textStatus,'errorObject':errorThrown};					this.onError(jqXHR, textStatus, errorThrown);				}});

}else{ if(this.msg) alert('nothing next'); if(this.cacheText) this.checkCache; }	}

this.continueLoading=function{ //alert('continue'); var c=true; this.loadWaiting=false; while(this.pendingLoads.length && c){ var p=this.pendingLoads.shift; c = this.loadRevision(p[0],p[1],p[2],p[3],p[4]); }	}

this.checkFinishedLoading=function(rObj){ if(this.pendingLoads.length==0 && this.loadCount==0){ while(this.afterLoadingContent.length){ var f=this.afterLoadingContent.shift; if(typeof f == 'function'){ this.tempF=f; this.tempF(rObj); }			}		}	}

this.loadRevision=function(i,after,error,caller,afterall){

this.afterLoadingContent.push(afterall);

if(this.loadCount<0 || this.loadCount>=this.loadThrottle){ this.pendingLoads.push([i,after,error,caller,afterall]); if(!this.loadWaiting){ this.loadWaiting=true; window.setTimeout("window.revisionsObject.data.continueLoading;",1000); }			return false; }

this.loadCount++;

var revid = this.revisions[i].revid; var url=this.baseURL+'query&titles='+ this.page +'&prop=revisions'; url += '&rvlimit=1&rvprop=timestamp|user|comment|ids|size|content&rvstartid='; url += revid +'&format=json';

var request={ 'revObj':this, 'url':url, 'i':i, 'caller': caller , 'after': (after) ? (after) : ( function{} ), 'error': (error) ? (error) : ( function(jqXHR, textStatus, errorThrown){ alert('Uncaught error loading revision text '+textStatus); } ) };

if(typeof this.revisions[i].text == 'string'){ this.loadCount--; request.after(i,request.caller,request); this.checkFinishedLoading; return true; }

$.ajax({	'url':url,				'context':request,				'dataType':'json',				'success':function(data) {					this.revObj.loadCount--;					var r=data.query.pages[this.revObj.pageId].revisions[0]; if(!r || !r['*'] && this.msg) alert(' details load failed '+ this.readingURL+' \n'+r); if(this.msg) $('body').append($(' '+(r['*'].length+' '+this.i)+' '));

if(this.cacheText) this.revObj.setCache(r.revid, r['*']); this.revObj.revisions[this.i].content=r['*']; //if{ alert('loading done'); this.after(this.i,this.caller,this); this.revObj.checkFinishedLoading; },				'error':function(jqXHR, textStatus, errorThrown){ this.revObj.loadCount--; this.errors.push( {'requestObject':jqXHR,'message':textStatus,'errorObject':errorThrown,'request':this} ); this.error(jqXHR, textStatus, errorThrown,this); }		});

return true;

}

this.loadInfo;

this.checkCache=function(revid){ var k=0; for(var i=0; i0) alert('Found ' +k +' cached revision texts'); }

this.setCache=function(revid,text){ if(!this.cacheText) return false; try{ localStorage.setItem(this.storagePrefix+revid+':'+(new Date).getTime ,text); }catch(e){ alert(e); window.status='Cache overflow'; //		this.purgeCache; }	}	this.purgeCache=function(purgeAll){ var revids={}; for(var i=0; i<this.revisions.length; i++) revids[this.revisions[i].revid]=this.revisions[i]; for(var i=0; i<localStorage.length;i++){ var k=localStorage.key(i); if(!revids[k]){ var parts=k.split(':'); localStorage.removeItem(k); }		}	}

//this.purgeCache;

}