TrueAchievements improver

Improves the TrueAchievements interface in various ways

当前为 2016-04-07 提交的版本,查看 最新版本

// ==UserScript==
// @name         TrueAchievements improver
// @namespace    mobiusevalon.tibbius.com
// @version      0.7
// @description  Improves the TrueAchievements interface in various ways
// @author       Mobius Evalon
// @require      https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js
// @include      /^https{0,1}:\/\/\w{0,}\.?trueachievements\.com.*$/
// @grant        none
// ==/UserScript==

var hide_ads = 1,
    normalize_dates = 1,
    improve_chat = 1,
    minimalize_chat = 1,
    session_user_links = 1,
    session_user_status = 1,
    feed_permalinks = 1,
    fix_spoilers = 1;

Date.prototype.getShortMonthString = function()
{
    switch(this.getMonth())
    {
        case 0: return "Jan";
        case 1: return "Feb";
        case 2: return "Mar";
        case 3: return "Apr";
        case 4: return "May";
        case 5: return "Jun";
        case 6: return "Jul";
        case 7: return "Aug";
        case 8: return "Sep";
        case 9: return "Oct";
        case 10: return "Nov";
        case 11: return "Dec";
    }
};

Date.prototype.getTwoDigitHours = function()
{
    var n = this.getHours();
    if(n < 10) return ("0"+n);
    else return n.toString();
};

Date.prototype.getTwoDigitMinutes = function()
{
    var n = this.getMinutes();
    if(n < 10) return ("0"+n);
    else return n.toString();
};

Date.prototype.getTwoDigitDate = function()
{
    var n = this.getDate();
    if(n < 10) return ("0"+n);
    else return n.toString();
};

Date.prototype.adjustDate = function(n)
{
    this.setDate(this.getDate()+n);
};

Date.prototype.getDateAfterAdjustment = function(n)
{
    this.adjustDate(n);
    return this.getDate();
};

Date.prototype.shortDate = function()
{
    return (this.getTwoDigitDate()+" "+this.getShortMonthString()+" "+this.getFullYear());
};

Date.prototype.shortDateTime = function()
{
    return (this.getTwoDigitDate()+" "+this.getShortMonthString()+" "+this.getFullYear()+", "+this.getTwoDigitHours()+":"+this.getTwoDigitMinutes());
};

function datetime_master(obj)
{
    var date = new Date();

    if(!obj.hasOwnProperty("minute") || obj.minute === undefined) obj.minute = "00";
    if(!obj.hasOwnProperty("hour") || obj.hour === undefined) obj.hour = "00";
    if($.type(obj.day) === "string") obj.day = obj.day.toLowerCase();
    if(!obj.hasOwnProperty("day") || obj.day === undefined || obj.day === "today") obj.day = date.getDate();
    else if(obj.day === "yesterday") obj.day = date.getDateAfterAdjustment(-1);
    else if(obj.day === "tomorrow") obj.day = date.getDateAfterAdjustment(+1);
    if(!obj.hasOwnProperty("month") || obj.month === undefined) obj.month = date.getShortMonthString();
    if(!obj.hasOwnProperty("year") || obj.year === undefined) obj.year = date.getFullYear();
    else if(obj.year.length === 2) obj.year = ("20"+obj.year);

    date = new Date(obj.month+" "+obj.day+" "+obj.year+" "+obj.hour+":"+obj.minute);

    return date;
}

function short_datetime_callback() // mon, jan 1 1900 at 00:00
{
    var len = arguments.length;
    var date = datetime_master({year:arguments[len-5],month:arguments[len-6],day:(arguments[len-7]||arguments[len-8]),hour:arguments[len-4],minute:arguments[len-3]});
    return date.shortDateTime();
}

function short_date_callback() // 1 jan 1900
{
    var len = arguments.length;
    var date = datetime_master({year:arguments[len-3],month:arguments[len-4],day:(arguments[len-5]||arguments[len-6])});
    return date.shortDate();
}

function uri()
{
	var m = window.location.href.match(/\/([\w-]*\.aspx)(?:\?|$)/i);
	if(m !== null) return m[1];
	return "";
}

function filter_settings_by_query(q)
{
    $("div#oOptionPanel div.inputform div.innerform").each(function() {
        $(this).children("div.filtered-out, div:not([class]), div[class='']").each(function() {
            if(!q.length || $(this).html().toLowerCase().indexOf(q) > -1) $(this).removeClass("filtered-out").show();
            else $(this).addClass("filtered-out").hide();
        });
        if(!q.length || $(this).children("div").not(".clearboth, .filtered-out").length) $(this).parent().show();
        else $(this).parent().hide();
    });
}

function json_obj(json)
{
    var obj;
    if(typeof json === "string")
    {
        try {obj = JSON.parse(json);}
        catch(e) {console.log("Malformed JSON object.  Error message from JSON library: ["+e.message+"]");}
    }
    return obj;
}

function localstorage_obj(key)
{
    var obj = json_obj(localStorage.getItem(key));
    if(typeof obj !== "object") localStorage.removeItem(key);
    return obj;
}

function default_settings()
{
    return {hide_ads:true,
            normalize_dates:true,
            improve_chat:true,
            session_userlinks_compare:true,
            session_hide_user_statuses:true,
            feed_permalinks:true,
            fix_spoilers:true,
            settings_page_filter:true};
}

function store_settings()
{
    localStorage.setItem("ta_improver_settings",JSON.stringify({hide_ads:checkbox("#tai_hide_ads"),
                                                                normalize_dates:checkbox("#tai_dates"),
                                                                improve_chat:checkbox("#tai_improve_chat"),
                                                                session_userlinks_compare:checkbox("#tai_session_compare"),
                                                                session_hide_user_statuses:checkbox("#tai_user_statuses"),
                                                                feed_permalinks:checkbox("#tai_permalinks"),
                                                                fix_spoilers:checkbox("#tai_spoilers"),
                                                                settings_page_filter:checkbox("#tai_filter")}));
}

function checkbox(id)
{
    return ($("#divImprover "+id).prop("checked") === true);
}

function setting_display(id,name,tooltip,checked)
{
    return $("<div/>")
        .append($("<label/>")
                .attr("class","vlargelabel")
                .append($("<img/>")
                        .attr({"src":"/images/icons/information.png",
                               "alt":tooltip,
                               "title":tooltip})
                        .css({"width":"16px",
                              "height":"16px",
                              "margin-right":"4px"}),
                        $("<span/>")
                        .text(name)
                       ),
                $("<div/>")
                .attr("class","singleline")
                .append($("<input/>")
                        .attr({"id":id,
                               "type":"checkbox"})
                        .prop("checked",((checked !== true) ? false : true))
                        .on("change onchange",function() {store_settings();})
                       )
               );
}

$(document).ready(function() {
    var settings = localstorage_obj("ta_improver_settings");
    if(typeof settings !== "object") settings = default_settings();

    if(settings.hide_ads) $("#topad-wrap, #divTAProHolder, #divGiftProPanel, .followuson, .internalad, .rightintergi, .sharepanel").remove(); // oops, the ads disappeared
    if(settings.normalize_dates)
    {
        $("td.lastpostdate, td.posted, div.info, td.time, td.sentdate, div.coveritem, td.ta, div.boostingdate, div.gamingsession h3, div.subcommentinfo, td.lastpost, div.links, #oGamer div.itemright p").each(function() {
            $(this).html($(this).html().replace(/(?:on )?(?:[A-Z]{1}[a-z]{2,8}, )?(today|yesterday|tomorrow|(?:\d{1,2}) ([A-Z]{1}[a-z]{2,8}) ?(\d{2,4})?) at (\d{2}):(\d{2})/g,short_datetime_callback));
        });
        $("div.addedby, td.hwr, table.comparison td.green, .maincolumnpanel .itemright h3, #oGamer div.itemright p").each(function() {
            $(this).html($(this).html().replace(/(?:on )?(?:[A-Z]{1}[a-z]{2,8}, )?(today|yesterday|tomorrow|(\d{1,2}) ([A-Z]{1}[a-z]{2,8}) (\d{2,4}))/g,short_date_callback));
        });
    }
    // fix spoilers
    if(settings.fix_spoilers) $("div.spoiler").each(function() {
        $(this)
            .css("border","1px solid #000")
            .children("a").first().replaceWith($("<span/>")
                                               .text("SPOILER: click to toggle")
                                               .css({"display":"inline-block",
                                                     "width":"100%",
                                                     "cursor":"pointer"})
                                               .click(function() {var $span_content = $(this).siblings("span.spoiler").first();

                                                                  if($span_content.css("display") === "none") $span_content.show();
                                                                  else $span_content.hide();
                                                                 })
                                              );
    });
    // friend feed permalinks
    if(settings.feed_permalinks) $("#oFriendFeed div.Comment p").each(function() {$(this).prepend($("<a/>")
                                                                                         .attr({"href":("?gfcid="+$(this).parent().attr("id").slice(5)),
                                                                                                "target":"_blank"})
                                                                                         .append($("<img/>")
                                                                                                 .attr({"src":"/images/icons/permalink.png",
                                                                                                        "title":"Permalink",
                                                                                                        "alt":"Permalink"})
                                                                                                 .css({"float":"right",
                                                                                                       "width":"16px",
                                                                                                       "height":"16px",
                                                                                                       "border":"none",
                                                                                                       "padding":"0px",
                                                                                                       "margin":"8px 2px 0px 5px"})
                                                                                                )
                                                                                        );
                                                                        });

    switch(uri())
    {
        case "gamingsessionfeedback.aspx":
            $(".gsdisclaimer").remove();
            break;
        case "gamingsession.aspx":
            $(".gsdisclaimer").remove();

            if(settings.session_userlinks_compare && $("#mnuMyPages").length) // change gamertag links to compare page
            {
                var game_id = $("h4 a[title='View on session calendar']").first().attr("href"),
                    user_id = $("#mnuMyPages li a[href*='/gamerstats.aspx?gamerid=']").attr("href");
                game_id = game_id.slice(game_id.lastIndexOf("=")+1);
                user_id = user_id.slice(user_id.lastIndexOf("=")+1);

                $("#oGamingSessionGamerList td.gamer").each(function() {
                    var $gamer_anchor = $(this).children("a").first(),
                        other_id = $gamer_anchor.attr("href");
                    other_id = other_id.slice(other_id.lastIndexOf("=")+1);

                    if(other_id != user_id) $gamer_anchor.attr("href",("/comparison.aspx?gameid="+game_id+"&gamerid="+user_id+"&friendid="+other_id));
                    $gamer_anchor.attr("target","_blank");
                });
            }

            if(settings.session_hide_user_statuses) $("span.sitestatus").remove();
            break;
        case "customize.aspx":
            // insert the options for this script on the page
            $("#oOptionPanel").prepend($("<div/>")
                                   .attr({"class":"inputform",
                                          "id":"divImprover"})
                                   .append($("<div/>")
                                           .attr("class","innerform")
                                           .append($("<h2/>")
                                                   .text("TA Improver Script"),
                                                   setting_display("tai_hide_ads","Hide advertisements","This is pretty obvious.",settings.hide_ads),
                                                   setting_display("tai_dates","Normalize dates","TA has a bad habit of using half a dozen different date formats and further using fuzzy dates by saying something like 'tomorrow' instead of listing a calendar date.  This option sets all dates to the same format.",settings.normalize_dates),
                                                   setting_display("tai_improve_chat","Improve chat interface","Rearrange the chat interface to look better and save space.",settings.improve_chat),
                                                   setting_display("tai_session_compare","Change user session links to compare","When clicking on a gamertag in a session roster table, this option will default the link to compare your achievements with them for that game instead of linking you to their homepage.",settings.session_userlinks_compare),
                                                   setting_display("tai_user_statuses","Hide user statuses in sessions","User statuses are generally just stretching the size of the table for no good reason, so using this option will hide statuses in the session roster table.",settings.session_hide_user_statuses),
                                                   setting_display("tai_permalinks","Friend feed permalinks","Add a permalink icon to comments on the friend feed for easily linking other people to the conversation.",settings.feed_permalinks),
                                                   setting_display("tai_spoilers","Fix spoiler tags","This option will change spoiler tags so that the header text always remains and can be clicked to collapse the spoiler content again.",settings.fix_spoilers),
                                                   setting_display("tai_filter","Filter settings","Adds a textbox to the top of this page to easily filter out options by search query.",settings.settings_page_filter)
                                                  ),
                                           $("<div/>")
                                           .attr("class","clearboth")
                                          )
                                  );
            // this page has become ridiculously bloated so this simple search filter helps quickly narrow relevant options down
            if(settings.settings_page_filter) $("div#main h1.pagetitle")
                .css("display","inline-block")
                .after($("<img/>")
                       .attr({"src":"/images/icons/information.png",
                              "alt":"Quickly find relevant options you're looking for by typing search text in the box, then hitting Enter/Return or clicking the Find button.",
                              "title":"Quickly find relevant options you're looking for by typing search text in the box, then hitting Enter/Return or clicking the Find button."})
                       .css("margin-left","8px"),
                       $("<input/>")
                       .attr({"type":"text",
                              "id":"filter-text"})
                       .css({"margin-left":"8px",
                             "margin-bottom":"-2px"})
                       .keyup(function(e) {if(e.which === 13 || !$(this).val().length) $("#execute-filter").click();}),
                       $("<input/>")
                       .attr({"type":"button",
                              "value":"Find",
                              "class":"button",
                              "id":"execute-filter"})
                       .css("margin-left","8px")
                       .click(function() {filter_settings_by_query($("#filter-text").val());})
                      );
            break;
        case "chat.aspx":
            if(settings.improve_chat)
            {
                // this whole section is overriding the default styling of the page when viewing the chatroom to change a whole
                // bunch of things, including:
                // # changing the font of the whole chat interface
                // # extending the height of the userlist to be the same as the chatbox
                // # collapses vertical space to fit the entire chat on one screen without scrolling
                // # extending the width of the input box
                // # giving the timestamp a fixed width
                // # giving the gamertag a fixed width
                // # positioning the buttons we'll be adding after the text input later
                // # preventing long words (spam) from adding horizontal scrolling
                // # moves the clear chat button out of the display box and puts it next to the input box
                // # removes the large footer for the chat guidelines and makes it a tiny button by the input box instead
                // # removes the "TrueAchievements Chat" page header

                // this section moves the clear chat button and creates a new rules button to the right of the input box at the bottom
                $("#btnClearChat")
                    .insertBefore($("#divChatKey"))
                    .after($("<a/>")
                           .attr({"href":"chatpolicy.aspx",
                                  "target":"_blank"})
                           .append($("<img/>")
                                   .attr({"src":"/images/itemflags/MainStoryline.png",
                                          "id":"btnChatRules",
                                          "title":"Chat guidelines",
                                          "alt":"Chat guidelines"})
                                  )
                          );
                $("#divChatKey, #divChatInformation, h1.pagetitle, #footer-wrap").remove();

                $("head").append($("<style/>")
                                 .attr("type","text/css")
                                 .text("div#divChatHolder {font-family: 'Droid Sans Mono',monospace !important} "+
                                       "div#divChatList {width: 175px !important; height: 450px !important;}" +
                                       "div#divChatBody {margin-right: 190px !important; height: 450px !important; overflow-wrap: break-word !important;} "+
                                       "input#txtChatMessage {width: 720px !important;} "+
                                       "span.chattime {display: inline-block !important; width: 65px !important; font-style: normal !important;} "+
                                       "span.gamertag {display: inline-block !important; width: 105px !important;} "+
                                       "a#btnClearChat {position: relative !important; top: -4px !important; right: auto !important; padding-right: 8px !important;} "+
                                       "img#btnChatRules {position: relative !important; top: -4px !important;} "+
                                       "div#main-holder {padding-bottom: 0 !important;} "+
                                       "div#main {padding: 10px 10px 0px 10px !important; min-height: 0 !important;} "+
                                       "div#page-wrap {padding-bottom: 0 !important;} "+
                                       "div#page {min-height: 0 !important;} ")
                            );
            }
            break;
    }
});