Unedit and Undelete for Reddit

Creates the option next to edited and deleted Reddit comments/posts to show the original comment from before it was edited

当前为 2020-07-25 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Unedit and Undelete for Reddit
// @namespace    http://tampermonkey.net/
// @version      3.0
// @description  Creates the option next to edited and deleted Reddit comments/posts to show the original comment from before it was edited
// @author       u/eyl327
// @match        http*://*.reddit.com/r/*
// @grant        none
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/showdown.min.js
// ==/UserScript==

(function () {
    'use strict';

    var isOldReddit = /old\.reddit/.test(window.location.href);

    var scriptTimeout = null;

    var currentLoading;

    var mdConverter = new showdown.Converter();

    /* find the id of a comment */
    function getId(e, old) {
        var id = "";
        try {
            if (!old) {
                var comment = e.parentElement.parentElement.parentElement.parentElement.querySelector(".Comment");
                id = Array.from(comment.classList).filter(function (x) { return x.indexOf("_") > -1; })[0];
            }
            else {
                id = e.parentElement.parentElement.parentElement.id;
                /* old reddit submission */
                if (id === "" && isInSubmission(e)) {
                    id = window.location.href.match(/comments\/([A-Za-z0-9]{5,8})\//)[1];
                }
                /* old reddit comment */
                else {
                    id = id.split("_").slice(1).join("_");
                }
                if (id === "") {
                    id = e.parentElement.parentElement.getElementsByClassName("reportform")[0].className.replace(/.*t1/,'t1');
                }
            }
        }
        catch (error) {
            return null;
        }
        return id;
    }

    /* get the last paragraph of the comment body */
    function getCommentBodyElement(id, old) {
        var el = null;
        try {
            if (!old) {
                el = Array.from(document.getElementById(id).getElementsByTagName("p")).slice(-1)[0];
                if (!el) { el = document.getElementById(id); }
            }
            else {
                if (document.querySelector("form[id*="+id+"] div.md") && document.querySelector("form[id*="+id+"] div.md").getElementsByTagName("p")) {
                    el = Array.from(document.querySelector("form[id*="+id+"] div.md").getElementsByTagName("p")).slice(-1)[0];
                }
                if (!el) { el = document.querySelector('.report-'+id).parentElement.parentElement; }
            }
        }
        catch (error) {
            return null;
        }
        return el;
    }

    function isInSubmission(e) {
        return e.parentElement.parentElement.className == "top-matter";
    }

    function isInViewport(e) {
        var rect = e.getBoundingClientRect();
        return (
            rect.top >= 0 &&
            rect.left >= 0 &&
            rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
            rect.right <= (window.innerWidth || document.documentElement.clientWidth)
        );
    }

    function showOriginalComment(x, commentBodyElement, postType, body) {
        /* create new paragraph containing the body of the original comment/post */
        var origBody = document.createElement("p");
        origBody.innerHTML = mdConverter.makeHtml("\n\n### Original "+postType+":\n\n" + body);
        //origBody.className = x.className;
        origBody.style.opacity = 0.96;
        origBody.style.fontSize = "14px";
        origBody.style.background = "#ffed4c5c";
        origBody.style.padding = "16px";
        origBody.style.color = "inherit";
        origBody.style.lineHeight = "20px";
        commentBodyElement.appendChild(origBody);
        // scroll into view
        setTimeout(function(){
            if (!isInViewport(origBody)) {
                origBody.scrollIntoView({behavior: "smooth"});
            }
        }, 500);
    }

    /* create links and define click event */
    function createLink(x) {
        /* create link */
        var l = document.createElement("a");
        l.innerText = "Show original";
        l.className = x.className + " showOriginal";
        l.style.textDecoration = "underline";
        l.style.cursor = "pointer";
        l.style.marginLeft = "6px";
        x.parentElement.appendChild(l);
        x.className += " found";
        /* click event */
        l.addEventListener("click", function () {
            /* allow only 1 request at a time */
            if ((typeof (currentLoading) != "undefined") && (currentLoading !== null)) { return; }
            /* collect info on selected comment */
            var id = getId(this, isOldReddit);
            var url = "";
            if (!isInSubmission(this)) {
                url = "https://api.pushshift.io/reddit/search/comment/?ids=" + id + "&sort=desc&sort_type=created_utc";
            }
            else {
                url = "https://api.pushshift.io/reddit/search/submission/?ids=" + id + "&sort=desc&sort_type=created_utc";
            }
            /* set loading status */
            currentLoading = this;
            this.innerHTML = "loading...";
            /* fetch original comment from pushshift api */
            fetch(url)
                .then(function (res) { return res.json(); })
                .then(function (out) {
                    /* locate the comment that was being loaded */
                    var loading = currentLoading;
                    /* reset status */
                    currentLoading = null;
                    /* locate comment body */
                    var id = getId(loading, isOldReddit);
                    var commentBodyElement = getCommentBodyElement(id, isOldReddit);
                    /* check that comment was fetched and body element exists */
                    if (commentBodyElement && out && out.data && (out.data.length > 0) && out.data[0].body) {
                        /* create new paragraph containing the body of the original comment */
                        showOriginalComment(x, commentBodyElement, "comment", out.data[0].body);
                        /* remove loading status from comment */
                        loading.innerHTML = "";
                    }
                    /* check if result has selftext instead of body (it is a submission post) */
                    else if (commentBodyElement && out && out.data && (out.data.length > 0) && out.data[0].selftext) {
                        /* create new paragraph containing the selftext of the original submission */
                        showOriginalComment(x, commentBodyElement, "post", out.data[0].selftext);
                        /* remove loading status from post */
                        loading.innerHTML = "";
                    }
                    else if (out && out.data && (out.data.length === 0)) {
                        loading.innerHTML = "not found";
                        console.log("id: "+id);
                        console.log(out);
                    }
                    else {
                        loading.innerHTML = "fetch failed";
                        console.log("id: "+id);
                        console.log(out);
                    }
                })
                .catch(function(err) { throw err; });
        }, false);
    }

    /* locate comments and call function to add links to each */
    function findEditedComments() {
        /* when function runs, cancel timeout */
        if (scriptTimeout) {
            scriptTimeout = null;
        }
        /* list of comments which have been edited */
        var editedComments = [];
        /* Redesign */
        if (!isOldReddit) {
            /* edited comments */
            editedComments = Array.from(document.querySelectorAll(".Comment div span")).filter(function (x, y, z) {
                return x.parentElement.querySelector("a.showOriginal") === null &&
                    x.innerText.substr(0, 6) == "edited";
            });
            /* include deleted comments */
            editedComments = editedComments.concat(Array.from(document.querySelectorAll(".Comment div span")).filter(function (x, y, z) {
                return x.parentElement.querySelector("a.showOriginal") === null &&
                    x.innerText.substr(0, 15) == "Comment deleted";
            }));
        }
        /* Old Reddit */
        else {
            /* edited comments and submissions */
            editedComments = Array.from(document.querySelectorAll("time")).filter(function (x, y, z) {
                return Array.from(x.classList).indexOf("found") < 0 &&
                    x.title.substr(0,11) == "last edited";
            });
        }
        /* create links */
        editedComments.forEach(function (x, y, z) { createLink(x); });
    }

    /* check for new comments when you scroll */
    window.onscroll = function () {
        if (!scriptTimeout) {
            scriptTimeout = setTimeout(findEditedComments, 1000);
        }
    };

    findEditedComments();
})();