diff --git a/js/client-chat.js b/js/client-chat.js index 7290ef9fe..132f5095a 100644 --- a/js/client-chat.js +++ b/js/client-chat.js @@ -71,10 +71,13 @@ animateDuration: 100, extraSpace: 0 }); + if (this === app.curSideRoom || this === app.curRoom) { + this.$chatbox.focus(); + } } }, focus: function() { - this.$chatAdd.find('textarea').focus(); + if (this.$chatbox) this.$chatbox.focus(); }, destroy: function() { this.send('/lobbychat off'); @@ -90,297 +93,7 @@ autoscroll = true; } for (var i = 0; i < log.length; i++) { - if (typeof log[i] === 'string') { - if (log[i].substr(0,1) !== '|') log[i] = '||'+log[i]; - var row = log[i].substr(1).split('|'); - switch (row[0]) { - case 'c': - case 'chat': - log[i] = { - name: row[1], - message: row.slice(2).join('|') - }; - break; - case 'b': - case 'B': - log[i] = { - action: 'battle', - room: row[1], - name: row[2], - name2: row[3], - silent: (row[0] === 'B') - }; - break; - case 'j': - case 'J': - log[i] = { - action: 'join', - name: row[1], - silent: (row[0] === 'J') - }; - break; - case 'l': - case 'L': - log[i] = { - action: 'leave', - name: row[1], - silent: (row[0] === 'L') - }; - break; - case 'n': - case 'N': - log[i] = { - action: 'rename', - name: row[1], - oldid: row[2], - silent: true - }; - break; - case 'raw': - log[i] = { - rawMessage: row.slice(1).join('|') - }; - break; - case 'refresh': - // refresh the page - document.location.reload(true); - break; - case 'formats': - var isSection = false; - var section = ''; - BattleFormats = {}; - for (var j=1; j' + Tools.escapeHTML(log[i].name.substr(1)) + ''; - var message = log[i].message; - var isHighlighted = this.getHighlight(message); - if (isHighlighted) { - notify({ - type: 'highlight', - user: log[i].name - }); - } - var highlight = isHighlighted ? ' style="background-color:#FDA;"' : ''; - var chatDiv = '
'; - var timestamp = this.getTimestamp(log[i].pm ? 'pms' : 'lobby'); - if (log[i].name.substr(0, 1) !== ' ') clickableName = '' + Tools.escapeHTML(log[i].name.substr(0, 1)) + ''+clickableName; - if (log[i].pm) { - var pmuserid = (userid === me.userid ? toUserid(log[i].pm) : userid); - if (!me.pm[pmuserid]) me.pm[pmuserid] = ''; - var pmcode = '
' + timestamp + '' + clickableName + ': ' + messageSanitize(message) + '
'; - for (var j = 0; j < me.popups.length; j++) { - if (pmuserid === me.popups[j]) break; - } - if (j == me.popups.length) { - // This is a new PM. - me.popups.unshift(pmuserid); - notify({ - type: 'pm', - user: log[i].name - }); - } - me.pm[pmuserid] += pmcode; - if (me.popups.length && me.popups[me.popups.length - 1] === pmuserid) { - this.updatePopup(pmcode); - } else { - this.updatePopup(); - } - this.$chat.append('
' + timestamp + '' + clickableName + ': (Private to ' + Tools.escapeHTML(log[i].pm) + ') ' + messageSanitize(message) + '
'); - //} else if (log[i].act) { - // this.$chat.append('
' + clickableName + ' ' + message + '
'); - } else if (message.substr(0,2) === '//') { - this.$chat.append(chatDiv + timestamp + '' + clickableName + ': ' + messageSanitize(message.substr(1)) + '
'); - } else if (message.substr(0,4).toLowerCase() === '/me ') { - this.$chat.append(chatDiv + timestamp + ' ' + clickableName + ' ' + messageSanitize(message.substr(4)) + ''); - } else if (message.substr(0,5).toLowerCase() === '/mee ') { - this.$chat.append(chatDiv + timestamp + ' ' + clickableName + '' + messageSanitize(message.substr(5)) + ''); - } else if (message.substr(0,10).toLowerCase() === '/announce ') { - this.$chat.append(chatDiv + timestamp + '' + clickableName + ': ' + messageSanitize(message.substr(10)) + ''); - } else if (message.substr(0,6).toLowerCase() === '/warn ') { - overlay('rules', {warning: message.substr(6)}); - } else if (message.substr(0,14).toLowerCase() === '/data-pokemon ') { - this.$chat.append('
    '+Chart.pokemonRow(Tools.getTemplate(message.substr(14)),'',{})+'
'); - } else if (message.substr(0,11).toLowerCase() === '/data-item ') { - this.$chat.append('
    '+Chart.itemRow(Tools.getItem(message.substr(11)),'',{})+'
'); - } else if (message.substr(0,14).toLowerCase() === '/data-ability ') { - this.$chat.append('
    '+Chart.abilityRow(Tools.getAbility(message.substr(14)),'',{})+'
'); - } else if (message.substr(0,11).toLowerCase() === '/data-move ') { - this.$chat.append('
    '+Chart.moveRow(Tools.getMove(message.substr(11)),'',{})+'
'); - } else { - // Normal chat message. - this.$chat.append(chatDiv + timestamp + '' + clickableName + ': ' + messageSanitize(message) + ''); - } - } else if (log[i].name && log[i].action === 'battle') { - var id = log[i].room; - var matches = this.parseBattleID(id); - if (!matches) { - continue; // bogus room ID could be used to inject JavaScript - } - var format = (matches ? matches[1] : ''); - - if (log[i].silent && !Tools.prefs('showbattles')) continue; - - this.$joinLeave = null; - this.joinLeave = { - 'join': [], - 'leave': [] - }; - var id = log[i].room; - var battletype = 'Battle'; - if (log[i].format) { - battletype = log[i].format + ' battle'; - if (log[i].format === 'Random Battle') battletype = 'Random Battle'; - } - this.$chat.append(''); - } else if (log[i].message) { - this.$chat.append('
' + Tools.escapeHTML(log[i].message) + '
'); - } else if (log[i].rawMessage) { - this.$chat.append('
' + Tools.sanitizeHTML(log[i].rawMessage) + '
'); - } else if (log[i].evalRulesRedirect || log[i].evalRawMessage) { - // TODO: This will be removed in due course. - window.location.href = 'http://pokemonshowdown.com/rules'; - } else if (log[i].name && (log[i].action === 'join' || log[i].action === 'leave' || log[i].action === 'rename')) { - var userid = toUserid(log[i].name); - if (log[i].action === 'join') { - if (log[i].oldid) delete this.users[toUserid(log[i].oldid)]; - if (!this.users[userid]) this.userCount.users++; - this.users[userid] = log[i].name; - this.userList.add(userid); - this.userList.updateUserCount(); - this.userList.updateNoUsersOnline(); - } else if (log[i].action === 'leave') { - if (this.users[userid]) this.userCount.users--; - delete this.users[userid]; - this.userList.remove(userid); - this.userList.updateUserCount(); - this.userList.updateNoUsersOnline(); - } else if (log[i].action === 'rename') { - if (log[i].oldid) delete this.users[toUserid(log[i].oldid)]; - this.users[userid] = log[i].name; - this.userList.remove(log[i].oldid); - this.userList.add(userid); - continue; - } - if (log[i].silent && !Tools.prefs('showjoins')) continue; - if (!this.$joinLeave) { - this.$chat.append('
Loading...
'); - this.$joinLeave = this.$chat.children().last(); - } - this.joinLeave[log[i].action].push(log[i].name); - var message = ''; - if (this.joinLeave['join'].length) { - var preList = this.joinLeave['join']; - var list = []; - var named = {}; - for (var j = 0; j < preList.length; j++) { - if (!named[preList[j]]) list.push(preList[j]); - named[preList[j]] = true; - } - for (var j = 0; j < list.length; j++) { - if (j >= 5) { - message += ', and ' + (list.length - 5) + ' others'; - break; - } - if (j > 0) { - if (j == 1 && list.length == 2) { - message += ' and '; - } else if (j == list.length - 1) { - message += ', and '; - } else { - message += ', '; - } - } - message += Tools.escapeHTML(list[j]); - } - message += ' joined'; - } - if (this.joinLeave['leave'].length) { - if (this.joinLeave['join'].length) { - message += '; '; - } - var preList = this.joinLeave['leave']; - var list = []; - var named = {}; - for (var j = 0; j < preList.length; j++) { - if (!named[preList[j]]) list.push(preList[j]); - named[preList[j]] = true; - } - for (var j = 0; j < list.length; j++) { - if (j >= 5) { - message += ', and ' + (list.length - 5) + ' others'; - break; - } - if (j > 0) { - if (j == 1 && list.length == 2) { - message += ' and '; - } else if (j == list.length - 1) { - message += ', and '; - } else { - message += ', '; - } - } - message += Tools.escapeHTML(list[j]); - } - message += ' left
'; - } - this.$joinLeave.html('' + message + ''); - } + this.addRow(log[i]); } if (autoscroll) { this.$chatFrame.scrollTop(this.$chat.height()); @@ -390,6 +103,280 @@ $children.slice(0,100).remove(); } }, + addRow: function(line) { + var name, name2, room, action, silent, oldid; + if (typeof line === 'string') { + if (line.substr(0,1) !== '|') line = '||'+line; + var row = line.substr(1).split('|'); + switch (row[0]) { + case 'c': + case 'chat': + this.addChat(row[1], row.slice(2).join('|')); + break; + + case 'b': + case 'B': + var id = row[1]; + name = row[2]; + name2 = row[3]; + silent = (row[0] === 'B'); + + var matches = this.parseBattleID(id); + if (!matches) { + return; // bogus room ID could be used to inject JavaScript + } + var format = (matches ? matches[1] : ''); + + if (silent && !Tools.prefs('showbattles')) return; + + this.addJoinLeave(); + var battletype = 'Battle'; + if (format) { + battletype = format + ' battle'; + if (format === 'Random Battle') battletype = 'Random Battle'; + } + this.$chat.append(''); + break; + + case 'j': + case 'J': + this.addJoinLeave('join', row[1], null, row[0] === 'J'); + break; + + case 'l': + case 'L': + this.addJoinLeave('leave', row[1], null, row[0] === 'L'); + break; + + case 'n': + case 'N': + this.addJoinLeave('rename', row[1], row[2], true); + break; + + case 'refresh': + // refresh the page + document.location.reload(true); + break; + + case 'formats': + this.parseFormats(row); + break; + + case 'raw': + this.$chat.append('
' + Tools.sanitizeHTML(row.slice(1).join('|')) + '
'); + break; + + case '': + default: + this.$chat.append('
' + Tools.escapeHTML(row.slice(1).join('|')) + '
'); + break; + } + } + }, + parseFormats: function(formatsList) { + var isSection = false; + var section = ''; + BattleFormats = {}; + for (var j=1; jLoading...'); + this.$joinLeave = this.$chat.children().last(); + } + this.joinLeave[action].push(name); + var message = ''; + if (this.joinLeave['join'].length) { + var preList = this.joinLeave['join']; + var list = []; + var named = {}; + for (var j = 0; j < preList.length; j++) { + if (!named[preList[j]]) list.push(preList[j]); + named[preList[j]] = true; + } + for (var j = 0; j < list.length; j++) { + if (j >= 5) { + message += ', and ' + (list.length - 5) + ' others'; + break; + } + if (j > 0) { + if (j == 1 && list.length == 2) { + message += ' and '; + } else if (j == list.length - 1) { + message += ', and '; + } else { + message += ', '; + } + } + message += Tools.escapeHTML(list[j]); + } + message += ' joined'; + } + if (this.joinLeave['leave'].length) { + if (this.joinLeave['join'].length) { + message += '; '; + } + var preList = this.joinLeave['leave']; + var list = []; + var named = {}; + for (var j = 0; j < preList.length; j++) { + if (!named[preList[j]]) list.push(preList[j]); + named[preList[j]] = true; + } + for (var j = 0; j < list.length; j++) { + if (j >= 5) { + message += ', and ' + (list.length - 5) + ' others'; + break; + } + if (j > 0) { + if (j == 1 && list.length == 2) { + message += ' and '; + } else if (j == list.length - 1) { + message += ', and '; + } else { + message += ', '; + } + } + message += Tools.escapeHTML(list[j]); + } + message += ' left
'; + } + this.$joinLeave.html('' + message + ''); + }, + addChat: function(name, message) { + var userid = toUserid(name); + var color = hashColor(userid); + var pm = false; + + // if (me.ignore[userid] && name.substr(0, 1) === ' ') continue; + + // Add this user to the list of people who have spoken recently. + this.markUserActive(userid); + + this.$joinLeave = null; + this.joinLeave = { + 'join': [], + 'leave': [] + }; + var clickableName = '' + Tools.escapeHTML(name.substr(1)) + ''; + var isHighlighted = this.getHighlight(message); + if (isHighlighted) { + // notify({ + // type: 'highlight', + // user: name + // }); + } + var highlight = isHighlighted ? ' style="background-color:#FDA;"' : ''; + var chatDiv = '
'; + var timestamp = this.getTimestamp('lobby'); + if (name.substr(0, 1) !== ' ') clickableName = '' + Tools.escapeHTML(name.substr(0, 1)) + ''+clickableName; + if (pm) { + var pmuserid = (userid === me.userid ? toUserid(pm) : userid); + if (!me.pm[pmuserid]) me.pm[pmuserid] = ''; + var pmcode = '
' + timestamp + '' + clickableName + ': ' + messageSanitize(message) + '
'; + for (var j = 0; j < me.popups.length; j++) { + if (pmuserid === me.popups[j]) break; + } + if (j == me.popups.length) { + // This is a new PM. + me.popups.unshift(pmuserid); + notify({ + type: 'pm', + user: name + }); + } + me.pm[pmuserid] += pmcode; + if (me.popups.length && me.popups[me.popups.length - 1] === pmuserid) { + this.updatePopup(pmcode); + } else { + this.updatePopup(); + } + this.$chat.append('
' + timestamp + '' + clickableName + ': (Private to ' + Tools.escapeHTML(pm) + ') ' + messageSanitize(message) + '
'); + } else if (message.substr(0,4).toLowerCase() === '/me ') { + this.$chat.append(chatDiv + timestamp + ' ' + clickableName + ' ' + messageSanitize(message.substr(4)) + '
'); + } else if (message.substr(0,5).toLowerCase() === '/mee ') { + this.$chat.append(chatDiv + timestamp + ' ' + clickableName + '' + messageSanitize(message.substr(5)) + ''); + } else if (message.substr(0,10).toLowerCase() === '/announce ') { + this.$chat.append(chatDiv + timestamp + '' + clickableName + ': ' + messageSanitize(message.substr(10)) + ''); + } else if (message.substr(0,6).toLowerCase() === '/warn ') { + overlay('rules', {warning: message.substr(6)}); + } else if (message.substr(0,14).toLowerCase() === '/data-pokemon ') { + this.$chat.append('
    '+Chart.pokemonRow(Tools.getTemplate(message.substr(14)),'',{})+'
'); + } else if (message.substr(0,11).toLowerCase() === '/data-item ') { + this.$chat.append('
    '+Chart.itemRow(Tools.getItem(message.substr(11)),'',{})+'
'); + } else if (message.substr(0,14).toLowerCase() === '/data-ability ') { + this.$chat.append('
    '+Chart.abilityRow(Tools.getAbility(message.substr(14)),'',{})+'
'); + } else if (message.substr(0,11).toLowerCase() === '/data-move ') { + this.$chat.append('
    '+Chart.moveRow(Tools.getMove(message.substr(11)),'',{})+'
'); + } else { + // Normal chat message. + if (message.substr(0,2) === '//') message = message.substr(1); + this.$chat.append(chatDiv + timestamp + '' + clickableName + ': ' + messageSanitize(message) + ''); + } + }, getHighlight: function(message) { var highlights = Tools.prefs('highlights') || []; if (!app.highlightRegExp) {