Badge Oneboxer for Chat.SE This script makes it possible for badges to onebox in Chat.





The install requires Tamper/GreaseMonkey. Click here to install,
and it's on GitHub and StackApps!

// ==UserScript==
// @name Badge Oneboxer
// @description Converts tag-like badge comments to badges
// @version 0.24
// @match *://chat.stackexchange.com/rooms/*
// @match *://chat.stackoverflow.com/rooms/*
// @match *://chat.meta.stackexchange.com/rooms/*
// @author The-Quill
// @downloadURL  https://raw.githubusercontent.com/The-Quill/badge-oneboxer/master/badge-oneboxer.user.js
// @updateURL https://raw.githubusercontent.com/The-Quill/badge-oneboxer/master/badge-oneboxer.user.js
// @grant GM_getResourceText
// @resource    badges  https://rawgit.com/The-Quill/badge-oneboxer/master/badges.json
// @run-at document-end
// ==/UserScript==

    'use strict';
    var Badges;
    $.get("https://rawgit.com/The-Quill/badge-oneboxer/master/badges.json", function(data){
        Badges = data;
    }).done(function(){
        var m = new MutationObserver(function(){
            ReplaceAll();
        });
        m.observe(document.getElementById("chat"), {childList: true});
        ReplaceAll();
    });
    function ReplaceAll(){
        var messages = document.getElementsByClassName('message');
        for (var i = 0, length = messages.length; i &lt; length - 1; i++){
            ReplaceText(messages[i])
        }
    }
    var regex = /(\[badge:([a-zA-Z#.\-]+)\])/i;
    var ColourTransforms = {
        bronze: "CC9966",
        silver: "C5C5C5",
        gold: "FFCC00"
    };
    function ReplaceText(node){
        if (!node) return false;
        var badgeProperties = SelectBadgeProperties(node.innerText);
        if (!badgeProperties) { return false };
        if (badgeProperties.total == "") return false;
        node.innerHTML = node.innerHTML.replace(
            badgeProperties.total,
            "&lt;span class=\"ob-post-tag\" style=\"background-color: #FFF; color: #000; border-color: #000; border-style: solid;\"&gt;" +
            "&lt;svg version=\"1.1\" height=\"18\" width=\"15\" xmlns=\"http://www.w3.org/2000/svg\"&gt;&lt;circle fill=\"#" +
            (Badges.hasOwnProperty(badgeProperties.name) ? ColourTransforms[Badges[badgeProperties.name]] : "000") +
            "\" r=\"3\" cy=\"13.5\" cx=\"3\" /&gt;&lt;/svg&gt;" +
            badgeProperties.name + "&lt;/span&gt;"
        );
        if (HasBadgeText(node.innerText)){
            console.log("again");
            ReplaceText(node);
        }
    };
    function HasBadgeText(text){
        return regex.test(text);
    }
    function SelectBadgeProperties(text){
        if (!HasBadgeText(text)) return false;
        var matchesArray = text.match(regex);
        return {
            total: matchesArray[0],
            name:  matchesArray[2]
        };
    }
N.b. the current GitHub source already has some of these fixed.

Firstly, all lines are indented one level more than I would expect (the
first comment is also indented in the GitHub source); that seems to
break the user script annotation, as at the moment I don't see either
the description, the name, or the @match restrictions applied after
installation.

Otherwise formatting is fine, though the naming convention (upper camel
case for top level definitions) is unusual.  My editor also marks a few
lines with missing semicolon; that could be fixed just for consistency.

Even though it might not happen usually I'd ensure that all referenced
functions are defined before calling them, in this case ReplaceAll is
run from the callback, when it's only defined a few lines later.

The function ReplaceAll also returns false in a couple of cases, but
firstly, the return value isn't used anywhere and secondly, the function
doesn't return a value in one case.  I'd suggest to either always return
a value, or not at all.

The left over console.log should likely be deleted as it doesn't give
the reader much information.

In SelectBadgeProperties the regex match is done twice; it would make
more sense to only do the match and distinguish between the null
value and an actual match.

A minor gripe with ColourTransforms is that the starting # is left
out of the colour definition - this means that some external editors,
plugins, etc. won't recognize it as a colour.  I'd leave it in, in the
interest of compatibility and readability, even if it takes three
additional characters in the source.

And lastly, inserting many copies of the SVG image doesn't sound
performant, but I can't back that up with data obviously; I also doubt
that people will insert a massive number of badges and therefore this
point is kinda moot.

Otherwise looks great to complement the chat functionality.