Bug 955366 - Use Maps and Sets in IRC code, convert whois information. r=aleth
authorPatrick Cloke <clokep@gmail.com>
Tue, 06 May 2014 20:29:06 -0400
changeset 16180 fe529f9dd6975c6ba574e0a083363c8aa5292efa
parent 16179 c6b03e55cb0ffe097bb33e8452ca9b32fe9f7767
child 16181 9c05e894da1e6e96537892c3ff9988e06fbc1ecc
push id10115
push userclokep@gmail.com
push dateThu, 08 May 2014 14:05:31 +0000
treeherdercomm-central@da34b03c7e57 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaleth
bugs955366
Bug 955366 - Use Maps and Sets in IRC code, convert whois information. r=aleth
chat/protocols/irc/irc.js
chat/protocols/irc/ircBase.jsm
--- a/chat/protocols/irc/irc.js
+++ b/chat/protocols/irc/irc.js
@@ -208,34 +208,34 @@ const GenericIRCConversation = {
 
     // If this is the last nick, remove the observer.
     if (!this._observedNicks.length)
       Services.obs.removeObserver(this, "user-info-received");
 
     // If we are waiting for the conversation name, set it.
     let account = this._account;
     if (this._waitingForNick && nick == this.normalizedName) {
-      if (hasOwnProperty(account.whoisInformation, nick))
-        this.updateNick(account.whoisInformation[nick]["nick"]);
+      if (account.whoisInformation.has(nick))
+        this.updateNick(account.whoisInformation.get(nick)["nick"]);
       delete this._waitingForNick;
       return;
     }
 
     // Otherwise, print the requested whois information.
     let type = {system: true, noLog: true};
     // RFC 2812 errors 401 and 406 result in there being no entry for the nick.
-    if (!hasOwnProperty(account.whoisInformation, nick)) {
+    if (!account.whoisInformation.has(nick)) {
       this.writeMessage(null, _("message.unknownNick", nick), type);
       return;
     }
     // If the nick is offline, tell the user. In that case, it's WHOWAS info.
     let msgType = "message.whois";
-    if ("offline" in account.whoisInformation[nick])
+    if ("offline" in account.whoisInformation.get(nick))
       msgType = "message.whowas";
-    let msg = _(msgType, account.whoisInformation[nick]["nick"]);
+    let msg = _(msgType, account.whoisInformation.get(nick)["nick"]);
 
     // Iterate over each field.
     let tooltipInfo = aSubject.QueryInterface(Ci.nsISimpleEnumerator);
     while (tooltipInfo.hasMoreElements()) {
       let elt = tooltipInfo.getNext().QueryInterface(Ci.prplITooltipInfo);
       switch (elt.type) {
         case Ci.prplITooltipInfo.pair:
         case Ci.prplITooltipInfo.sectionHeader:
@@ -594,18 +594,18 @@ ircParticipant.prototype = {
   get op() this._modes.indexOf("o") != -1,
   get founder()
     this._modes.indexOf("O") != -1 || this._modes.indexOf("q") != -1,
   get typing() false
 };
 
 function ircConversation(aAccount, aName) {
   let nick = aAccount.normalize(aName);
-  if (hasOwnProperty(aAccount.whoisInformation, nick))
-    aName = aAccount.whoisInformation[nick]["nick"];
+  if (aAccount.whoisInformation.has(nick))
+    aName = aAccount.whoisInformation.get(nick)["nick"];
 
   this._init(aAccount, aName);
   this._observedNicks = [];
 
   // Fetch correctly capitalized name.
   // Always request the info as it may be out of date.
   this._waitingForNick = true;
   this.requestBuddyInfo(aName);
@@ -795,17 +795,17 @@ function ircAccount(aProtocol, aImAccoun
   this._server = this.name.slice(splitter + 1);
 
   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 = {};
+  this.whoisInformation = new NormalizedMap(this.normalizeNick.bind(this));
   this._chatRoomFieldsList = {};
   this._caps = [];
 
   this._roomInfoCallbacks = new Set();
 }
 ircAccount.prototype = {
   __proto__: GenericAccountPrototype,
   _socket: null,
@@ -984,17 +984,17 @@ ircAccount.prototype = {
       }
     }
     this._roomInfoCallbacks.clear();
     delete this._pendingList;
   },
 
   // The whois information: nicks are used as keys and refer to a map of field
   // to value.
-  whoisInformation: {},
+  whoisInformation: null,
   // Request WHOIS information on a buddy when the user requests more
   // information.
   requestBuddyInfo: function(aBuddyName) {
     if (!this.connected)
       return;
 
     this.removeBuddyInfo(aBuddyName);
     this.sendMessage("WHOIS", aBuddyName);
@@ -1006,21 +1006,20 @@ ircAccount.prototype = {
   // Request WHOWAS information on a buddy when the user requests more
   // information.
   requestOfflineBuddyInfo: function(aBuddyName) {
     this.removeBuddyInfo(aBuddyName);
     this.sendMessage("WHOWAS", aBuddyName);
   },
   // Return an nsISimpleEnumerator of imITooltipInfo for a given nick.
   getBuddyInfo: function(aNick) {
-    let nick = this.normalizeNick(aNick);
-    if (!hasOwnProperty(this.whoisInformation, nick))
+    if (!this.whoisInformation.has(aNick))
       return EmptyEnumerator;
 
-    let whoisInformation = this.whoisInformation[nick];
+    let whoisInformation = this.whoisInformation.get(aNick);
     if (whoisInformation.serverName && whoisInformation.serverInfo) {
       whoisInformation.server =
         _("tooltip.serverValue", whoisInformation.serverName,
           whoisInformation.serverInfo);
     }
 
     // Sort the list of channels, ignoring the prefixes of channel and user.
     let prefixes = this.userPrefixes.concat(this.channelPrefixes);
@@ -1084,39 +1083,35 @@ ircAccount.prototype = {
     else if ("lastActivity" in whoisInformation &&
              whoisInformation["lastActivity"] > kSetIdleStatusAfterSeconds)
       statusType = Ci.imIStatusInfo.STATUS_IDLE;
     tooltipInfo.push(new TooltipInfo(statusType, statusText, true));
 
     return new nsSimpleEnumerator(tooltipInfo);
   },
   // Remove a WHOIS entry.
-  removeBuddyInfo: function(aNick) {
-    let nick = this.normalizeNick(aNick);
-    if (hasOwnProperty(this.whoisInformation, nick))
-      delete this.whoisInformation[nick];
-  },
+  removeBuddyInfo: function(aNick) this.whoisInformation.delete(aNick),
   // Copies the fields of aFields into the whois table. If the field already
   // exists, that field is ignored (it is assumed that the first server response
   // is the most up to date information, as is the case for 312/314). Note that
   // the whois info for a nick is reset whenever whois information is requested,
   // so the first response from each whois is recorded.
   setWhois: function(aNick, aFields = {}) {
-    let nick = this.normalizeNick(aNick);
     // If the nickname isn't in the list yet, add it.
-    if (!hasOwnProperty(this.whoisInformation, nick))
-      this.whoisInformation[nick] = {};
+    if (!this.whoisInformation.has(aNick))
+      this.whoisInformation.set(aNick, {});
 
     // Set non-normalized nickname field.
-    this.whoisInformation[nick]["nick"] = aNick;
+    let whoisInfo = this.whoisInformation.get(aNick);
+    whoisInfo.nick = aNick;
 
     // Set the WHOIS fields, but only the first time a field is set.
     for (let field in aFields) {
-      if (!this.whoisInformation[nick].hasOwnProperty(field))
-        this.whoisInformation[nick][field] = aFields[field];
+      if (!whoisInfo.hasOwnProperty(field))
+        whoisInfo[field] = aFields[field];
     }
 
     return true;
   },
 
   trackBuddy: function(aNick) {
     // Put the username as the first to be checked on the next ISON call.
     this.trackQueue.unshift(aNick);
@@ -1496,21 +1491,21 @@ ircAccount.prototype = {
   get canJoinChat() true,
 
   hasConversation: function(aConversationName)
     hasOwnProperty(this._conversations, this.normalize(aConversationName)),
 
   // Returns a conversation (creates it if it doesn't exist)
   getConversation: function(aName) {
     let name = this.normalize(aName);
-    // If the whois information has been received, we have the proper nick
-    // capitalization.
-    if (hasOwnProperty(this.whoisInformation, name))
-      aName = this.whoisInformation[name].nick;
     if (!this.hasConversation(aName)) {
+      // If the whois information has been received, we have the proper nick
+      // capitalization.
+      if (this.whoisInformation.has(aName))
+        aName = this.whoisInformation.get(aName).nick;
       let constructor = this.isMUCName(aName) ? ircChannel : ircConversation;
       this._conversations[name] = new constructor(this, aName, this._nickname);
     }
     return this._conversations[name];
   },
 
   removeConversation: function(aConversationName) {
     if (this.hasConversation(aConversationName))
@@ -1689,17 +1684,17 @@ ircAccount.prototype = {
     }
 
     // If we disconnected during a pending LIST request, make sure callbacks
     // receive any remaining channels.
     if (this._pendingList)
       this._sendRemainingRoomInfo();
 
     // Clear whois table.
-    this.whoisInformation = {};
+    this.whoisInformation.clear();
 
     this.reportDisconnected();
   },
 
   remove: function() {
     for each (let conv in this._conversations)
       conv.close();
     delete this._conversations;
--- a/chat/protocols/irc/ircBase.jsm
+++ b/chat/protocols/irc/ircBase.jsm
@@ -735,19 +735,19 @@ var ircBase = {
       // <nick> <integer> :seconds idle
       return this.setWhois(aMessage.params[1],
                            {lastActivity: parseInt(aMessage.params[2])});
     },
     "318": function(aMessage) { // RPL_ENDOFWHOIS
       // <nick> :End of WHOIS list
       // We've received everything about WHOIS, tell the tooltip that is waiting
       // for this information.
-      let nick = this.normalizeNick(aMessage.params[1]);
+      let nick = aMessage.params[1];
 
-      if (hasOwnProperty(this.whoisInformation, nick))
+      if (this.whoisInformation.has(nick))
         this.notifyWhois(nick);
       else {
         // If there is no whois information stored at this point, the nick
         // is either offline or does not exist, so we run WHOWAS.
         this.requestOfflineBuddyInfo(nick);
       }
       return true;
     },