');
},
// news
addNews: function () {
var self = this;
$.ajax({
url: "https://" + Config.routes.root + "/news.json",
dataType: "json",
success: function (data) {
var html = '';
for (var i = 0; i < 2; i++) {
var post = data[i];
var hasRead = data[i].id && Dex.prefs('readnews') === '' + data[i].id;
html += '
';
if (post.title) html += '
' + post.title + '
';
if (post.summaryHTML) html += '
' + post.summaryHTML + '
';
html += '
';
if (post.author) html += '—' + post.author + '';
if (post.date) {
html += ' on ' + new Date(post.date * 1000).toDateString() + '';
}
html += '
';
}
self.addPseudoPM({
title: 'Latest News',
html: html,
attributes: 'data-newsid="' + (data[0].id ? data[0].id : '1990') + '"',
cssClass: 'news-embed',
maxHeight: 'none'
});
}
});
},
/*********************************************************
* PMs
*********************************************************/
addPM: function (name, message, target) {
var userid = toUserid(name);
if (app.ignore[userid] && " +\u2606\u203D\u2716!".includes(name.charAt(0))) {
if (!app.ignoreNotified) {
message = '/nonotify A message from ' + BattleLog.escapeHTML(name) + ' was ignored.';
app.ignoreNotified = true;
}
return;
}
var isSelf = (toID(name) === app.user.get('userid'));
var oName = isSelf ? target : name;
Storage.logChat('pm-' + toID(oName), '' + name + ': ' + message);
var $pmWindow = this.openPM(oName, true);
var $chatFrame = $pmWindow.find('.pm-log');
var $chat = $pmWindow.find('.inner');
var autoscroll = ($chatFrame.scrollTop() + 60 >= $chat.height() - $chatFrame.height());
var parsedMessage = MainMenuRoom.parseChatMessage(message, name, ChatRoom.getTimestamp('pms'), false, $chat, false);
if (typeof parsedMessage.challenge === 'string') {
this.updateChallenge($pmWindow, parsedMessage.challenge, name, oName);
return;
}
var canNotify = true;
if (typeof parsedMessage === 'object' && 'noNotify' in parsedMessage) {
canNotify = !parsedMessage.noNotify;
parsedMessage = parsedMessage.message;
}
if (!$.isArray(parsedMessage)) parsedMessage = [parsedMessage];
for (var i = 0; i < parsedMessage.length; i++) {
if (!parsedMessage[i]) continue;
$chat.append(parsedMessage[i]);
}
var $lastMessage = $chat.children().last();
var textContent = $lastMessage.html().includes('') ? '(spoiler)' : $lastMessage.children().last().text();
if (textContent && app.curSideRoom && app.curSideRoom.addPM && Dex.prefs('inchatpm')) {
app.curSideRoom.addPM(name, message, target);
}
if (canNotify && !isSelf && textContent) {
this.notifyOnce("PM from " + name, "\"" + textContent + "\"", 'pm');
}
if (autoscroll) {
$chatFrame.scrollTop($chat.height());
}
if (!$pmWindow.hasClass('focused') && name.substr(1) !== app.user.get('name')) {
$pmWindow.find('h3').addClass('pm-notifying');
}
},
updateChallenge: function ($pmWindow, challenge, name, oName) {
var splitChallenge = challenge.split('|');
var formatName = splitChallenge[0];
var teamFormat = splitChallenge[1];
var message = splitChallenge[2];
var acceptButtonLabel = splitChallenge[3] || 'Accept';
var rejectButtonLabel = splitChallenge[4] || 'Reject';
var oUserid = toID(oName);
var userid = toID(name);
var $challenge = $pmWindow.find('.challenge');
if ($challenge.find('button[name=makeChallenge]').length) {
// we're currently trying to challenge that user; suppress the challenge and wait until later
$challenge.find('button[name=dismissChallenge]').attr(
'data-pendingchallenge', challenge ? (name + '|' + oName + '|' + challenge) : ''
);
return;
}
if (!formatName && !message) {
if ($challenge.length) {
$challenge.remove();
this.closeNotification('challenge:' + oUserid);
}
return;
}
$challenge = this.openChallenge(oName, $pmWindow);
if (userid !== oUserid) {
// we are sending the challenge
var buf = '';
$challenge.html(buf);
return;
}
app.playNotificationSound();
this.notifyOnce("Challenge from " + name, "Format: " + BattleLog.escapeFormat(formatName), 'challenge:' + userid);
var buf = '';
$challenge.html(buf);
},
openPM: function (name, dontFocus) {
var userid = toID(name);
var $pmWindow = this.$pmBox.find('.pm-window-' + userid);
if (!$pmWindow.length) {
var group = name.charAt(0);
if (group === ' ') {
group = '';
} else if (/[a-zA-Z0-9]/.test(group)) {
group = '';
name = ' ' + name;
} else {
group = '' + BattleLog.escapeHTML(group) + '';
}
var buf = '
');
app.saveIgnore();
}
break;
case 'nick':
if ($.trim(data)) {
app.user.rename(data);
} else {
app.addPopup(LoginPopup);
}
return false;
case 'chal':
case 'chall':
case 'challenge':
this.challenge(userid, data);
break;
case 'clear':
$chat.empty();
break;
case 'rank': case 'ranking': case 'rating': case 'ladder':
case 'user': case 'open':
case 'debug':
case 'news':
case 'ignorelist':
case 'clearpms':
case 'showdebug': case 'hidedebug':
case 'showjoins': case 'hidejoins':
case 'showbattles': case 'hidebattles':
case 'packhidden': case 'unpackhidden':
case 'timestamps':
case 'hl': case 'highlight':
case 'buttonban': case 'buttonmute': case 'buttonunmute': case 'buttonkick': case 'buttonwarn':
case 'part': case 'leave':
case 'afd':
$chat.append('
Use this command in a proper chat room.
');
break;
default:
if (!userid) userid = '~';
if (text.startsWith('\n')) text = text.slice(1);
if (text.endsWith('\n')) text = text.slice(0, -1);
text = ('\n' + text).replace(/\n/g, '\n/pm ' + userid + ', ').slice(1);
if (text.length > 80000) {
app.addPopupMessage("Your message is too long.");
return;
}
if (!(text.startsWith('/') || text.startsWith('!')) && app.ignore[userid]) {
app.addPopupMessage("You can't PM a user you've ignored. Use /unignore to remove them from your ignore list.");
return;
}
this.send(text);
}
$target.val('');
$target.trigger('keyup'); // force a resize
},
keyDown: function (e) {
var cmdKey = (((e.cmdKey || e.metaKey) ? 1 : 0) + (e.ctrlKey ? 1 : 0) === 1) && !e.altKey && !e.shiftKey;
if (e.keyCode === 13 && !e.shiftKey) { // Enter
this.submitPM(e);
} else if (e.keyCode === 27) { // Esc
if (app.curSideRoom && app.curSideRoom.undoTabComplete && app.curSideRoom.undoTabComplete($(e.currentTarget))) {
e.preventDefault();
e.stopPropagation();
} else {
this.closePM(e);
}
} else if (e.keyCode === 73 && cmdKey) { // Ctrl + I key
if (ConsoleRoom.toggleFormatChar(e.currentTarget, '_')) {
e.preventDefault();
e.stopPropagation();
}
} else if (e.keyCode === 66 && cmdKey) { // Ctrl + B key
if (ConsoleRoom.toggleFormatChar(e.currentTarget, '*')) {
e.preventDefault();
e.stopPropagation();
}
} else if (e.keyCode === 33) { // Pg Up key
var $target = $(e.currentTarget);
var $pmWindow = $target.closest('.pm-window');
var $chat = $pmWindow.find('.pm-log');
$chat.scrollTop($chat.scrollTop() - $chat.height() + 60);
} else if (e.keyCode === 34) { // Pg Dn key
var $target = $(e.currentTarget);
var $pmWindow = $target.closest('.pm-window');
var $chat = $pmWindow.find('.pm-log');
$chat.scrollTop($chat.scrollTop() + $chat.height() - 60);
} else if (e.keyCode === 9 && !e.ctrlKey) { // Tab key
var reverse = !!e.shiftKey; // Shift+Tab reverses direction
var handlerRoom = app.curSideRoom;
if (!handlerRoom) {
for (var roomid in app.rooms) {
if (!app.rooms[roomid].handleTabComplete) continue;
handlerRoom = app.rooms[roomid];
break;
}
}
if (handlerRoom && handlerRoom.handleTabComplete && handlerRoom.handleTabComplete($(e.currentTarget), reverse)) {
e.preventDefault();
e.stopPropagation();
}
} else if (e.keyCode === 38 && !e.shiftKey && !e.altKey) { // Up key
if (this.chatHistoryUp(e)) {
e.preventDefault();
e.stopPropagation();
}
} else if (e.keyCode === 40 && !e.shiftKey && !e.altKey) { // Down key
if (this.chatHistoryDown(e)) {
e.preventDefault();
e.stopPropagation();
}
}
},
chatHistoryUp: function (e) {
var $textbox = $(e.currentTarget);
var idx = +$textbox.prop('selectionStart');
var line = $textbox.val();
if (e && !e.ctrlKey && idx !== 0 && idx !== line.length) return false;
var userid = $textbox.closest('.pm-window').data('userid');
var chatHistory = this.chatHistories[userid];
if (chatHistory.index === 0) return false;
$textbox.val(chatHistory.up(line));
return true;
},
chatHistoryDown: function (e) {
var $textbox = $(e.currentTarget);
var idx = +$textbox.prop('selectionStart');
var line = $textbox.val();
if (e && !e.ctrlKey && idx !== 0 && idx !== line.length) return false;
var userid = $textbox.closest('.pm-window').data('userid');
var chatHistory = this.chatHistories[userid];
$textbox.val(chatHistory.down(line));
return true;
},
chatHistories: {},
clickPMBackground: function (e) {
if (!e.shiftKey && !e.cmdKey && !e.ctrlKey) {
if (window.getSelection && !window.getSelection().isCollapsed) {
return;
}
app.dismissPopups();
var $target = $(e.currentTarget);
var newsid = $target.data('newsid');
if ($target.data('minimized')) {
this.minimizePM(e);
} else if ($(e.target).closest('h3').length) {
// only preventDefault here, so clicking links/buttons in PMs
// still works
e.preventDefault();
e.stopPropagation();
this.minimizePM(e);
return;
} else if (newsid) {
if (Storage.prefs('newsid', newsid)) {
$target.find('.unread').removeClass('unread');
}
return;
}
$target.find('textarea[name=message]').focus();
}
},
dblClickPMHeader: function (e) {
e.preventDefault();
e.stopPropagation();
if (window.getSelection) {
window.getSelection().removeAllRanges();
} else if (document.selection) {
document.selection.empty();
}
},
clickSpoiler: function (e) {
$(e.currentTarget).toggleClass('spoiler-shown');
},
// support for buttons that can be sent by the server:
joinRoom: function (room) {
app.joinRoom(room);
},
avatars: function () {
app.addPopup(AvatarsPopup);
},
openSounds: function () {
app.addPopup(SoundsPopup, {type: 'semimodal'});
},
openOptions: function () {
app.addPopup(OptionsPopup, {type: 'semimodal'});
},
// challenges and searching
challengesFrom: null,
challengeTo: null,
resetPending: function () {
this.updateSearch();
var self = this;
this.$('form.pending').closest('.pm-window').each(function (i, el) {
$(el).find('.challenge').remove();
self.challenge($(el).data('userid'));
});
this.$('button[name=acceptChallenge]').each(function (i, el) {
el.disabled = false;
});
},
searching: false,
updateSearch: function (data) {
if (data) {
this.searching = data.searching;
this.games = data.games;
}
var $searchForm = $('.mainmenu button.big').closest('form');
var $formatButton = $searchForm.find('button[name=format]');
var $teamButton = $searchForm.find('button[name=team]');
if (!this.searching || $.isArray(this.searching) && !this.searching.length) {
var format = $formatButton.val();
var teamIndex = $teamButton.val();
$formatButton.replaceWith(this.renderFormats(format));
$teamButton.replaceWith(this.renderTeams(format, teamIndex));
$searchForm.find('button.big').html('Battle! Find a random opponent').removeClass('disabled');
$searchForm.find('p.cancel').remove();
} else {
$formatButton.addClass('preselected')[0].disabled = true;
$teamButton.addClass('preselected')[0].disabled = true;
$searchForm.find('button.big').html(' Searching...').addClass('disabled');
var searchEntries = $.isArray(this.searching) ? this.searching : [this.searching];
for (var i = 0; i < searchEntries.length; i++) {
var format = searchEntries[i].format || searchEntries[i];
if (format.substr(0, 4) === 'gen5' && !Dex.loadedSpriteData['bw']) {
Dex.loadSpriteData('bw');
break;
}
}
}
var $searchGroup = $searchForm.closest('.menugroup');
if (this.games) {
var newlyCreated = false;
if (!this.$gamesGroup) {
this.$gamesGroup = $('');
$searchGroup.before(this.$gamesGroup);
newlyCreated = true;
}
if (!this.$gamesGroup.is(':visible') || newlyCreated) {
$searchGroup.hide();
this.$gamesGroup.show();
}
var buf = '';
this.$gamesGroup.html(buf);
} else {
if (this.$gamesGroup) {
this.$gamesGroup.hide();
$searchGroup.show();
}
}
},
showSearchGroup: function (v, el) {
var $searchGroup = $('.mainmenu button.big').closest('.menugroup');
$searchGroup.show();
$(el).closest('p').hide();
},
updateChallenges: function (data) {
this.challengesFrom = data.challengesFrom;
this.challengeTo = data.challengeTo;
for (var i in data.challengesFrom) {
if (app.ignore[i]) {
delete data.challengesFrom[i];
continue;
}
this.openPM(' ' + i, true);
}
var atLeastOneGen5 = false;
var challengeToUserid = '';
if (data.challengeTo) {
var challenge = data.challengeTo;
var name = challenge.to;
var userid = toID(name);
var $challenge = this.openChallenge(name);
var buf = '';
$challenge.html(buf);
if (challenge.format.substr(0, 4) === 'gen5') atLeastOneGen5 = true;
challengeToUserid = userid;
}
var self = this;
this.$('.pm-window').each(function (i, el) {
var $pmWindow = $(el);
var userid = el.getAttribute('data-userid');
var name = $pmWindow.data('name');
if (data.challengesFrom[userid]) {
var format = data.challengesFrom[userid];
if (!$pmWindow.find('.challenge').length) {
self.notifyOnce("Challenge from " + name, "Format: " + BattleLog.escapeFormat(format), 'challenge:' + userid);
}
var $challenge = self.openChallenge(name, $pmWindow);
if (!$challenge.find('button[name=makeChallenge]').length) {
app.playNotificationSound();
var buf = '';
$challenge.html(buf);
if (format.substr(0, 4) === 'gen5') atLeastOneGen5 = true;
}
} else {
var $challenge = $pmWindow.find('.challenge');
if ($challenge.length) {
var $acceptButton = $challenge.find('button[name=acceptChallenge]');
if ($acceptButton.length) {
if ($acceptButton[0].disabled) {
// You accepted someone's challenge and it started
$challenge.remove();
} else {
// Someone was challenging you, but cancelled their challenge
$challenge.html('');
}
} else if ($challenge.find('button[name=cancelChallenge]').length && challengeToUserid !== userid) {
// You were challenging someone else, and they either accepted
// or rejected it
$challenge.remove();
}
self.closeNotification('challenge:' + userid);
}
}
});
if (atLeastOneGen5 && !Dex.loadedSpriteData['bw']) Dex.loadSpriteData('bw');
},
openChallenge: function (name, $pmWindow) {
if (!$pmWindow) $pmWindow = this.openPM(name, true);
var $challenge = $pmWindow.find('.challenge');
if (!$challenge.length) {
$challenge = $('').insertAfter($pmWindow.find('h3'));
}
return $challenge;
},
updateFormats: function () {
if (!window.BattleFormats) {
this.$('.mainmenu button.big').html('Connecting...').addClass('disabled');
return;
} else if (app.isDisconnected) {
var $searchForm = $('.mainmenu button.big').closest('form');
$searchForm.find('button.big').html('Disconnected').addClass('disabled');
$searchForm.find('.mainmenu p.cancel').remove();
$searchForm.append('');
this.$('button.onlineonly').addClass('disabled');
return;
}
this.$('button.onlineonly').removeClass('disabled');
if (!this.searching) this.$('.mainmenu button.big').html('Battle! Find a random opponent').removeClass('disabled');
var self = this;
this.$('button[name=format]').each(function (i, el) {
var val = el.value;
var $teamButton = $(el).closest('form').find('button[name=team]');
$(el).replaceWith(self.renderFormats(val));
$teamButton.replaceWith(self.renderTeams(val));
});
},
reconnect: function () {
document.location.reload();
},
updateTeams: function () {
if (!window.BattleFormats) return;
var self = this;
this.$('button[name=team]').each(function (i, el) {
if (el.value === 'random') return;
var format = $(el).closest('form').find('button[name=format]').val();
$(el).replaceWith(self.renderTeams(format));
});
},
updateRightMenu: function () {
if (app.curSideRoom) {
this.$('.rightmenu').hide();
} else {
this.$('.rightmenu').show();
}
},
// challenge buttons
challenge: function (name, format, team) {
var userid = toID(name);
var $challenge = this.$('.pm-window-' + userid + ' .challenge');
if ($challenge.length && !$challenge.find('button[name=dismissChallenge]').length) {
return;
}
if (format) {
var formatParts = format.split('@@@', 2);
formatParts[0] = toID(formatParts[0]);
if (!formatParts[0].startsWith('gen')) formatParts[0] = 'gen8' + formatParts[0];
format = formatParts.length > 1 ? formatParts[0] + '@@@' + formatParts[1] : formatParts[0];
}
$challenge = this.openChallenge(name);
var buf = '';
$challenge.html(buf);
},
acceptChallenge: function (i, target) {
this.requestNotifications();
var $pmWindow = $(target).closest('.pm-window');
var userid = $pmWindow.data('userid');
var format = $pmWindow.find('button[name=format]').val();
var $teamButton = $pmWindow.find('button[name=team]');
var privacy = this.adjustPrivacy($pmWindow.find('input[name=private]').is(':checked'));
target.disabled = true;
if ($teamButton.length) {
var teamIndex = $teamButton.val();
var team = null;
if (Storage.teams[teamIndex]) team = Storage.teams[teamIndex];
if (format.indexOf('@@@') === -1 && !window.BattleFormats[format].team && !team) {
app.addPopupMessage("You need to go into the Teambuilder and build a team for this format.");
return;
}
app.sendTeam(team);
}
app.send(privacy + '/accept ' + userid);
},
rejectChallenge: function (i, target) {
var userid = $(target).closest('.pm-window').data('userid');
$(target).closest('.challenge').remove();
app.send('/reject ' + userid);
},
makeChallenge: function (i, target) {
this.requestNotifications();
var $pmWindow = $(target).closest('.pm-window');
var userid = $pmWindow.data('userid');
var name = $pmWindow.data('name');
var format = $pmWindow.find('button[name=format]').val();
var teamIndex = $pmWindow.find('button[name=team]').val();
var privacy = this.adjustPrivacy($pmWindow.find('input[name=private]').is(':checked'));
var team = null;
if (Storage.teams[teamIndex]) team = Storage.teams[teamIndex];
// if it's a custom format, let the user figure it out
if (window.BattleFormats[format] && !window.BattleFormats[format].team && !team) {
app.addPopupMessage("You need to go into the Teambuilder and build a team for this format.");
return;
}
var buf = '';
$(target).closest('.challenge').html(buf);
app.sendTeam(team);
app.send(privacy + '/challenge ' + userid + ', ' + format);
},
cancelChallenge: function (i, target) {
var userid = $(target).closest('.pm-window').data('userid');
$(target).closest('.challenge').remove();
app.send('/cancelchallenge ' + userid);
},
dismissChallenge: function (i, target) {
var $challenge = $(target).closest('.challenge');
var pChallenge = $challenge.find('button[name=dismissChallenge]').attr('data-pendingchallenge');
var $pmWindow = $challenge.closest('.pm-window');
$challenge.remove();
if (pChallenge) {
var pChallengeParts = pChallenge.split('|');
var name = pChallengeParts[0];
var oName = pChallengeParts[1];
var challenge = pChallengeParts.slice(2).join('|');
this.updateChallenge($pmWindow, challenge, name, oName);
}
},
format: function (format, button) {
if (window.BattleFormats) app.addPopup(FormatPopup, {format: format, sourceEl: button});
},
adjustPrivacy: function (disallowSpectators) {
Storage.prefs('disallowspectators', disallowSpectators);
if (disallowSpectators) return '/noreply /hidenext\n';
var settings = app.user.get('settings');
return (settings.hiddenNextBattle ? '/noreply /hidenext off\n' : '') + (settings.inviteOnlyNextBattle ? '/noreply /ionext off\n' : '');
},
team: function (team, button) {
var format = $(button).closest('form').find('button[name=format]').val();
app.addPopup(TeamPopup, {team: team, format: format, sourceEl: button, folderToggleOn: true, folderNotExpanded: []});
},
// format/team selection
curFormat: '',
renderFormats: function (formatid, noChoice) {
if (!window.BattleFormats) {
return '';
}
if (_.isEmpty(BattleFormats)) {
return '';
}
if (!noChoice) {
this.curFormat = formatid;
if (!this.curFormat) {
if (BattleFormats['gen8randombattle']) {
this.curFormat = 'gen8randombattle';
} else for (var i in BattleFormats) {
if (!BattleFormats[i].searchShow || !BattleFormats[i].challengeShow) continue;
this.curFormat = i;
break;
}
}
formatid = this.curFormat;
}
return '';
},
curTeamFormat: '',
curTeamIndex: 0,
renderTeams: function (formatid, teamIndex) {
if (Storage.whenTeamsLoaded.error) {
return '';
}
if (!Storage.teams || !window.BattleFormats) {
return '';
}
if (!formatid) formatid = this.curFormat;
var atIndex = formatid.indexOf('@@@');
if (atIndex >= 0) formatid = formatid.slice(0, atIndex);
if (!window.BattleFormats[formatid]) {
return '';
}
if (window.BattleFormats[formatid].team) {
return '';
}
var format = window.BattleFormats[formatid];
var teamFormat = (format.teambuilderFormat || (format.isTeambuilderFormat ? formatid : false));
var teams = Storage.teams;
if (!teams.length) {
return '';
}
if (teamIndex === undefined) teamIndex = -1;
if (teamIndex < 0) {
if (this.curTeamIndex >= 0) {
teamIndex = this.curTeamIndex;
}
if (this.curTeamFormat !== teamFormat) {
for (var i = 0; i < teams.length; i++) {
if (teams[i].format === teamFormat && teams[i].capacity === 6) {
teamIndex = i;
break;
}
}
}
} else {
teamIndex = +teamIndex;
}
return '';
},
// buttons
search: function (i, button) {
if (!window.BattleFormats) return;
this.requestNotifications();
var $searchForm = $(button).closest('form');
if ($searchForm.find('.cancel').length) {
return;
}
if (!app.user.get('named')) {
app.addPopup(LoginPopup);
return;
}
var $formatButton = $searchForm.find('button[name=format]');
var $teamButton = $searchForm.find('button[name=team]');
var $privacyCheckbox = $searchForm.find('input[name=private]');
var format = $formatButton.val();
var teamIndex = $teamButton.val();
var team = null;
if (Storage.teams[teamIndex]) team = Storage.teams[teamIndex];
if (!window.BattleFormats[format].team && (teamIndex === '' || !team)) {
if (Storage.teams) {
app.addPopupMessage("Please select a team.");
} else {
app.addPopupMessage("You need to go into the Teambuilder and build a team for this format.");
}
return;
}
$formatButton.addClass('preselected')[0].disabled = true;
$teamButton.addClass('preselected')[0].disabled = true;
$searchForm.find('button.big').html(' Connecting...').addClass('disabled');
$searchForm.append('');
app.sendTeam(team);
var self = this;
this.searchDelay = setTimeout(function () {
app.send(self.adjustPrivacy($privacyCheckbox.is(':checked')) + '/search ' + format);
}, 3000);
},
cancelSearch: function () {
clearTimeout(this.searchDelay);
app.send('/cancelsearch');
this.searching = false;
this.updateSearch();
},
finduser: function () {
if (app.isDisconnected) {
app.addPopupMessage("You are offline.");
return;
}
app.addPopupPrompt("Username", "Open", function (target) {
if (!target) return;
if (toID(target) === 'zarel') {
app.addPopup(Popup, {htmlMessage: "Zarel is very busy; please don't contact him this way. If you're looking for help, try joining the Help room?"});
return;
}
if (target === '~') {
app.focusRoom('');
app.rooms[''].focusPM('~');
return;
}
app.addPopup(UserPopup, {name: target});
});
}
}, {
parseChatMessage: function (message, name, timestamp, isHighlighted, $chatElem, isNotPM) {
var showMe = !((Dex.prefs('chatformatting') || {}).hideme);
var group = ' ';
if (!/[A-Za-z0-9]/.test(name.charAt(0))) {
// Backwards compatibility
group = name.charAt(0);
name = name.substr(1);
}
var color = BattleLog.hashColor(toID(name));
var clickableName = '' + BattleLog.escapeHTML(group) + '' + BattleLog.escapeHTML(name) + '';
var hlClass = isHighlighted ? ' highlighted' : '';
var mineClass = (window.app && app.user && app.user.get('name') === name ? ' mine' : '');
var cmd = '';
var target = '';
if (message.charAt(0) === '/') {
if (message.charAt(1) === '/') {
message = message.slice(1);
} else {
var spaceIndex = message.indexOf(' ');
cmd = (spaceIndex >= 0 ? message.slice(1, spaceIndex) : message.slice(1));
if (spaceIndex >= 0) target = message.slice(spaceIndex + 1);
}
}
switch (cmd) {
case 'me':
if (!showMe) return '
';
case 'data-pokemon':
case 'data-item':
case 'data-ability':
case 'data-move':
return '[outdated message type not supported]';
case 'text':
return {message: '
', noNotify: isNotPM};
case 'uhtml':
case 'uhtmlchange':
var parts = target.split(',');
var $elements = $chatElem.find('div.uhtml-' + toID(parts[0]));
var html = parts.slice(1).join(',');
if (!html) {
$elements.remove();
} else if (!$elements.length) {
$chatElem.append('
', noNotify: true};
case 'challenge':
return {challenge: target};
default:
// Not a command or unsupported. Parsed as a normal chat message.
if (!name) {
return '