About
Timeline lets you navigate through revision history for a question and updates the page in real time. This app can be activated by clicking a bookmarklet while viewing an individual question.
This is a very basic prototype, but I do have a lot of cool ideas about how to improve this if there is an interest in the community.
Download
Create a new bookmark with the following URL location:
javascript:(function(){%20var%20API_KEY='Hi_vp0zvN0mS3ou-O1NzHA';var%20loadingMessage;var%20container;var%20revisions;var%20slider;var%20detail;var%20domain;var%20link=$("<link>");link.attr({type:'text/css',rel:'stylesheet',href:'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css'});$("head").append(link);function%20createContainer(){var%20postCell=$('#question%20.postcell');container=$('.timeline-container');if(container.length==0){container=$('<div></div>');container.attr({class:'timeline-container',style:'margin-bottom:15px;'});postCell.prepend(container);}container.children().remove();}function%20displayLoadingMessage(){loadingMessage=$('<h2></h2>');loadingMessage.html('<img%20src="http://kevinx.net/loading.gif"%20alt=""%20/>%20Loading%20timeline...');container.prepend(loadingMessage);}function%20hideLoadingMessage(){loadingMessage.remove();}function%20onSliderTick(evt,ui){var%20rev=findRevision(ui.value);if(rev!=null){updatePage(rev);}}function%20updatePage(revision){$('#question-header%20h1%20a').text(getRevisionValue(revision,'title'));$('#question%20.post-text').html(getRevisionValue(revision,'body'));showDetail(revision);}function%20getRevisionValue(revision,field){if(revision==null)return%20null;if(revision[field]==null){var%20previousRevision=findRevision(revision.revision_number-1);return%20getRevisionValue(previousRevision,field);}return%20revision[field];}function%20findRevision(revNum){for(var%20i=0;i<revisions.length;i++){if(revisions[i].revision_number==revNum){return%20revisions[i];}}return%20null;}function%20showDetail(revision){var%20creation_date=new%20Date();creation_date.setTime(revision.creation_date*1000);detail.find("img").attr('src','http://www.gravatar.com/avatar/'+revision.user.email_hash+'?s=32');detail.find(".userlink").attr('href','http://'+domain+'/users/'+revision.user.user_id);detail.find(".reputation-score").text(addCommas(revision.user.reputation));detail.find(".userlink").text(revision.user.display_name);detail.find(".revdate").text(creation_date.toDateString());detail.find(".revnote").html(revision.comment==''?'<em>no%20comment</em>':revision.comment);detail.find(".viewsource").attr('href','http://'+domain+'/revisions/'+revision.revision_guid+'/view-source');detail.show();}function%20addCommas(nStr){nStr+='';x=nStr.split('.');x1=x[0];x2=x.length>1?'.'+x[1]:'';var%20rgx=/(\d+)(\d{3})/;while(rgx.test(x1)){x1=x1.replace(rgx,'$1'+','+'$2');}return%20x1+x2;}function%20onLoad(){var%20result=/questions\/(\d+)/.exec($(location).attr('href'));if(result.length<=1){hideLoadingMessage();return;}var%20questionId=result[1];domain=$(location).attr('host');$.getJSON('http://api.'+domain+'/1.0/revisions/'+questionId+'/?key='+API_KEY+'&jsonp=?',function(data){hideLoadingMessage();revisions=new%20Array();for(var%20i=0;i<data.revisions.length;i++){if(data.revisions[i].revision_number!=null){revisions.push(data.revisions[i]);}}slider=$('<h2></h2>');container.prepend(slider);slider.slider({min:1,max:revisions.length,value:revisions.length,slide:onSliderTick});detail=$('<div></div>');detail.attr({class:'timeline-detail',style:'padding:2px;border:1px%20solid%20#999;background:#eee;border-radius:5px;-moz-border-radius:5px;margin-bottom:10px;display:none;'});detail.html('<table><tr><td%20style="padding:5px;"><img%20src=""%20alt=""%20border="0"%20style="vertical-align:top;"%20/></td><td%20style="border-right:1px%20solid%20#999;padding:5px%2010px%205px%203px;"><div%20style="margin-bottom:4px;"><a%20href=""%20class="userlink"></a></div><span%20title="reputation%20score"%20class="reputation-score"></span><br%20/><span%20class="revdate"%20style="font-size:smaller;"></span></td><td%20style="padding:5px%2010px;"><p%20class="revnote"></p><p><a%20href=""%20target="_blank"%20class="viewsource">view%20source</a></p></td></tr></table>');container.prepend(detail);showDetail(revisions[0]);var%20tbl=$('<table></table>');tbl.attr({width:'100%'});var%20tr=$('<tr></tr>');tbl.append(tr);var%20endWidth=(container.children('.ui-slider').width()/revisions.length)/2;for(var%20i=0;i<revisions.length;i++){var%20td=$('<td></td>');td.attr({align:i==0?'left':i==revisions.length-1?'right':'center',width:i==0||i==revisions.length-1?endWidth:''});td.text('^');tr.append(td);}container.append(tbl);});}createContainer();displayLoadingMessage();$.getScript('http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/jquery-ui.min.js',onLoad);}())
Activate Timeline by clicking the bookmark while viewing an individual question.
Source Code
Non-minified source code can be viewed here:
Updates
2010-7-12
- Added revision details above slider.
- Added tick marks below slider.
TODO
- Add support for tags.
- Fix error when viewing questions that have been migrated from other StackExchange sites.