patternjavascriptModerate
"The 2nd Monitor" chatroom translator
Viewed 0 times
thechatroommonitortranslator2nd
Problem
For those who go to The 2nd Monitor chatroom, you already know how bad I am at remembering everything. And, sometimes, the new visitors will wonder what something means.
For that, I've developed a very simple chat translator.
`;(function(window, undefined){
'use strict';
var memes = {
'zombie': {
'title': 'Unanswered question (or with answers without upvotes)',
'href': 'http://meta.codereview.stackexchange.com/a/1511/',
'find': new RegExp('(zombie)','gi')
},
'Jamalized': {
'title': 'Being Jamalized means that Jamal edited your question/answer',
'href': 'http://meta.codereview.stackexchange.com/a/1675/',
'find': new RegExp('(jamalized)','gi')
},
'TS': {
'title': 'Theoretical Star (star it and say "RSA")',
'href': 'http://meta.codereview.stackexchange.com/a/1526/',
'find': new RegExp('(TS)','g')
},
'RSA': {
'title': 'Real Star Applied (you say it after staring a message with "TS")',
'href': 'http://meta.codereview.stackexchange.com/a/1526/',
'find': new RegExp('(RSA)','g')
},
'Thanks, Santa!': {
'title': 'When someone upvotes a post, and you don\'t know who, just say this',
'href': 'http://meta.codereview.stackexchange.com/a/1526/'
},
'IWNPFETTOLAI': {
'title': 'I will not provide further explanation than this overly long acronym itself',
'href': 'http://meta.codereview.stackexchange.com/a/1673/'
},
'Monking': {
'title': 'A greeting to the Monkey doing his monkey-business',
'href': 'http://meta.codereview.stackexchange.com/a/1678/',
'find': new RegExp('(monk(?:ing|ernoon|evening|night))','gi')
},
'TTQW': {
'title': 'Time To Quit Work',
'href': 'http://meta.codereview.stack
For that, I've developed a very simple chat translator.
`;(function(window, undefined){
'use strict';
var memes = {
'zombie': {
'title': 'Unanswered question (or with answers without upvotes)',
'href': 'http://meta.codereview.stackexchange.com/a/1511/',
'find': new RegExp('(zombie)','gi')
},
'Jamalized': {
'title': 'Being Jamalized means that Jamal edited your question/answer',
'href': 'http://meta.codereview.stackexchange.com/a/1675/',
'find': new RegExp('(jamalized)','gi')
},
'TS': {
'title': 'Theoretical Star (star it and say "RSA")',
'href': 'http://meta.codereview.stackexchange.com/a/1526/',
'find': new RegExp('(TS)','g')
},
'RSA': {
'title': 'Real Star Applied (you say it after staring a message with "TS")',
'href': 'http://meta.codereview.stackexchange.com/a/1526/',
'find': new RegExp('(RSA)','g')
},
'Thanks, Santa!': {
'title': 'When someone upvotes a post, and you don\'t know who, just say this',
'href': 'http://meta.codereview.stackexchange.com/a/1526/'
},
'IWNPFETTOLAI': {
'title': 'I will not provide further explanation than this overly long acronym itself',
'href': 'http://meta.codereview.stackexchange.com/a/1673/'
},
'Monking': {
'title': 'A greeting to the Monkey doing his monkey-business',
'href': 'http://meta.codereview.stackexchange.com/a/1678/',
'find': new RegExp('(monk(?:ing|ernoon|evening|night))','gi')
},
'TTQW': {
'title': 'Time To Quit Work',
'href': 'http://meta.codereview.stack
Solution
And here I go:
-
Take advantage of the fact that SE sites use jQuery. This will trim down your DOM manipulation code to a high degree.
-
We usually have a rule in our team that the most you should nest for conditions is 2. If you have 3 or more nested, then it's time you use a function.
-
One problem I find problematic about nested
-
I suggest against "one
-
Use "early return" if you happen to have
Now my jQuery is a bit rusty, but I think your logic can be simplified to the following. It may not be complete, but you get the idea.
-
Take advantage of the fact that SE sites use jQuery. This will trim down your DOM manipulation code to a high degree.
-
We usually have a rule in our team that the most you should nest for conditions is 2. If you have 3 or more nested, then it's time you use a function.
-
One problem I find problematic about nested
if-else and other conditional blocks is that it's hard to trace what they changed. Try writing ala Functional Programming, where you call a function, pass in a value, and get a new value. Combine it with ternaries or hash maps and it ain't so bad.-
I suggest against "one
var for all vars" as it becomes hard to determine when the vars end and the real code starts. For instance, I tried cleaning your code, but the indent is off at first glance, then discovered the "one var".-
Use "early return" if you happen to have
if blocks with no else and nothing after it.function foo(){
if(bar){
// code at second level
}
}
// is the same as
function foo(){
if(!bar) return;
// code at first level
}Now my jQuery is a bit rusty, but I think your logic can be simplified to the following. It may not be complete, but you get the idea.
setInterval(function translate() {
// Look for a child element that is not .onebox from .content that's under a non-checked ancestor .message in #chat
// Phew! That's a long one!
$('#chat .message:not([data-checked="1"]) .content > :not(.onebox)').each(function(index, content){
// Mark the ancestor .message as checked.
// We use attr() instead of .data() because we're using a selector to look, and data() doesn't alter attributes
$(content).closest('.message').attr('data-checked', 1);
var contentChildren = $(content).children();
// Looking for text nodes with jQuery filter
contentChildren.filter(function(index, element){
return element.nodeType === 3;
}).each(function(index, element){
var html = $(element).text();
$.each(memes, function(key, meme){
html.replace(meme.find || meme, '' + meme + '');
});
element.replaceWith(html);
});
});
}, 5000);Code Snippets
function foo(){
if(bar){
// code at second level
}
}
// is the same as
function foo(){
if(!bar) return;
// code at first level
}setInterval(function translate() {
// Look for a child element that is not .onebox from .content that's under a non-checked ancestor .message in #chat
// Phew! That's a long one!
$('#chat .message:not([data-checked="1"]) .content > :not(.onebox)').each(function(index, content){
// Mark the ancestor .message as checked.
// We use attr() instead of .data() because we're using a selector to look, and data() doesn't alter attributes
$(content).closest('.message').attr('data-checked', 1);
var contentChildren = $(content).children();
// Looking for text nodes with jQuery filter
contentChildren.filter(function(index, element){
return element.nodeType === 3;
}).each(function(index, element){
var html = $(element).text();
$.each(memes, function(key, meme){
html.replace(meme.find || meme, '<a href="' + meme.href + '" title="' + meme.title + '">' + meme + '</a>');
});
element.replaceWith(html);
});
});
}, 5000);Context
StackExchange Code Review Q#96724, answer score: 13
Revisions (0)
No revisions yet.