Bug 450724 Implement New/Edit Card inline features for message header display - implement initial version of Star UI on message header. r=dmose,ui-review=clarkbw
authorMark Banner <bugzilla@standard8.plus.com>
Tue, 23 Sep 2008 23:37:07 +0100
changeset 410 7f9f210762cdb0055c912d9e3cd4b19e111b1d44
parent 409 dba6f5a634ec4811889485b1788928057c89773d
child 411 2f10b93d7a68d8c5b53414014367af5a1ed3cc78
push idunknown
push userunknown
push dateunknown
reviewersdmose
bugs450724
Bug 450724 Implement New/Edit Card inline features for message header display - implement initial version of Star UI on message header. r=dmose,ui-review=clarkbw
mail/base/content/messageWindow.xul
mail/base/content/messenger.css
mail/base/content/messenger.xul
mail/base/content/msgHdrViewOverlay.js
mail/themes/pinstripe/mail/jar.mn
mail/themes/pinstripe/mail/messageHeader.css
mail/themes/pinstripe/mail/starIcons.png
mail/themes/qute/mail/contactStarred.png
mail/themes/qute/mail/jar.mn
mail/themes/qute/mail/messageHeader.css
mail/themes/qute/mail/starContact.png
mailnews/base/resources/content/mailWidgets.xml
--- a/mail/base/content/messageWindow.xul
+++ b/mail/base/content/messageWindow.xul
@@ -111,40 +111,40 @@
   <keyset id="mailKeys">
     <keyset id="tasksKeys"/>
     <key keycode="VK_ESCAPE" oncommand="window.close();"/>
   </keyset>
 
   <popupset>
     <panel id="editContactPanel"/>
     <popup id="emailAddressPopup" popupanchor="bottomleft"
-           onpopupshowing="setupEmailAddressPopup(document.popupNode); goUpdateCommand('cmd_createFilterFromPopup')">
+           onpopupshowing="setupEmailAddressPopup(document.popupNode.parentNode); goUpdateCommand('cmd_createFilterFromPopup')">
       <menuitem id="emailAddressPlaceHolder" label=""
                 disabled="true"/>
       <menuseparator/>
       <menuitem id="addToAddressBookItem"
                 label="&AddDirectlyToAddressBook.label;"
                 accesskey="&AddDirectlyToAddressBook.accesskey;"
-                oncommand="AddContact(document.popupNode)"/>
+                oncommand="AddContact(document.popupNode.parentNode)"/>
       <menuitem id="editContactItem" label="&EditContact.label;" hidden="true"
                 accesskey="&EditContact.accesskey;"
-                oncommand="EditContact(document.popupNode)"/>
+                oncommand="EditContact(document.popupNode.parentNode)"/>
       <menuitem id="viewContactItem" label="&ViewContact.label;" hidden="true"
                 accesskey="&ViewContact.accesskey;"
-                oncommand="EditContact(document.popupNode)"/>
+                oncommand="EditContact(document.popupNode.parentNode)"/>
       <menuitem id="sendMailToItem" label="&SendMailTo.label;"
                 accesskey="&SendMailTo.accesskey;"
-                oncommand="SendMailToNode(document.popupNode)"/>
+                oncommand="SendMailToNode(document.popupNode.parentNode)"/>
       <menuitem id="copyEmailAddressItem" label="&CopyEmailAddress.label;"
                 accesskey="&CopyEmailAddress.accesskey;"
-                oncommand="CopyEmailAddress(document.popupNode)"/>
+                oncommand="CopyEmailAddress(document.popupNode.parentNode)"/>
       <menuseparator/>
       <menuitem id="createFilterFromItem" label="&CreateFilterFrom.label;"
                 accesskey="&CreateFilterFrom.accesskey;"
-                oncommand="CreateFilter(document.popupNode)"
+                oncommand="CreateFilter(document.popupNode.parentNode)"
                 observes="cmd_createFilterFromPopup"/>
     </popup>
 
     <popup id="messageIdContext"/>
 
     <popup id="messagePaneContext"/>
   </popupset>
 
--- a/mail/base/content/messenger.css
+++ b/mail/base/content/messenger.css
@@ -60,21 +60,28 @@ mail-messageid {
 }
 
 mail-messageids-headerfield {
   -moz-binding: url("chrome://messenger/content/mailWidgets.xml#mail-messageids-headerfield");
 }
 
 mail-emailaddress {
   -moz-binding: url("chrome://messenger/content/mailWidgets.xml#mail-emailaddress");
+}
+
+.emailDisplayButton {
   -moz-user-focus: normal;
 }
 
-mail-emailaddress:focus { 
-  border: dotted; border-width: 1px;
+.emailStar {
+  -moz-user-focus: normal;
+}
+
+.emailPopup {
+  -moz-user-focus: normal;
 }
 
 mail-emailheaderfield {
   -moz-binding: url("chrome://messenger/content/mailWidgets.xml#mail-emailheaderfield");
 }
 
 mail-toggle-headerfield {
   -moz-binding: url("chrome://messenger/content/mailWidgets.xml#mail-toggle-headerfield");
--- a/mail/base/content/messenger.xul
+++ b/mail/base/content/messenger.xul
@@ -133,40 +133,40 @@
 <popup id="folderPaneContext"/>
 <popup id="attachmentListContext"/>
 <popup id="copyUrlPopup"/>
 <popup id="toolbar-context-menu"/>
 
 <tooltip id="attachmentListTooltip"/>
 
 <popup id="emailAddressPopup" popupanchor="bottomleft"
-       onpopupshowing="setupEmailAddressPopup(document.popupNode); goUpdateCommand('cmd_createFilterFromPopup')">
+       onpopupshowing="setupEmailAddressPopup(document.popupNode.parentNode); goUpdateCommand('cmd_createFilterFromPopup')">
     <menuitem id="emailAddressPlaceHolder" label=""
               disabled="true"/>
     <menuseparator/>
     <menuitem id="addToAddressBookItem"
               label="&AddDirectlyToAddressBook.label;"
               accesskey="&AddDirectlyToAddressBook.accesskey;"
-              oncommand="AddContact(document.popupNode)"/>
+              oncommand="AddContact(document.popupNode.parentNode)"/>
     <menuitem id="editContactItem" label="&EditContact.label;" hidden="true"
               accesskey="&EditContact.accesskey;"
-              oncommand="EditContact(document.popupNode)"/>
+              oncommand="EditContact(document.popupNode.parentNode)"/>
     <menuitem id="viewContactItem" label="&ViewContact.label;" hidden="true"
               accesskey="&ViewContact.accesskey;"
-              oncommand="EditContact(document.popupNode)"/>
+              oncommand="EditContact(document.popupNode.parentNode)"/>
     <menuitem id="sendMailToItem" label="&SendMailTo.label;"
               accesskey="&SendMailTo.accesskey;"
-              oncommand="SendMailToNode(document.popupNode)"/>
+              oncommand="SendMailToNode(document.popupNode.parentNode)"/>
     <menuitem id="copyEmailAddressItem" label="&CopyEmailAddress.label;"
               accesskey="&CopyEmailAddress.accesskey;"
-              oncommand="CopyEmailAddress(document.popupNode)"/>
+              oncommand="CopyEmailAddress(document.popupNode.parentNode)"/>
     <menuseparator/>
     <menuitem id="createFilterFromItem" label="&CreateFilterFrom.label;"
               accesskey="&CreateFilterFrom.accesskey;"
-              oncommand="CreateFilter(document.popupNode)"
+              oncommand="CreateFilter(document.popupNode.parentNode)"
               observes="cmd_createFilterFromPopup"/>
 </popup>
 
 <popup id="messageIdContext"/>
 
 <tooltip id="folderpopup" class="folderSummaryPopup"/>
 
 <popup id="messagePaneContext"/>
--- a/mail/base/content/msgHdrViewOverlay.js
+++ b/mail/base/content/msgHdrViewOverlay.js
@@ -336,25 +336,32 @@ var AddressBookListener =
       OnAddressBookDataChanged(nsIAbListener.itemChanged, null, aItem);
   }
 };
 
 function OnAddressBookDataChanged(aAction, aParentDir, aItem) {
   gEmailAddressHeaderNames.forEach(function (headerName) {
       var headerEntry = null;
 
-      if (gCollapsedHeaderViewMode && headerName in gCollapsedHeaderView)
+      // Ensure both collapsed and expanded are updated in case we toggle
+      // between the two.
+      if (headerName in gCollapsedHeaderView) {
         headerEntry = gCollapsedHeaderView[headerName];
-      else if (headerName in gExpandedHeaderView)
+        if (headerEntry)
+          headerEntry.enclosingBox.updateExtraAddressProcessing(aAction,
+                                                                aParentDir,
+                                                                aItem);
+      }
+      if (headerName in gExpandedHeaderView) {
         headerEntry = gExpandedHeaderView[headerName];
-
-      if (headerEntry)
-        headerEntry.enclosingBox.updateExtraAddressProcessing(aAction,
-                                                              aParentDir,
-                                                              aItem);
+        if (headerEntry)
+          headerEntry.enclosingBox.updateExtraAddressProcessing(aAction,
+                                                                aParentDir,
+                                                                aItem);
+      }
     });
 }
 
 // The messageHeaderSink is the class that gets notified of a message's headers as we display the message
 // through our mime converter.
 
 var messageHeaderSink = {
     onStartHeaders: function()
@@ -1005,134 +1012,146 @@ function OutputEmailAddresses(headerEntr
 }
 
 function updateEmailAddressNode(emailAddressNode, address)
 {
   emailAddressNode.setAttribute("label", address.fullAddress || address.displayName);
   emailAddressNode.setAttribute("emailAddress", address.emailAddress);
   emailAddressNode.setAttribute("fullAddress", address.fullAddress);
   emailAddressNode.setAttribute("displayName", address.displayName);
-  emailAddressNode.removeAttribute("tooltiptext");
+  emailAddressNode.removeAttribute("tooltipemail");
 
   AddExtraAddressProcessing(address.emailAddress, emailAddressNode);
 }
 
 function AddExtraAddressProcessing(emailAddress, documentNode)
 {
   // Always get the card details so we can show add or edit menu options.
   var cardDetails = getCardForEmail(emailAddress);
   documentNode.cardDetails = cardDetails;
 
-  if (!gShowCondensedEmailAddresses)
+  if (!cardDetails.card) {
+    documentNode.setAttribute("hascard", "false");
+    documentNode.setAttribute("tooltipstar",
+      document.getElementById("addToAddressBookItem").label);
     return;
+  }
 
-  // always show the address for the from and reply-to fields
-  if (documentNode.parentNode.id == "expandedfromBox" ||
-      documentNode.parentNode.id == "expandedreply-toBox")
-    return;
+  documentNode.setAttribute("hascard", "true");
+  documentNode.setAttribute("tooltipstar",
+    document.getElementById("editContactItem").label);
 
-  if (!cardDetails.card)
+  if (!gShowCondensedEmailAddresses)
     return;
 
   var displayName = cardDetails.card.displayName;
 
   if (!displayName)
     return;
 
   documentNode.setAttribute("label", displayName);
-  documentNode.setAttribute("tooltiptext", emailAddress);
+  documentNode.setAttribute("tooltipemail", emailAddress);
 }
 
-function UpdateEmailNodeDetails(aEmailAddress, aDocumentNode, aCondenseName,
-                                aCardDetails) {
-  // The directory for this card has been removed. Re-query to find
-  // any other cards.
-
+function UpdateEmailNodeDetails(aEmailAddress, aDocumentNode, aCardDetails) {
   // If we haven't been given specific details, search for a card.
   var cardDetails = aCardDetails ? aCardDetails :
                                    getCardForEmail(aEmailAddress);
   var displayName = null;
 
   aDocumentNode.cardDetails = cardDetails;
 
-  if (cardDetails.card)
+  if (cardDetails.card) {
     displayName = cardDetails.card.displayName;
+    aDocumentNode.setAttribute("hascard", "true");
+    aDocumentNode.setAttribute("tooltipstar", 
+                               document.getElementById("editContactItem").label);
+  }
+  else {
+    aDocumentNode.setAttribute("hascard", "false");
+    aDocumentNode.setAttribute("tooltipstar", 
+                               document.getElementById("editContactItem").label);
+  }
 
-  if (aCondenseName && displayName) {
+  // When we are adding cards, we don't want to move the display around if the
+  // user has clicked on the star, therefore if it is locked, just exit and
+  // leave the display updates until later.
+  if (aDocumentNode.hasAttribute("updatingUI"))
+    return;
+
+  if (gShowCondensedEmailAddresses && displayName) {
     aDocumentNode.setAttribute("label", displayName);
-    aDocumentNode.setAttribute("tooltiptext", aEmailAddress);
+    aDocumentNode.setAttribute("tooltipemail", aEmailAddress);
+  }
+  else if (aDocumentNode.parentNode.useShortView &&
+           aDocumentNode.getAttribute("displayName")) {
+    aDocumentNode.setAttribute("label",
+                               aDocumentNode.getAttribute("displayName"));
+    aDocumentNode.setAttribute("tooltipemail", aEmailAddress);
   }
   else
     aDocumentNode.setAttribute("label",
                               aDocumentNode.getAttribute("fullAddress") ||
                               aDocumentNode.getAttribute("displayName"));
 }
 
 function UpdateExtraAddressProcessing(aAddressData, aDocumentNode, aAction,
                                       aParentDir, aItem)
 {
-  var condenseName = gShowCondensedEmailAddresses &&
-                     !(aDocumentNode.parentNode.id == "expandedfromBox" ||
-                       aDocumentNode.parentNode.id == "expandedreply-toBox");
-
   switch (aAction) {
   case nsIAbListener.itemChanged:
     if (aAddressData &&
         aDocumentNode.cardDetails.card &&
         aItem.hasEmailAddress(aAddressData.emailAddress)) {
       aDocumentNode.cardDetails.card = aItem;
       var displayName = aItem.displayName;
 
-      if (condenseName && displayName)
+      if (gShowCondensedEmailAddresses && displayName)
         aDocumentNode.setAttribute("label", displayName);
       else
         aDocumentNode.setAttribute("label",
                                    aDocumentNode.getAttribute("fullAddress") ||
                                    aDocumentNode.getAttriubte("displayName"));
     }
     break;
   case nsIAbListener.itemAdded:
     // Is it a new address book?
     if (aItem instanceof Components.interfaces.nsIAbDirectory) {
       // If we don't have a match, search again for updates (e.g. a interface
       // to an existing book may just have been added).
       if (!aDocumentNode.cardDetails.card)
-        UpdateEmailNodeDetails(aAddressData.emailAddress, aDocumentNode,
-                               condenseName);
+        UpdateEmailNodeDetails(aAddressData.emailAddress, aDocumentNode);
     }
     else if (aItem instanceof nsIAbCard) {
       // If we don't have a card, does this new one match?
       if (!aDocumentNode.cardDetails.card &&
           aItem.hasEmailAddress(aAddressData.emailAddress)) {
         // Just in case we have a bogus parent directory
         if (aParentDir instanceof Components.interfaces.nsIAbDirectory) {
           var cardDetails = { book: aParentDir, card: aItem };
           UpdateEmailNodeDetails(aAddressData.emailAddress, aDocumentNode,
-                                 condenseName, cardDetails);
+                                 cardDetails);
         }
         else
-          UpdateEmailNodeDetails(aAddressData.emailAddress, aDocumentNode,
-                                 condenseName);
+          UpdateEmailNodeDetails(aAddressData.emailAddress, aDocumentNode);
       }
     }
     break;
   case nsIAbListener.directoryItemRemoved:
     // Unfortunately we don't necessarily get the same card object back.
     if (aAddressData &&
         aDocumentNode.cardDetails.card &&
         aDocumentNode.cardDetails.book == aParentDir &&
         aItem.hasEmailAddress(aAddressData.emailAddress)) {
-      UpdateEmailNodeDetails(aAddressData.emailAddress, aDocumentNode,
-                             condenseName);
+      UpdateEmailNodeDetails(aAddressData.emailAddress, aDocumentNode);
     }
     break;
   case nsIAbListener.directoryRemoved:
     if (aDocumentNode.cardDetails.book == aItem)
-      UpdateEmailNodeDetails(aAddressData.emailAddress, aDocumentNode,
-                             condenseName);
+      UpdateEmailNodeDetails(aAddressData.emailAddress, aDocumentNode);
     break;
   }
 }
 
 function setupEmailAddressPopup(emailAddressNode)
 {
   var emailAddressPlaceHolder = document.getElementById('emailAddressPlaceHolder');
   var emailAddress = emailAddressNode.getAttribute('emailAddress');
@@ -1184,26 +1203,48 @@ function getCardForEmail(emailAddress)
       }
     }
     catch (ex) { }
   }
 
   return result;
 }
 
+function onClickEmailStar(event, emailAddressNode)
+{
+  // Only care about left-click events
+  if (event.button != 0)
+    return;
+
+  if (emailAddressNode && emailAddressNode.cardDetails &&
+      emailAddressNode.cardDetails.card)
+    EditContact(emailAddressNode);
+  else
+    AddContact(emailAddressNode);
+}
+
 function AddContact(emailAddressNode)
 {
   if (emailAddressNode) {
+    // When we collect an address, it updates the AB which sends out
+    // notifications to update the UI. In the add case we don't want to update
+    // the UI so that accidentally double-clicking on the star doesn't lead
+    // to something strange (i.e star would be moved out from underneath,
+    // leaving something else there).
+    emailAddressNode.setAttribute("updatingUI", true);
+
     // Just save the new node straight away
     Components.classes["@mozilla.org/addressbook/services/addressCollecter;1"]
       .getService(Components.interfaces.nsIAbAddressCollecter)
       .collectSingleAddress(emailAddressNode.getAttribute("emailAddress"),
                             emailAddressNode.getAttribute("displayName"), true,
                             Components.interfaces.nsIAbPreferMailFormat.unknown,
                             true);
+
+    emailAddressNode.removeAttribute("updatingUI");
   }
 }
 
 function EditContact(emailAddressNode)
 {
   if (emailAddressNode.cardDetails.card)
     editContactInlineUI.showEditContactPanel(emailAddressNode.cardDetails,
                                              emailAddressNode);
--- a/mail/themes/pinstripe/mail/jar.mn
+++ b/mail/themes/pinstripe/mail/jar.mn
@@ -19,16 +19,17 @@ classic.jar:
      skin/classic/messenger/subscribe.css
      skin/classic/messenger/virtualFolderListDialog.css
      skin/classic/messenger/searchDialog.css
      skin/classic/messenger/filterDialog.css
 *    skin/classic/messenger/tabmailBindings.xml
      skin/classic/messenger/tabmail.css
      skin/classic/messenger/editContactOverlay.css
      skin/classic/messenger/starred48.png
+     skin/classic/messenger/starIcons.png
      skin/classic/messenger/hud-style-button-middle-background.png
      skin/classic/messenger/addressbook/addressbook.css             (addrbook/addressbook.css)
      skin/classic/messenger/addressbook/abContactsPanel.css         (addrbook/abContactsPanel.css)
      skin/classic/messenger/addressbook/cardDialog.css              (addrbook/cardDialog.css)
      skin/classic/messenger/addressbook/abResultsPane.css           (addrbook/abResultsPane.css)
      skin/classic/messenger/addressbook/icons/abcard.png            (addrbook/abcard.png)
      skin/classic/messenger/addressbook/icons/ablist.png            (addrbook/ablist.png) 
      skin/classic/messenger/addressbook/icons/addressbook-toolbar.png         (addrbook/addressbook-toolbar.png)
--- a/mail/themes/pinstripe/mail/messageHeader.css
+++ b/mail/themes/pinstripe/mail/messageHeader.css
@@ -368,26 +368,69 @@ description[selectable="true"]:focus > d
   color: blue;
   background: url("chrome://messenger/skin/icons/arrow-dn-black.png") no-repeat center right;
 }
 
 /* ::::: msg header email addresses ::::: */
 
 .emailDisplayButton {
   margin: 0;
-  padding: 0 10px 0 0 !important;
   background-color: transparent;
-  background: url("chrome://messenger/skin/icons/arrow-dn-grey.png") no-repeat center right;
 }
 
 .emailDisplayButton:hover {
   cursor: pointer;
   text-decoration: underline;
   color: #2A46C7;
-  background: url("chrome://messenger/skin/icons/arrow-dn-blue.png") no-repeat center right;
+}
+
+.emailDisplayButton:focus, .emailStar:focus, .emailPopup:focus {
+  border: 1px dotted;
+}
+
+.emailStar {
+  max-width: 1em;
+  max-height: 1em;
+  -moz-appearance: none;
+  -moz-box-orient: vertical;
+  padding: 0px;
+  margin: 0px 2px;
+  list-style-image: url("chrome://messenger/skin/starIcons.png");
+  -moz-image-region: rect(0px, 16px, 16px, 0px);
+}
+
+.emailStar:hover {
+  -moz-image-region: rect(0px, 32px, 16px, 16px);
+}
+
+.emailStar:hover:active {
+  -moz-image-region: rect(0px, 48px, 16px, 32px);
+}
+
+.emailStar[hascard="true"] {
+  -moz-image-region: rect(16px, 16px, 32px, 0px);
+}
+
+.emailStar:hover[hascard="true"] {
+  -moz-image-region: rect(16px, 32px, 32px, 16px);
+}
+
+.emailStar:hover:active[hascard="true"] {
+  -moz-image-region: rect(16px, 48px, 32px, 32px);
+}
+
+.emailPopup {
+  font-size: inherit;
+  max-height: 7px; /* the height of the image */
+  margin: 0.2em 2px 0px 2px; /* 0.2em just to move it off the top of the text */
+  list-style-image: url("chrome://messenger/skin/icons/arrow-dn-7.png");
+}
+
+.emailPopup:hover {
+  list-style-image: url("chrome://messenger/skin/icons/arrow-dn-blue.png");
 }
  
 /* ::::: email address twisty ::::: */
 
 .addresstwisty {
   list-style-image:url("chrome://messenger/skin/icons/twisty-closed.gif");
 }
 
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..a69f8b29c35834d730354a56a9e29cb7570e203f
GIT binary patch
literal 3563
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
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..91aefceef89650b2385c32092ce4ef668aad885c
GIT binary patch
literal 1998
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
--- a/mail/themes/qute/mail/jar.mn
+++ b/mail/themes/qute/mail/jar.mn
@@ -26,16 +26,18 @@ classic.jar:
     skin/classic/messenger/filterDialog.css
     skin/classic/messenger/dialogs.css
     skin/classic/messenger/newmailalert.css
     skin/classic/messenger/newMailAlertUnix.css
 *   skin/classic/messenger/tabmailBindings.xml
     skin/classic/messenger/tabmail.css
     skin/classic/messenger/editContactOverlay.css
     skin/classic/messenger/starred48.png
+    skin/classic/messenger/contactStarred.png
+    skin/classic/messenger/starContact.png
     skin/classic/messenger/addressbook/addressbook.css          (addrbook/addressbook.css)
     skin/classic/messenger/addressbook/abContactsPanel.css      (addrbook/abContactsPanel.css)
     skin/classic/messenger/addressbook/cardDialog.css           (addrbook/cardDialog.css)
     skin/classic/messenger/addressbook/abResultsPane.css        (addrbook/abResultsPane.css)
     skin/classic/messenger/addressbook/icons/abcard.png         (addrbook/abcard.png)
     skin/classic/messenger/addressbook/icons/addrbook.png       (addrbook/addrbook.png)
     skin/classic/messenger/addressbook/icons/ablist.png         (addrbook/ablist.png)
     skin/classic/messenger/addressbook/icons/addressbook-toolbar.png         (addrbook/addressbook-toolbar.png)
--- a/mail/themes/qute/mail/messageHeader.css
+++ b/mail/themes/qute/mail/messageHeader.css
@@ -295,17 +295,17 @@ description[selectable="true"]:focus > d
   margin: 0;
   min-width: 50px;
   white-space: normal;
   background-color: transparent;
   color: black !important;
 }
 
 .headerValueBox {
-  margin: 0 0 5px 0; // XXX needed?
+  margin: 0 0 5px 0; /* XXX needed?*/
 }
 
 .headerValueUrl {
   cursor: pointer;
   color: #0000FF;
   text-decoration: underline;
 }
 
@@ -355,32 +355,64 @@ description[selectable="true"]:focus > d
 }
 
 
 /* ::::: msg header email addresses ::::: */
 
 .emailDisplayButton {
   cursor: pointer;
   margin: 0;
-  padding: 0 10px 0 0 !important;
   background-color: transparent;
-  background: url("chrome://messenger/skin/icons/arrow-dn-grey.png") no-repeat center right;
 }
 
 .headerValueUrl:hover,
 .emailDisplayButton:hover {
   color: #2A46C7;
+}
+
+.headerValueUrl:hover {
   background: url("chrome://messenger/skin/icons/arrow-dn-blue.png") no-repeat center right;
 }
 
-.emailDisplayImage {
-  -moz-padding-start: 2px;
-  -moz-box-pack: end;
+.emailDisplayButton:focus, .emailStar:focus, .emailPopup:focus {
+  border: 1px dotted;
+}
+
+.emailStar {
+  max-width: 1em;
+  max-height: 1em;
+  padding: 0px;
+  margin: 0px 2px;
+  list-style-image: url("chrome://messenger/skin/starContact.png");
+  -moz-image-region:rect(0px 16px 16px 0px);
+}
+
+.emailStar:hover {
+  -moz-image-region:rect(0px 32px 16px 16px);
 }
- 
+
+.emailStar:hover:active {
+  -moz-image-region:rect(0px 48px 16px 32px);
+}
+
+.emailStar[hascard="true"] {
+  list-style-image: url("chrome://messenger/skin/contactStarred.png");
+}
+
+.emailPopup {
+  font-size: inherit;
+  max-height: 7px; /* the height of the image */
+  margin: 0.2em 2px 0px 2px; /* 0.2em just to move it off the top of the text */
+  list-style-image: url("chrome://messenger/skin/icons/arrow-dn-grey.png");
+}
+
+.emailPopup:hover {
+  list-style-image: url("chrome://messenger/skin/icons/arrow-dn-blue.png");
+}
+
 /* ::::: email address twisty ::::: */
 
 .addresstwisty {
   -moz-padding-end: 5px;
   padding-top: 4px;
   list-style-image: url("chrome://global/skin/tree/twisty-clsd.png");
 }
 
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..b8197d87f232dd9b46786c4de7bdd4d3465568c8
GIT binary patch
literal 1515
zc$@+21r+*;P)<h;3K|Lk000e1NJLTq001xm000mO1^@s6P_F#300009a7bBm0000;
z0000;07l7cJ^%m!33hNnX8-^IFaQ7m5CB_hsPzB<00v@9M??Ss00000`9r&Z000Gc
zNkl<ZNXMO4ZA_C_6z)Hx$uj@Ve`evQ+k_T3{0I!E;&AQ<*^Fk{vTVV*E&f=xOu#Qt
z1}ZURQd&MczB-XCfUr1liKxVowpIiID}^#eS&JD+fwy!8o}H(zq${n~-Q=V<_de(C
z^PF?;xmN{170!+yKfdDV(W6Eh=aFzXZrliKTCH|fSy@>Jjq^yjNZ-9#s##&t#~LmA
zI3wqga1lR{nVGr&!i5W{udfH^|3g4dXJ;p_U%w8{UsQlu`}+RjwtX0C+Y6KSjr}hq
z;MlQat0eMvm&*mG(+SSG7OeoCPWN(kb+vP9Y6_E+li-|d(F(AXs8?A^;_Qm60?Jq+
zBolV7MJ*sBBO~2tG$Jr+YipT>^k@YX7Z+zU@_}*f+BJxP>}Um;w6CSxFMR|o{0?}l
zFxaw-SxA4T0EzO-!-o&Y2>FylhYs0BMn;wh3=Iu|Yur0><VXy$p#sjGJNHsiQBj=O
zC#9vOW8>rFOa9Cv*SII;6h~~R0EzfYvu=HikWVoct+ToBmjLsvz+4HYY+s3h^)^$n
zI>n+_$5=`<OaITqdLTPHyE8X8*C8MF)YQ}<IC>n5i;K8&<q9e*D^XZj=s9`vq=P>6
z6=FYBRaM#Q>gpahH#hq_Iyx{gFtE)3&Ye5BeEBjO8ykJZ(uclsKo3~U;yZ6uCOG=)
zcX$R{_ux;<_d>iGPz-?k6!6!#cyx6qYz-UHTeHDqEsuAIUnhN45>YGvbb5Lk^Yim~
z-tc<8c=F^4+S}V98M7J;1_#M`JRU48EIilW=ksA^W(M8e-KeOja9DJ))<@>A@%M}o
zi=HNl`Xw<TKU)Dz6#x^N!1xz{YcDXGius}K@D6On=x>|kY^bd)oz#MY0%dG$4AG8<
z4<F+6>C*~*%gf6@ZEbD!@~}obCMG7(($eCkue8b3o|-Mn>{z~}s#c<22F&~@<nsiW
zA>_XV9_<4jya$Zzkl*c?xs`<5hImCvDb-&`Sy@@T^YioPq7gyzd3kwr^r7$FyLVL*
z$<Hocyy%NY1j!RiANu-RX7T#n-9IJF&5nL20&;=LEGe6BgnW7s`R%|T+x+CaE8^$O
zdiC!A9AY7qCYhKHK765rZS~BVGt<N_^=q?Pb?@FiiZ~#dP~2{JM1QtbiM&EAedxRN
zo#NQEp6Y~Y&;8FurL=wL$3p%C;Qp?s<VUtax$Teqv{|Q43)@De%XIbi^+hDWJz_%J
zD2dqZc9k4*8#DB*>=8pOeL~x)NgLZWaVr&g{Gou~m&osYS~kPm0LNBLbZ&-pqOP!Q
zR4%I3IXO8lw!BD#d&CeM+D4_Lydt;u6c2c$!98M#UEW4DtF2`kmtuPt7~A!f{DTxJ
z8;QPsD=?S@<>nR;L+mmE(v8+i3C${svh;@zhr@4y!98M#4Hcl*>(@zbd)cJ|gXI`p
zlH4PP*f0Xt_Efz&>vK?mWZ}UMxGhO=n-WF9+ae$lzT2D8V~C$6c9{UF>tw0TrARk4
zH1G-Gq;Vd|3^Bw83+U?VqJTZTD*}-=nM{zk)Fh4bKxT*`mOjA(q^^@~4GB{BsZjdf
z!Ep0N$n(J|WSzr}Z$U9{0{S<>_H#VUdQEaT0SD#Hg0{9coH%j9E46-BN@Wd=bFOiZ
z7-B;ONLifXlcBe_7fnq~KDi(2#9sZ^>bS-|Vu%eR;Najd8!_7MFB7lS`q`T$nl*A+
ztug7;XSp`ovH^qjegOxU36NVgQS7R`c?=TuxX?ET*SJRvvB3f)!Yb+MY3I+M@0A<&
zS0S7%PZ3prf4|>2=Nk8jA(lSD0)%Ly*i{i?kf_Hkf8c52%sP#M7-9qK{{VPD$Ycq_
RrvCr{002ovPDHLkV1hhe*ChY|
--- a/mailnews/base/resources/content/mailWidgets.xml
+++ b/mailnews/base/resources/content/mailWidgets.xml
@@ -458,34 +458,52 @@
             this.clearChildNodes(this.emailAddresses);
           ]]>
         </body>
       </method>
     </implementation>
   </binding>
 
   <binding id="mail-emailaddress">
+#ifndef MOZ_THUNDERBIRD
     <content popup="emailAddressPopup" context="emailAddressPopup">
       <xul:description anonid="emailValue" class="emailDisplayButton plain"
                  xbl:inherits="xbl:text=label,crop" flex="1"/>
       <xul:image class="emailDisplayImage" anonid="emailImage"
                  xbl:inherits="src=image"/>
     </content>
+#else
+    <content>
+      <xul:description anonid="emailValue" class="emailDisplayButton plain"
+                       context="emailAddressPopup" popup="emailAddressPopup"
+                       xbl:inherits="xbl:text=label,crop,tooltiptext=tooltipemail"
+                       flex="1"/>
+      <xul:image class="emailStar" anonid="emailStar"
+                 context="emailAddressPopup"
+                 onclick="onClickEmailStar(event, this.parentNode);"
+                 xbl:inherits="hascard,tooltiptext=tooltipstar"/>
+      <xul:image class="emailPopup" anonid="emailPopup"
+                 context="emailAddressPopup" popup="emailAddressPopup"
+                 xbl:inherits="hascard,tooltiptext=tooltipemail"/>
+    </content>
+#endif
 
     <implementation>
       <property name="label"      onset="this.getPart('emailValue').setAttribute('label',val); return val;"
                                   onget="return this.getPart('emailValue').getAttribute('label');"/>
       <property name="crop"       onset="this.getPart('emailValue').setAttribute('crop',val); return val;"
                                   onget="return this.getPart('emailValue').getAttribute('crop');"/>
       <property name="disabled"   onset="this.getPart('emailValue').setAttribute('disabled',val); return val;"
                                   onget="return this.getPart('emailValue').getAttribute('disabled');"/>
+#ifndef MOZ_THUNDERBIRD
       <property name="src"        onset="this.getPart('emailImage').setAttribute('src',val); return val;"
                                   onget="return this.getPart('emailImage').getAttribute('src');"/>
       <property name="imgalign"   onset="this.getPart('emailImage').setAttribute('imgalign',val); return val;"
                                   onget="return this.getPart('emailImage').getAttribute('imgalign');"/>
+#endif
 
       <method name="getPart">
         <parameter name="aPartId"/>
         <body><![CDATA[
           return document.getAnonymousElementByAttribute(this, "anonid", aPartId);
         ]]></body>
       </method>
     </implementation>