Bug 1635454 - Update instant messaging fields in the address book. r=frg DONTBUILD
authorIan Neal <iann_cvs@blueyonder.co.uk>
Tue, 05 May 2020 13:01:07 +0100
changeset 29642 17a3b9a2aeedb1652edd44b506dc037679ff5d4c
parent 29641 6a077945683b32ef107dca9ceb7ed9959a5bc5c7
child 29643 b12d34446556d9b4356cc0a7d314cab6c3c55967
push id17469
push userfrgrahl@gmx.net
push dateFri, 22 May 2020 13:09:08 +0000
treeherdercomm-central@17a3b9a2aeed [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfrg
bugs1635454, 759328, 792800
Bug 1635454 - Update instant messaging fields in the address book. r=frg DONTBUILD Port the relevant parts of the following bugs to SeaMonkey: * Bug 759328 - Add instant messaging fields to the address book cards * Bug 792800 - Add a field for IRC nicknames in the Address Book
mailnews/addrbook/src/nsAbCardProperty.cpp
suite/locales/en-US/chrome/mailnews/addressbook/abCardOverlay.dtd
suite/locales/en-US/chrome/mailnews/addressbook/abMainWindow.dtd
suite/locales/en-US/chrome/mailnews/addressbook/abResultsPaneOverlay.dtd
suite/locales/en-US/chrome/mailnews/addressbook/addressBook.properties
suite/mailnews/addrbook/content/abResultsPaneOverlay.xul
suite/mailnews/components/addrbook/content/abCardOverlay.js
suite/mailnews/components/addrbook/content/abCardOverlay.xul
suite/mailnews/components/addrbook/content/abCardViewOverlay.js
suite/mailnews/components/addrbook/content/addressbook.xul
--- a/mailnews/addrbook/src/nsAbCardProperty.cpp
+++ b/mailnews/addrbook/src/nsAbCardProperty.cpp
@@ -47,23 +47,17 @@ struct AppendItem {
   const char *mLabel;
   EAppendType mAppendType;
 };
 
 static const AppendItem NAME_ATTRS_ARRAY[] = {
     {kDisplayNameProperty, "propertyDisplayName", eAppendLabel},
     {kNicknameProperty, "propertyNickname", eAppendLabel},
     {kPriEmailProperty, "", eAppendLine},
-#ifndef MOZ_THUNDERBIRD
-    {k2ndEmailProperty, "", eAppendLine},
-    {kScreenNameProperty, "propertyScreenName", eAppendLabel}
-#else
-    {k2ndEmailProperty, "", eAppendLine}
-#endif
-};
+    {k2ndEmailProperty, "", eAppendLine}};
 
 static const AppendItem PHONE_ATTRS_ARRAY[] = {
     {kWorkPhoneProperty, "propertyWork", eAppendLabel},
     {kHomePhoneProperty, "propertyHome", eAppendLabel},
     {kFaxProperty, "propertyFax", eAppendLabel},
     {kPagerProperty, "propertyPager", eAppendLabel},
     {kCellularProperty, "propertyCellular", eAppendLabel}};
 
@@ -86,29 +80,26 @@ static const AppendItem WORK_ATTRS_ARRAY
 
 static const AppendItem CUSTOM_ATTRS_ARRAY[] = {
     {kCustom1Property, "propertyCustom1", eAppendLabel},
     {kCustom2Property, "propertyCustom2", eAppendLabel},
     {kCustom3Property, "propertyCustom3", eAppendLabel},
     {kCustom4Property, "propertyCustom4", eAppendLabel},
     {kNotesProperty, "", eAppendLine}};
 
-#ifdef MOZ_THUNDERBIRD
-
 static const AppendItem CHAT_ATTRS_ARRAY[] = {
     {kGtalkProperty, "propertyGtalk", eAppendLabel},
     {kAIMProperty, "propertyAIM", eAppendLabel},
     {kYahooProperty, "propertyYahoo", eAppendLabel},
     {kSkypeProperty, "propertySkype", eAppendLabel},
     {kQQProperty, "propertyQQ", eAppendLabel},
     {kMSNProperty, "propertyMSN", eAppendLabel},
     {kICQProperty, "propertyICQ", eAppendLabel},
     {kXMPPProperty, "propertyXMPP", eAppendLabel},
     {kIRCProperty, "propertyIRC", eAppendLabel}};
-#endif
 
 nsAbCardProperty::nsAbCardProperty() : m_IsMailList(false) {
   // Initialize some default properties
   SetPropertyAsUint32(kPreferMailFormatProperty,
                       nsIAbPreferMailFormat::unknown);
   SetPropertyAsUint32(kPopularityIndexProperty, 0);
   // Uninitialized...
   SetPropertyAsUint32(kLastModifiedDateProperty, 0);
@@ -636,21 +627,19 @@ nsresult nsAbCardProperty::ConvertToXMLP
   rv = AppendSection(PHONE_ATTRS_ARRAY,
                      sizeof(PHONE_ATTRS_ARRAY) / sizeof(AppendItem),
                      NS_LITERAL_STRING("headingPhone"), bundle, conv, xmlStr);
 
   if (!m_IsMailList) {
     rv = AppendSection(CUSTOM_ATTRS_ARRAY,
                        sizeof(CUSTOM_ATTRS_ARRAY) / sizeof(AppendItem),
                        NS_LITERAL_STRING("headingOther"), bundle, conv, xmlStr);
-#ifdef MOZ_THUNDERBIRD
     rv = AppendSection(CHAT_ATTRS_ARRAY,
                        sizeof(CHAT_ATTRS_ARRAY) / sizeof(AppendItem),
                        NS_LITERAL_STRING("headingChat"), bundle, conv, xmlStr);
-#endif
   } else {
     rv = AppendSection(
         CUSTOM_ATTRS_ARRAY, sizeof(CUSTOM_ATTRS_ARRAY) / sizeof(AppendItem),
         NS_LITERAL_STRING("headingDescription"), bundle, conv, xmlStr);
 
     xmlStr.AppendLiteral("<section><sectiontitle>");
 
     nsString headingAddresses;
--- a/suite/locales/en-US/chrome/mailnews/addressbook/abCardOverlay.dtd
+++ b/suite/locales/en-US/chrome/mailnews/addressbook/abCardOverlay.dtd
@@ -27,31 +27,30 @@
 <!ENTITY NameField1.accesskey           "F">
 <!ENTITY NameField2.label               "Last:">
 <!ENTITY NameField2.accesskey           "L">
 <!ENTITY PhoneticField1.label           "Phonetic:">
 <!ENTITY PhoneticField2.label           "Phonetic:">
 <!ENTITY DisplayName.label              "Display:">
 <!ENTITY DisplayName.accesskey          "D">
 <!ENTITY preferDisplayName.label        "Always prefer display name over message header">
-<!ENTITY preferDisplayName.accesskey    "A">
+<!ENTITY preferDisplayName2.accesskey   "y">
 <!ENTITY NickName.label                 "Nickname:">
 <!ENTITY NickName.accesskey             "N">
 
 <!ENTITY PrimaryEmail.label             "Email:">
 <!ENTITY PrimaryEmail.accesskey         "E">
 <!ENTITY SecondEmail.label              "Additional Email:">
 <!ENTITY SecondEmail.accesskey          "i">
 <!ENTITY PreferMailFormat.label         "Prefers to receive messages formatted as:">
 <!ENTITY PreferMailFormat.accesskey     "v">
 <!ENTITY PlainText.label                "Plain Text">
 <!ENTITY HTML.label                     "HTML">
 <!ENTITY Unknown.label                  "Unknown">
-<!ENTITY ScreenName.label               "Screen Name:">
-<!ENTITY ScreenName.accesskey           "S">
+<!ENTITY chatName.label                 "Chat Name:">
 
 <!ENTITY WorkPhone.label                "Work:">
 <!ENTITY WorkPhone.accesskey            "k">
 <!ENTITY HomePhone.label                "Home:">
 <!ENTITY HomePhone.accesskey            "m">
 <!ENTITY FaxNumber.label                "Fax:">
 <!ENTITY FaxNumber.accesskey            "x">
 <!ENTITY PagerNumber.label              "Pager:">
@@ -114,16 +113,37 @@
 <!ENTITY Custom2.accesskey              "2">
 <!ENTITY Custom3.label                  "Custom 3:">
 <!ENTITY Custom3.accesskey              "3">
 <!ENTITY Custom4.label                  "Custom 4:">
 <!ENTITY Custom4.accesskey              "4">
 <!ENTITY Notes.label                    "Notes:">
 <!ENTITY Notes.accesskey                "N">
 
+<!ENTITY Chat.tab                       "Chat">
+<!ENTITY Chat.accesskey                 "a">
+<!ENTITY Gtalk.label                    "Google Talk:">
+<!ENTITY Gtalk.accesskey                "G">
+<!ENTITY AIM.label                      "AIM:">
+<!ENTITY AIM.accesskey                  "M">
+<!ENTITY Yahoo.label                    "Yahoo!:">
+<!ENTITY Yahoo.accesskey                "Y">
+<!ENTITY Skype.label                    "Skype:">
+<!ENTITY Skype.accesskey                "S">
+<!ENTITY QQ.label                       "QQ:">
+<!ENTITY QQ.accesskey                   "Q">
+<!ENTITY MSN.label                      "MSN:">
+<!ENTITY MSN.accesskey                  "N">
+<!ENTITY ICQ.label                      "ICQ:">
+<!ENTITY ICQ.accesskey                  "I">
+<!ENTITY XMPP.label                     "Jabber ID:">
+<!ENTITY XMPP.accesskey                 "J">
+<!ENTITY IRC.label                      "IRC Nick:">
+<!ENTITY IRC.accesskey                  "R">
+
 <!ENTITY Photo.tab                      "Photo">
 <!ENTITY Photo.accesskey                "o">
 <!ENTITY PhotoDesc.label                "Pick one of the following:">
 <!ENTITY GenericPhoto.label             "Generic Photo">
 <!ENTITY GenericPhoto.accesskey         "G">
 <!ENTITY DefaultPhoto.label             "Default">
 <!ENTITY PhotoFile.label                "On this Computer">
 <!ENTITY PhotoFile.accesskey            "n">
--- a/suite/locales/en-US/chrome/mailnews/addressbook/abMainWindow.dtd
+++ b/suite/locales/en-US/chrome/mailnews/addressbook/abMainWindow.dtd
@@ -100,16 +100,17 @@
 <!-- Dir Tree header -->
 <!ENTITY dirTreeHeader.label                            "Address Books">
 
 <!-- Card Summary Pane -->
 <!-- Box Headings -->
 <!ENTITY contact.heading                                "Contact">
 <!ENTITY home.heading                                   "Home">
 <!ENTITY other.heading                                  "Other">
+<!ENTITY chat.heading                                   "Chat">
 <!ENTITY phone.heading                                  "Phone">
 <!ENTITY work.heading                                   "Work">
 <!-- Special Box Headings, for mailing lists -->
 <!ENTITY description.heading                            "Description">
 <!ENTITY addresses.heading                              "Addresses">
 <!-- For Map It! -->
 <!ENTITY mapItButton.label                              "Get Map">
 <!ENTITY mapIt.tooltip                                  "Display a map of this address from the Web">
--- a/suite/locales/en-US/chrome/mailnews/addressbook/abResultsPaneOverlay.dtd
+++ b/suite/locales/en-US/chrome/mailnews/addressbook/abResultsPaneOverlay.dtd
@@ -23,18 +23,18 @@
 <!ENTITY PagerNumber.label                     "Pager">
 <!ENTITY PagerNumber.accesskey                 "P">
 <!ENTITY FaxNumber.label                       "Fax">
 <!ENTITY FaxNumber.accesskey                   "F">
 <!ENTITY HomePhone.label                       "Home Phone">
 <!ENTITY HomePhone.accesskey                   "H">
 <!ENTITY WorkPhone.label                       "Work Phone">
 <!ENTITY WorkPhone.accesskey                   "W">
-<!ENTITY ScreenName.label                      "Screen Name">
-<!ENTITY ScreenName.accesskey                  "S">
+<!ENTITY ChatName.label                        "Chat Name">
+<!ENTITY ChatName.accesskey                    "C">
 <!ENTITY sortAscending.label                   "Ascending">
 <!ENTITY sortAscending.accesskey               "A">
 <!ENTITY sortDescending.label                  "Descending">
 <!ENTITY sortDescending.accesskey              "D">
 
 <!-- context menu -->
 <!ENTITY composeEmail.label                    "Compose Email To">
 <!ENTITY composeEmail.accesskey                "C">
--- a/suite/locales/en-US/chrome/mailnews/addressbook/addressBook.properties
+++ b/suite/locales/en-US/chrome/mailnews/addressbook/addressBook.properties
@@ -42,30 +42,39 @@ confirmDeleteContact=Are you sure you wa
 confirmDeleteContacts=Are you sure you want to delete the selected contacts?
 confirmDeleteMailingList=Are you sure you want to delete the selected mailing list?
 confirmDeleteListsAndContacts=Are you sure you want to delete the selected contacts and mailing lists?
 confirmDeleteMailingLists=Are you sure you want to delete the selected mailing lists?
 
 propertyPrimaryEmail=Email
 propertyListName=List Name
 propertySecondaryEmail=Additional Email
-propertyScreenName=Screen Name
 propertyNickname=Nickname
 propertyDisplayName=Display Name
 propertyWork=Work
 propertyHome=Home
 propertyFax=Fax
 propertyCellular=Mobile
 propertyPager=Pager
 propertyBirthday=Birthday
 propertyCustom1=Custom 1
 propertyCustom2=Custom 2
 propertyCustom3=Custom 3
 propertyCustom4=Custom 4
 
+propertyGtalk=Google Talk
+propertyAIM=AIM
+propertyYahoo=Yahoo!
+propertySkype=Skype
+propertyQQ=QQ
+propertyMSN=MSN
+propertyICQ=ICQ
+propertyXMPP=Jabber ID
+propertyIRC=IRC Nick
+
 ## LOCALIZATION NOTE (cityAndStateAndZip): 
 ## %1$S is city, %2$S is state, %3$S is zip
 cityAndStateAndZip=%1$S, %2$S %3$S
 ## LOCALIZATION NOTE (cityAndStateNoZip): 
 ## %1$S is city, %2$S is state
 cityAndStateNoZip=%1$S, %2$S
 ## LOCALIZATION NOTE (cityOrStateAndZip): 
 ## %1$S is city or state, %2$S is zip
@@ -141,16 +150,17 @@ AuthDlgDesc=To access the directory serv
 # LOCALIZATION NOTE(joinMeInThisChat)
 # use + for spaces
 joinMeInThisChat=Join+me+in+this+Chat.
 
 # For printing
 headingHome=Home
 headingWork=Work
 headingOther=Other
+headingChat=Chat
 headingPhone=Phone
 headingDescription=Description
 headingAddresses=Addresses
 
 ## For address books
 addressBookTitleNew=New Address Book
 # LOCALIZATION NOTE (addressBookTitleEdit):
 # %S is the current name of the address book.
--- a/suite/mailnews/addrbook/content/abResultsPaneOverlay.xul
+++ b/suite/mailnews/addrbook/content/abResultsPaneOverlay.xul
@@ -16,28 +16,28 @@
 
 <tree id="abResultsTree" flex="1" enableColumnDrag="true" class="plain focusring"
     onclick="AbResultsPaneOnClick(event);"
     onselect="this.view.selectionChanged(); document.commandDispatcher.updateCommands('addrbook-select');"
     sortCol="GeneratedName"
     persist="sortCol height">
 
   <treecols id="abResultsTreeCols">
-  <!-- these column ids must match up to the mork column names, except for GeneratedName, see nsIAddrDatabase.idl -->
+  <!-- these column ids must match up to the mork column names, except for GeneratedName and ChatName, see nsIAddrDatabase.idl -->
     <treecol id="GeneratedName"
              persist="hidden ordinal width sortDirection" flex="1"
              label="&GeneratedName.label;" primary="true"/>
     <splitter class="tree-splitter"/>
     <treecol id="PrimaryEmail"
              persist="hidden ordinal width sortDirection" flex="1"
              label="&PrimaryEmail.label;"/>
     <splitter class="tree-splitter"/>
-    <treecol id="_AimScreenName"
+    <treecol id="ChatName"
              persist="hidden ordinal width sortDirection" flex="1"
-             label="&ScreenName.label;"/>
+             label="&ChatName.label;"/>
     <splitter class="tree-splitter"/>
     <treecol id="Company"
              persist="hidden ordinal width sortDirection" flex="1"
              label="&Company.label;"/>
     <splitter class="tree-splitter"/>
     <treecol id="NickName"
              persist="hidden ordinal width sortDirection" flex="1"
              label="&NickName.label;" hidden="true"/>
--- a/suite/mailnews/components/addrbook/content/abCardOverlay.js
+++ b/suite/mailnews/components/addrbook/content/abCardOverlay.js
@@ -16,17 +16,16 @@ const kVcardFields =
         [ // Contact > Name
          ["FirstName", "FirstName"],
          ["LastName", "LastName"],
          ["DisplayName", "DisplayName"],
          ["NickName", "NickName"],
           // Contact > Internet
          ["PrimaryEmail", "PrimaryEmail"],
          ["SecondEmail", "SecondEmail"],
-         ["ScreenName", "_AimScreenName"], // NB: AIM.
           // Contact > Phones
          ["WorkPhone", "WorkPhone"],
          ["HomePhone", "HomePhone"],
          ["FaxNumber", "FaxNumber"],
          ["PagerNumber", "PagerNumber"],
          ["CellularNumber", "CellularNumber"],
           // Address > Home
          ["HomeAddress", "HomeAddress"],
@@ -48,17 +47,28 @@ const kVcardFields =
          ["WorkCountry", "WorkCountry"],
          ["WebPage1", "WebPage1"],
           // Other > (custom)
          ["Custom1", "Custom1"],
          ["Custom2", "Custom2"],
          ["Custom3", "Custom3"],
          ["Custom4", "Custom4"],
           // Other > Notes
-         ["Notes", "Notes"]];
+         ["Notes", "Notes"],
+          // Chat
+         ["Gtalk", "_GoogleTalk"],
+         ["AIM", "_AimScreenName"],
+         ["Yahoo", "_Yahoo"],
+         ["Skype", "_Skype"],
+         ["QQ", "_QQ"],
+         ["MSN", "_MSN"],
+         ["ICQ", "_ICQ"],
+         ["XMPP", "_JabberId"],
+         ["IRC", "_IRC"]
+        ];
 
 var gEditCard;
 var gOnSaveListeners = [];
 var gOnLoadListeners = [];
 var gOkCallback = null;
 var gHideABPicker = false;
 var gPhotoHandlers = {};
 
@@ -487,16 +497,18 @@ function GetCardValues(cardproperty, doc
 
   // Store the original photo URI and update the photo
   // Select the type if there is a valid value stored for that type, otherwise
   // select the generic photo
   var photoType = cardproperty.getProperty("PhotoType", "");
   document.getElementById("PhotoType").value = photoType;
   loadPhoto(cardproperty);
   setCardEditorPhoto(photoType, cardproperty);
+
+  updateChatName();
 }
 
 // when the ab card dialog is being loaded to show a vCard,
 // hide the fields which aren't supported
 // by vCard so the user does not try to edit them.
 function HideNonVcardFields()
 {
   document.getElementById("homeTabButton").hidden = true;
@@ -839,16 +851,54 @@ function modifyDatepicker(aDatepicker) {
       this.monthField.value = null;
     }
     // make the field's value null if aValue is null and the field's value isn't
     if (aValue == null && aField.value != null)
       aField.value = null;
   }
 }
 
+var chatNameFieldIds =
+  ["Gtalk", "AIM", "Yahoo", "Skype", "QQ", "MSN", "ICQ", "XMPP", "IRC"];
+
+/**
+ * Show the 'Chat' tab and focus the first field that has a value, or
+ * the first field if none of them has a value.
+ */
+function showChat()
+{
+  document.getElementById('abTabPanels').parentNode.selectedTab =
+    document.getElementById('chatTabButton');
+  for (let id of chatNameFieldIds) {
+    let elt = document.getElementById(id);
+    if (elt.value) {
+      elt.focus();
+      return;
+    }
+  }
+  document.getElementById(chatNameFieldIds[0]).focus();
+}
+
+/**
+ * Fill in the value of the ChatName readonly field with the first
+ * value of the fields in the Chat tab.
+ */
+function updateChatName()
+{
+  let value = "";
+  for (let id of chatNameFieldIds) {
+    let val = document.getElementById(id).value;
+    if (val) {
+      value = val;
+      break;
+    }
+  }
+  document.getElementById("ChatName").value = value;
+}
+
 /**
  * Updates the photo displayed in the contact editor based on the
  * type of photo selected.  If the type is not recognized, the
  * photo will automatically switch to the generic photo.
  *
  * @param aType The type of photo (web, file, or generic available
  *              by default).
  * @param aCard The nsIAbCard being edited
--- a/suite/mailnews/components/addrbook/content/abCardOverlay.xul
+++ b/suite/mailnews/components/addrbook/content/abCardOverlay.xul
@@ -20,16 +20,17 @@
 <vbox id="editcard">
   <tabbox>
     <tabs id="abTabs">
       <tab id="contactTabButton" label="&Contact.tab;"
            accesskey="&Contact.accesskey;"/>
       <tab id="homeTabButton" label="&Home.tab;" accesskey="&Home.accesskey;"/>
       <tab id="workTabButton" label="&Work.tab;" accesskey="&Work.accesskey;"/>
       <tab id="otherTabButton" label="&Other.tab;" accesskey="&Other.accesskey;"/>
+      <tab id="chatTabButton" label="&Chat.tab;" accesskey="&Chat.accesskey;"/>
       <tab id="photoTabButton" label="&Photo.tab;" accesskey="&Photo.accesskey;"/>
     </tabs>
 
     <tabpanels id="abTabPanels" flex="1">
       <!-- ** Name Tab ** -->
       <!-- The following vbox contains two hboxes
            top: Name/Email/Phonenumber bottom: Email prefs. -->
       <vbox id="abNameTab" >
@@ -92,17 +93,17 @@
                          oninput="DisplayNameChanged()"/>
               </hbox>
             </hbox>
             <hbox id="PreferDisplayNameContainer" align="center">
               <spacer flex="1"/>
               <hbox class="CardEditWidth">
                 <checkbox id="preferDisplayName"
                           label="&preferDisplayName.label;"
-                          accesskey="&preferDisplayName.accesskey;"/>
+                          accesskey="&preferDisplayName2.accesskey;"/>
               </hbox>
             </hbox>
 
             <hbox id="NickNameContainer" align="center">
               <spacer flex="1"/>
               <label control="NickName" value="&NickName.label;"
                      accesskey="&NickName.accesskey;"/>
               <hbox class="CardEditWidth">
@@ -122,20 +123,21 @@
               <label control="SecondEmail" value="&SecondEmail.label;"
                      accesskey="&SecondEmail.accesskey;"/>
               <hbox class="CardEditWidth">
                 <textbox id="SecondEmail" flex="1" class="uri-element"/>
               </hbox>
             </hbox>
             <hbox id="ScreenNameContainer" align="center">
               <spacer flex="1"/>
-              <label control="ScreenName" value="&ScreenName.label;"
-                     accesskey="&ScreenName.accesskey;"/>
+              <label class="text-link" value="&chatName.label;"
+                     onclick="showChat();"/>
               <hbox class="CardEditWidth">
-                <textbox id="ScreenName" flex="1"/>
+                <textbox id="ChatName" readonly="true" flex="1"
+                         onclick="showChat();"/>
               </hbox>
             </hbox>
           </vbox> <!-- End of Name/Email -->
           <!-- Phone Number section -->
           <vbox id="PhoneNumbers">
             <hbox id="WorkPhoneContainer" align="center">
               <spacer flex="1"/>
               <label control="WorkPhone" value="&WorkPhone.label;"
@@ -363,16 +365,94 @@
             <textbox id="Custom4" flex="1"/>
           </hbox>
         </vbox>
         <label control="Notes" value="&Notes.label;"
                accesskey="&Notes.accesskey;"/>
         <textbox id="Notes" multiline="true" wrap="virtual" flex="1"/>
       </vbox>
 
+      <!-- ** Chat Tab ** -->
+      <hbox id="abChatTab">
+        <vbox>
+          <hbox id="GtalkContainer" align="center">
+            <spacer flex="1"/>
+            <label control="Gtalk" value="&Gtalk.label;"
+                   accesskey="&Gtalk.accesskey;"/>
+            <hbox class="CardEditWidth">
+              <textbox id="Gtalk" flex="1" onchange="updateChatName();"/>
+            </hbox>
+          </hbox>
+          <hbox id="AIMContainer" align="center">
+            <spacer flex="1"/>
+            <label control="AIM" value="&AIM.label;"
+                   accesskey="&AIM.accesskey;"/>
+            <hbox class="CardEditWidth">
+              <textbox id="AIM" flex="1" onchange="updateChatName();"/>
+            </hbox>
+          </hbox>
+          <hbox id="YahooContainer" align="center">
+            <spacer flex="1"/>
+            <label control="Yahoo" value="&Yahoo.label;"
+                   accesskey="&Yahoo.accesskey;"/>
+            <hbox class="CardEditWidth">
+              <textbox id="Yahoo" flex="1" onchange="updateChatName();"/>
+            </hbox>
+          </hbox>
+          <hbox id="SkypeContainer" align="center">
+            <spacer flex="1"/>
+            <label control="Skype" value="&Skype.label;"
+                   accesskey="&Skype.accesskey;"/>
+            <hbox class="CardEditWidth">
+              <textbox id="Skype" flex="1" onchange="updateChatName();"/>
+            </hbox>
+          </hbox>
+          <hbox id="QQContainer" align="center">
+            <spacer flex="1"/>
+            <label control="QQ" value="&QQ.label;"
+                   accesskey="&QQ.accesskey;"/>
+            <hbox class="CardEditWidth">
+              <textbox id="QQ" flex="1" onchange="updateChatName();"/>
+            </hbox>
+          </hbox>
+          <hbox id="MSNContainer" align="center">
+            <spacer flex="1"/>
+            <label control="MSN" value="&MSN.label;"
+                   accesskey="&MSN.accesskey;"/>
+            <hbox class="CardEditWidth">
+              <textbox id="MSN" flex="1" onchange="updateChatName();"/>
+            </hbox>
+          </hbox>
+          <hbox id="ICQContainer" align="center">
+            <spacer flex="1"/>
+            <label control="ICQ" value="&ICQ.label;"
+                   accesskey="&ICQ.accesskey;"/>
+            <hbox class="CardEditWidth">
+              <textbox id="ICQ" flex="1" onchange="updateChatName();"/>
+            </hbox>
+          </hbox>
+          <hbox id="XMPPContainer" align="center">
+            <spacer flex="1"/>
+            <label control="XMPP" value="&XMPP.label;"
+                   accesskey="&XMPP.accesskey;"/>
+            <hbox class="CardEditWidth">
+              <textbox id="XMPP" flex="1" onchange="updateChatName();"/>
+            </hbox>
+          </hbox>
+          <hbox id="IRCContainer" align="center">
+            <spacer flex="1"/>
+            <label control="IRC" value="&IRC.label;"
+                   accesskey="&IRC.accesskey;"/>
+            <hbox class="CardEditWidth">
+              <textbox id="IRC" flex="1" onchange="updateChatName();"/>
+            </hbox>
+          </hbox>
+        </vbox>
+      </hbox>
+
       <!-- ** Photo Tab ** -->
       <hbox id="abPhotoTab" align="center">
         <vbox align="center" style="min-width: 25ch; max-width: 25ch;">
           <image id="photo" style="max-width: 25ch; max-height: 25ch;"/>
         </vbox>
         <groupbox flex="1">
           <caption label="&PhotoDesc.label;"/>
           <radiogroup id="PhotoType" onselect="onSwitchPhotoType(this.value);">
--- a/suite/mailnews/components/addrbook/content/abCardViewOverlay.js
+++ b/suite/mailnews/components/addrbook/content/abCardViewOverlay.js
@@ -10,52 +10,68 @@ var gProfileDirURL;
 var gMapItURLFormat;
 
 var gFileHandler = Services.io.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler);
 var gPhotoDisplayHandlers = {};
 
 var zListName;
 var zPrimaryEmail;
 var zSecondaryEmail;
-var zScreenName;
 var zNickname;
 var zDisplayName;
 var zWork;
 var zHome;
 var zFax;
 var zCellular;
 var zPager;
 var zBirthday;
 var zCustom1;
 var zCustom2;
 var zCustom3;
 var zCustom4;
+var zGtalk;
+var zAIM;
+var zYahoo;
+var zSkype;
+var zQQ;
+var zMSN;
+var zICQ;
+var zXMPP;
+var zIRC;
 
 var cvData;
 
 function OnLoadCardView()
 {
   gMapItURLFormat = GetLocalizedStringPref("mail.addr_book.mapit_url.format");
 
   zPrimaryEmail = gAddressBookBundle.getString("propertyPrimaryEmail");
   zSecondaryEmail = gAddressBookBundle.getString("propertySecondaryEmail");
-  zScreenName = gAddressBookBundle.getString("propertyScreenName");
   zNickname = gAddressBookBundle.getString("propertyNickname");
   zDisplayName = gAddressBookBundle.getString("propertyDisplayName");
   zListName = gAddressBookBundle.getString("propertyListName");
   zWork = gAddressBookBundle.getString("propertyWork");
   zHome = gAddressBookBundle.getString("propertyHome");
   zFax = gAddressBookBundle.getString("propertyFax");
   zCellular = gAddressBookBundle.getString("propertyCellular");
   zPager = gAddressBookBundle.getString("propertyPager");
   zBirthday = gAddressBookBundle.getString("propertyBirthday");
   zCustom1 = gAddressBookBundle.getString("propertyCustom1");
   zCustom2 = gAddressBookBundle.getString("propertyCustom2");
   zCustom3 = gAddressBookBundle.getString("propertyCustom3");
   zCustom4 = gAddressBookBundle.getString("propertyCustom4");
+  zGtalk = gAddressBookBundle.getString("propertyGtalk");
+  zAIM = gAddressBookBundle.getString("propertyAIM");
+  zYahoo = gAddressBookBundle.getString("propertyYahoo");
+  zSkype = gAddressBookBundle.getString("propertySkype");
+  zQQ = gAddressBookBundle.getString("propertyQQ");
+  zMSN = gAddressBookBundle.getString("propertyMSN");
+  zICQ = gAddressBookBundle.getString("propertyICQ");
+  zXMPP = gAddressBookBundle.getString("propertyXMPP");
+  zIRC = gAddressBookBundle.getString("propertyIRC");
 
   var doc = document;
 
   /* data for address book, prefixes: "cvb" = card view box
                                       "cvh" = crad view header
                                       "cv"  = card view (normal fields) */
   cvData = new Object;
 
@@ -65,18 +81,16 @@ function OnLoadCardView()
   cvData.CardTitle = doc.getElementById("CardTitle");
   // Name section
   cvData.cvbContact = doc.getElementById("cvbContact");
   cvData.cvhContact = doc.getElementById("cvhContact");
   cvData.cvNickname = doc.getElementById("cvNickname");
   cvData.cvDisplayName = doc.getElementById("cvDisplayName");
   cvData.cvEmail1Box = doc.getElementById("cvEmail1Box");
   cvData.cvEmail1 = doc.getElementById("cvEmail1");
-  cvData.cvScreennameBox = doc.getElementById("cvScreennameBox");
-  cvData.cvScreenname = doc.getElementById("cvScreenname");
   cvData.cvBuddyIcon = doc.getElementById("cvBuddyIcon");
   cvData.cvListNameBox = doc.getElementById("cvListNameBox");
   cvData.cvListName = doc.getElementById("cvListName");
   cvData.cvEmail2Box = doc.getElementById("cvEmail2Box");
   cvData.cvEmail2 = doc.getElementById("cvEmail2");
   // Home section
   cvData.cvbHome = doc.getElementById("cvbHome");
   cvData.cvhHome = doc.getElementById("cvhHome");
@@ -124,16 +138,28 @@ function OnLoadCardView()
   cvData.cvWorkCityStZip = doc.getElementById("cvWorkCityStZip");
   cvData.cvWorkCountry = doc.getElementById("cvWorkCountry");
   cvData.cvbWorkMapItBox = doc.getElementById("cvbWorkMapItBox");
   cvData.cvWorkMapIt = doc.getElementById("cvWorkMapIt");
   cvData.cvWorkWebPageBox = doc.getElementById("cvWorkWebPageBox");
   cvData.cvWorkWebPage = doc.getElementById("cvWorkWebPage");
   cvData.cvbPhoto = doc.getElementById("cvbPhoto");
   cvData.cvPhoto = doc.getElementById("cvPhoto");
+  // Chat section
+  cvData.cvbChat      = doc.getElementById("cvbChat");
+  cvData.cvhChat      = doc.getElementById("cvhChat");
+  cvData.cvGtalk      = doc.getElementById("cvGtalk");
+  cvData.cvAIM        = doc.getElementById("cvAIM");
+  cvData.cvYahoo      = doc.getElementById("cvYahoo");
+  cvData.cvSkype      = doc.getElementById("cvSkype");
+  cvData.cvQQ         = doc.getElementById("cvQQ");
+  cvData.cvMSN        = doc.getElementById("cvMSN");
+  cvData.cvICQ        = doc.getElementById("cvICQ");
+  cvData.cvXMPP       = doc.getElementById("cvXMPP");
+  cvData.cvIRC        = doc.getElementById("cvIRC");
 }
 
 // XXX todo
 // some similar code (in spirit) already exists, see OnLoadEditList()
 // perhaps we could combine and put in abCommon.js?
 function GetAddressesFromURI(uri)
 {
   var addresses = "";
@@ -181,36 +207,31 @@ function DisplayCardViewPane(realCard)
     cvSetNode(data.CardTitle, gAddressBookBundle.getFormattedString("viewListTitle", [generatedName]));
   else
     cvSetNode(data.CardTitle, titleString);
 
   // Contact section
   cvSetNodeWithLabel(data.cvNickname, zNickname, card.getProperty("NickName"));
 
   if (card.isMailList) {
-    // email1, display name and screenname always hidden when a mailing list.
+    // email1 and display name always hidden when a mailing list.
     cvSetVisible(data.cvDisplayName, false);
     cvSetVisible(data.cvEmail1Box, false);
-    cvSetVisible(data.cvScreennameBox, false);
 
     visible = HandleLink(data.cvListName, zListName, card.displayName, data.cvListNameBox, "mailto:" + encodeURIComponent(GenerateAddressFromCard(card))) || visible;
   }
   else {
     // listname always hidden if not a mailing list
     cvSetVisible(data.cvListNameBox, false);
 
     cvSetNodeWithLabel(data.cvDisplayName, zDisplayName, card.displayName);
 
     visible = HandleLink(data.cvEmail1, zPrimaryEmail, card.primaryEmail, data.cvEmail1Box, "mailto:" + card.primaryEmail) || visible;
   }
 
-  var goimURL = "aim:goim?screenname=" + card.getProperty("_AimScreenName");
-  var hasScreenName = HandleLink(data.cvScreenname, zScreenName, card.getProperty("_AimScreenName"), data.cvScreennameBox, goimURL);
-
-  visible = hasScreenName || visible;
   visible = HandleLink(data.cvEmail2, zSecondaryEmail, card.getProperty("SecondEmail"), data.cvEmail2Box, "mailto:" + card.getProperty("SecondEmail")) || visible;
 
   // Home section
   visible = cvSetNode(data.cvHomeAddress, card.getProperty("HomeAddress"));
   visible = cvSetNode(data.cvHomeAddress2, card.getProperty("HomeAddress2")) || visible;
   visible = cvSetCityStateZip(data.cvHomeCityStZip, card.getProperty("HomeCity"), card.getProperty("HomeState"), card.getProperty("HomeZipCode")) || visible;
   visible = cvSetNode(data.cvHomeCountry, card.getProperty("HomeCountry")) || visible;
 
@@ -228,18 +249,19 @@ function DisplayCardViewPane(realCard)
     // Description section
     visible = cvSetNode(data.cvDescription, card.getProperty("Notes"))
     cvSetVisible(data.cvbDescription, visible);
 
     // Addresses section
     visible = cvAddAddressNodes(data.cvAddresses, card.mailListURI);
     cvSetVisible(data.cvbAddresses, visible);
 
-    // Other section, not shown for mailing lists.
+    // Other and Chat sections, not shown for mailing lists.
     cvSetVisible(data.cvbOther, false);
+    cvSetVisible(data.cvbChat, false);
   }
   else {
     // Other section
     /// setup the birthday information
     var day = card.getProperty("BirthDay", null);
     var month = card.getProperty("BirthMonth", null);
     var year = card.getProperty("BirthYear", null);
     var dateStr;
@@ -271,16 +293,38 @@ function DisplayCardViewPane(realCard)
     visible = cvSetNodeWithLabel(data.cvCustom3, zCustom3, card.getProperty("Custom3")) || visible;
     visible = cvSetNodeWithLabel(data.cvCustom4, zCustom4, card.getProperty("Custom4")) || visible;
     visible = cvSetNode(data.cvNotes, card.getProperty("Notes")) || visible;
     visible = setBuddyIcon(card, data.cvBuddyIcon) || visible;
 
     cvSetVisible(data.cvhOther, visible);
     cvSetVisible(data.cvbOther, visible);
 
+    // Chat section
+    visible = cvSetNodeWithLabel(data.cvGtalk, zGtalk,
+                                 card.getProperty("_GoogleTalk"));
+    visible = cvSetNodeWithLabel(data.cvAIM, zAIM,
+                                 card.getProperty("_AimScreenName")) || visible;
+    visible = cvSetNodeWithLabel(data.cvYahoo, zYahoo,
+                                 card.getProperty("_Yahoo")) || visible;
+    visible = cvSetNodeWithLabel(data.cvSkype, zSkype,
+                                 card.getProperty("_Skype")) || visible;
+    visible = cvSetNodeWithLabel(data.cvQQ, zQQ,
+                                 card.getProperty("_QQ")) || visible;
+    visible = cvSetNodeWithLabel(data.cvMSN, zMSN,
+                                 card.getProperty("_MSN")) || visible;
+    visible = cvSetNodeWithLabel(data.cvICQ, zICQ,
+                                 card.getProperty("_ICQ")) || visible;
+    visible = cvSetNodeWithLabel(data.cvXMPP, zXMPP,
+                                 card.getProperty("_JabberId")) || visible;
+    visible = cvSetNodeWithLabel(data.cvIRC, zIRC,
+                                 card.getProperty("_IRC")) || visible;
+    cvSetVisible(data.cvhChat, visible);
+    cvSetVisible(data.cvbChat, visible);
+
     // hide description section, not show for non-mailing lists
     cvSetVisible(data.cvbDescription, false);
 
     // hide addresses section, not show for non-mailing lists
     cvSetVisible(data.cvbAddresses, false);
   }
 
   // Phone section
@@ -383,35 +427,22 @@ function cvSetCityStateZip(node, city, s
     text = city + state + zip;
   }
 
   return cvSetNode(node, text);
 }
 
 function cvSetNode(node, text)
 {
-  if ( node )
-  {
-    if ( !node.hasChildNodes() )
-    {
-      var textNode = document.createTextNode(text);
-      node.appendChild(textNode);
-    }
-    else if ( node.childNodes.length == 1 )
-      node.childNodes[0].nodeValue = text;
+  if (!node)
+    return false;
 
-    var visible;
-
-    if ( text )
-      visible = true;
-    else
-      visible = false;
-
-    cvSetVisible(node, visible);
-  }
+  node.textContent = text;
+  let visible = !!text;
+  cvSetVisible(node, visible);
 
   return visible;
 }
 
 function cvAddAddressNodes(node, uri)
 {
   var visible = false;
 
--- a/suite/mailnews/components/addrbook/content/addressbook.xul
+++ b/suite/mailnews/components/addrbook/content/addressbook.xul
@@ -359,20 +359,23 @@
             <menuitem label="&GeneratedName.label;"
                                   id="cmd_SortByGeneratedName"
                                   accesskey="&GeneratedName.accesskey;"
                                   oncommand="SortResultPane('GeneratedName');" name="sortas" type="radio" checked="true"/>
             <menuitem label="&PrimaryEmail.label;"
                                   id="cmd_SortByPrimaryEmail"
                                   accesskey="&PrimaryEmail.accesskey;"
                                   oncommand="SortResultPane('PrimaryEmail');" name="sortas" type="radio" checked="true"/>
-            <menuitem label="&ScreenName.label;"
-                                  id="cmd_SortBy_AimScreenName"
-                                  accesskey="&ScreenName.accesskey;"
-                                  oncommand="SortResultPane('_AimScreenName');" name="sortas" type="radio" checked="true"/>
+            <menuitem label="&ChatName.label;"
+                      id="cmd_SortByChatName"
+                      accesskey="&ChatName.accesskey;"
+                      oncommand="SortResultPane('ChatName');"
+                      name="sortas"
+                      type="radio"
+                      checked="true"/>
             <menuitem label="&Company.label;"
                                   id="cmd_SortByCompany"
                                   accesskey="&Company.accesskey;"
                                   oncommand="SortResultPane('Company');" name="sortas" type="radio" checked="true"/>
             <!-- LOCALIZATION NOTE:
              Fields for phonetic are disabled as default and can be enabled by
              editing "mail.addr_book.show_phonetic_fields"
              -->
@@ -574,19 +577,16 @@
                   <description class="CardViewText" id="cvDisplayName"/>
                   <description class="CardViewText" id="cvNickname"/>
                   <description class="CardViewLink" id="cvEmail1Box">
                     <html:a href="" id="cvEmail1"/>
                   </description>
                   <description class="CardViewLink" id="cvEmail2Box">
                     <html:a href="" id="cvEmail2"/>
                   </description>
-                  <description class="CardViewLink" id="cvScreennameBox">
-                    <html:a href="" id="cvScreenname"/>
-                  </description>
                 </vbox>
                 <vbox id="cvbHome" class="cardViewGroup">
                   <description class="CardViewHeading" id="cvhHome">&home.heading;</description>
                   <hbox>
                     <vbox flex="1">
                       <description class="CardViewText" id="cvHomeAddress"/>
                       <description class="CardViewText" id="cvHomeAddress2"/>
                       <description class="CardViewText" id="cvHomeCityStZip"/>
@@ -616,16 +616,28 @@
                   <description class="CardViewText" id="cvCustom3"/>
                   <description class="CardViewText" id="cvCustom4"/>
                   <description class="CardViewText" id="cvNotes"
                                style="white-space: pre-wrap;"/>
                   <hbox>
                     <image id="cvBuddyIcon"/>
                   </hbox>
                 </vbox>
+                <vbox id="cvbChat" class="cardViewGroup">
+                  <description class="CardViewHeading" id="cvhChat">&chat.heading;</description>
+                  <description class="CardViewText" id="cvGtalk"/>
+                  <description class="CardViewText" id="cvAIM"/>
+                  <description class="CardViewText" id="cvYahoo"/>
+                  <description class="CardViewText" id="cvSkype"/>
+                  <description class="CardViewText" id="cvQQ"/>
+                  <description class="CardViewText" id="cvMSN"/>
+                  <description class="CardViewText" id="cvICQ"/>
+                  <description class="CardViewText" id="cvXMPP"/>
+                  <description class="CardViewText" id="cvIRC"/>
+                </vbox>
                 <!-- the description and addresses groups are only for
                       mailing lists -->
                 <vbox id="cvbDescription" class="cardViewGroup">
                   <description class="CardViewHeading" id="cvhDescription">&description.heading;</description>
                   <description class="CardViewText" id="cvDescription"/>
                 </vbox>
                 <vbox id="cvbAddresses" class="cardViewGroup">
                   <description class="CardViewHeading" id="cvhAddresses">&addresses.heading;</description>