Bug 1475817 - Part 9: Convert simple <listbox> to <richlistbox>, address list dialogs. r=jorgk DONTBUILD
authorGeoff Lankow <geoff@darktrojan.net>
Wed, 18 Jul 2018 20:36:42 +1200
changeset 31771 7962d601822d193cccf877bba6c2f0e3908af7a9
parent 31770 d70436bc01deae26240f769ea22c7987901c77ca
child 31772 2f3444aec397e9fb3807d7fabb8b2859b377bf15
push id2308
push userclokep@gmail.com
push dateWed, 05 Sep 2018 00:34:58 +0000
treeherdercomm-beta@e326b2dcd127 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjorgk
bugs1475817
Bug 1475817 - Part 9: Convert simple <listbox> to <richlistbox>, address list dialogs. r=jorgk DONTBUILD
mail/components/addrbook/content/abEditListDialog.xul
mail/components/addrbook/content/abMailListDialog.xul
mail/components/compose/content/addressingWidgetOverlay.js
mail/components/compose/content/messengercompose.xul
mailnews/addrbook/content/abMailListDialog.js
--- a/mail/components/addrbook/content/abEditListDialog.xul
+++ b/mail/components/addrbook/content/abEditListDialog.xul
@@ -48,29 +48,29 @@
     </hbox>
 
     <spacer style="height:1em"/>
     <label control="addressCol1#1"
            value="&AddressTitle.label;"
            accesskey="&AddressTitle.accesskey;"/>
     <spacer style="height:0.1em"/>
 
-    <listbox id="addressingWidget" style="height: 15em;" onclick="awClickEmptySpace(event.target, true)">
-      <listitem class="addressingWidgetItem" allowevents="true">
-        <listcell class="addressingWidgetCell">
+    <richlistbox id="addressingWidget" style="height: 15em;" onclick="awClickEmptySpace(event.target, true)">
+      <richlistitem class="addressingWidgetItem" allowevents="true">
+        <hbox class="addressingWidgetCell" flex="1">
           <textbox id="addressCol1#1" class="plain textbox-addressingWidget uri-element"
                    type="autocomplete" flex="1"
                    autocompletesearch="addrbook ldap"
                    autocompletesearchparam="{}" timeout="300" maxrows="4"
                    completedefaultindex="true" forcecomplete="true"
                    completeselectedindex="true"
                    minresultsforpopup="3"
                    ontextentered="awRecipientTextCommand(param, this)"
                    onkeypress="awHandleKeyPress(this, event);"
                    onkeydown="awRecipientKeyDown(event, this);"
                    onclick="awNotAnEmptyArea(event);">
             <image onclick="this.parentNode.select();" class="person-icon"/>
           </textbox>
-        </listcell>
-      </listitem>
-    </listbox>
+        </hbox>
+      </richlistitem>
+    </richlistbox>
   </vbox>
 </dialog>
--- a/mail/components/addrbook/content/abMailListDialog.xul
+++ b/mail/components/addrbook/content/abMailListDialog.xul
@@ -59,29 +59,29 @@
     </hbox>
 
     <spacer style="height:1em"/>
     <label control="addressCol1#1"
            value="&AddressTitle.label;"
            accesskey="&AddressTitle.accesskey;"/>
     <spacer style="height:0.1em"/>
 
-    <listbox id="addressingWidget" style="height: 15em;" onclick="awClickEmptySpace(event.target, true)">
-      <listitem class="addressingWidgetItem" allowevents="true">
-        <listcell class="addressingWidgetCell">
+    <richlistbox id="addressingWidget" style="height: 15em;" onclick="awClickEmptySpace(event.target, true)">
+      <richlistitem class="addressingWidgetItem" allowevents="true">
+        <hbox class="addressingWidgetCell" flex="1">
           <textbox id="addressCol1#1" class="plain textbox-addressingWidget uri-element"
                    type="autocomplete" flex="1"
                    autocompletesearch="addrbook ldap"
                    autocompletesearchparam="{}" timeout="300" maxrows="4"
                    completedefaultindex="true" forcecomplete="true"
                    completeselectedindex="true"
                    minresultsforpopup="3"
                    ontextentered="awRecipientTextCommand(param, this)"
                    onkeypress="awHandleKeyPress(this, event);"
                    onkeydown="awRecipientKeyDown(event, this);"
                    onclick="awNotAnEmptyArea(event);">
             <image onclick="this.parentNode.select();" class="person-icon"/>
           </textbox>
-        </listcell>
-      </listitem>
-    </listbox>
+        </hbox>
+      </richlistitem>
+    </richlistbox>
   </vbox>
 </dialog>
--- a/mail/components/compose/content/addressingWidgetOverlay.js
+++ b/mail/components/compose/content/addressingWidgetOverlay.js
@@ -29,18 +29,18 @@ function awGetMaxRecipients()
 {
   return top.MAX_RECIPIENTS;
 }
 
 function awGetNumberOfCols()
 {
   if (gNumberOfCols == 0)
   {
-    var listbox = document.getElementById('addressingWidget');
-    var listCols = listbox.getElementsByTagName('listcol');
+    var listbox = document.getElementById("addressingWidget");
+    var listCols = listbox.getElementsByTagName("treecol");
     gNumberOfCols = listCols.length;
     if (!gNumberOfCols)
       gNumberOfCols = 1;  /* if no cols defined, that means we have only one! */
   }
 
   return gNumberOfCols;
 }
 
@@ -63,19 +63,19 @@ function awInitializeNumberOfRowsShown()
   // Set minimum number of rows shown for address widget, per hardwired
   // rows="1" attribute of addressingWidget, to prevent resizing the
   // subject and format toolbar over the address widget.
   // This lets users shrink the address widget to one row (with delicate UX)
   // and thus maximize the space available for composition body,
   // especially on small screens.
   msgHeadersToolbar.minHeight = msgHeadersToolbar.boxObject.height;
 
-  // Set default number of rows shown for address widget.
-  addressingWidget.setAttribute("rows", awNumRowsShownDefault);
-  msgHeadersToolbar.height = msgHeadersToolbar.boxObject.height + extraHeight;
+  msgHeadersToolbar.height = msgHeadersToolbar.boxObject.height +
+    addressingWidget.boxObject.height * (awNumRowsShownDefault - 1) +
+    extraHeight;
 
   // Update addressingWidget internals.
   awCreateOrRemoveDummyRows();
 }
 
 function awInputElementName()
 {
   if (inputElementType == "")
@@ -183,21 +183,21 @@ function Recipients2CompFields(msgCompFi
     msgCompFields.replyTo = addrReply;
     msgCompFields.newsgroups = addrNg;
     msgCompFields.followupTo = addrFollow;
 }
 
 function CompFields2Recipients(msgCompFields)
 {
   if (msgCompFields) {
-    let listbox = document.getElementById('addressingWidget');
+    let listbox = document.getElementById("addressingWidget");
     let newListBoxNode = listbox.cloneNode(false);
     let listBoxColsClone = listbox.firstChild.cloneNode(true);
     newListBoxNode.appendChild(listBoxColsClone);
-    let templateNode = listbox.querySelector("listitem");
+    let templateNode = listbox.getElementsByTagName("richlistitem")[0];
     // dump("replacing child in comp fields 2 recips \n");
     listbox.parentNode.replaceChild(newListBoxNode, listbox);
 
     top.MAX_RECIPIENTS = 0;
     let msgReplyTo = msgCompFields.replyTo;
     let msgTo = msgCompFields.to;
     let msgCC = msgCompFields.cc;
     let msgBCC = msgCompFields.bcc;
@@ -430,18 +430,18 @@ function awTestRowSequence()
     You need to define the pref mail.debug.test_addresses_sequence to true in order to activate it
   */
 
   if (!test_addresses_sequence)
     return true;
 
   /* debug code to verify the sequence still good */
 
-  let listbox = document.getElementById('addressingWidget');
-  let listitems = listbox.getElementsByTagName('listitem');
+  let listbox = document.getElementById("addressingWidget");
+  let listitems = listbox.getElementsByTagName("richlistitem");
   if (listitems.length >= top.MAX_RECIPIENTS )
   {
     for (let i = 1; i <= listitems.length; i ++)
     {
       let item = listitems [i - 1];
       let inputID = item.querySelector(awInputElementName()).id.split("#")[1];
       let popupID = item.querySelector(awSelectElementName()).id.split("#")[1];
       if (inputID != i || popupID != i)
@@ -490,19 +490,19 @@ function awDeleteRow(rowToDelete)
     awSetInputAndPopupId(awGetInputElement(row), awGetPopupElement(row), (row-1));
 
   awTestRowSequence();
 }
 
 function awClickEmptySpace(target, setFocus)
 {
   if (document.getElementById("addressCol2#1").disabled || target == null ||
-      (target.localName != "listboxbody" &&
-      target.localName != "listcell" &&
-      target.localName != "listitem"))
+      (target.localName != "richlistbox" &&
+      target.localName != "richlistcell" &&
+      target.localName != "richlistitem"))
     return;
 
   var lastInput = awGetInputElement(top.MAX_RECIPIENTS);
 
   if ( lastInput && lastInput.value )
     awAppendNewRow(setFocus);
   else
     if (setFocus)
@@ -669,35 +669,36 @@ function awGetInputElement(row)
 function awGetElementByCol(row, col)
 {
   var colID = "addressCol" + col + "#" + row;
   return document.getElementById(colID);
 }
 
 function awGetListItem(row)
 {
-  var listbox = document.getElementById('addressingWidget');
+  var listbox = document.getElementById("addressingWidget");
 
   if ( listbox && row > 0)
   {
-    var listitems = listbox.getElementsByTagName('listitem');
+    var listitems = listbox.getElementsByTagName("richlistitem");
     if ( listitems && listitems.length >= row )
       return listitems[row-1];
   }
   return 0;
 }
 
 function awGetRowByInputElement(inputElement)
 {
   var row = 0;
   if (inputElement) {
     var listitem = inputElement.parentNode.parentNode;
     while (listitem) {
-      if (listitem.localName == "listitem")
+      if (listitem.localName == "richlistitem") {
         ++row;
+      }
       listitem = listitem.previousSibling;
     }
   }
   return row;
 }
 
 
 // Copy Node - copy this node and insert ahead of the (before) node.  Append to end if before=0
@@ -939,49 +940,61 @@ function awCreateOrRemoveDummyRows()
       gAWContentHeight += gAWRowHeight;
     }
   }
 }
 
 function awCalcContentHeight()
 {
   var listbox = document.getElementById("addressingWidget");
-  var items = listbox.getElementsByTagName("listitem");
+  var items = listbox.getElementsByTagName("richlistitem");
 
   gAWContentHeight = 0;
   if (items.length > 0) {
     // all rows are forced to a uniform height in xul listboxes, so
     // find the first listitem with a boxObject and use it as precedent
     var i = 0;
     do {
       gAWRowHeight = items[i].boxObject.height;
       ++i;
     } while (i < items.length && !gAWRowHeight);
     gAWContentHeight = gAWRowHeight*items.length;
   }
 }
 
 function awCreateDummyItem(aParent)
 {
-  var titem = document.createElement("listitem");
+  var listbox = document.getElementById("addressingWidget");
+  var item = listbox.getElementsByTagName("richlistitem")[0];
+
+  var titem = document.createElement("richlistitem");
   titem.setAttribute("_isDummyRow", "true");
   titem.setAttribute("class", "dummy-row");
+  titem.style.height = item.boxObject.height + "px";
 
-  for (var i = awGetNumberOfCols(); i > 0; i--)
-    awCreateDummyCell(titem);
+  for (let i = 0; i < awGetNumberOfCols(); i++) {
+    let cell = awCreateDummyCell(titem);
+    if (item.children[i].hasAttribute("style")) {
+      cell.setAttribute("style", item.children[i].getAttribute("style"));
+    }
+    if (item.children[i].hasAttribute("flex")) {
+      cell.setAttribute("flex", item.children[i].getAttribute("flex"));
+    }
+  }
 
-  if (aParent)
+  if (aParent) {
     aParent.appendChild(titem);
+  }
 
   return titem;
 }
 
 function awCreateDummyCell(aParent)
 {
-  var cell = document.createElement("listcell");
+  var cell = document.createElement("hbox");
   cell.setAttribute("class", "addressingWidgetCell dummy-row-cell");
   if (aParent)
     aParent.appendChild(cell);
 
   return cell;
 }
 
 function awGetNextDummyRow()
--- a/mail/components/compose/content/messengercompose.xul
+++ b/mail/components/compose/content/messengercompose.xul
@@ -1924,42 +1924,42 @@
                      accesskey="&fromAddr.accesskey;" control="msgIdentity"/>
             </hbox>
             <menulist id="msgIdentity" type="description" flex="1"
                       disableautoselect="true" onkeypress="fromKeyPress(event);"
                       oncommand="LoadIdentity(false);" disableonsend="true">
               <menupopup id="msgIdentityPopup"/>
             </menulist>
           </hbox>
-          <listbox id="addressingWidget" flex="1" seltype="multiple" rows="1"
-                   onkeydown="awKeyDown(event, this)"
-                   onclick="awClickEmptySpace(event.originalTarget, true)"
-                   disableonsend="true">
-            <listcols>
-              <listcol id="typecol-addressingWidget" style="&headersSpace.style;"/>
-              <listcol id="textcol-addressingWidget" flex="1"/>
-            </listcols>
-            <listitem class="addressingWidgetItem" allowevents="true">
-              <listcell class="addressingWidgetCell">
+          <richlistbox id="addressingWidget" flex="1" seltype="multiple"
+                       onkeydown="awKeyDown(event, this)"
+                       onclick="awClickEmptySpace(event.originalTarget, true)"
+                       disableonsend="true">
+            <treecols hidden="true">
+              <treecol id="typecol-addressingWidget" style="&headersSpace.style;"/>
+              <treecol id="textcol-addressingWidget" flex="1"/>
+            </treecols>
+            <richlistitem class="addressingWidgetItem" allowevents="true">
+              <hbox class="addressingWidgetCell" align="center" style="&headersSpace.style;">
                 <menulist id="addressCol1#1" disableonsend="true"
                           class="aw-menulist" flex="1"
                           oncommand="onAddressColCommand(this.id);">
                   <menupopup>
                     <menuitem value="addr_to" label="&toAddr.label;"/>
                     <menuitem value="addr_cc" label="&ccAddr.label;"/>
                     <menuitem value="addr_bcc" label="&bccAddr.label;"/>
                     <menuitem value="addr_reply" label="&replyAddr.label;"/>
                     <menuitem value="addr_newsgroups" label="&newsgroupsAddr.label;"/>
                     <menuitem value="addr_followup" label="&followupAddr.label;"/>
                   </menupopup>
                 </menulist>
                 <image class="deleteAddress close-icon"
                        onclick="awDeleteHit(this.parentNode.nextSibling.querySelector('textbox.textbox-addressingWidget'));"/>
-              </listcell>
-              <listcell class="addressingWidgetCell">
+              </hbox>
+              <hbox class="addressingWidgetCell" flex="1">
                 <textbox id="addressCol2#1" class="plain textbox-addressingWidget uri-element"
                          aria-labelledby="addressCol1#1"
                          type="autocomplete" flex="1"
                          autocompletesearch="mydomain addrbook ldap news"
                          autocompletesearchparam="{}"
                          timeout="300"
                          maxrows="6"
                          completedefaultindex="true" forcecomplete="true"
@@ -1967,19 +1967,19 @@
                          minresultsforpopup="2" ignoreblurwhilesearching="true"
                          ontextentered="awRecipientTextCommand(param, this)"
                          onchange="onRecipientsChanged();"
                          oninput="onRecipientsChanged();"
                          onkeypress="awRecipientKeyPress(event, this)"
                          onkeydown="awRecipientKeyDown(event, this)"
                          disableonsend="true">
                 </textbox>
-              </listcell>
-            </listitem>
-          </listbox>
+              </hbox>
+            </richlistitem>
+          </richlistbox>
           <hbox id="subject-box">
             <hbox align="center" pack="end" style="&headersSpace.style;">
               <label id="subjectLabel" value="&subject.label;" accesskey="&subject.accesskey;" control="msgSubject"/>
             </hbox>
             <textbox id="msgSubject" flex="1" class="toolbar" disableonsend="true" spellcheck="true"
                      oninput="gContentChanged=true;SetComposeWindowTitle();"
                      onkeypress="subjectKeyPress(event);" />
           </hbox>
--- a/mailnews/addrbook/content/abMailListDialog.js
+++ b/mailnews/addrbook/content/abMailListDialog.js
@@ -259,19 +259,19 @@ function OnLoadEditList()
 
   document.title = gAddressBookBundle.getFormattedString("mailingListTitleEdit", [oldListName]);
 
   if (gEditList.addressLists)
   {
     let total = gEditList.addressLists.length;
     if (total)
     {
-      let listbox = document.getElementById('addressingWidget');
+      let listbox = document.getElementById("addressingWidget");
       let newListBoxNode = listbox.cloneNode(false);
-      let templateNode = listbox.querySelector("listitem");
+      let templateNode = listbox.querySelector("richlistitem");
 
       top.MAX_RECIPIENTS = 0;
       for (let i = 0; i < total; i++)
       {
         let card = gEditList.addressLists.queryElementAt(i, Ci.nsIAbCard);
         let address = MailServices.headerParser.makeMailboxObject(
           card.displayName, card.primaryEmail).toString();
         SetInputValue(address, newListBoxNode, templateNode);
@@ -355,19 +355,19 @@ function awNotAnEmptyArea(event)
     awAppendNewRow(false);
 
   event.stopPropagation();
 }
 
 function awClickEmptySpace(target, setFocus)
 {
   if (target == null ||
-      (target.localName != "listboxbody" &&
-      target.localName != "listcell" &&
-      target.localName != "listitem"))
+      (target.localName != "richlistbox" &&
+      target.localName != "richlistcell" &&
+      target.localName != "richlistitem"))
     return;
 
   var lastInput = awGetInputElement(top.MAX_RECIPIENTS);
 
   if (lastInput && lastInput.value)
     awAppendNewRow(setFocus);
   else
     if (setFocus)
@@ -456,17 +456,17 @@ function awAppendNewRow(setFocus)
 function awGetInputElement(row)
 {
     return document.getElementById("addressCol1#" + row);
 }
 
 
 function _awSetFocus()
 {
-  var listbox = document.getElementById('addressingWidget');
+  var listbox = document.getElementById("addressingWidget");
   try
   {
     var theNewRow = awGetListItem(top.awRow);
 
     listbox.ensureElementIsVisible(theNewRow);
     top.awInputElement.focus();
   }
   catch(ex)