monners
4/23/2014 - 12:20 AM

so snippets userscript WIP

so snippets userscript WIP

// ==UserScript==
// @name          Chat Snippets
// @author        Robert Lemon
// @version       1.35
// @namespace     
// @description   tab complete snippets for chat input
// @include       http://chat.stackoverflow.com/rooms/*
// ==/UserScript==
 
function exec(fn) {
    var script = document.createElement('script');
    script.setAttribute('type', 'application/javascript');
    script.textContent = '(' + fn + ')();';
    document.body.appendChild(script); // run the script
}
function inject(str) {
    var style = document.createElement('style');
    style.setAttribute('type','text/css');
    style.textContent = str;
    document.head.appendChild(style);
} 
inject('.csm_tip_content{font:13px/1.7\'Helvetica Neue\',Helvetica,Arial,sans-serif;background-color:#fff;color:#333;padding:9px 17px}.csm_tip_container{display:none;position:absolute;margin-top:-75px;z-index:1000}.csm_tip_point{position:relative;background:#fff;border:1px solid #dcdcdc}.csm_tip_point:after,.csm_tip_point:before{position:absolute;pointer-events:none;border:solid transparent;top:100%;content:"";height:0;width:0}.csm_tip_point:after{border-top-color:#fff;border-width:8px;left:50%;margin-left:-8px}.csm_tip_point:before{border-top-color:#dcdcdc;border-width:9px;left:50%;margin-left:-9px}');
exec(function () {
    function parseContents(str) {
        if (/^\s*(https?:\/\/[^\s<>'"?]+)\.(bmp|png|webp|gif|jpg|jpeg|svg)(\?[^\s<>?]*)?\s*$/.test(str)) {
            return '<img src="' + str + '" style="width:98px;"/>';
        }
        return str.replace(/\r\n/g, '<br />');
    }
    var btn = $('<button class="button" style="margin-left: 2px;">Snippets</button>'),
        room = document.forms[0].elements.room.value,
        snippets = window.localStorage.getItem('so_chat_snippets');
    if( snippets ) {
        snippets = JSON.parse(snippets);
    } else {
        snippets = {};
    }
    btn.on('click', function () {
        var modal = $('<div style="overflow: inherit !important;"><h4>Chat Snippet Manager</h4></div>');
        var btnNew = $('<button class="button">new</button>'),
            btnImp = $('<button class="button">import</button>'),
            btnExp = $('<button class="button">export</button>'),
            list = $('<ul></ul>');
        var addItem = function(name, replace) {
            var item = $('<li style="height:1.45em;"></li>');
            item.data('replace', replace);
            item.hover(function() {
                $(this).css('background-color', 'rgba(0,0,0,0.05)');
                var out = '<div class="csm_tip_container"><div class="csm_tip_point"><div class="csm_tip_content">' + parseContents($(this).data('replace')) + '</div></div></div>';
                $(this).append(out);
                var w_t = $('.csm_tip_container', this).outerWidth();
                var w_e = $(this).width();
                var m_l = (w_e / 2) - (w_t / 2);
                $('.csm_tip_container', this).css('margin-left', m_l + 'px').fadeIn(300);
            },
                function() {
                    $(this).css('background-color', 'Transparent');
                    $('.csm_tip_container', this).remove();
                })
            item.text(name);
            var del = $('<div class="btn-close" title="Delete">X</div>');
            del.on('click', function() {
                $(this).remove();
                var key = item.text();
                item.remove();
                delete snippets[key];
                window.localStorage.setItem('so_chat_snippets', JSON.stringify(snippets));
            });
            item.append(del);
            list.append(item);
        };
        for( var key in snippets ) {
            addItem(key, snippets[key] );
        }
        btnNew.on('click', function() {
            var name, replace;
            name = prompt('enter the snippet trigger word');
            if( name ) replace = prompt('enter the replacement string');

            if( name && replace && !( name in snippets ) ) {
                snippets[name] = replace;
                window.localStorage.setItem('so_chat_snippets', JSON.stringify(snippets));
                addItem(name, replace);
            }
            return false;
        });
        btnImp.on('click', function() {
            var input = prompt('please enter the JSON input');
            if( input ) {
                if( JSON.parse(input) ) {
                    window.localStorage.setItem('so_chat_snippets', input);
                }
            }
        });
        btnExp.on('click', function() {
            var win = window.open();
            win.document.write(JSON.stringify(snippets));
        });
        modal.append(btnNew);
        modal.append(btnImp);
        modal.append(btnExp);
        modal.append('<hr>');
        modal.append(list);
        modal.addClass('popup room-popup').css({
            bottom: btn.position().top,
            left: btn.position().left
        }).on('click', function (e) {
            modal.remove();
            return false;
        });
        $(document.body).append(modal);
        return false;
    });
    $('#chat-buttons').append(btn);

    input.addEventListener('keydown', function (e) {
        if (e.which === 9) { // TAB
            var pos = input.selectionStart,
                words = input.value.substr(0, pos).split(' ');
            last = words[words.length - 1];
            if (last.length > 0) {
                if (last in snippets) {
                    e.preventDefault();
                    input.value = input.value.substr(0, pos - last.length) + snippets[last];
                }
            }
        }
    });

});

so chat snippets

okay here is the deal, this is a WIP and i'm still working on it but in the meantime you might enjoy it.

install by downloading the script, and dragging and dropping on chrome://extensions/

refresh the chat page and click the 'snippets' button.

the interface is pretty simple:

clicking the 'x' deletes the snippet, hovering the snippet key gives you the replacement.

click 'new' to enter a new snippet, 'import' to enter the export data, and 'export' to export that data. the snippets are saved in localStorage so import/export is a bandaid fix for sharing this cross-pc.

to use it just type your key

then without a space hit TAB and it will convert to the replacement

Enjoy!