Bug 1513110 - Replace <attachmentlist> with <richlistbox> and replace <attachmentitem> with <richlistitem>; rs=bustage-fix
authorGeoff Lankow <geoff@darktrojan.net>
Tue, 11 Dec 2018 21:38:10 +1300
changeset 25368 713a7a7a6cdb2552020fb9fca9e88da4e752ce41
parent 25367 fa11fa3237109466511798ad6fc80aac517981c0
child 25369 71c50d951771a03efa9f2ec5731cef0846fa52d1
push id15219
push usergeoff@darktrojan.net
push dateTue, 11 Dec 2018 08:39:12 +0000
treeherdercomm-central@713a7a7a6cdb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbustage-fix
bugs1513110
Bug 1513110 - Replace <attachmentlist> with <richlistbox> and replace <attachmentitem> with <richlistitem>; rs=bustage-fix
mail/base/content/attachmentList.css
mail/base/content/mailWidgets.xml
mail/base/content/msgAttachmentView.inc
mail/base/content/msgHdrView.js
mail/components/compose/content/MsgComposeCommands.js
mail/components/compose/content/messengercompose.xul
mail/test/mozmill/attachment/test-attachment-size.js
mail/test/mozmill/composition/test-attachment.js
mail/test/mozmill/shared-modules/test-compose-helpers.js
mail/themes/linux/mail/attachmentList.css
mail/themes/linux/mail/compose/messengercompose.css
mail/themes/osx/mail/attachmentList.css
mail/themes/osx/mail/compose/messengercompose.css
mail/themes/osx/mail/messageHeader.css
mail/themes/windows/mail/attachmentList.css
mail/themes/windows/mail/compose/messengercompose.css
--- a/mail/base/content/attachmentList.css
+++ b/mail/base/content/attachmentList.css
@@ -1,63 +1,63 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-attachmentlist {
+.attachmentList {
   -moz-appearance: listbox;
   -moz-user-focus: normal;
 }
 
-attachmentlist[orient="horizontal"] {
+.attachmentList[orient="horizontal"] {
   -moz-binding: url("chrome://messenger/content/mailWidgets.xml#attachmentlist-horizontal");
 }
 
-attachmentlist[orient="vertical"] {
+.attachmentList[orient="vertical"] {
   -moz-binding: url("chrome://messenger/content/mailWidgets.xml#attachmentlist-vertical");
 }
 
 .attachmentlist-wrapper {
   display: block;
   margin: 0;
   padding: 0;
   line-height: 0;
 }
 
-attachmentitem {
+.attachmentItem {
   -moz-binding: url("chrome://messenger/content/mailWidgets.xml#attachmentitem");
 }
 
 .attachmentcell-content {
   -moz-box-orient: horizontal;
 }
 
 .attachmentcell-text {
   -moz-box-orient: horizontal;
 }
 
-attachmentlist[view="large"] .attachmentcell-content {
+.attachmentList[view="large"] .attachmentcell-content {
   -moz-box-orient: horizontal;
 }
 
-attachmentlist[view="large"] .attachmentcell-text {
+.attachmentList[view="large"] .attachmentcell-text {
   -moz-box-align: start;
   -moz-box-orient: vertical;
 }
 
-attachmentlist[view="tile"] .attachmentcell-content {
+.attachmentList[view="tile"] .attachmentcell-content {
   -moz-box-align: center;
   -moz-box-orient: vertical;
 }
 
-attachmentlist[view="tile"] .attachmentcell-text {
+.attachmentList[view="tile"] .attachmentcell-text {
   -moz-box-align: center;
   -moz-box-orient: vertical;
 }
 
-attachmentlist[orient="horizontal"] > attachmentitem {
+.attachmentList[orient="horizontal"] > .attachmentItem {
   min-width: 10em;
 }
 
-attachmentlist[orient="horizontal"][view="tile"] > attachmentitem {
+.attachmentList[orient="horizontal"][view="tile"] > .attachmentItem {
   min-width: 5em;
   max-width: 10em;
 }
--- a/mail/base/content/mailWidgets.xml
+++ b/mail/base/content/mailWidgets.xml
@@ -178,17 +178,18 @@
         ]]></body>
       </method>
       <method name="insertItemAt">
         <parameter name="index"/>
         <parameter name="attachment"/>
         <parameter name="name"/>
         <body><![CDATA[
           const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
-          let item = this.ownerDocument.createElementNS(XULNS, "attachmentitem");
+          let item = this.ownerDocument.createElementNS(XULNS, "richlistitem");
+          item.className = "attachmentItem";
           item.setAttribute("name", name || attachment.name);
           item.setAttribute("role", "option");
 
           let size;
           if (attachment.size != null && attachment.size != -1)
             size = this.messenger.formatFileSize(attachment.size);
           else // Use a zero-width space so the size label has the right height.
             size = "\u200b";
@@ -232,17 +233,21 @@
               return item;
           }
           return null;
         ]]></body>
       </method>
 
       <!-- ///////////////// private members ///////////////// -->
 
-      <field name="_childNodes" readonly="true">this.getElementsByTagName("attachmentitem")</field>
+      <property name="_childNodes" readonly="true">
+        <getter><![CDATA[
+          return this.querySelectorAll("richlistitem.attachmentItem");
+        ]]></getter>
+      </property>
       <property name="scrollbox" readonly="true">
         <getter><![CDATA[
           return document.getAnonymousElementByAttribute(this, "anonid", "scrollbox");
         ]]></getter>
       </property>
 
       <method name="_fireOnSelect">
         <body><![CDATA[
@@ -320,17 +325,17 @@
                action="if (document.commandDispatcher.focusedElement != this) this.focus();"/>
     </handlers>
   </binding>
 
   <binding id="attachmentlist-horizontal" extends="chrome://messenger/content/mailWidgets.xml#attachmentlist-base">
     <content>
       <xul:scrollbox flex="1" anonid="scrollbox" style="overflow: auto;">
         <xul:hbox flex="1" class="attachmentlist-wrapper">
-          <children includes="attachmentitem"/>
+          <children includes="richlistitem"/>
         </xul:hbox>
       </xul:scrollbox>
     </content>
     <implementation>
       <method name="setOptimumWidth">
         <body><![CDATA[
           if (this._childNodes.length == 0)
             return;
@@ -361,17 +366,17 @@
                phase="target" preventdefault="true"/>
     </handlers>
   </binding>
 
   <binding id="attachmentlist-vertical" extends="chrome://messenger/content/mailWidgets.xml#attachmentlist-base">
     <content>
       <xul:scrollbox orient="vertical" flex="1" anonid="scrollbox"
                      style="overflow: auto;">
-        <children includes="attachmentitem"/>
+        <children includes="richlistitem"/>
       </xul:scrollbox>
     </content>
     <implementation>
       <method name="_itemsPerRow">
         <body><![CDATA[
           // Vertical attachment lists have one item per row by definition.
           return 1;
         ]]></body>
--- a/mail/base/content/msgAttachmentView.inc
+++ b/mail/base/content/msgAttachmentView.inc
@@ -95,13 +95,18 @@
                             </toolbarpalette>
                             <toolbar id="attachment-view-toolbar" class="inline-toolbar"
                                      customizable="true" mode="full"
                                      context="attachment-toolbar-context-menu"
                                      defaulticonsize="small" defaultmode="full"
                                      defaultset="attachmentSaveAll"/>
                           </toolbox>
                         </hbox>
-                        <attachmentlist orient="horizontal" id="attachmentList" flex="1"
-                                        seltype="multiple" context="attachmentListContext"
-                                        role="listbox" itemcontext="attachmentItemContext"
-                                        ondragstart="nsDragAndDrop.startDrag(event,attachmentListDNDObserver);"
-                                        ondragover="nsDragAndDrop.dragOver(event, attachmentListDNDObserver);"/>
+                        <richlistbox id="attachmentList"
+                                     class="attachmentList"
+                                     orient="horizontal"
+                                     flex="1"
+                                     seltype="multiple"
+                                     context="attachmentListContext"
+                                     itemcontext="attachmentItemContext"
+                                     role="listbox"
+                                     ondragstart="nsDragAndDrop.startDrag(event,attachmentListDNDObserver);"
+                                     ondragover="nsDragAndDrop.dragOver(event, attachmentListDNDObserver);"/>
--- a/mail/base/content/msgHdrView.js
+++ b/mail/base/content/msgHdrView.js
@@ -2632,17 +2632,17 @@ function ClearAttachmentList() {
   while (list.hasChildNodes())
     list.lastChild.remove();
 }
 
 var attachmentListDNDObserver = {
   onDragStart(aEvent, aAttachmentData, aDragAction) {
     let target = aEvent.target;
 
-    if (target.localName == "attachmentitem") {
+    if (target.localName == "richlistitem") {
       let selection = target.parentNode.selectedItems;
       aAttachmentData.data = new TransferDataSet();
       for (let item of selection) {
         let transferData = CreateAttachmentTransferData(item.attachment);
         if (transferData)
           aAttachmentData.data.push(transferData);
       }
     }
--- a/mail/components/compose/content/MsgComposeCommands.js
+++ b/mail/components/compose/content/MsgComposeCommands.js
@@ -4426,17 +4426,17 @@ function attachmentsGetSortedArray(aAsce
     // ("non-live") array of selected items, sorted by their index in the list.
     listItems = [...bucketList.selectedItems];
   } else {
     // All attachments.
     if (attachmentsCount() < 1)
       return [];
 
     bucketList = document.getElementById("attachmentBucket");
-    listItems = [...bucketList.querySelectorAll("attachmentitem")];
+    listItems = [...bucketList.querySelectorAll("richlistitem.attachmentItem")];
   }
 
   if (aAscending) {
     listItems.sort(
       (a, b) => bucketList.getIndexOfItem(a) - bucketList.getIndexOfItem(b));
   } else { // descending
     listItems.sort(
       (a, b) => bucketList.getIndexOfItem(b) - bucketList.getIndexOfItem(a));
@@ -5670,17 +5670,17 @@ var envelopeDragObserver = {
         // We'll check below if this is a valid target.
       } else {
         // Top half of attachment list header: sorry, can't drop here.
         return "none";
       }
     }
 
     // Target is an attachmentitem.
-    if (target.tagName == "attachmentitem") {
+    if (target.matches("richlistitem.attachmentItem")) {
       // If we're dragging/dropping in bottom half of attachmentitem,
       // adjust target to target.nextSibling (to show dropmarker above that).
       let box = target.boxObject;
       if ((aEvent.screenY - box.screenY) / box.height >= 0.5) {
         target = target.nextSibling;
 
         // If there's no target.nextSibling, we're dragging/dropping
         // to the bottom of the list.
@@ -5711,32 +5711,32 @@ var envelopeDragObserver = {
 
     return "none";
   },
 
   _showDropMarker(targetItem) {
     let bucket = document.getElementById("attachmentBucket");
 
     let oldDropMarkerItem =
-      bucket.querySelector("attachmentitem[dropOn]");
+      bucket.querySelector("richlistitem.attachmentItem[dropOn]");
     if (oldDropMarkerItem)
       oldDropMarkerItem.removeAttribute("dropOn");
 
     if (targetItem == "afterLastItem") {
       targetItem = bucket.lastChild;
       targetItem.setAttribute("dropOn", "bottom");
     } else {
       targetItem.setAttribute("dropOn", "top");
     }
   },
 
   _hideDropMarker() {
    let oldDropMarkerItem =
      document.getElementById("attachmentBucket")
-             .querySelector("attachmentitem[dropOn]");
+             .querySelector("richlistitem.attachmentItem[dropOn]");
     if (oldDropMarkerItem)
       oldDropMarkerItem.removeAttribute("dropOn");
   },
 
   onDrop(aEvent, aData, aDragSession) {
     let bucket = document.getElementById("attachmentBucket");
     let dragSourceNode = aDragSession.sourceNode;
     if (dragSourceNode && dragSourceNode.parentNode == bucket) {
@@ -5750,17 +5750,17 @@ var envelopeDragObserver = {
       let selItems = attachmentsSelectionGetSortedArray();
       // Keep track of the item we had focused originally. Deselect it though,
       // since listbox gets confused if you move its focused item around.
       let focus = bucket.currentItem;
       bucket.currentItem = null;
 
       // Moving possibly non-coherent multiple selections around correctly
       // is much more complex than one might think...
-      if (target.tagName == "attachmentitem" || target == "afterLastItem") {
+      if (target.matches("richlistitem.attachmentItem") || target == "afterLastItem") {
         // Drop before targetItem in the list, or after last item.
         let blockItems = [];
         let targetItem;
         for (let item of selItems) {
           blockItems.push(item);
           if (target == "afterLastItem") {
             // Original target is the end of the list; append all items there.
             bucket.appendChild(item);
@@ -5915,17 +5915,17 @@ var envelopeDragObserver = {
     let bucket = document.getElementById("attachmentBucket");
     let dragSourceNode = aDragSession.sourceNode;
     if (dragSourceNode && dragSourceNode.parentNode == bucket) {
       // If we're dragging from the attachment bucket onto itself, we need to
       // show a drop marker.
 
       let target = this._adjustDropTarget(aEvent);
 
-      if (target && (target.tagName == "attachmentitem" || target == "afterLastItem")) {
+      if (target && (target.matches("richlistitem.attachmentItem") || target == "afterLastItem")) {
         // Adjusted target is an attachment list item; show dropmarker.
         this._showDropMarker(target);
       } else {
         // target == "none", target is not a listItem, or no target:
         // Indicate that we can't drop here.
         this._hideDropMarker();
         aEvent.dataTransfer.dropEffect = "none";
       }
@@ -5957,17 +5957,17 @@ var envelopeDragObserver = {
     return flavourSet;
   },
 };
 
 var attachmentBucketDNDObserver = {
   onDragStart(aEvent, aAttachmentData, aDragAction) {
     var target = aEvent.target;
 
-    if (target.localName == "attachmentitem")
+    if (target.matches("richlistitem.attachmentItem"))
       aAttachmentData.data = CreateAttachmentTransferData(target.attachment);
   },
 };
 
 function DisplaySaveFolderDlg(folderURI) {
   try {
     var showDialog = gCurrentIdentity.showSaveMsgDlg;
   } catch (e) {
--- a/mail/components/compose/content/messengercompose.xul
+++ b/mail/components/compose/content/messengercompose.xul
@@ -2008,31 +2008,32 @@
               <label id="attachmentBucketSize"/>
             </hbox>
             <toolbarbutton id="attachmentBucketCloseButton"
                            class="ab-closebutton close-icon"
                            tooltiptext="&attachmentBucketCloseButton.tooltip;"
                            context=""
                            oncommand="attachmentBucketCloseButtonOnCommand();"/>
           </hbox>
-          <attachmentlist id="attachmentBucket"
-                          tooltiptext=""
-                          disableonsend="true"
-                          seltype="multiple"
-                          orient="vertical"
-                          flex="1"
-                          height="0"
-                          role="listbox"
-                          context="msgComposeAttachmentListContext"
-                          itemcontext="msgComposeAttachmentItemContext"
-                          onclick="attachmentBucketOnClick(event);"
-                          onkeypress="attachmentBucketOnKeyPress(event);"
-                          onselect="attachmentBucketOnSelect();"
-                          ondragstart="attachmentBucketOnDragStart(event);"
-                          onblur="attachmentBucketOnBlur();"/>
+          <richlistbox id="attachmentBucket"
+                       class="attachmentList"
+                       tooltiptext=""
+                       disableonsend="true"
+                       seltype="multiple"
+                       orient="vertical"
+                       flex="1"
+                       height="0"
+                       role="listbox"
+                       context="msgComposeAttachmentListContext"
+                       itemcontext="msgComposeAttachmentItemContext"
+                       onclick="attachmentBucketOnClick(event);"
+                       onkeypress="attachmentBucketOnKeyPress(event);"
+                       onselect="attachmentBucketOnSelect();"
+                       ondragstart="attachmentBucketOnDragStart(event);"
+                       onblur="attachmentBucketOnBlur();"/>
         </vbox>
         <vbox id="attachments-placeholder-box"
               hidden="true"
               tooltiptext=""
               onclick="goDoCommand('cmd_toggleAttachmentPane')"/>
       </hbox>
     </toolbar>
 
--- a/mail/test/mozmill/attachment/test-attachment-size.js
+++ b/mail/test/mozmill/attachment/test-attachment-size.js
@@ -234,17 +234,17 @@ function setupModule(module) {
 
 /**
  * Make sure that the attachment's size is what we expect
  * @param index the attachment's index, starting at 0
  * @param expectedSize the expected size of the attachment, in bytes
  */
 function check_attachment_size(index, expectedSize) {
   let list = mc.e('attachmentList');
-  let node = list.getElementsByTagName('attachmentitem')[index];
+  let node = list.querySelectorAll("richlistitem.attachmentItem")[index];
 
   // First, let's check that the attachment size is correct
   let size = node.attachment.size;
   if (Math.abs(size - expectedSize) > epsilon)
     throw new Error('Reported attachment size ('+size+') not within epsilon ' +
                     'of actual attachment size ('+expectedSize+')');
 
   // Next, make sure that the formatted size in the label is correct
@@ -256,17 +256,17 @@ function check_attachment_size(index, ex
 }
 
 /**
  * Make sure that the attachment's size is not displayed
  * @param index the attachment's index, starting at 0
  */
 function check_no_attachment_size(index) {
   let list = mc.e('attachmentList');
-  let node = list.getElementsByTagName('attachmentitem')[index];
+  let node = list.querySelectorAll("richlistitem.attachmentItem")[index];
 
   if (node.attachment.size != null)
     throw new Error('attachmentSize attribute of deleted attachment should ' +
                     'be null!');
 
   // If there's no size, the size attribute is the zero-width space.
   if (node.getAttribute('size') != '\u200b')
     throw new Error('Attachment size should not be displayed!');
@@ -275,17 +275,17 @@ function check_no_attachment_size(index)
 /**
  * Make sure that the total size of all attachments is what we expect.
  * @param count the expected number of attachments
  * @param expectedSize the expected size in bytes of all the attachments
  * @param exact true if the size of all attachments is known, false otherwise
  */
 function check_total_attachment_size(count, expectedSize, exact) {
   let list = mc.e('attachmentList');
-  let nodes = list.getElementsByTagName('attachmentitem');
+  let nodes = list.querySelectorAll("richlistitem.attachmentItem");
   let sizeNode = mc.e('attachmentSize');
 
   if (nodes.length != count)
     throw new Error('Saw '+nodes.length+' attachments, but expected '+count);
 
   let lastPartID;
   let size = 0;
   for (let i = 0; i < nodes.length; i++) {
--- a/mail/test/mozmill/composition/test-attachment.js
+++ b/mail/test/mozmill/composition/test-attachment.js
@@ -87,17 +87,17 @@ function setupModule(module) {
 /**
  * Make sure that the attachment's size is what we expect
  * @param controller the controller for the compose window
  * @param index the attachment to examine, as an index into the listbox
  * @param expectedSize the expected size of the attachment, in bytes
  */
 function check_attachment_size(controller, index, expectedSize) {
   let bucket = controller.e('attachmentBucket');
-  let node = bucket.getElementsByTagName('attachmentitem')[index];
+  let node = bucket.querySelectorAll("richlistitem.attachmentItem")[index];
 
   // First, let's check that the attachment size is correct
   let size = node.attachment.size;
   if (Math.abs(size - expectedSize) > epsilon)
     throw new Error('Reported attachment size ('+size+') not within epsilon ' +
                     'of actual attachment size ('+expectedSize+')');
 
   // Next, make sure that the formatted size in the label is correct
@@ -110,34 +110,34 @@ function check_attachment_size(controlle
 
 /**
  * Make sure that the attachment's size is not displayed
  * @param controller the controller for the compose window
  * @param index the attachment to examine, as an index into the listbox
  */
 function check_no_attachment_size(controller, index) {
   let bucket = controller.e('attachmentBucket');
-  let node = bucket.getElementsByTagName('attachmentitem')[index];
+  let node = bucket.querySelectorAll("richlistitem.attachmentItem")[index];
 
   if (node.attachment.size != -1)
     throw new Error('attachment.size attribute should be -1!');
 
   // If there's no size, the size attribute is the zero-width space.
   if (node.getAttribute('size') != '\u200b')
     throw new Error('Attachment size should not be displayed!');
 }
 
 /**
  * Make sure that the total size of all attachments is what we expect.
  * @param controller the controller for the compose window
  * @param count the expected number of attachments
  */
 function check_total_attachment_size(controller, count) {
   let bucket = controller.e("attachmentBucket");
-  let nodes = bucket.getElementsByTagName("attachmentitem");
+  let nodes = bucket.querySelectorAll("richlistitem.attachmentItem");
   let sizeNode = controller.e("attachmentBucketSize");
 
   if (nodes.length != count)
     throw new Error("Saw "+nodes.length+" attachments, but expected "+count);
 
   let size = 0;
   for (let i = 0; i < nodes.length; i++) {
     let currSize = nodes[i].attachment.size;
@@ -218,17 +218,17 @@ function test_rename_attachment() {
 
   let url = filePrefix + "some/file/here.txt";
   let size = 1234;
 
   add_attachment(cwc, url, size);
 
   // Now, rename the attachment.
   let bucket = cwc.e("attachmentBucket");
-  let node = bucket.querySelector("attachmentitem");
+  let node = bucket.querySelector("richlistitem.attachmentItem");
   cwc.click(new elib.Elem(node));
   plan_for_modal_dialog("commonDialog", subtest_rename_attachment);
   cwc.window.RenameSelectedAttachment();
   wait_for_modal_dialog("commonDialog");
 
   assert_equals(node.getAttribute("name"), "renamed.txt");
 
   check_attachment_size(cwc, 0, size);
@@ -251,17 +251,17 @@ function test_open_attachment() {
                             .QueryInterface(Ci.nsIFileProtocolHandler);
   let url = fileHandler.getURLSpecFromFile(file);
   let size = file.fileSize;
 
   add_attachment(cwc, url, size);
 
   // Now, open the attachment.
   let bucket = cwc.e("attachmentBucket");
-  let node = bucket.querySelector("attachmentitem");
+  let node = bucket.querySelector("richlistitem.attachmentItem");
   plan_for_modal_dialog("unknownContentType", subtest_open_attachment);
   cwc.doubleClick(new elib.Elem(node));
   wait_for_modal_dialog("unknownContentType");
 
   close_compose_window(cwc);
 }
 
 function test_forward_raw_attachment() {
--- a/mail/test/mozmill/shared-modules/test-compose-helpers.js
+++ b/mail/test/mozmill/shared-modules/test-compose-helpers.js
@@ -429,17 +429,17 @@ function add_cloud_attachments(aControll
 
 /**
  * Delete an attachment from the compose window
  * @param aComposeWindow the composition window in question
  * @param aIndex the index of the attachment in the attachment pane
  */
 function delete_attachment(aComposeWindow, aIndex) {
   let bucket = aComposeWindow.e('attachmentBucket');
-  let node = bucket.getElementsByTagName('attachmentitem')[aIndex];
+  let node = bucket.querySelectorAll("richlistitem.attachmentItem")[aIndex];
 
   aComposeWindow.click(new elib.Elem(node));
   aComposeWindow.window.RemoveSelectedAttachment();
 }
 
 /**
  * Helper function returns the message body element of a composer window.
  *
--- a/mail/themes/linux/mail/attachmentList.css
+++ b/mail/themes/linux/mail/attachmentList.css
@@ -16,43 +16,43 @@
 .attachmentcell-size {
   padding-top: 1px;
 }
 
 .attachmentcell-size {
   color: GrayText;
 }
 
-attachmentlist[orient="horizontal"] > attachmentitem {
+.attachmentList[orient="horizontal"] > .attachmentItem {
   pointer-events: none;
 }
 
-attachmentlist[orient="horizontal"] .attachmentcell-icon,
-attachmentlist[orient="horizontal"] .attachmentcell-nameselection {
+.attachmentList[orient="horizontal"] .attachmentcell-icon,
+.attachmentList[orient="horizontal"] .attachmentcell-nameselection {
   pointer-events: auto;
 }
 
-attachmentlist:focus > attachmentitem[selected="true"][current="true"] .attachmentcell-nameselection {
+.attachmentList:focus > .attachmentItem[selected="true"][current="true"] .attachmentcell-nameselection {
   outline: 1px dotted #F3D982;
 }
 
-attachmentlist:focus > attachmentitem[current="true"] .attachmentcell-nameselection {
+.attachmentList:focus > .attachmentItem[current="true"] .attachmentcell-nameselection {
   outline: 1px dotted;
   outline-offset: -1px;
 }
 
-attachmentitem[selected="true"] .attachmentcell-nameselection {
+.attachmentItem[selected="true"] .attachmentcell-nameselection {
   background-color: -moz-CellHighlight;
   color: -moz-CellHighlightText;
 }
 
-attachmentlist:focus > attachmentitem[selected="true"] .attachmentcell-nameselection {
+.attachmentList:focus > .attachmentItem[selected="true"] .attachmentcell-nameselection {
   background-color: Highlight;
   color: HighlightText;
 }
 
-attachmentitem[selected="true"] .attachmentcell-icon {
+.attachmentItem[selected="true"] .attachmentcell-icon {
   filter: url("chrome://messenger/skin/imageFilters.svg#selected");
 }
 
-attachmentlist:focus > attachmentitem[selected="true"] .attachmentcell-icon {
+.attachmentList:focus > .attachmentItem[selected="true"] .attachmentcell-icon {
   filter: url("chrome://messenger/skin/imageFilters.svg#selected-focus");
 }
--- a/mail/themes/linux/mail/compose/messengercompose.css
+++ b/mail/themes/linux/mail/compose/messengercompose.css
@@ -10,29 +10,29 @@
 @import url("chrome://messenger/skin/shared/messengercompose.css");
 
 @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
 
 #attachments-box[empty] > #attachmentBucket:focus {
   box-shadow: 0 0 2px Highlight inset, 0 0 2px Highlight inset;
 }
 
-#attachmentBucket attachmentitem {
+#attachmentBucket .attachmentItem {
   border-top: 1px solid transparent;
 }
 
-#attachmentBucket attachmentitem:last-child {
+#attachmentBucket .attachmentItem:last-child {
   border-bottom: 1px solid transparent;
 }
 
-#attachmentBucket attachmentitem[dropOn="top"] {
+#attachmentBucket .attachmentItem[dropOn="top"] {
   border-top-color: Highlight;
 }
 
-#attachmentBucket attachmentitem[dropOn="bottom"] {
+#attachmentBucket .attachmentItem[dropOn="bottom"] {
   border-bottom-color: Highlight;
 }
 
 #compose-toolbox {
   background-color: var(--toolbar-bgcolor);
   border-bottom: 1px solid var(--chrome-content-separator-color);
 }
 
--- a/mail/themes/osx/mail/attachmentList.css
+++ b/mail/themes/osx/mail/attachmentList.css
@@ -18,34 +18,34 @@
 .attachmentcell-size {
   padding-top: 1px;
 }
 
 .attachmentcell-size {
   color: GrayText;
 }
 
-attachmentlist:focus > attachmentitem[selected="true"][current="true"] {
+.attachmentList:focus > .attachmentItem[selected="true"][current="true"] {
   outline: 1px dotted #F3D982;
 }
 
-attachmentlist:focus > attachmentitem[current="true"] {
+.attachmentList:focus > .attachmentItem[current="true"] {
   outline: 1px dotted;
   outline-offset: -1px;
 }
 
-attachmentitem[selected="true"] {
+.attachmentItem[selected="true"] {
   background-color: -moz-CellHighlight;
   color: -moz-CellHighlightText;
 }
 
-attachmentlist:focus > attachmentitem[selected="true"] {
+.attachmentList:focus > .attachmentItem[selected="true"] {
   background-color: Highlight;
   color: HighlightText;
 }
 
-attachmentitem[selected="true"] .attachmentcell-size {
+.attachmentItem[selected="true"] .attachmentcell-size {
   color: -moz-CellHighlightText;
 }
 
-attachmentlist:focus >attachmentitem[selected="true"] .attachmentcell-size {
+.attachmentList:focus >.attachmentItem[selected="true"] .attachmentcell-size {
   color: HighlightText;
 }
--- a/mail/themes/osx/mail/compose/messengercompose.css
+++ b/mail/themes/osx/mail/compose/messengercompose.css
@@ -20,27 +20,27 @@
   height: 1px;
   border-bottom: 1px solid var(--chrome-content-separator-color);
 }
 
 #attachments-box[empty] > #attachmentBucket:focus {
   box-shadow: 0 0 1.5px 1px -moz-mac-focusring inset;
 }
 
-#attachmentBucket attachmentitem {
+#attachmentBucket .attachmentItem {
   border-top: 1px solid transparent;
   border-bottom: 1px solid #fff;
 }
 
-#attachmentBucket attachmentitem[dropOn="top"] {
+#attachmentBucket .attachmentItem[dropOn="top"] {
   border-top-color: #000;
   outline-color: transparent;
 }
 
-#attachmentBucket attachmentitem[dropOn="bottom"] {
+#attachmentBucket .attachmentItem[dropOn="bottom"] {
   border-bottom-color: #000;
 }
 
 #compose-toolbox toolbarbutton[checked="true"] {
   background-color: transparent;
 }
 
 /* Inactive window state */
--- a/mail/themes/osx/mail/messageHeader.css
+++ b/mail/themes/osx/mail/messageHeader.css
@@ -103,40 +103,40 @@
 .attachmentcell-size {
   padding-top: 1px;
 }
 
 .attachmentcell-size {
   color: GrayText;
 }
 
-attachmentlist:focus > attachmentitem[selected="true"][current="true"] {
+.attachmentList:focus > .attachmentItem[selected="true"][current="true"] {
   outline: 1px dotted #F3D982;
 }
 
-attachmentlist:focus > attachmentitem[current="true"] {
+.attachmentList:focus > .attachmentItem[current="true"] {
   outline: 1px dotted;
   outline-offset: -1px;
 }
 
-attachmentitem[selected="true"] {
+.attachmentItem[selected="true"] {
   background-color: -moz-CellHighlight;
   color: -moz-CellHighlightText;
 }
 
-attachmentlist:focus > attachmentitem[selected="true"] {
+.attachmentList:focus > .attachmentItem[selected="true"] {
   background-color: Highlight;
   color: HighlightText;
 }
 
-attachmentitem[selected="true"] .attachmentcell-size {
+.attachmentItem[selected="true"] .attachmentcell-size {
   color: -moz-CellHighlightText;
 }
 
-attachmentlist:focus >attachmentitem[selected="true"] .attachmentcell-size {
+.attachmentList:focus > .attachmentItem[selected="true"] .attachmentcell-size {
   color: HighlightText;
 }
 
 /* ::::: msg header captions ::::: */
 
 #msgHeaderView {
   font-size: 100%;
   padding: 0;
--- a/mail/themes/windows/mail/attachmentList.css
+++ b/mail/themes/windows/mail/attachmentList.css
@@ -16,65 +16,65 @@
 .attachmentcell-size {
   padding-top: 1px;
 }
 
 .attachmentcell-size {
   color: GrayText;
 }
 
-attachmentlist[orient="horizontal"] > attachmentitem {
+.attachmentList[orient="horizontal"] > .attachmentItem {
   pointer-events: none;
 }
 
-attachmentlist[orient="horizontal"] .attachmentcell-icon,
-attachmentlist[orient="horizontal"] .attachmentcell-nameselection {
+.attachmentList[orient="horizontal"] .attachmentcell-icon,
+.attachmentList[orient="horizontal"] .attachmentcell-nameselection {
   pointer-events: auto;
 }
 
-attachmentlist:focus > attachmentitem[selected="true"][current="true"] .attachmentcell-nameselection {
+.attachmentList:focus > .attachmentItem[selected="true"][current="true"] .attachmentcell-nameselection {
   outline: 1px dotted #F3D982;
 }
 
-attachmentlist:focus > attachmentitem[current="true"] .attachmentcell-nameselection {
+.attachmentList:focus > .attachmentItem[current="true"] .attachmentcell-nameselection {
   outline: 1px dotted;
   outline-offset: -1px;
 }
 
-attachmentitem[selected="true"] .attachmentcell-nameselection {
+.attachmentItem[selected="true"] .attachmentcell-nameselection {
   background-color: -moz-CellHighlight;
   color: -moz-CellHighlightText;
 }
 
-attachmentlist:focus > attachmentitem[selected="true"] .attachmentcell-nameselection {
+.attachmentList:focus > .attachmentItem[selected="true"] .attachmentcell-nameselection {
   background-color: Highlight;
   color: HighlightText;
 }
 
-attachmentlist:focus > attachmentitem[selected="true"] .attachmentcell-icon {
+.attachmentList:focus > .attachmentItem[selected="true"] .attachmentcell-icon {
   filter: url("chrome://messenger/skin/imageFilters.svg#selected-focus");
 }
 
 @media (-moz-windows-default-theme) {
-  attachmentitem {
+  .attachmentItem {
     pointer-events: auto !important;
     border: 1px solid transparent;
     color: -moz-FieldText;
     background-color: transparent;
     background-repeat: no-repeat;
     background-size: 100% 100%;
     padding: 1px;
   }
 
   .attachmentlist-wrapper {
     margin-inline-end: 1px;
     margin-bottom: 1px;
   }
 
-  attachmentlist[orient="horizontal"] > attachmentitem {
+  .attachmentList[orient="horizontal"] > .attachmentItem {
     margin-top: 1px;
     margin-inline-start: 1px;
   }
 
   .attachmentcell-nameselection {
     outline: none !important;
     background-color: inherit !important;
     color: inherit !important;
@@ -84,104 +84,104 @@ attachmentlist:focus > attachmentitem[se
     filter: none !important;
   }
 
   .attachmentcell-name, .attachmentcell-size {
     margin: 0 4px;
   }
 
   @media (-moz-os-version: windows-win7) {
-    attachmentitem {
+    .attachmentItem {
       border-radius: 3px;
     }
 
-    attachmentitem[selected="true"] {
+    .attachmentItem[selected="true"] {
       border-color: rgb(217, 217, 217);
       background-image: linear-gradient(rgba(190, 190, 190, 0.1),
                                         rgba(190, 190, 190, 0.4));
     }
 
-    attachmentitem[selected="true"]:hover {
+    .attachmentItem[selected="true"]:hover {
       border-color: rgb(125, 162, 206);
       background-image: linear-gradient(rgba(131, 183, 249, 0.28),
                                         rgba(131, 183, 249, 0.5));
     }
 
-    attachmentlist:focus > attachmentitem[current="true"] {
+    .attachmentList:focus > .attachmentItem[current="true"] {
       border-color: rgb(125, 162, 206);
     }
 
-    attachmentlist:focus > attachmentitem[current="true"]:hover {
+    .attachmentList:focus > .attachmentItem[current="true"]:hover {
       border-color: rgb(125, 162, 206);
       background-image: linear-gradient(rgba(131, 183, 249, 0.05),
                                         rgba(131, 183, 249, 0.16));
     }
 
-    attachmentlist:focus > attachmentitem[selected="true"] {
+    .attachmentList:focus > .attachmentItem[selected="true"] {
       border-color: rgb(132, 172, 221);
       background-image: linear-gradient(rgba(131, 183, 249, 0.16),
                                         rgba(131, 183, 249, 0.375));
     }
 
-    attachmentlist:focus > attachmentitem[selected="true"]:hover,
-    attachmentlist:focus > attachmentitem[selected="true"][current="true"] {
+    .attachmentList:focus > .attachmentItem[selected="true"]:hover,
+    .attachmentList:focus > .attachmentItem[selected="true"][current="true"] {
       border-color: rgb(125, 162, 206);
       background-image: linear-gradient(rgba(131, 183, 249, 0.28),
                                         rgba(131, 183, 249, 0.5));
     }
 
-    attachmentitem:hover {
+    .attachmentItem:hover {
       border-color: rgb(184, 214, 251);
       background-image: linear-gradient(rgba(131, 183, 249, 0.05),
                                         rgba(131, 183, 249, 0.16));
     }
 
     #attachmentBucket[orient="vertical"]:focus >
-      attachmentitem:-moz-any([current="true"], [selected="true"]) +
-      attachmentitem:-moz-any([current="true"], [selected="true"]) {
+      .attachmentItem:-moz-any([current="true"], [selected="true"]) +
+      .attachmentItem:-moz-any([current="true"], [selected="true"]) {
       border-top-color: rgba(131, 183, 249, 0.375);
     }
   }
 
   @media not all and (-moz-os-version: windows-win7) {
-    attachmentitem[selected="true"] {
+    .attachmentItem[selected="true"] {
       border-color: rgb(217, 217, 217);
       background-color: rgb(217, 217, 217);
     }
 
-    attachmentitem[selected="true"]:hover {
+    .attachmentItem[selected="true"]:hover {
       border-color: rgb(229, 243, 255);
       background-color: rgb(229, 243, 255);
     }
 
-    attachmentlist:focus > attachmentitem[selected="true"] {
+    .attachmentList:focus > .attachmentItem[selected="true"] {
       border-color: rgb(142, 186, 235);
       background-color: rgb(205, 232, 255);
     }
 
     #attachmentBucket[orient="vertical"]:focus >
-      attachmentitem[selected="true"]:not(:-moz-any([current="true"], :hover)) {
+      .attachmentItem[selected="true"]:not(:-moz-any([current="true"], :hover)) {
       border-right-color: transparent;
       border-left-color: transparent;
     }
 
-    attachmentlist:focus > attachmentitem[current="true"] {
+    .attachmentList:focus > .attachmentItem[current="true"] {
       border-color: rgb(125, 162, 206);
     }
 
-    attachmentlist:focus > attachmentitem[current="true"]:hover,
-    attachmentlist:focus > attachmentitem[selected="true"]:hover,
-    attachmentlist:focus > attachmentitem[selected="true"][current="true"] {
+    .attachmentList:focus > .attachmentItem[current="true"]:hover,
+    .attachmentList:focus > .attachmentItem[selected="true"]:hover,
+    .attachmentList:focus > .attachmentItem[selected="true"][current="true"] {
       border-color: rgb(125, 162, 206);
     }
 
-    attachmentitem:hover {
+    .attachmentItem:hover {
       border-color: rgb(229, 243, 255);
       background-color: rgb(229, 243, 255);
     }
 
     #attachmentBucket[orient="vertical"]:focus >
-      attachmentitem:-moz-any([current="true"], [selected="true"]) +
-      attachmentitem:-moz-any([current="true"], [selected="true"]) {
+      .attachmentItem:-moz-any([current="true"], [selected="true"]) +
+      .attachmentItem:-moz-any([current="true"], [selected="true"]) {
       border-top-color: transparent;
     }
   }
 }
--- a/mail/themes/windows/mail/compose/messengercompose.css
+++ b/mail/themes/windows/mail/compose/messengercompose.css
@@ -19,30 +19,30 @@
   color: -moz-FieldText;
 }
 
 #attachments-box[empty] > #attachmentBucket:focus {
   box-shadow: 0 0 1px Highlight inset, 0 0 1px Highlight inset;
 }
 
 @media (-moz-windows-default-theme: 0) {
-  #attachmentBucket attachmentitem {
+  #attachmentBucket .attachmentItem {
     border-top: 1px solid transparent;
   }
 
-  #attachmentBucket attachmentitem:last-child {
+  #attachmentBucket .attachmentItem:last-child {
     border-bottom: 1px solid transparent;
   }
 }
 
-#attachmentBucket attachmentitem[dropOn="top"] {
+#attachmentBucket .attachmentItem[dropOn="top"] {
   border-top-color: Highlight;
 }
 
-#attachmentBucket attachmentitem[dropOn="bottom"] {
+#attachmentBucket .attachmentItem[dropOn="bottom"] {
   border-bottom-color: Highlight;
 }
 
 /* ::::: special toolbar colors ::::: */
 
 #composeContentBox {
   -moz-appearance: none;
   color: -moz-dialogtext;