Bug 1012660 - Remove _chatRoomFieldsList from IRC code. r=aleth
authorPatrick Cloke <clokep@gmail.com>
Tue, 20 May 2014 19:03:18 -0400
changeset 16227 0568cdefd554e3e5d32261b5f5a762db90d7bfe7
parent 16226 a218c71265fa9b7d12d4ea3153fc672ea3332a7f
child 16228 007931222e161a87ffa7c1865fc8fc8973f82354
push id10141
push userclokep@gmail.com
push dateTue, 20 May 2014 23:03:46 +0000
treeherdercomm-central@0568cdefd554 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaleth
bugs1012660
Bug 1012660 - Remove _chatRoomFieldsList from IRC code. r=aleth
chat/locales/en-US/irc.properties
chat/protocols/irc/irc.js
chat/protocols/irc/ircBase.jsm
chat/protocols/irc/ircUtils.jsm
--- a/chat/locales/en-US/irc.properties
+++ b/chat/locales/en-US/irc.properties
@@ -104,17 +104,17 @@ message.nick.fail=Could not use the spec
 #    The parameter is the message.parted.reason, if a part message is given.
 message.parted.you=You have left the room (Part%1$S).
 #    %1$S is the user's nick, %2$S is message.parted.reason, if a part message is given.
 message.parted=%1$S has left the room (Part%2$S).
 #    %S is the part message supplied by the user.
 message.parted.reason=: %S
 #    %1$S is the user's nick, %2$S is message.quit2 if a quit message is given.
 message.quit=%1$S has left the room (Quit%2$S).
-#    The paramter is the quit message given by the user.
+#    The parameter is the quit message given by the user.
 message.quit2=: %S
 #    %1$S is the nickname of the user that invited us, %2$S is the conversation
 #    name.
 message.inviteReceived=%1$S has invited you to %2$S.
 #    %1$S is the nickname of the invited user, %2$S is the conversation name
 #    they were invited to.
 message.invited=%1$S was successfully invited to %2$S.
 #    %1$S is the nickname of the invited user, %2$S is the conversation name
@@ -156,18 +156,22 @@ error.nickCollision=Nick already in use,
 error.erroneousNickname=%S is not an allowed nickname.
 error.banned=You are banned from this server.
 error.bannedSoon=You will soon be banned from this server.
 error.mode.wrongUser=You cannot change modes for other users.
 #    %S is the nickname or channel name that isn't available.
 error.noSuchNick=%S is not online.
 error.wasNoSuchNick=There was no nickname: %S
 error.noSuchChannel=There is no channel: %S.
+error.unavailable=%S is temporarily unavailable.
 #    %S is the channel name.
+error.channelBanned=You have been banned from %S.
 error.cannotSendToChannel=You cannot send messages to %S.
+error.channelFull=The channel %S is full.
+error.inviteOnly=You must be invited to join %S.
 error.nonUniqueTarget=%S is not a unique user@host or shortname or you have tried to join too many channels at once.
 error.notChannelOp=You are not a channel operator on %S.
 error.notChannelOwner=You are not a channel owner of %S.
 error.wrongKey=Cannot join %S, invalid channel password.
 error.sendMessageFailed=An error occurred while sending your last message. Please try again once the connection has been reestablished.
 
 # LOCALIZATION NOTE (tooltip.*):
 #    These are the descriptions given in a tooltip with information received
--- a/chat/protocols/irc/irc.js
+++ b/chat/protocols/irc/irc.js
@@ -790,17 +790,16 @@ function ircAccount(aProtocol, aImAccoun
 
   this._nickname = this._accountNickname;
   this._requestedNickname = this._nickname;
 
   // For more information, see where these are defined in the prototype below.
   this.trackQueue = [];
   this.pendingIsOnQueue = [];
   this.whoisInformation = new NormalizedMap(this.normalizeNick.bind(this));
-  this._chatRoomFieldsList = {};
   this._caps = [];
 
   this._roomInfoCallbacks = new Set();
 }
 ircAccount.prototype = {
   __proto__: GenericAccountPrototype,
   _socket: null,
   _MODE_WALLOPS: 1 << 2, // mode 'w'
@@ -1423,27 +1422,24 @@ ircAccount.prototype = {
     // Give the server 2 seconds to respond, otherwise just forcefully
     // disconnect the socket. This will be cancelled if a response is heard from
     // the server.
     this._quitTimer = setTimeout(this.gotDisconnected.bind(this), 2 * 1000);
   },
 
   createConversation: function(aName) this.getConversation(aName),
 
-  // Temporarily stores the prplIChatRoomFieldValues passed to joinChat for
-  // each channel to enable later reconnections.
-  _chatRoomFieldsList: {},
-
   // aComponents implements prplIChatRoomFieldValues.
   joinChat: function(aComponents) {
     let channel = aComponents.getValue("channel");
     if (!channel) {
       this.ERROR("joinChat called without a channel name.");
       return null;
     }
+
     // A channel prefix is required. If the user didn't include one,
     // we prepend # automatically to match the behavior of other
     // clients. Not doing it used to cause user confusion.
     if (this.channelPrefixes.indexOf(channel[0]) == -1)
       channel = "#" + channel;
 
     // No need to join a channel we are already in.
     if (this.conversations.has(channel)) {
@@ -1452,23 +1448,23 @@ ircAccount.prototype = {
         return conv;
     }
 
     let params = [channel];
     let key = aComponents.getValue("password");
     if (key)
       params.push(key);
     let defaultName = key ? channel + " " + key : channel;
-    this._chatRoomFieldsList[this.normalize(channel)] =
-      this.getChatRoomDefaultFieldValues(defaultName);
     // Send the join command, but don't log the channel key.
     this.sendMessage("JOIN", params,
                      "JOIN " + channel + (key ? " <key not logged>" : ""));
     // Open conversation early for better responsiveness.
     let conv = this.getConversation(channel);
+    // Store the prplIChatRoomFieldValues to enable later reconnections.
+    conv._chatRoomFields = this.getChatRoomDefaultFieldValues(defaultName);
     conv.joining = true;
     return conv;
   },
 
   chatRoomFields: {
     "channel": {get label() _("joinChat.channel"), required: true},
     "password": {get label() _("joinChat.password"), isPassword: true}
   },
--- a/chat/protocols/irc/ircBase.jsm
+++ b/chat/protocols/irc/ircBase.jsm
@@ -181,30 +181,25 @@ var ircBase = {
           // an automatic reconnection, for which we already notify the user.
           if (!conversation._firstJoin && !conversation._chatRoomFields) {
             conversation.writeMessage(aMessage.nickname, _("message.rejoined"),
                                       {system: true});
           }
           delete conversation._firstJoin;
 
           // Ensure chatRoomFields information is available for reconnection.
-          let nName = this.normalize(channelName);
-          if (hasOwnProperty(this._chatRoomFieldsList, nName)) {
-            conversation._chatRoomFields = this._chatRoomFieldsList[nName];
-            delete this._chatRoomFieldsList[nName];
-          }
-          else {
+          if (!conversation._chatRoomFields) {
             this.WARN("Opening a MUC without storing its " +
                       "prplIChatRoomFieldValues first.");
             conversation._chatRoomFields =
               this.getChatRoomDefaultFieldValues(channelName);
           }
         }
         else {
-          // Don't worry about adding ourself, RPL_NAMES takes care of that
+          // Don't worry about adding ourself, RPL_NAMREPLY takes care of that
           // case.
           conversation.getParticipant(aMessage.nickname, true);
           let msg = _("message.join", aMessage.nickname, aMessage.source || "");
           conversation.writeMessage(aMessage.nickname, msg, {system: true,
                                                              noLinkification: true});
         }
       }
       // If the joiner is a buddy, mark as online.
@@ -1081,41 +1076,40 @@ var ircBase = {
     },
     "402": function(aMessage) { // ERR_NOSUCHSERVER
       // <server name> :No such server
       // TODO Parse & display an error to the user.
       return false;
     },
     "403": function(aMessage) { // ERR_NOSUCHCHANNEL
       // <channel name> :No such channel
-      delete this._chatRoomFieldsList[this.normalize(aMessage.params[1])];
-      return conversationErrorMessage(this, aMessage, "error.noChannel");
+      return conversationErrorMessage(this, aMessage, "error.noChannel", true,
+                                      false);
     },
     "404": function(aMessage) { // ERR_CANNOTSENDTOCHAN
       // <channel name> :Cannot send to channel
       // Notify the user that they can't send to that channel.
       return conversationErrorMessage(this, aMessage,
                                       "error.cannotSendToChannel");
     },
     "405": function(aMessage) { // ERR_TOOMANYCHANNELS
       // <channel name> :You have joined too many channels
-      delete this._chatRoomFieldsList[this.normalize(aMessage.params[1])];
-      return serverErrorMessage(this, aMessage,
-                                _("error.tooManyChannels", aMessage.params[1]));
+      return conversationErrorMessage(this, aMessage, "error.tooManyChannels",
+                                      true);
     },
     "406": function(aMessage) { // ERR_WASNOSUCHNICK
       // <nickname> :There was no such nickname
       // Can arise in response to WHOWAS.
       return serverErrorMessage(this, aMessage,
                                 _("error.wasNoSuchNick", aMessage.params[1]));
     },
     "407": function(aMessage) { // ERR_TOOMANYTARGETS
       // <target> :<error code> recipients. <abort message>
-      delete this._chatRoomFieldsList[this.normalize(aMessage.params[1])];
-      return conversationErrorMessage(this, aMessage, "error.nonUniqueTarget");
+      return conversationErrorMessage(this, aMessage, "error.nonUniqueTarget",
+                                      false, false);
     },
     "408": function(aMessage) { // ERR_NOSUCHSERVICE
       // <service name> :No such service
       // TODO
       return false;
     },
     "409": function(aMessage) { // ERR_NOORIGIN
       // :No origin specified
@@ -1200,19 +1194,18 @@ var ircBase = {
       return this.tryNewNick(aMessage.params[1]);
     },
     "436": function(aMessage) { // ERR_NICKCOLLISION
       // <nick> :Nickname collision KILL from <user>@<host>
       return this.tryNewNick(aMessage.params[1]);
     },
     "437": function(aMessage) { // ERR_UNAVAILRESOURCE
       // <nick/channel> :Nick/channel is temporarily unavailable
-      // TODO
-      delete this._chatRoomFieldsList[this.normalize(aMessage.params[1])];
-      return false;
+      return conversationErrorMessage(this, aMessage, "error.unavailable",
+                                      true);
     },
     "441": function(aMessage) { // ERR_USERNOTINCHANNEL
       // <nick> <channel> :They aren't on that channel
       // TODO
       return false;
     },
     "442": function(aMessage) { // ERR_NOTONCHANNEL
       // <channel> :You're not on that channel
@@ -1286,56 +1279,42 @@ var ircBase = {
     },
     "467": function(aMessage) { // ERR_KEYSET
       // <channel> :Channel key already set
       // TODO
       return false;
     },
     "471": function(aMessage) { // ERR_CHANNELISFULL
       // <channel> :Cannot join channel (+l)
-      // TODO
-      delete this._chatRoomFieldsList[this.normalize(aMessage.params[1])];
-      return false;
+      return conversationErrorMessage(this, aMessage, "error.channelFull",
+                                      true);
     },
     "472": function(aMessage) { // ERR_UNKNOWNMODE
       // <char> :is unknown mode char to me for <channel>
       // TODO
       return false;
     },
     "473": function(aMessage) { // ERR_INVITEONLYCHAN
       // <channel> :Cannot join channel (+i)
-      // TODO
-      delete this._chatRoomFieldsList[this.normalize(aMessage.params[1])];
-      return false;
+      return conversationErrorMessage(this, aMessage, "error.inviteOnly",
+                                      true, false);
     },
     "474": function(aMessage) { // ERR_BANNEDFROMCHAN
       // <channel> :Cannot join channel (+b)
-      // TODO
-      delete this._chatRoomFieldsList[this.normalize(aMessage.params[1])];
-      return false;
+      return conversationErrorMessage(this, aMessage, "error.channelBanned",
+                                      true, false);
     },
     "475": function(aMessage) { // ERR_BADCHANNELKEY
       // <channel> :Cannot join channel (+k)
-      let channelName = aMessage.params[1];
-
-      // Display an error message to the user.
-      let msg = _("error.wrongKey", channelName);
-      let conversation = this.getConversation(channelName);
-      conversation.writeMessage(aMessage.servername, msg, {system: true});
-
-      // The stored information is out of date, remove it.
-      delete conversation._chatRoomFields;
-      delete this._chatRoomFieldsList[this.normalize(channelName)];
-
-      return true;
+      return conversationErrorMessage(this, aMessage, "error.wrongKey",
+                                      true, false);
     },
     "476": function(aMessage) { // ERR_BADCHANMASK
       // <channel> :Bad Channel Mask
       // TODO
-      delete this._chatRoomFieldsList[this.normalize(aMessage.params[1])];
       return false;
     },
     "477": function(aMessage) { // ERR_NOCHANMODES
       // <channel> :Channel doesn't support modes
       // TODO
       return false;
     },
     "478": function(aMessage) { // ERR_BANLISTFULL
--- a/chat/protocols/irc/ircUtils.jsm
+++ b/chat/protocols/irc/ircUtils.jsm
@@ -211,15 +211,30 @@ function mIRCColoring(aStack, aInput) {
         length = matches[0].length;
       }
     }
   }
 
   return [stack, output, length];
 }
 
-function conversationErrorMessage(aAccount, aMessage, aError) {
+// Print an error message into a conversation, optionally mark the conversation
+// as not joined and/or not rejoinable.
+function conversationErrorMessage(aAccount, aMessage, aError,
+                                  aJoinFailed = false, aRejoinable = true) {
   let conv = aAccount.getConversation(aMessage.params[1]);
   conv.writeMessage(aMessage.servername, _(aError, aMessage.params[1]),
                     {error: true, system: true});
   delete conv._pendingMessage;
+
+  // Channels have a couple extra things that can be done to them.
+  if (aAccount.isMUCName(aMessage.params[1])) {
+    // If a value for joining is explictly given, mark it.
+    if (aJoinFailed)
+      conv.joining = false;
+    // If the conversation cannot be rejoined automatically, delete
+    // _chatRoomFields.
+    if (!aRejoinable)
+      delete conv._chatRoomFields;
+  }
+
   return true;
 }