User:Dorumin/pings.​js

//  window.PING_REGEX = /(doru|dorium|\bdor\b|\bdory\b|\bdrumi|betterthancube)\w*/i;

mw.hook('dev.chat.render').add(function {   var avatars = {};    if (Notification.permission === 'default') {        Notification.requestPermission;    }

function parseInlineAlertRegex(elem) { // We could probably make it prettier, but as long as it's abstracted inside this function we probably won't need to deal with it again var msg = mw.messages.get(elem) .replace(/[-[\]{}*+?.,\\^$|#\s]/g, '\\$&') //escape regex .replace(/(\\\$\d)(?!.*\1)/g, '(.+?)') //place capturing groups .replace(/\\\$\d/g, '.+?'); //replace remaining $Ns

return new RegExp(msg); }

function notify(title, text, icon) {

if (Notification.permission !== 'granted' || document.hasFocus && mainRoom.active) { return; }       var notification = new Notification(title, {            body: text,            icon: icon        }); notification.onclick = function { window.focus; notification.close; };   }

function formatAvi(avatar) { // Aaanyways, this regex matches only the last occurrence of 28 in the string // (?!) means a negative lookahead, so it looks ahead of the match for any occurrences of (any character) times 0 to infinity // immediately followed by 28 return avatar.replace(/28(?!.*28)/, '150'); }

function highlight($elem, match) { var $message = $elem, html = $message.html, lastIndex = match.index + match[0].length, text = html.slice(match.index, lastIndex), span = $(' ', {               id: 'ping',                text: text,                css: {                    color: 'red'                }            }).get(0);

html = html.slice(0, match.index) + span.outerHTML + html.slice(lastIndex); $message.html(html); }

function saveAvatar(user) { avatars[user.attributes.name] = formatAvi(user.attributes.avatarSrc); }

var kick_regex = parseInlineAlertRegex('chat-user-was-kicked'), ban_regex = parseInlineAlertRegex('chat-user-was-banned');

function afterChat(chat) { var $elem = $('#entry-' + chat.cid).find('.message'), html = $elem.html, text = chat.attributes.text, name = chat.attributes.name, icon = formatAvi(chat.attributes.avatarSrc), inline = chat.attributes.isInlineAlert || false, match;

if (name !== mw.config.get('wgUserName') && !inline) { if (match = html.match(PING_REGEX)) { notify(name + ' pinged you!', text, icon); highlight($elem, match); }       } else if (inline) { if (match = text.match(kick_regex)) { notify(match[1] + ' was kicked!', '', avatars[match[1]]); } else if (match = text.match(ban_regex)) { notify(match[1] + ' was banned!', '', avatars[match[1]]); }       }    }

/* Bindings */ mainRoom.model.chats.bind('afteradd', afterChat); mainRoom.model.users.models.forEach(saveAvatar); mainRoom.model.users.bind('add', saveAvatar); });