Greasy Fork

Greasy Fork is available in English.

Scratch Forums Composer Swag

Adds more posting tools to the Scratch forums composer

当前为 2015-03-31 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Scratch Forums Composer Swag
// @namespace    http://aputurk.tk/
// @version      0.1
// @description  Adds more posting tools to the Scratch forums composer
// @author       MegaApuTurkUltra
// @include      http://scratch.mit.edu/discuss*
// @include      https://scratch.mit.edu/discuss*
// @require      https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js
// @require      https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.3/jquery-ui.min.js
// @grant        none
// ==/UserScript==
this.$ = this.jQuery = jQuery.noConflict(true);

console.log("Scratch forums swag running");
// buttons for color, center, and code
$('<li class="markItUpButton markItUpButtonSwag1 "><a href="" title="Color">Color</a></li>').insertAfter(".markItUpButton7")
.find("a").css("background-image", "url(http://i.cubeupload.com/PsGwu4.png)").click(function(e){
    var color = prompt("Enter a hex color, rgb(a) color, or CSS color name");
    if(color === null || color === ""){ e.preventDefault(); return false; }
    $("#id_body").replaceSel('[color='+color+']'+$("#id_body").getSel()+'[/color]');
    e.preventDefault();
    return false;
});
$('<li class="markItUpButton markItUpButtonSwag3 "><a href="" title="Center">Center</a></li>').insertAfter(".markItUpButtonSwag1")
.find("a").css("background-image", "url(http://i.cubeupload.com/tfrXFd.png)").click(function(e){
    $("#id_body").replaceSel('[center]'+$("#id_body").getSel()+'[/center]');
    e.preventDefault();
    return false;
});
$('<li class="markItUpButton markItUpButtonSwag3 "><a href="" title="Code">Code</a></li>').insertAfter(".markItUpButton14")
.find("a").css("background-image", "url(http://i.cubeupload.com/XqOaKz.png)").click(function(e){
    var code = prompt("Enter a language");
    if(code === null || code === ""){ e.preventDefault(); return false; }
    $("#id_body").replaceSel('[code='+code+']\n'+$("#id_body").getSel()+'\n[/code]');
    e.preventDefault();
    return false;
});
// and now for the swaggy sticky quoter
var currentStickyTitle = "";
var currentStickyLink = "";
var onSelectionPage = false;
var cannedDlg = $("<div id='canned-dlg' title='Insert Canned Quote'>Loading...<br/><div id='canned-progress'></div></div>").dialog({
    autoOpen: false,
    buttons: {
        "Cancel": function(){
            $(this).dialog("close");
        }
    },
    width: 500,
    height: 500,
    show: "fade",
    hide: "fade",
    dialogClass: "jqui-modal canned-dlg"
});
var menu;
var select = $("<div id='canned-page2'><p>Select the part of the post you want, then click OK</p>\
<textarea id='canned-select'>Loading...</textarea><br/><button id='canned-ok'>Use selection</button></div>");
var ajaxLoading = false;
function loadAjax(){
    if(ajaxLoading) return;
    ajaxLoading = true;
    $.get("/discuss/", {dataType:"html"}, function(data){
        menu = $("<ul id='canned-menu'></ul>");
        $(data).find(".tclcon a").each(function(){
            menu.append(
                $("<li></li>").addClass("canned-menu-item").attr("data-link", $(this).attr("href")).append($("<button></button")
                                                                                                           .text($(this).text()).addClass("canned-menu-button canned-primary")));
        });
        var completeXHRs = 0;
        var totalXHRs = menu.find("li").length;
        var complete = function(){
            completeXHRs++;
            $("#canned-progress").progressbar({value:Math.round(100*completeXHRs/totalXHRs)});
            if(completeXHRs >= totalXHRs){
                $("#canned-dlg").html("");
                $("#canned-dlg").append(menu);
                cannedDlg.append(select);
                $("#canned-select").css({"width":"100%"}).attr("rows","10");
                $("#canned-ok").click(function(e){
                    var sel = $("#canned-select").getSel();
                    console.log(sel);
                    if(sel===null || sel==="") return;
                    $("#id_body").replaceSel('[quote]\n[b]As stated on the sticky [url=https://scratch.mit.edu'+currentStickyLink+']'
                                             +currentStickyTitle.replace("(New Posts)", "")+'[/url]:[/b]\n\n'+sel+'\n[/quote]');
                    cannedDlg.dialog("close");
                    e.preventDefault();
                    return false;
                });
                select.hide();
                $(".canned-menu-button").button().css("width", "100%");
                $(".canned-menu-button.canned-primary").click(function(){
                    $(this).parent().find(".canned-submenu").slideToggle();
                    cannedDlg.dialog({title: "Select a sticky topic"});
                });
                $(".canned-menu-button.canned-secondary").click(function(){
                    cannedDlg.dialog({title: "Select the part of the sticky you want"});
                    $("#canned-select").val("Loading...");
                    var url = $(this).parent().attr("data-sticky-link");
                    currentStickyTitle = $(this).parent().attr("data-sticky-title");
                    currentStickyLink = $(this).parent().attr("data-sticky-link");
                    menu.fadeOut(700, function(){
                        select.fadeIn();
                    });
                    onSelectPage = true;
                    $.get(url, {dataType:"html"}, function(data3){
                        var source = $(data3).find(".firstpost").eq(0).find(".conr").next().attr("href");
                        $.get(source+"source/", function(data4){
                            $("#canned-select").val(data4);
                        });
                    });
                });
                $(".canned-submenu").hide();
                menu.css("list-style-type", "none");
                $(".canned-submenu").css("list-style-type", "none");
            }
        };
        menu.find("li").each(function(){
            var thisLi = $(this);
            $.get($(this).attr("data-link"), {dataType:"html"}, function(data2){
                var submenu = $("<ul class='canned-submenu'></ul");
                $(data2).find(".isticky").each(function(){
                    var a = $(this).next().find("a");
                    submenu.append(
                        $("<li></li>").addClass("canned-menu-item").attr("data-sticky-link", a.attr("href")).attr("data-sticky-title", a.text()).append($("<button></button")
                                                                                                                                                        .text(a.text()).addClass("canned-menu-button canned-secondary")));
                });
                thisLi.append(submenu);
            }).always(function(){
                complete();
            });
        });

    });
}
$(".canned-dlg button.ui-dialog-titlebar-close").hide();
$('<li class="markItUpButton markItUpButtonSwag2 "><a href="" title="Canned quotes">Canned quotes</a></li>').insertAfter(".markItUpButton11")
.find("a").css("background-image", "url(http://i.cubeupload.com/l6I5Sk.png)").click(function(e){
    loadAjax();
    cannedDlg.dialog({title: "Select a forum section to find stickies in"}).dialog("open");
    if(typeof menu !== "undefined") menu.show();
    select.hide();
    onSelectPage = false;
    e.preventDefault();
    return false;
});

var draftStatus = $("<span></span>");
var currentSessionRnd = Math.round(Math.random() * 1000000000);

$('<li class="markItUpButton markItUpButtonSwag3 "><a href="javascript:void(0)" title="Save draft">Save draft</a></li>').insertAfter(".markItUpButton16")
.find("a").css("background-image", "url(http://i.cubeupload.com/NY2bfk.png)").click(function(e){
    var title = "draft_" + currentSessionRnd;
    if($("#id_name").length > 0) title = $("#id_name").val();
    var content = $("#id_body").val();
    var drafts = {};
    if(typeof localStorage['forumSwagDrafts'] !== "undefined")
        drafts = JSON.parse(localStorage['forumSwagDrafts']);
    if(drafts.hasOwnProperty(title)){
        if(!confirm("Overwrite draft '" + title + "'?")){
            e.preventDefault();
            return false;
        }
    }
    drafts[title] = content;
    localStorage['forumSwagDrafts'] = JSON.stringify(drafts);
    draftStatus.text("Saved draft: "+title).show().fadeOut(1000);
    e.preventDefault();
    return false;
});

$('<li class="markItUpButton markItUpButtonSwag4 "><a href="javascript:void(0)" title="Open draft">Open draft</a></li>').insertAfter(".markItUpButton16")
.find("a").css("background-image", "url(http://i.cubeupload.com/BSsouH.png)").click(function(e){
    if(typeof localStorage['forumSwagDrafts'] === "undefined") localStorage['forumSwagDrafts'] = JSON.stringify({});
    var drafts = JSON.parse(localStorage['forumSwagDrafts']);
    var select = $("<select><option value='__internal_default' disabled>&gt; Select a draft</option></select").css("height","16px");
    select.append("<option value='__internal_del'>&gt; Delete a draft</option>");
    var hasItems = false;
    for(var key in drafts){
        if(drafts.hasOwnProperty(key)){
            select.append($("<option></option>").attr("value", key).text(key));
            hasItems = true;
        }
    }
    if(!hasItems) {
        draftStatus.text("No drafts!").show().fadeOut(1000);
        e.preventDefault();
        return false;
    }
    select.append($("<option></option>").attr("value", "__internal_none").text("Cancel"));
    draftStatus.html("").append(select).show();
    select.on("change", function(){
        var value = $(this).val();
        if(value === "__internal_none"){
            draftStatus.fadeOut();
            return;
        }
        var is_del = typeof $(this).attr("data-delete") !== "undefined";
        if(is_del){
            if(!confirm("Delete '"+value+"'?")){
                $(this).val("__internal_default");
                return;
            }
            var drafts = JSON.parse(localStorage['forumSwagDrafts']);
            delete drafts[value];
            localStorage['forumSwagDrafts'] = JSON.stringify(drafts);
            draftStatus.fadeOut();
            return;
        }
        
        if(value === "__internal_del"){
            $(this).attr("data-delete", "yes");
            $(this).find("option").eq(0).text("Select a draft to delete");
            $(this).find("option").eq(1).remove();
            $(this).val("__internal_default");
            return;
        }

        if($("#id_body").val().trim() !== ""){
            if(!confirm("Overwrite text in editor?")){
                $(this).val("__internal_default");
                return;
            }
        }

        var drafts2 = JSON.parse(localStorage['forumSwagDrafts']);
        if($("#id_name").length > 0) {
            $("#id_name").val(value);
        }
        $("#id_body").val(drafts2[value]);
        draftStatus.text("Loaded draft: " + value).show().fadeOut(1000);
    });
    e.preventDefault();
    return false;
});

draftStatus.insertAfter(".markItUpButtonSwag4");

// <hah>
$(".postsignature").each(function(){
    var img = $("<img/>").attr("src","http://i.cubeupload.com/h1KKLg.gif").css({
        "height": $(this).height(),
        "position": "absolute",
        "top": "0px",
        "left": "-110px"
    }).addClass("es").click(window.open.bind(window, "http://scratch.mit.edu/discuss/youtube/2HQaBWziYvY", "_blank", ""));
    $(this).css("position", "relative").append(img);
    (function(img, width){
        setInterval(function(){
            img.css("left", "-110px").delay(Math.round(Math.random()*1000)).animate({left: width+100}, 5000, "linear");
        }, 6000);
    })(img, $(this).width());
});
// </hah>

// mostly from http://stackoverflow.com/a/3966822/1021196
function getInputSelection(el) {
    var start = 0, end = 0, normalizedValue, range,
        textInputRange, len, endRange;

    if (typeof el.selectionStart == "number" && typeof el.selectionEnd == "number") {
        start = el.selectionStart;
        end = el.selectionEnd;
    } else {
        range = document.selection.createRange();

        if (range && range.parentElement() == el) {
            len = el.value.length;
            normalizedValue = el.value.replace(/\r\n/g, "\n");

            // Create a working TextRange that lives only in the input
            textInputRange = el.createTextRange();
            textInputRange.moveToBookmark(range.getBookmark());

            // Check if the start and end of the selection are at the very end
            // of the input, since moveStart/moveEnd doesn't return what we want
            // in those cases
            endRange = el.createTextRange();
            endRange.collapse(false);

            if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
                start = end = len;
            } else {
                start = -textInputRange.moveStart("character", -len);
                start += normalizedValue.slice(0, start).split("\n").length - 1;

                if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) {
                    end = len;
                } else {
                    end = -textInputRange.moveEnd("character", -len);
                    end += normalizedValue.slice(0, end).split("\n").length - 1;
                }
            }
        }
    }

    return {
        start: start,
        end: end
    };
}
function getSelectedText(el){
    var sel = getInputSelection(el), val = el.value;
    return val.slice(sel.start, sel.end);
}
function replaceSelectedText(el, text) {
    var sel = getInputSelection(el), val = el.value;
    el.value = val.slice(0, sel.start) + text + val.slice(sel.end);
}
$.fn.getSel = function() {
    return getSelectedText($(this).get(0));
};
$.fn.replaceSel = function(text){
    replaceSelectedText($(this).get(0), text);
};