Bug 1531901 - convert the mail-messageids-headerfield binding to custom element. r=mkmelin
authorAlessandro Castellani <alessandro@thunderbird.net>
Sat, 16 Mar 2019 23:06:49 +0100
changeset 26108 e77ea756f198
parent 26107 ccdb9a2b3b7e
child 26109 86cdbc8a3cef
push id15674
push usermozilla@jorgk.com
push dateSat, 16 Mar 2019 22:12:32 +0000
treeherdercomm-central@34babfc74629 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmkmelin
bugs1531901
Bug 1531901 - convert the mail-messageids-headerfield binding to custom element. r=mkmelin
mail/base/content/mailWidgets.js
mail/base/content/mailWidgets.xml
mail/base/content/messenger.css
mail/test/mozmill/message-header/test-message-header.js
mail/themes/osx/mail/messageHeader.css
mail/themes/shared/mail/messageHeader.css
--- a/mail/base/content/mailWidgets.js
+++ b/mail/base/content/mailWidgets.js
@@ -166,16 +166,116 @@ class MozMailMessageid extends MozXULEle
     return val;
   }
 
   get label() {
     return this.getAttribute("label");
   }
 }
 
+/**
+ * MozMailMessageidsHeaderfield is a widget used to show/link messages in the message header.
+ * Shown by default for nntp messages, not for regular emails.
+ * @extends {MozXULElement}
+ */
+class MozMailMessageidsHeaderfield extends MozXULElement {
+  connectedCallback() {
+    if (this.hasChildNodes() || this.delayConnectedCallback()) {
+      return;
+    }
+
+    this.setAttribute("context", "messageIdsHeaderfieldContext");
+
+    this.mMessageIds = [];
+    this.showFullMessageIds = false;
+
+    this.toggleIcon = document.createElement("image");
+    this.toggleIcon.classList.add("emailToggleHeaderfield");
+    this.toggleIcon.addEventListener("click", () => {
+      this._toggleWrap();
+    });
+    this.appendChild(this.toggleIcon);
+
+    this.headerValue = document.createElement("hbox");
+    this.headerValue.classList.add("headerValue");
+    this.headerValue.setAttribute("flex", "1");
+    this.appendChild(this.headerValue);
+  }
+
+  _toggleWrap() {
+    for (let i = 0; i < this.headerValue.childNodes.length; i += 2) {
+      if (!this.showFullMessageIds) {
+        this.toggleIcon.classList.add("open");
+        this.headerValue.childNodes[i].setAttribute("label", this.mMessageIds[i / 2]);
+        this.headerValue.childNodes[i].removeAttribute("tooltiptext");
+        this.headerValue.removeAttribute("singleline");
+      } else {
+        this.toggleIcon.classList.remove("open");
+        this.headerValue.childNodes[i].setAttribute("label", i / 2 + 1);
+        this.headerValue.childNodes[i].setAttribute("tooltiptext", this.mMessageIds[i / 2]);
+      }
+    }
+
+    this.showFullMessageIds = !this.showFullMessageIds;
+  }
+
+  fillMessageIdNodes() {
+    while (this.headerValue.childNodes.length > this.mMessageIds.length * 2 - 1) {
+      this.headerValue.lastChild.remove();
+    }
+
+    this.toggleIcon.hidden = this.mMessageIds.length <= 1;
+
+    for (let i = 0; i < this.mMessageIds.length; i++) {
+      if (i * 2 <= this.headerValue.childNodes.length - 1) {
+        this._updateMessageIdNode(this.headerValue.childNodes[i * 2], i + 1,
+          this.mMessageIds[i], this.mMessageIds.length);
+      } else {
+        let newMessageIdNode = document.createElement("mail-messageid");
+
+        if (i > 0) {
+          let textNode = document.createElement("text");
+          textNode.setAttribute("value", ", ");
+          textNode.setAttribute("class", "messageIdSeparator");
+          this.headerValue.appendChild(textNode);
+        }
+        let itemInDocument = this.headerValue.appendChild(newMessageIdNode);
+        this._updateMessageIdNode(itemInDocument, i + 1,
+          this.mMessageIds[i], this.mMessageIds.length);
+      }
+    }
+  }
+
+  _updateMessageIdNode(messageIdNode, index, messageId, lastId) {
+    if (this.showFullMessageIds || index == lastId) {
+      messageIdNode.setAttribute("label", messageId);
+      messageIdNode.removeAttribute("tooltiptext");
+    } else {
+      messageIdNode.setAttribute("label", index);
+      messageIdNode.setAttribute("tooltiptext", messageId);
+    }
+
+    messageIdNode.setAttribute("index", index);
+    messageIdNode.setAttribute("messageid", messageId);
+  }
+
+  addMessageIdView(messageId) {
+    this.mMessageIds.push(messageId);
+  }
+
+  clearHeaderValues() {
+    this.mMessageIds = [];
+    if (this.showFullMessageIds) {
+      this.showFullMessageIds = false;
+      this.toggleIcon.classList.remove("open");
+    }
+  }
+}
+customElements.define("mail-messageids-headerfield", MozMailMessageidsHeaderfield);
+
 class MozMailEmailaddress extends MozXULElement {
   static get observedAttributes() {
     return [
       "hascard",
       "label",
       "crop",
       "tooltipstar",
       "chatStatus",
--- a/mail/base/content/mailWidgets.xml
+++ b/mail/base/content/mailWidgets.xml
@@ -862,157 +862,16 @@
             // remove anything inside of each of our labels....
             this.clearChildNodes(this.emailAddresses);
           ]]>
         </body>
       </method>
     </implementation>
   </binding>
 
-  <binding id="mail-messageids-headerfield">
-    <content>
-      <xul:hbox class="headerNameBox" align="start" pack="end">
-        <xul:image class="addresstwisty" anonid="toggleIcon"
-                   onclick="toggleWrap();"/>
-      </xul:hbox>
-      <xul:hbox class="headerValueBox" flex="1">
-        <xul:label class="headerValue" anonid="headerValue" flex="1"/>
-      </xul:hbox>
-    </content>
-
-    <implementation>
-      <constructor>
-        <![CDATA[
-          this.mMessageIds = [];
-          this.showFullMessageIds = false;
-        ]]>
-      </constructor>
-
-      <property name="headerValue" readonly="true">
-        <getter><![CDATA[
-          return document.getAnonymousElementByAttribute(this, "anonid", "headerValue");
-        ]]></getter>
-      </property>
-      <property name="toggleIcon" readonly="true">
-        <getter><![CDATA[
-          return document.getAnonymousElementByAttribute(this, "anonid", "toggleIcon");
-        ]]></getter>
-      </property>
-
-      <field name="mMessageIds"/>
-
-      <!-- addMessageIdView: a public method used to add a message-id to this widget. -->
-      <method name="addMessageIdView">
-        <parameter name="aMessageId"/>
-        <body>
-          <![CDATA[
-            this.mMessageIds.push(aMessageId);
-          ]]>
-        </body>
-      </method>
-
-      <!-- updateMessageIdNode: private method used to set properties on an MessageId node -->
-      <method name="updateMessageIdNode">
-        <parameter name="aMessageIdNode"/>
-        <parameter name="aIndex"/>
-        <parameter name="aMessageId"/>
-        <parameter name="aLastId"/>
-        <body>
-          <![CDATA[
-            var showFullMessageIds = this.showFullMessageIds;
-
-            if (showFullMessageIds || aIndex == aLastId) {
-              aMessageIdNode.setAttribute("label", aMessageId);
-              aMessageIdNode.removeAttribute("tooltiptext");
-            } else {
-              aMessageIdNode.setAttribute("label", aIndex);
-              aMessageIdNode.setAttribute("tooltiptext", aMessageId);
-            }
-
-            aMessageIdNode.setAttribute("index", aIndex);
-            aMessageIdNode.setAttribute("messageid", aMessageId);
-          ]]>
-        </body>
-      </method>
-
-      <method name="fillMessageIdNodes">
-        <body>
-          <![CDATA[
-            var headerValue    = this.headerValue;
-            var messageIdNodes = headerValue.childNodes;
-            var numMessageIds  = this.mMessageIds.length;
-
-            while (messageIdNodes.length > numMessageIds * 2 - 1)
-              headerValue.lastChild.remove();
-
-            this.toggleIcon.hidden = numMessageIds <= 1;
-
-            for (var index = 0; index < numMessageIds; index++) {
-              if (index * 2 <= messageIdNodes.length - 1) {
-                this.updateMessageIdNode(messageIdNodes[index * 2], index + 1,
-                                         this.mMessageIds[index], numMessageIds);
-              } else {
-                var newMessageIdNode = document.createElement("mail-messageid");
-
-                if (index > 0) {
-                  var textNode = document.createElement("text");
-                  textNode.setAttribute("value", ", ");
-                  textNode.setAttribute("class", "messageIdSeparator");
-                  headerValue.appendChild(textNode);
-                }
-                var itemInDocument = headerValue.appendChild(newMessageIdNode);
-                this.updateMessageIdNode(itemInDocument, index + 1,
-                                         this.mMessageIds[index], numMessageIds);
-              }
-            }
-          ]]>
-        </body>
-      </method>
-
-      <method name="toggleWrap">
-        <body>
-          <![CDATA[
-            var headerValue        = this.headerValue;
-            var messageIdNodes     = headerValue.childNodes;
-            var showFullMessageIds = !this.showFullMessageIds;
-            var messageIds         = this.mMessageIds;
-
-            for (var i = 0; i < messageIdNodes.length; i += 2) {
-              if (showFullMessageIds) {
-                this.toggleIcon.setAttribute("open", "true");
-                messageIdNodes[i].setAttribute("label", messageIds[i / 2]);
-                messageIdNodes[i].removeAttribute("tooltiptext");
-                headerValue.removeAttribute("singleline");
-              } else {
-                this.toggleIcon.removeAttribute("open");
-                messageIdNodes[i].setAttribute("label", i / 2 + 1);
-                messageIdNodes[i].setAttribute("tooltiptext", messageIds[i / 2]);
-              }
-            }
-
-            this.showFullMessageIds = showFullMessageIds;
-          ]]>
-        </body>
-      </method>
-
-      <method name="clearHeaderValues">
-        <body>
-          <![CDATA[
-            // clear out our local state
-            this.mMessageIds = [];
-            if (this.showFullMessageIds) {
-              this.showFullMessageIds = false;
-              this.toggleIcon.removeAttribute("open");
-            }
-          ]]>
-        </body>
-      </method>
-    </implementation>
-  </binding>
-
   <binding id="search-menulist-abstract" name="searchMenulistAbstract">
     <content>
       <xul:menulist class="search-menulist" xbl:inherits="flex,disabled" oncommand="this.parentNode.onSelect(event)">
         <xul:menupopup class="search-menulist-popup"/>
       </xul:menulist>
     </content>
 
     <implementation>
--- a/mail/base/content/messenger.css
+++ b/mail/base/content/messenger.css
@@ -14,21 +14,16 @@
   --lwt-background-tiling: no-repeat;
 
   --toolbar-bgcolor: var(--toolbar-non-lwt-bgcolor);
   --toolbar-bgimage: var(--toolbar-non-lwt-bgimage);
   --toolbar-color: var(--toolbar-non-lwt-textcolor);
 }
 
 /* message header widgets */
-
-mail-messageids-headerfield {
-  -moz-binding: url("chrome://messenger/content/mailWidgets.xml#mail-messageids-headerfield");
-}
-
 .emailDisplayButton {
   -moz-user-focus: normal;
 }
 
 .emailStar {
   -moz-user-focus: normal;
 }
 
--- a/mail/test/mozmill/message-header/test-message-header.js
+++ b/mail/test/mozmill/message-header/test-message-header.js
@@ -429,17 +429,17 @@ function test_msg_id_context_menu() {
     }});
   add_message_to_folder(folder, msg);
   be_in_folder(folder);
 
   // Open the latest message.
   let curMessage = select_click_row(-1);
 
   // Right click to show the context menu.
-  mc.rightClick(mc.aid("expandedreferencesBox", {tagName: "mail-messageid"}));
+  mc.rightClick(mc.eid("expandedreferencesBox", {tagName: "mail-messageid"}));
   wait_for_popup_to_open(mc.e("messageIdContext"));
 
   // Ensure Open Message For ID is shown... and that Open Browser With Message-ID
   // isn't shown.
   assert_shown("messageIdContext-openMessageForMsgId", true);
   assert_shown("messageIdContext-openBrowserWithMsgId", false);
 
   close_popup(mc, mc.eid("messageIdContext"));
--- a/mail/themes/osx/mail/messageHeader.css
+++ b/mail/themes/osx/mail/messageHeader.css
@@ -326,26 +326,24 @@ toolbar[mode="icons"] > #otherActionsBut
 
 /* ::::: msg header message ids ::::: */
 
 .messageIdDisplayButton {
   margin: 0;
   padding-top: 0px !important;
   padding-bottom: 0px !important;
   padding-inline-start: 0px !important;
-  padding-inline-end: 10px !important;
+  padding-inline-end: 0px !important;
   background-color: transparent !important;
-  background: url("chrome://messenger/skin/icons/arrow-dn-grey.png") no-repeat center right;
 }
 
 .messageIdDisplayButton:hover {
   cursor: pointer;
   text-decoration: underline;
   color: -moz-hyperlinktext;
-  background: url("chrome://messenger/skin/icons/arrow-dn-black.png") no-repeat center right;
 }
 
 /* ::::: msg header email addresses ::::: */
 
 .emailDisplayButton {
   border-radius: 3px;
 }
 
@@ -390,16 +388,21 @@ mail-emailaddress[selected="true"] > .em
 
 .emailPopup {
   font-size: inherit;
   max-height: 7px; /* the height of the image */
   margin: 0.2em 2px 0; /* 0.2em just to move it off the top of the text */
   list-style-image: url("chrome://messenger/skin/icons/arrow-dn-7.png");
 }
 
+.emailToggleHeaderfield {
+  margin-inline-end: 3px;
+  margin-inline-start: 1px;
+}
+
 /* ::::: collapsed view styles ::::: */
 
 window[inlinetoolbox] #newtoolbar {
   display: none;
 }
 
 #header-view-toolbox {
   float: right;
--- a/mail/themes/shared/mail/messageHeader.css
+++ b/mail/themes/shared/mail/messageHeader.css
@@ -94,16 +94,17 @@ toolbarpaletteitem #hdrSmartReplyButton 
 
 .inline-toolbox[doCustomization] #hdrDummyReplyButton,
 toolbarpaletteitem #hdrDummyReplyButton {
   display: -moz-box !important;
 }
 
 .headerValue {
   overflow-wrap: anywhere;
+  display: block;
 }
 
 .headerValue[containsEmail="true"] {
   margin-inline-start: 0px !important;
 }
 
 #otherActionsBox {
   margin-inline-start: 8px;
@@ -254,16 +255,35 @@ mail-emailaddress[selected="true"] > .em
 .addresstwisty[open] {
   list-style-image:url("chrome://messenger/skin/icons/arrow/arrow-down-dim.png");
 }
 
 .addresstwisty[open]:hover {
   list-style-image:url("chrome://messenger/skin/icons/arrow/arrow-down.png");
 }
 
+.emailToggleHeaderfield {
+  padding-top: 1px;
+  width: 8px; /* The image's width is 8 pixels */
+  height: 8px;
+  margin-inline-end: 2px;
+  margin-inline-start: 4px;
+  background: url("chrome://global/skin/icons/twisty-collapsed.svg") no-repeat left 7px;
+  -moz-context-properties: fill;
+  fill: currentColor;
+}
+
+.emailToggleHeaderfield:-moz-locale-dir(rtl) {
+  background: url("chrome://global/skin/icons/twisty-collapsed-rtl.svg");
+}
+
+.emailToggleHeaderfield.open {
+  background: url("chrome://global/skin/icons/twisty-expanded.svg") no-repeat left 6px;
+}
+
 /* ::::: view expand and collapse twisties  ::::: */
 
 mail-multi-emailHeaderField,
 mail-headerfield,
 mail-urlfield,
 mail-newsgroups-headerfield {
   -moz-box-align: baseline;
 }