// ==UserScript== // @name Stack Exchange Deleted Question Viewer // @version 1.3 // @description Allows you to view some deleted questions on Stack Exchange. // @namespace http://jeremybanks.ca/ // @include http://stackoverflow.com/questions/* // @include http://*.stackoverflow.com/questions/* // @include http://superuser.com/questions/* // @include http://*.superuser.com/questions/* // @include http://serverfault.com/questions/* // @include http://*.serverfault.com/questions/* // @include http://stackexchange.com/questions/* // @include http://*.stackexchange.com/questions/* // @include http://answers.onstartups.com/questions/* // ==/UserScript== ; var inject; var __slice = Array.prototype.slice; inject = function(f) { var script; script = document.createElement('script'); script.textContent = "(" + f + ")();"; return document.body.appendChild(script); }; inject(function() { var DeferringThrottle, POST_TEMPLATE, answerFrame, commentsThrottle, continueWithjQuery, deletedPost, editPageThrottle, from, knownIds, markdownLoaded, myVotesThrottle, showAnswerIfNew, siteName, start, updateTitle, voteCountThrottle; start = function() { var script; if (!(location.pathname.match(/^\/questions\/\d+[\/$]/) && document.title.match(/^Page Not Found - /) && document.querySelector(".revision-comment"))) { return; } console.log('Deleted question detected, attempting to retrieve...'); if (typeof $ !== "undefined" && $ !== null) { return continueWithjQuery(); } else { script = document.createElement('script'); script.src = 'http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js'; script.addEventListener('load', continueWithjQuery); return document.body.appendChild(script); } }; markdownLoaded = void 0; answerFrame = null; continueWithjQuery = function() { var m, question; markdownLoaded = $.ajax({ dataType: 'script', cache: true, url: '/content/js/wmd.js' }); question = deletedPost(location.pathname.match(/^\/questions\/(\d+)[\/$]/)[1]); knownIds[question.id] = true; updateTitle('[deleted]'); $('.leftcol').remove(); $('.rightcol').remove(); $('#mainbar-full').append(question.element); if (m = location.hash.match(/^#(\d+)$/)) showAnswerIfNew(m[1]); return question.title.then(function(title) { return updateTitle("" + title + " [deleted]"); }); }; knownIds = {}; showAnswerIfNew = function(id) { var answer; if (!(String(id) in knownIds)) { knownIds[String(id)] = true; if (answerFrame == null) { answerFrame = $('
\n
\n
\n

Known Answers

\n
\n
\n
').appendTo($('#mainbar-full')); } answer = deletedPost(id); answerFrame.append(answer.element); return answer.element.addClass('answer'); } }; deletedPost = function(id) { var comments, editDoc, editPage, element, html, html_, myVotes, revisions, source, title, voteCounts; id = Number(id); editPage = editPageThrottle.throttle(function() { return $.ajax({ dataType: 'text', cache: true, url: "/posts/" + id + "/edit" }); }); myVotes = myVotesThrottle.throttle(function() { return $.ajax({ dataType: 'json', cache: true, url: "/posts/" + id + "/votes" }); }); comments = commentsThrottle.throttle(function() { return $.ajax({ dataType: 'html', cache: true, url: "/posts/" + id + "/comments" }); }); voteCounts = voteCountThrottle.throttle(function() { return $.ajax({ dataType: 'json', cache: true, url: "/posts/" + id + "/vote-counts" }); }); editDoc = from(editPage, function() { return $(this.split(/]+>/i)[1]); }); title = from(editDoc, function() { return this.find("input[name=title]").val(); }); source = from(editDoc, function() { return $(this).find("textarea").val(); }); revisions = from(editDoc, function() { return this.find('#revisions-list option').map(function() { var comment, date, id_, isCurrent, name, _, _ref; _ref = $(this).text().match(/^(.*?) \((.*?)\)(?: (.+))?/), _ = _ref[0], name = _ref[1], date = _ref[2], comment = _ref[3]; id_ = +$(this).attr('value'); isCurrent = $(this).is(':selected'); return { name: name, date: date, comment: comment, id: id_, isCurrent: isCurrent }; }); }); html_ = new $.Deferred; source.then(function(s) { return markdownLoaded.then(function() { return html_.resolve((new Markdown.Converter).makeHtml(s)); }, function() { return html_.reject(); }); }, function() { return html_.reject(); }); html = html_.promise(); element = $(POST_TEMPLATE); source.then(function(sourcep) { element.find('.post-text').empty().append($('
').text(sourcep));
      return html.then(function(htmlp) {
        console.log('Displaying rendered HTML.');
        return element.find('.post-text').html(htmlp);
      });
    }, function() {
      return element.find('.post-text').html('

\n This deleted post couldn\'t be retrieved.\n This will occur if you have less than 500 reputation or the post has been locked.\n

'); }); voteCounts.then(function(_arg) { var down, up; up = _arg.up, down = _arg.down; element.find('.JB_upvotes').text(up); return element.find('.JB_downvotes').text(down); }, function() { element.find('.JB_upvotes').text('?'); return element.find('.JB_downvotes').text('?'); }); myVotes.then(function(votes) { var vote, _i, _len; for (_i = 0, _len = votes.length; _i < _len; _i++) { vote = votes[_i]; showAnswerIfNew(vote.PostId); if (vote.PostId === id) { switch (vote.VoteTypeId) { case 1: element.find('.JB_accepted').show(); break; case 2: element.find('.JB_vote_up').removeClass('vote-up-off').addClass('vote-up-on'); break; case 3: element.find('.JB_vote_down').removeClass('vote-down-off').addClass('vote-down-on'); break; case 5: element.find('.JB_star').show().addClass('star-on'); } } } return; }); revisions.then(function(revisionsp) { var latest, original; latest = revisionsp[0]; original = revisionsp[revisionsp.length - 1]; element.find('.post-signature-owner .user-action-time').text('Posted ').append($('').text(original.date)); element.find('.post-signature-owner .user-details').text(original.name); if (latest !== original) { element.find('.post-signature .user-action-time').text('Edited ').append($('').text(latest.date)); return element.find('.post-signature .user-details').text(latest.name); } else { return element.find('.post-signature').remove(); } }, function() { element.find('.post-signature-owner').remove(); return element.find('.post-signature').remove(); }); comments.then(function(commentsp) { if (commentsp.length > 0) { return element.find('.comments').html(commentsp); } else { return element.find('.comments').remove(); } }); return { id: id, editPage: editPage, voteCounts: voteCounts, myVotes: myVotes, comments: comments, title: title, source: source, html: html, revisions: revisions, element: element }; }; siteName = $('title').text().match(/.* - (.+)$/)[1]; from = function(promise, f) { var result; result = new $.Deferred; promise.then(function(x) { var filterResult; filterResult = f.call(x, x); if ((filterResult != null ? filterResult.length : void 0) !== 0) { return result.resolve(filterResult); } else { return result.reject('no elements selected'); } }, function() { return result.reject(); }); return result.promise(); }; updateTitle = function(title) { $('title').text("" + title + " - " + siteName); return $('h1').text(title); }; DeferringThrottle = (function() { function DeferringThrottle(interval, initialDelay) { this._queue = []; this.interval = interval; if (initialDelay != null) { this.last = (Number(new Date)) - (this.interval - initialDelay); } else { this.last = 0; } this.awake = false; } DeferringThrottle.prototype._process = function() { var now; var _this = this; if (this._queue.length > 0) { now = Number(new Date); if (now > this.last + this.interval) { this._resolve.apply(this, this._queue.shift()); this.last = now; } return setTimeout(function() { return _this._process(); }, this.last + this.interval - now); } }; DeferringThrottle.prototype._resolve = function(deferred, f, args) { var secondaryValue; secondaryValue = f.apply(deferred, args); if (!(deferred.isResolved() || deferred.isRejected())) { $.when(secondaryValue).then((function() { return deferred.resolve.apply(deferred, arguments); }), (function() { return deferred.reject.apply(deferred, arguments); })); } return deferred; }; DeferringThrottle.prototype.throttle = function() { var args, f, result; f = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; result = new $.Deferred; this._queue.push([result, f, args]); this._process(); return result.promise(); }; return DeferringThrottle; })(); editPageThrottle = new DeferringThrottle(700); commentsThrottle = new DeferringThrottle(500, 500); myVotesThrottle = new DeferringThrottle(5000, 1000); voteCountThrottle = new DeferringThrottle(1700); POST_TEMPLATE = '
\n\n \n \n\n\n \n \n\n
\n \n \n
\n ...\n
\n
\n
\n ...\n
\n
\n \n \n \n
\n
\n

Attempting to load deleted post...

\n
\n \n \n \n \n \n \n \n
\n \n \n \n
\n
\n Attempting to load comments...\n
'; return start(); });