Bug 1518823 - Port bug 1482389: Remove acces via .treeBoxObject and .boxObject. rs=bustage-fix
authorJorg K <jorgk@jorgk.com>
Tue, 15 Jan 2019 10:42:53 +0100
changeset 33349 96b12a150fe1
parent 33348 85114397b4c8
child 33350 561033e56bac
push id2368
push userclokep@gmail.com
push dateMon, 28 Jan 2019 21:12:50 +0000
treeherdercomm-beta@56d23c07d815 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbustage-fix
bugs1518823, 1482389
Bug 1518823 - Port bug 1482389: Remove acces via .treeBoxObject and .boxObject. rs=bustage-fix
editor/ui/dialogs/content/EdSelectProps.js
editor/ui/dialogs/content/EditorSaveAsCharset.js
mail/base/content/SearchDialog.js
mail/base/content/folderDisplay.js
mail/base/content/folderPane.js
mail/base/content/foldersummary.js
mail/base/content/mailCommands.js
mail/base/content/mailContextMenus.js
mail/base/content/mailTabs.js
mail/base/content/mailWidgets.xml
mail/base/content/messageWindow.js
mail/base/content/msgMail3PaneWindow.js
mail/base/content/threadPane.js
mail/components/addrbook/content/abCommon.js
mail/components/addrbook/content/abContactsPanel.js
mail/components/extensions/test/browser/browser_ext_menus.js
mail/components/im/content/chat-messenger.js
mail/components/preferences/cookies.js
mail/components/preferences/permissions.js
mail/test/mozmill/folder-display/test-right-click-middle-click-messages.js
mail/test/mozmill/shared-modules/test-folder-display-helpers.js
mailnews/addrbook/content/abResultsPane.js
mailnews/base/content/msgSelectOfflineFolders.js
mailnews/base/content/msgSynchronize.js
mailnews/base/content/subscribe.js
mailnews/base/content/virtualFolderListEdit.js
mailnews/base/prefs/content/AccountManager.js
mailnews/base/util/jsTreeSelection.js
mailnews/extensions/newsblog/content/FeedUtils.jsm
mailnews/extensions/newsblog/content/feed-subscriptions.js
mailnews/extensions/newsblog/content/newsblogOverlay.js
--- a/editor/ui/dialogs/content/EdSelectProps.js
+++ b/editor/ui/dialogs/content/EdSelectProps.js
@@ -3,17 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // Global variables
 
 var hasValue;
 var oldValue;
 var insertNew;
 var itemArray;
-var treeBoxObject;
+var theTree;
 var treeSelection;
 var selectElement;
 var currentItem = null;
 var selectedOption = null;
 var selectedOptionCount = 0;
 
 // Utility functions
 
@@ -89,24 +89,24 @@ optionObject.prototype.cycleCell = funct
   else
   {
     // Different handling for multiselect lists
     if (gDialog.selectMultiple.checked || !selectedOption)
       selectedOptionCount++;
     else if (selectedOption)
     {
       selectedOption.removeAttribute("selected");
-      var column = treeBoxObject.columns["SelectSelCol"];
-      treeBoxObject.invalidateColumn(column);
+      var column = theTree.columns["SelectSelCol"];
+      theTree.invalidateColumn(column);
       selectedOption = null;
     }
     this.element.setAttribute("selected", "");
     selectedOption = this.element;
-    var column = treeBoxObject.columns["SelectSelCol"];
-    treeBoxObject.invalidateCell(index, column);
+    var column = theTree.columns["SelectSelCol"];
+    theTree.invalidateCell(index, column);
   }
   if (currentItem == this)
     // Also update the deck
     gDialog.optionSelected.setAttribute("checked", this.element.hasAttribute("selected"));
   UpdateSelectMultiple();
 };
 
 optionObject.prototype.onFocus = function onFocus()
@@ -173,20 +173,20 @@ optionObject.prototype.destroy = functio
 
 optionObject.prototype.moveUp = function moveUp()
 {
   var i;
   var index = treeSelection.currentIndex;
   if (itemArray[index].level < itemArray[index - 1].level + itemArray[index - 1].container)
   {
     // we need to repaint the tree's lines
-    treeBoxObject.invalidateRange(getParentIndex(index), index);
+    theTree.invalidateRange(getParentIndex(index), index);
     // a) option is just after an optgroup, so it becomes the last child
     itemArray[index].level = 2;
-    treeBoxObject.view.selectionChanged();
+    theTree.view.selectionChanged();
   }
   else
   {
     // otherwise new option level is now the same as the previous item
     itemArray[index].level = itemArray[index - 1].level;
     // swap the option with the previous item
     itemArray.splice(index, 0, itemArray.splice(--index, 1)[0]);
   }
@@ -201,20 +201,20 @@ optionObject.prototype.canMoveDown = fun
 
 optionObject.prototype.moveDown = function moveDown()
 {
   var i;
   var index = treeSelection.currentIndex;
   if (index + 1 == itemArray.length || itemArray[index].level > itemArray[index + 1].level)
   {
     // we need to repaint the tree's lines
-    treeBoxObject.invalidateRange(getParentIndex(index), index);
+    theTree.invalidateRange(getParentIndex(index), index);
     // a) option is last child of an optgroup, so it moves just after
     itemArray[index].level = 1;
-    treeBoxObject.view.selectionChanged();
+    theTree.view.selectionChanged();
   }
   else
   {
     // level increases if the option was preceding an optgroup
     itemArray[index].level += itemArray[index + 1].container;
     // swap the option with the next item
     itemArray.splice(index, 0, itemArray.splice(++index, 1)[0]);
   }
@@ -287,17 +287,17 @@ optgroupObject.prototype.moveUp = functi
   var i = index;
   while (itemArray[--index].level > 1);
   var j = gDialog.nextChild(i);
   // Cut out the element, cut the array in two, then join together
   var movedItems = itemArray.splice(i, j - i);
   var endItems = itemArray.splice(index);
   itemArray = itemArray.concat(movedItems).concat(endItems);
   // Repaint the lot
-  treeBoxObject.invalidateRange(index, j);
+  theTree.invalidateRange(index, j);
   selectTreeIndex(index, true);
 }
 
 optgroupObject.prototype.canMoveDown = function canMoveDown()
 {
   return gDialog.lastChild() > treeSelection.currentIndex;
 }
 
@@ -307,30 +307,30 @@ optgroupObject.prototype.moveDown = func
   var index = treeSelection.currentIndex;
   var i = gDialog.nextChild(index);
   var j = gDialog.nextChild(i);
   // Cut out the element, cut the array in two, then join together
   var movedItems = itemArray.splice(i, j - 1);
   var endItems = itemArray.splice(index);
   itemArray = itemArray.concat(movedItems).concat(endItems);
   // Repaint the lot
-  treeBoxObject.invalidateRange(index, j);
+  theTree.invalidateRange(index, j);
   index += j - i;
   selectTreeIndex(index, true);
 }
 
 optgroupObject.prototype.appendOption = function appendOption(child, parent)
 {
   var index = gDialog.nextChild(parent);
   // XXX need to repaint the lines, tree won't do this
-  var primaryCol = treeBoxObject.columns.getPrimaryColumn();
-  treeBoxObject.invalidateCell(index - 1, primaryCol);
+  var primaryCol = theTree.columns.getPrimaryColumn();
+  theTree.invalidateCell(index - 1, primaryCol);
   // insert the wrapped object as the last child
   itemArray.splice(index, 0, new optionObject(child, 2));
-  treeBoxObject.rowCountChanged(index, 1);
+  theTree.rowCountChanged(index, 1);
   selectTreeIndex(index, false);
 };
 
 // dialog initialization code
 
 function Startup()
 {
   var editor = GetCurrentEditor();
@@ -427,20 +427,20 @@ function Startup()
         this.element.setAttribute("tabindex", gDialog.selectTabIndex.value);
       else
         this.element.removeAttribute("tabindex");
     },
     appendOption:     function appendOption(child, parent)
     {
       var index = itemArray.length;
       // XXX need to repaint the lines, tree won't do this
-      treeBoxObject.invalidateRange(this.lastChild(), index);
+      theTree.invalidateRange(this.lastChild(), index);
       // append the wrapped object
       itemArray.push(new optionObject(child, 1));
-      treeBoxObject.rowCountChanged(index, 1);
+      theTree.rowCountChanged(index, 1);
       selectTreeIndex(index, false);
     },
     canDestroy:       function canDestroy(prompt)
     {
       return false;
     },
     canMoveDown:      function canMoveDown()
     {
@@ -476,18 +476,18 @@ function Startup()
         if (grandchild.tagName == "OPTION")
           itemArray.push(new optionObject(grandchild.cloneNode(true), 2));
     }
   }
 
   UpdateSelectMultiple();
 
   // Define a custom view for the tree
-  treeBoxObject = gDialog.tree.treeBoxObject;
-  treeBoxObject.view = {
+  theTree = gDialog.tree;
+  theTree.view = {
     QueryInterface: ChromeUtils.generateQI(["nsITreeView",
                                             "nsISupportsWeakReference"]),
     // useful for debugging
     get wrappedJSObject() { return this; },
     get rowCount() { return itemArray.length; },
     get selection() { return treeSelection; },
     set selection(selection) { return treeSelection = selection; },
     getRowProperties: function getRowProperties(index) { return ""; },
@@ -623,20 +623,20 @@ function AddOption()
   SetTextboxFocus(gDialog.optionText);
 }
 
 function AddOptGroup()
 {
   var optgroupElement = GetCurrentEditor().createElementWithDefaults("optgroup");
   var index = itemArray.length;
   // XXX need to repaint the lines, tree won't do this
-  treeBoxObject.invalidateRange(gDialog.lastChild(), index);
+  theTree.invalidateRange(gDialog.lastChild(), index);
   // append the wrapped object
   itemArray.push(new optgroupObject(optgroupElement));
-  treeBoxObject.rowCountChanged(index, 1);
+  theTree.rowCountChanged(index, 1);
   selectTreeIndex(index, false);
   SetTextboxFocus(gDialog.optgroupLabel);
 }
 
 function RemoveElement()
 {
   if (currentItem.canDestroy(true))
   {
@@ -646,20 +646,20 @@ function RemoveElement()
     // Perform necessary cleanup and remove the wrapper
     itemArray[index].destroy();
     itemArray.splice(index, 1);
     --index;
     // XXX need to repaint the lines, tree won't do this
     if (level == 1) {
       var last = gDialog.lastChild();
       if (index > last)
-        treeBoxObject.invalidateRange(last, index);
+        theTree.invalidateRange(last, index);
     }
     selectTreeIndex(index, true);
-    treeBoxObject.rowCountChanged(++index, -1);
+    theTree.rowCountChanged(++index, -1);
   }
 }
 
 // Event handler
 function onTreeKeyUp(event)
 {
   if (event.keyCode == event.DOM_VK_SPACE)
     currentItem.cycleCell();
@@ -667,51 +667,51 @@ function onTreeKeyUp(event)
 
 function onNameInput()
 {
   var disabled = !gDialog.selectName.value;
   if (gDialog.accept.disabled != disabled)
     gDialog.accept.disabled = disabled;
   gDialog.element.setAttribute("name", gDialog.selectName.value);
   // repaint the tree
-  var primaryCol = treeBoxObject.columns.getPrimaryColumn();
-  treeBoxObject.invalidateCell(treeSelection.currentIndex, primaryCol);
+  var primaryCol = theTree.columns.getPrimaryColumn();
+  theTree.invalidateCell(treeSelection.currentIndex, primaryCol);
 }
 
 function onLabelInput()
 {
   currentItem.element.setAttribute("label", gDialog.optgroupLabel.value);
   // repaint the tree
-  var primaryCol = treeBoxObject.columns.getPrimaryColumn();
-  treeBoxObject.invalidateCell(treeSelection.currentIndex, primaryCol);
+  var primaryCol = theTree.columns.getPrimaryColumn();
+  theTree.invalidateCell(treeSelection.currentIndex, primaryCol);
 }
 
 function onTextInput()
 {
   currentItem.element.text = gDialog.optionText.value;
   // repaint the tree
   if (hasValue) {
-    var primaryCol = treeBoxObject.columns.getPrimaryColumn();
-    treeBoxObject.invalidateCell(treeSelection.currentIndex, primaryCol);
+    var primaryCol = theTree.columns.getPrimaryColumn();
+    theTree.invalidateCell(treeSelection.currentIndex, primaryCol);
   }
   else
   {
     gDialog.optionValue.value = gDialog.optionText.value;
-    treeBoxObject.invalidateRow(treeSelection.currentIndex);
+    theTree.invalidateRow(treeSelection.currentIndex);
   }
 }
 
 function onValueInput()
 {
   gDialog.optionHasValue.checked = hasValue = true;
   oldValue = gDialog.optionValue.value;
   currentItem.element.setAttribute("value", oldValue);
   // repaint the tree
-  var column = treeBoxObject.columns["SelectValCol"];
-  treeBoxObject.invalidateCell(treeSelection.currentIndex, column);
+  var column = theTree.columns["SelectValCol"];
+  theTree.invalidateCell(treeSelection.currentIndex, column);
 }
 
 function onHasValueClick()
 {
   hasValue = gDialog.optionHasValue.checked;
   if (hasValue)
   {
     gDialog.optionValue.value = oldValue;
@@ -719,26 +719,26 @@ function onHasValueClick()
   }
   else
   {
     oldValue = gDialog.optionValue.value;
     gDialog.optionValue.value = gDialog.optionText.value;
     currentItem.element.removeAttribute("value");
   }
   // repaint the tree
-  var column = treeBoxObject.columns["SelectValCol"];
-  treeBoxObject.invalidateCell(treeSelection.currentIndex, column);
+  var column = theTree.columns["SelectValCol"];
+  theTree.invalidateCell(treeSelection.currentIndex, column);
 }
 
 function onSelectMultipleClick()
 {
   // Recalculate the unique selected option if we need it and have lost it
   if (!gDialog.selectMultiple.checked && selectedOptionCount == 1 && !selectedOption)
     for (var i = 1; !(selectedOption = itemArray[i].element).hasAttribute("selected"); i++);
 }
 
 function selectTreeIndex(index, focus)
 {
   treeSelection.select(index);
-  treeBoxObject.ensureRowIsVisible(index);
+  theTree.ensureRowIsVisible(index);
   if (focus)
     gDialog.tree.focus();
 }
--- a/editor/ui/dialogs/content/EditorSaveAsCharset.js
+++ b/editor/ui/dialogs/content/EditorSaveAsCharset.js
@@ -99,17 +99,17 @@ function Startup()
 function InitDialog()
 {
   gDialog.TitleInput.value = GetDocumentTitle();
 
   var tree = gDialog.charsetTree;
   var index = gCharsetInfo.map(info => info.value).indexOf(gCharset);
   if (index >= 0) {
     tree.view.selection.select(index);
-    tree.treeBoxObject.ensureRowIsVisible(index);
+    tree.ensureRowIsVisible(index);
   }
 }
 
 
 function onAccept()
 {
   var editor = GetCurrentEditor();
   editor.beginTransaction();
--- a/mail/base/content/SearchDialog.js
+++ b/mail/base/content/SearchDialog.js
@@ -228,17 +228,16 @@ function searchOnLoad() {
   gSearchStopButton.setAttribute("label", gSearchBundle.getString("labelForSearchButton"));
   gSearchStopButton.setAttribute("accesskey", gSearchBundle.getString("labelForSearchButton.accesskey"));
 
   gMessageDisplay = new NeverVisibleMessageDisplayWidget();
   gFolderDisplay = new SearchFolderDisplayWidget(gMessageDisplay);
   gFolderDisplay.messenger = messenger;
   gFolderDisplay.msgWindow = msgWindow;
   gFolderDisplay.tree = document.getElementById("threadTree");
-  gFolderDisplay.treeBox = gFolderDisplay.tree.boxObject;
   gFolderDisplay.view.openSearchView();
   gFolderDisplay.makeActive();
 
   gFolderDisplay.setColumnStates({
     subjectCol: { visible: true },
     correspondentCol: { visible: Services.prefs.getBoolPref("mail.threadpane.use_correspondents") },
     senderCol: { visible: !Services.prefs.getBoolPref("mail.threadpane.use_correspondents") },
     dateCol: { visible: true },
--- a/mail/base/content/folderDisplay.js
+++ b/mail/base/content/folderDisplay.js
@@ -106,22 +106,16 @@ function FolderDisplayWidget(aTabInfo, a
   this.messageDisplay = aMessageDisplayWidget;
   this.messageDisplay.folderDisplay = this;
 
   /**
    * The XUL tree node, as retrieved by getDocumentElementById.  The caller is
    *  responsible for setting this.
    */
   this.tree = null;
-  /**
-   * The nsITreeBoxObject on the XUL tree node, accessible from this.tree as
-   *  this.tree.boxObject and QueryInterfaced as such.  The caller is
-   *  responsible for setting this.
-   */
-  this.treeBox = null;
 
   /**
    * The nsIMsgWindow corresponding to the window that holds us.  There is only
    *  one of these per tab.  The caller is responsible for setting this.
    */
   this.msgWindow = null;
   /**
    * The nsIMessenger instance that corresponds to our tab/window.  We do not
@@ -172,29 +166,29 @@ function FolderDisplayWidget(aTabInfo, a
 
   // We care about onselect events, so add a listener for that.
   let self = this;
   domNode.addEventListener("select", function() {
     self.view.dbView.selectionChanged();
   });
 
   /**
-   * Create a fake tree box object for if/when this folder is in the background.
+   * Create a fake tree object for if/when this folder is in the background.
    * We need to give it a DOM object to send events to, including the onselect
    * event we care about and for which we added a handler above, and all the
    * other events we don't care about.
    */
-  this._fakeTreeBox = new FakeTreeBoxObject(domNode);
+  this._fakeTree = new FakeTree(domNode);
 
   /**
    * Create a fake tree selection for cases where we have opened a background
    * tab. We'll get rid of this as soon as we've switched to the tab for the
    * first time, and have a real tree selection.
    */
-  this._fakeTreeSelection = new JSTreeSelection(this._fakeTreeBox);
+  this._fakeTreeSelection = new JSTreeSelection(this._fakeTree);
 
   this._mostRecentSelectionCounts = [];
   this._mostRecentCurrentIndices = [];
 }
 FolderDisplayWidget.prototype = {
   /**
    * @return the currently displayed folder.  This is just proxied from the
    *     view wrapper.
@@ -827,17 +821,17 @@ FolderDisplayWidget.prototype = {
     //  anything else because closing the view could theoretically propagate
     //  down to the message display and we don't want it doing anything it
     //  doesn't have to do.
     this.messageDisplay._close();
 
     this.view.close();
     this.messenger.setWindow(null, null);
     this.messenger = null;
-    this._fakeTreeBox = null;
+    this._fakeTree = null;
     this._fakeTreeSelection = null;
   },
   // @}
 
   /*   ===============================   */
   /* ===== IDBViewWrapper Listener ===== */
   /*   ===============================   */
 
@@ -939,18 +933,18 @@ FolderDisplayWidget.prototype = {
   _activeCreatedView() {
     gDBView = this.view.dbView;
 
     // A change in view may result in changes to sorts, the view menu, etc.
     // Do this before we 'reroot' the dbview.
     this._updateThreadDisplay();
 
     // this creates a new selection object for the view.
-    if (this.treeBox)
-      this.treeBox.view = this.view.dbView;
+    if (this.tree)
+      this.tree.view = this.view.dbView;
 
     FolderDisplayListenerManager._fireListeners("onActiveCreatedView",
                                                 [this]);
 
     // The data payload used to be viewType + ":" + viewFlags.  We no longer
     //  do this because we already have the implied contract that gDBView is
     //  valid at the time we generate the notification.  In such a case, you
     //  can easily get that information from the gDBView.  (The documentation
@@ -1631,46 +1625,46 @@ FolderDisplayWidget.prototype = {
       // Make sure said thread pane is visible.  If we do this after we re-root
       //  the tree, the thread pane may not actually replace the account central
       //  pane.  Concerning...
       this._showThreadPane();
 
       // some things only need to happen if we are transitioning from inactive
       //  to active
       if (wasInactive) {
-        if (this.treeBox) {
+        if (this.tree) {
           // We might have assigned our JS tree selection to
-          //  this.view.dbView.selection back in _hookUpFakeTreeBox. If we've
+          //  this.view.dbView.selection back in _hookUpFakeTree. If we've
           //  done so, null the selection out so that the line after this
           //  causes a real selection to be created.
           // If we haven't done so, we're fine as selection would be null here
           //  anyway. (The fake tree selection should persist only till the
           //  first time the tab is switched to.)
           if (fakeTreeSelection)
             this.view.dbView.selection = null;
 
           // Setting the 'view' attribute on treeBox results in the following
           //  effective calls, noting that in makeInactive we made sure to null
           //  out its view so that it won't try and clean up any views or their
           //  selections.  (The actual actions happen in
           //  nsTreeBodyFrame::SetView)
-          // - this.view.dbView.selection.tree = this.treeBox
-          // - this.view.dbView.setTree(this.treeBox)
-          // - this.treeBox.view = this.view.dbView (in
+          // - this.view.dbView.selection.tree = this.tree
+          // - this.view.dbView.setTree(this.tree)
+          // - this.tree.view = this.view.dbView (in
           //   nsTreeBodyObject::SetView)
-          this.treeBox.view = this.view.dbView;
+          this.tree.view = this.view.dbView;
 
           if (fakeTreeSelection) {
             fakeTreeSelection.duplicateSelection(this.view.dbView.selection);
             // Since duplicateSelection will fire a selectionChanged event,
             // which will try to reload the message, we shouldn't do the same.
             dontReloadMessage = true;
           }
           if (this._savedFirstVisibleRow != null)
-            this.treeBox.scrollToRow(this._savedFirstVisibleRow);
+            this.tree.scrollToRow(this._savedFirstVisibleRow);
         }
       }
 
       // Always restore the column state if we have persisted state.  We restore
       //  state on folder entry, in which case we were probably not inactive.
       this._restoreColumnStates();
 
       // the tab mode knows whether we are folder or message display, which
@@ -1733,59 +1727,59 @@ FolderDisplayWidget.prototype = {
     this._active = false;
 
     // - (everything after this point doesn't care that we are marked inactive)
     // save the folder pane's state always
     this._folderPaneVisible =
       !document.getElementById("folderPaneBox").collapsed;
 
     if (this.view.dbView) {
-      if (this.treeBox)
-        this._savedFirstVisibleRow = this.treeBox.getFirstVisibleRow();
+      if (this.tree)
+        this._savedFirstVisibleRow = this.tree.getFirstVisibleRow();
 
       // save the message pane's state only when it is potentially visible
       this.messagePaneCollapsed =
         document.getElementById("messagepaneboxwrapper").collapsed;
 
-      this.hookUpFakeTreeBox(true);
+      this.hookUpFakeTree(true);
     }
 
     this.messageDisplay.makeInactive();
   },
   // @}
 
   /**
    * Called when we want to "disable" the real treeBox for a while and hook up
    * the fake tree box to the db view. This also takes care of our
    * treeSelection object.
    *
    * @param aNullRealTreeBoxView true if we want to null out the real tree box.
    *          We don't want to null out the view if we're opening a background
    *          tab, for example.
    * @private
    */
-  hookUpFakeTreeBox(aNullRealTreeBoxView) {
+  hookUpFakeTree(aNullRealTreeBoxView) {
     // save off the tree selection object.  the nsTreeBodyFrame will make the
     //  view forget about it when our view is removed, so it's up to us to
     //  save it.
     // We use this.treeSelection instead of this.view.dbView.selection here,
     //  so that we get the fake tree selection if we have it.
     let treeSelection = this.treeSelection;
     // if we want to, make the tree forget about the view right now so we can
     //  tell the db view about its selection object so it can try and keep it
     //  up-to-date even while hidden in the background
-    if (aNullRealTreeBoxView && this.treeBox)
-      this.treeBox.view = null;
+    if (aNullRealTreeBoxView && this.tree)
+      this.tree.view = null;
     // (and tell the db view about its selection again...)
     this.view.dbView.selection = treeSelection;
 
     // hook the dbview up to the fake tree box
-    this._fakeTreeBox.view = this.view.dbView;
-    this.view.dbView.setTree(this._fakeTreeBox);
-    treeSelection.tree = this._fakeTreeBox;
+    this._fakeTree.view = this.view.dbView;
+    this.view.dbView.setTree(this._fakeTree);
+    treeSelection.tree = this._fakeTree;
   },
 
   /**
    * @name Command Support
    */
   // @{
 
   /**
@@ -2400,25 +2394,25 @@ FolderDisplayWidget.prototype = {
    * Minimum number of lines to display between the 'focused' message and the
    *  top / bottom of the thread pane.
    */
   get visibleRowPadding() {
     let topPadding, bottomPadding;
 
     // If we can get the height of the folder pane, treat the values as
     //  percentages of that.
-    if (this.treeBox) {
+    if (this.tree) {
       let topPercentPadding = Services.prefs.getIntPref(
                               "mail.threadpane.padding.top_percent");
       let bottomPercentPadding = Services.prefs.getIntPref(
                                  "mail.threadpane.padding.bottom_percent");
 
       // Assume the bottom row is half-visible and should generally be ignored.
       // (We could actually do the legwork to see if there is a partial one...)
-      let paneHeight = this.treeBox.getPageLength() - 1;
+      let paneHeight = this.tree.getPageLength() - 1;
 
       // Convert from percentages to absolute row counts.
       topPadding = Math.ceil((topPercentPadding / 100) * paneHeight);
       bottomPadding = Math.ceil((bottomPercentPadding / 100) * paneHeight);
 
       // We need one visible row not counted in either padding, for the actual
       //  target message. Also helps correct for rounding errors.
       if (topPadding + bottomPadding > paneHeight) {
@@ -2456,46 +2450,46 @@ FolderDisplayWidget.prototype = {
     //  change logic gets to run to completion before we run ourselves.
     if (!aBounced) {
       let dis = this;
       window.setTimeout(function() {
           dis.ensureRowIsVisible(aViewIndex, true);
         }, 0);
     }
 
-    let treeBox = this.treeBox;
-    if (!treeBox || !treeBox.view)
+    let tree = this.tree;
+    if (!tree || !tree.view)
       return;
 
     // try and trigger a reflow...
-    treeBox.height;
+    tree.height;
 
-    let maxIndex = treeBox.view.rowCount - 1;
+    let maxIndex = tree.view.rowCount - 1;
 
-    let first = treeBox.getFirstVisibleRow();
+    let first = tree.getFirstVisibleRow();
     // Assume the bottom row is half-visible and should generally be ignored.
     // (We could actually do the legwork to see if there is a partial one...)
     const halfVisible = 1;
-    let last  = treeBox.getLastVisibleRow() - halfVisible;
-    let span = treeBox.getPageLength() - halfVisible;
+    let last  = tree.getLastVisibleRow() - halfVisible;
+    let span = tree.getPageLength() - halfVisible;
     let [topPadding, bottomPadding] = this.visibleRowPadding;
 
     let target;
     // If the index is after the last visible guy (with padding), move down
     //  so that the target index is padded in 1 from the bottom.
     if (aViewIndex >= (last - bottomPadding))
       target = Math.min(maxIndex, (aViewIndex + bottomPadding)) - span;
     // If the index is before the first visible guy (with padding), move up
     else if (aViewIndex <= (first + topPadding))  // move up
       target = Math.max(0, (aViewIndex - topPadding));
     else // it is already visible
       return;
 
     // this sets the first visible row
-    treeBox.scrollToRow(target);
+    tree.scrollToRow(target);
   },
 
   /**
    * Ensure that the given range of rows is maximally visible in the thread
    *  pane.  If the range is larger than the number of rows that can be
    *  displayed in the thread pane, we bias towards showing the min row (with
    *  padding).
    *
@@ -2512,23 +2506,23 @@ FolderDisplayWidget.prototype = {
     //  change logic gets to run to completion before we run ourselves.
     if (!aBounced) {
       let dis = this;
       window.setTimeout(function() {
           dis.ensureRowRangeIsVisible(aMinRow, aMaxRow, true);
         }, 0);
     }
 
-    let treeBox = this.treeBox;
-    if (!treeBox)
+    let tree = this.tree;
+    if (!tree)
       return;
-    let first = treeBox.getFirstVisibleRow();
+    let first = tree.getFirstVisibleRow();
     const halfVisible = 1;
-    let last  = treeBox.getLastVisibleRow() - halfVisible;
-    let span = treeBox.getPageLength() - halfVisible;
+    let last  = tree.getLastVisibleRow() - halfVisible;
+    let span = tree.getPageLength() - halfVisible;
     let [topPadding, bottomPadding] = this.visibleRowPadding;
 
     // bail if the range is already visible with padding constraints handled
     if (((first + topPadding) <= aMinRow) &&
         ((last - bottomPadding) >= aMaxRow))
       return;
 
     let target;
@@ -2538,17 +2532,17 @@ FolderDisplayWidget.prototype = {
       target = Math.max(0, (aMinRow - topPadding));
     } else {
       // So the range must fit, and it's a question of how we want to position
       //  it.  For now, the answer is we try and center it, why not.
       let rowSpan = aMaxRow - aMinRow + 1;
       let halfSpare = Math.floor((span - rowSpan - topPadding - bottomPadding) / 2);
       target = aMinRow - halfSpare - topPadding;
     }
-    treeBox.scrollToRow(target);
+    tree.scrollToRow(target);
   },
 
   /**
    * Ensure that the selection is visible to the extent possible.
    */
   ensureSelectionIsVisible() {
     let treeSelection = this.treeSelection; // potentially magic getter
     if (!treeSelection || !treeSelection.count)
@@ -2580,21 +2574,21 @@ FolderDisplayWidget.prototype = {
  * This does not need to exist once we abandon multiplexed tabbing.
  *
  * Sometimes, nsTreeSelection tries to turn us into an nsIBoxObject and then in
  *  turn get the associated element, and then create DOM events on that. The
  *  only event that we care about is onselect, so we get a DOM node here (with
  *  an event listener for onselect already attached), and pass its boxObject in
  *  whenever nsTreeSelection QIs us to nsIBoxObject.
  */
-function FakeTreeBoxObject(aDOMNode) {
+function FakeTree(aDOMNode) {
   this.domNode = aDOMNode;
   this.view = null;
 }
-FakeTreeBoxObject.prototype = {
+FakeTree.prototype = {
   view: null,
   ensureRowIsVisible() {
     // NOP
   },
   /**
    * No need to actually invalidate, as when we re-root the view this will
    *  happen.
    */
@@ -2655,17 +2649,17 @@ FakeTreeBoxObject.prototype = {
   },
   setProperty(propertyName, value) {
     return this.domNode.boxObject.setProperty(propertyName, value);
   },
   removeProperty(propertyName) {
     return this.domNode.boxObject.removeProperty(propertyName);
   },
   QueryInterface: ChromeUtils.generateQI(["nsIBoxObject",
-                                          "nsITreeBoxObject"]),
+                                          "XULTreeElement"]),
 };
 /*
  * Provide attribute and function implementations that complain very loudly if
  *  they are used.  Now, XPConnect will return an error to callers if we don't
  *  implement part of the interface signature, but this is unlikely to provide
  *  the visibility we desire.  In fact, since it is a simple nsresult error,
  *  it may make things completely crazy.  So this way we can yell via dump,
  *  throw an exception, etc.
@@ -2692,26 +2686,26 @@ function FTBO_stubOutMethods(aObj, aMeth
     let myMethodName = methodName;
     aObj[myMethodName] = function() {
       let msg = "Call to stubbed method " + myMethodName;
       dump(msg + "\n");
       throw new Error(msg);
     };
   }
 }
-FTBO_stubOutAttributes(FakeTreeBoxObject.prototype, [
+FTBO_stubOutAttributes(FakeTree.prototype, [
   "columns",
   "focused",
   "treeBody",
   "rowHeight",
   "rowWidth",
   "horizontalPosition",
   "selectionRegion",
   ]);
-FTBO_stubOutMethods(FakeTreeBoxObject.prototype, [
+FTBO_stubOutMethods(FakeTree.prototype, [
   "getFirstVisibleRow",
   "getLastVisibleRow",
   "getPageLength",
   "ensureCellIsVisible",
   "scrollToRow",
   "scrollByLines",
   "scrollByPages",
   "scrollToCell",
--- a/mail/base/content/folderPane.js
+++ b/mail/base/content/folderPane.js
@@ -262,28 +262,27 @@ var gFolderTreeView = {
    * @param event  the double-click event
    */
   onDoubleClick(aEvent) {
     if (aEvent.button != 0 || aEvent.originalTarget.localName == "twisty" ||
         aEvent.originalTarget.localName == "slider" ||
         aEvent.originalTarget.localName == "scrollbarbutton")
       return;
 
-    let row = gFolderTreeView._treeElement.treeBoxObject.getRowAt(aEvent.clientX,
-                                                                  aEvent.clientY);
+    let row = gFolderTreeView._treeElement.getRowAt(aEvent.clientX, aEvent.clientY);
     let folderItem = gFolderTreeView._rowMap[row];
     if (folderItem)
       folderItem.command();
 
     // Don't let the double-click toggle the open state of the folder here
     aEvent.stopPropagation();
   },
 
   getFolderAtCoords(aX, aY) {
-    let row = gFolderTreeView._treeElement.treeBoxObject.getRowAt(aX, aY);
+    let row = gFolderTreeView._treeElement.getRowAt(aX, aY);
     if (row in gFolderTreeView._rowMap)
       return gFolderTreeView._rowMap[row]._folder;
     return null;
   },
 
   /**
    * Toggle displaying the headers of columns in the folder pane.
    * @param aSetup  Set to true if the columns should be set up according
@@ -569,17 +568,17 @@ var gFolderTreeView = {
         // We don't want to get stuck in an infinite recursion, so pass in false
         return this.selectFolder(aFolder, false);
       }
 
       return false;
     }
 
     this.selection.select(folderIndex);
-    this._treeElement.treeBoxObject.ensureRowIsVisible(folderIndex);
+    this._treeElement.ensureRowIsVisible(folderIndex);
     return true;
   },
 
   /**
    * Returns the index of a folder in the current display.
    *
    * @param aFolder  the folder whose index should be returned.
    * @returns The index of the folder in the view (a number).
--- a/mail/base/content/foldersummary.js
+++ b/mail/base/content/foldersummary.js
@@ -201,26 +201,25 @@ class MozFolderTooltip extends MozFolder
     }
 
     let tooltipnode = event.target;
     let asyncResults = {};
     if (tooltipnode.parseFolder(msgFolder, null, asyncResults)) {
       return true;
     }
 
-    let row = {}, col = {};
-    gFolderTreeView._tree.getCellAt(event.clientX, event.clientY, row, col, {});
-    if (col.value.id == "folderNameCol") {
-      let cropped = gFolderTreeView._tree.isCellCropped(row.value, col.value);
+    let treeCellInfo = gFolderTreeView._tree.getCellAt(event.clientX, event.clientY);
+    if (treeCellInfo.col.id == "folderNameCol") {
+      let cropped = gFolderTreeView._tree.isCellCropped(treeCellInfo.row, treeCellInfo.col);
       if (this._addLocationInfo(msgFolder, cropped, tooltipnode)) {
         return true;
       }
     }
 
-    let counts = gFolderTreeView.getSummarizedCounts(row.value, col.value.id);
+    let counts = gFolderTreeView.getSummarizedCounts(treeCellInfo.row, treeCellInfo.col.id);
     return this._addSummarizeExplain(counts, tooltipnode);
   }
 
   /** Handle the popuphiding event. */
   folderpopupHiding(event) {
     let node = event.target;
     while (node.hasChildNodes()) {
       node.lastChild.remove();
--- a/mail/base/content/mailCommands.js
+++ b/mail/base/content/mailCommands.js
@@ -301,18 +301,17 @@ function ComposeMessage(type, format, fo
       }
   }
 }
 /* eslint-enable complexity */
 
 function NewMessageToSelectedAddresses(type, format, identity) {
   var abSidebarPanel = document.commandDispatcher.focusedWindow;
   var abResultsTree = abSidebarPanel.document.getElementById("abResultsTree");
-  var abResultsBoxObject = abResultsTree.treeBoxObject;
-  var abView = abResultsBoxObject.view;
+  var abView = abResultsTree.view;
   abView = abView.QueryInterface(Ci.nsIAbView);
   var addresses = abView.selectedAddresses;
   var params = Cc["@mozilla.org/messengercompose/composeparams;1"].createInstance(Ci.nsIMsgComposeParams);
   if (params) {
     params.type = type;
     params.format = format;
     params.identity = identity;
     var composeFields = Cc["@mozilla.org/messengercompose/composefields;1"].createInstance(Ci.nsIMsgCompFields);
--- a/mail/base/content/mailContextMenus.js
+++ b/mail/base/content/mailContextMenus.js
@@ -29,17 +29,17 @@ function RestoreSelectionWithoutContentL
     view.selection = realSelection;
     // replay any calls to adjustSelection, this handles suppression.
     transientSelection.replayAdjustSelectionLog(realSelection);
     // Avoid possible cycle leaks.
     gRightMouseButtonSavedSelection.view = null;
     gRightMouseButtonSavedSelection = null;
 
     if (tree)
-      tree.treeBoxObject.invalidate();
+      tree.invalidate();
 
     UpdateMailToolbar("RestoreSelectionWithoutContentLoad");
   }
 }
 
 /**
  * Function to clear out the global nsContextMenu, and in the case when we
  * were a threadpane context menu, restore the selection so that a right-click
@@ -61,17 +61,17 @@ function mailContextOnPopupHiding(aEvent
 function fillMailContextMenu(event) {
   // If the popupshowing was for a submenu, we don't need to do anything.
   if (event.target != event.currentTarget)
     return true;
 
   // No menu on grouped header row currently, any command would be an implied
   // multiselect.
   if (gFolderDisplay.tree) {
-    let row = gFolderDisplay.treeBox.getRowAt(event.clientX, event.clientY);
+    let row = gFolderDisplay.tree.getRowAt(event.clientX, event.clientY);
     if (gFolderDisplay.view.isGroupedByHeaderAtIndex(row)) {
       RestoreSelectionWithoutContentLoad(gFolderDisplay.tree);
       return false;
     }
   }
 
   goUpdateCommand("cmd_killThread");
   goUpdateCommand("cmd_killSubthread");
@@ -223,17 +223,17 @@ function OpenMessageByHeader(messageHead
         gDBView.selectMsgByKey(messageHeader.messageKey);
       } catch (e) {
          dump("select messagekey " + messageHeader.messageKey +
               " failed in folder " + folder.URI);
       }
     }
 
     if (tree && tree.currentIndex != -1)
-      tree.treeBoxObject.ensureRowIsVisible(tree.currentIndex);
+      tree.ensureRowIsVisible(tree.currentIndex);
   }
 }
 
 // search for message by message id in given folder and its subfolders
 // return message header if message was found
 function SearchForMessageIdInSubFolder(folder, messageId) {
   var messageHeader;
   var subFolders = folder.subFolders;
--- a/mail/base/content/mailTabs.js
+++ b/mail/base/content/mailTabs.js
@@ -353,17 +353,17 @@ var mailTabType = {
         // we only want to make it active after setting up the view and the message
         //  to avoid generating bogus summarization events.
         if (!background) {
           aTab.folderDisplay.makeActive();
           this.restoreFocus(aTab);
         } else {
           // We don't want to null out the real tree box view, as that
           // corresponds to the _current_ tab, not the new one
-          aTab.folderDisplay.hookUpFakeTreeBox(false);
+          aTab.folderDisplay.hookUpFakeTree(false);
         }
       },
       persistTab(aTab) {
         let msgHdr = aTab.folderDisplay.selectedMessage;
         return {
           messageURI: msgHdr.folder.getUriForMsg(msgHdr),
         };
       },
@@ -494,17 +494,16 @@ var mailTabType = {
     // Set the messagepane as the primary browser for content.
     document.getElementById("messagepane").setAttribute("type", "content");
     document.getElementById("messagepane").setAttribute("primary", "true");
 
     aTab.messageDisplay = aMessageDisplay;
     aTab.folderDisplay = new FolderDisplayWidget(aTab, aTab.messageDisplay);
     aTab.folderDisplay.msgWindow = msgWindow;
     aTab.folderDisplay.tree = document.getElementById("threadTree");
-    aTab.folderDisplay.treeBox = aTab.folderDisplay.tree.boxObject;
     aTab.folderDisplay.folderPaneVisible = aFolderPaneVisible;
 
     if (aIsFirstTab) {
       aTab.folderDisplay.messenger = messenger;
     } else {
       // Each tab gets its own messenger instance; this provides each tab with
       // its own undo/redo stack and back/forward navigation history.
       // If this is a foreground tab, folderDisplay.makeActive() is going to
--- a/mail/base/content/mailWidgets.xml
+++ b/mail/base/content/mailWidgets.xml
@@ -1830,20 +1830,19 @@
     <implementation>
       <field name="tree" readonly="true">
         document.getAnonymousNodes(this)[0];
       </field>
       <method name="updateHover">
         <parameter name="event"/>
         <body>
           <![CDATA[
-            var box = this.tree.treeBoxObject;
-            if (event.originalTarget == box.treeBody) {
-              var index = box.getRowAt(event.clientX, event.clientY);
-              box.view.selection.select(index);
+            if (event.originalTarget == this.tree.treeBody) {
+              var index = this.tree.getRowAt(event.clientX, event.clientY);
+              this.tree.view.selection.select(index);
               return index;
             }
             return -1;
           ]]>
         </body>
       </method>
       <method name="fire">
         <body>
@@ -1865,27 +1864,26 @@
         </body>
       </method>
       <field name="onKeyPressMenuList" readonly="true">
         <![CDATA[
           ({
             self: this,
             tree: this.tree,
             parentNode: this.parentNode,
-            getLastVisibleRow(box) {
-              var f = box.getFirstVisibleRow();
-              var p = box.getPageLength();
-              var l = box.view.rowCount;
+            getLastVisibleRow(tree) {
+              var f = tree.getFirstVisibleRow();
+              var p = tree.getPageLength();
+              var l = tree.view.rowCount;
               return (l < f + p ? l : f + p) - 1;
             },
             handleEvent(event) {
               if (event.altKey)
                 return;
               var index;
-              var box = this.tree.treeBoxObject;
               if (this.parentNode.hasAttribute("open")) {
                 event.stopPropagation();
                 event.preventDefault();
                 switch (event.keyCode) {
                   case event.DOM_VK_ESCAPE:
                     this.self.hidePopup();
                     return;
                   case event.DOM_VK_RETURN:
@@ -1904,47 +1902,47 @@
               switch (event.keyCode) {
                 case event.DOM_VK_UP:
                   if (index <= 0)
                     return;
                   index--;
                   break;
                 case event.DOM_VK_DOWN:
                   index++;
-                  if (index == box.view.rowCount)
+                  if (index == this.tree.view.rowCount)
                     return;
                   break;
                 case event.DOM_VK_PAGE_UP:
-                  if (index == box.getFirstVisibleRow())
-                    box.scrollByPages(-1);
-                  index = box.getFirstVisibleRow();
+                  if (index == this.tree.getFirstVisibleRow())
+                    this.tree.scrollByPages(-1);
+                  index = this.tree.getFirstVisibleRow();
                   break;
                 case event.DOM_VK_PAGE_DOWN:
-                  if (index == this.getLastVisibleRow(box))
-                    box.scrollByPages(1);
-                  index = this.getLastVisibleRow(box);
+                  if (index == this.getLastVisibleRow(this.tree))
+                    this.tree.scrollByPages(1);
+                  index = this.getLastVisibleRow(this.tree);
                   break;
                 case event.DOM_VK_HOME:
                   index = 0;
                   break;
                 case event.DOM_VK_END:
-                  index = box.view.rowCount - 1;
+                  index = this.tree.view.rowCount - 1;
                   break;
                 default:
                   if (event.charCode > 0 && !event.ctrlKey && !event.metaKey) {
                     event.preventDefault();
                     index = this.tree.keyNavigate(event);
                     if (index >= 0)
                       break;
                   }
                   return;
               }
-              box.view.selection.select(index);
+              this.tree.view.selection.select(index);
               if (this.parentNode.hasAttribute("open"))
-                box.ensureRowIsVisible(index);
+                this.tree.ensureRowIsVisible(index);
               else
                 this.self.fire();
             },
           })
         ]]>
       </field>
       <method name="setInitialSelection">
         <body>
@@ -1991,24 +1989,23 @@
       </destructor>
     </implementation>
     <handlers>
       <handler event="mousemove" action="this.updateHover(event);"/>
       <handler event="click" button="0" action="if (this.updateHover(event) >= 0) this.fire();"/>
       <handler event="popupshowing">
         <![CDATA[
           this.parentNode.addEventListener("blur", this.onBlurMenuList);
-          var box = this.tree.treeBoxObject;
-          box.focused = true;
+          this.tree.focused = true;
           var index = this.setInitialSelection();
-          var height = box.view.rowCount * box.rowHeight;
-          height += this.boxObject.height - box.treeBody.boxObject.height;
+          var height = this.tree.view.rowCount * this.tree.rowHeight;
+          height += this.boxObject.height - this.tree.treeBody.boxObject.height;
           this.height = height;
           if (index >= 0)
-            setTimeout(function() { box.ensureRowIsVisible(index); }, 0);
+            setTimeout(function() { this.tree.ensureRowIsVisible(index); }, 0);
         ]]>
       </handler>
       <handler event="popuphiding">
         <![CDATA[
           this.parentNode.removeEventListener("blur", this.onBlurMenuList);
         ]]>
       </handler>
     </handlers>
--- a/mail/base/content/messageWindow.js
+++ b/mail/base/content/messageWindow.js
@@ -86,28 +86,28 @@ StandaloneFolderDisplayWidget.prototype 
              [this.messageDisplay.displayedMessage] : [];
   },
 
   /**
    * We never have a real treeview, so we always want to tell the view about
    *  the fake tree box so it will actually do something in NoteChange.
    */
   onCreatedView() {
-    this._fakeTreeBox.view = this.view.dbView;
+    this._fakeTree.view = this.view.dbView;
     // Need to clear out this reference later.
     this._magicTreeSelection.view = this.view.dbView;
 
     // only if we're not dealing with a dummy message (from .eml file /
     //  attachment should we try and hook up the selection object.)  Otherwise
     //  the view will not operate in stand alone message mode.
     // XXX the sequencing here may break re-using a message window that is
     //  showing an .eml file to go to a real message, at least in terms of
     //  having the selection object properly associated with the tree.
     if (!this.messageDisplay.isDummy) {
-      this.view.dbView.setTree(this._fakeTreeBox);
+      this.view.dbView.setTree(this._fakeTree);
       this.view.dbView.selection = this._magicTreeSelection;
       // This lets the dbView know we don't really have a tree, so it can
       // avoid operating on messages in collapsed threads.
       this._magicTreeSelection.tree = null;
     }
     this.__proto__.__proto__.onCreatedView.call(this);
   },
 
--- a/mail/base/content/msgMail3PaneWindow.js
+++ b/mail/base/content/msgMail3PaneWindow.js
@@ -392,17 +392,17 @@ var MailPrefObserver = {
 
         currentDisplayNameVersion =
             Services.prefs.getIntPref("mail.displayname.version");
 
         Services.prefs.setIntPref("mail.displayname.version",
                                   ++currentDisplayNameVersion);
 
         // refresh the thread pane
-        threadTree.treeBoxObject.invalidate();
+        threadTree.invalidate();
       }
     }
   },
 };
 
 /**
  * Called on startup if there are no accounts.
  */
@@ -1070,63 +1070,58 @@ function ClearMessagePane() {
  *
  * @param aSingleSelect Should the selection we create be a single selection?
  *     This is relevant if the row being clicked on is already part of the
  *     selection.  If it is part of the selection and !aSingleSelect, then we
  *     leave the selection as is.  If it is part of the selection and
  *     aSingleSelect then we create a transient single-row selection.
  */
 function ChangeSelectionWithoutContentLoad(event, tree, aSingleSelect) {
-  var treeBoxObj = tree.treeBoxObject;
-  if (!treeBoxObj) {
-    event.stopPropagation();
-    return;
-  }
 
-  var treeSelection = treeBoxObj.view.selection;
+  var treeSelection = tree.view.selection;
 
-  var row = treeBoxObj.getRowAt(event.clientX, event.clientY);
+  var row = tree.getRowAt(event.clientX, event.clientY);
   // Only do something if:
   // - the row is valid
   // - it's not already selected (or we want a single selection)
   if (row >= 0 &&
       (aSingleSelect || !treeSelection.isSelected(row))) {
     // Check if the row is exactly the existing selection.  In that case
     //  there is no need to create a bogus selection.
     if (treeSelection.count == 1) {
       let minObj = {};
       treeSelection.getRangeAt(0, minObj, {});
       if (minObj.value == row) {
         event.stopPropagation();
         return;
       }
     }
 
-    let transientSelection = new JSTreeSelection(treeBoxObj);
+    let transientSelection = new JSTreeSelection(tree);
     transientSelection.logAdjustSelectionForReplay();
 
     gRightMouseButtonSavedSelection = {
       // Need to clear out this reference later.
-      view: treeBoxObj.view,
+      view: tree.view,
       realSelection: treeSelection,
       transientSelection,
     };
 
     var saveCurrentIndex = treeSelection.currentIndex;
 
     // tell it to log calls to adjustSelection
     // attach it to the view
-    treeBoxObj.view.selection = transientSelection;
+    tree.view.selection = transientSelection;
     // Don't generate any selection events! (we never set this to false, because
     //  that would generate an event, and we never need one of those from this
     //  selection object.
     transientSelection.selectEventsSuppressed = true;
     transientSelection.select(row);
     transientSelection.currentIndex = saveCurrentIndex;
-    treeBoxObj.ensureRowIsVisible(row);
+    tree.ensureRowIsVisible(row);
   }
   event.stopPropagation();
 }
 
 function TreeOnMouseDown(event) {
   // Detect right mouse click and change the highlight to the row
   // where the click happened without loading the message headers in
   // the Folder or Thread Pane.
@@ -1149,21 +1144,18 @@ function FolderPaneOnClick(event) {
   var folderTree = document.getElementById("folderTree");
 
   // Middle click on a folder opens the folder in a tab
   if (event.button == 1 && event.originalTarget.localName != "slider" &&
       event.originalTarget.localName != "scrollbarbutton") {
     FolderPaneContextMenuNewTab(event);
     RestoreSelectionWithoutContentLoad(folderTree);
   } else if (event.button == 0) {
-    var row = {};
-    var col = {};
-    var elt = {};
-    folderTree.treeBoxObject.getCellAt(event.clientX, event.clientY, row, col, elt);
-    if (row.value == -1) {
+    var treeCellInfo = folderTree.getCellAt(event.clientX, event.clientY);
+    if (treeCellInfo.row == -1) {
       if (event.originalTarget.localName == "treecol") {
         // clicking on the name column in the folder pane should not sort
         event.stopPropagation();
       }
     } else if ((event.originalTarget.localName == "slider") ||
              (event.originalTarget.localName == "scrollbarbutton")) {
       event.stopPropagation();
     }
--- a/mail/base/content/threadPane.js
+++ b/mail/base/content/threadPane.js
@@ -27,55 +27,52 @@ function ThreadPaneOnClick(event) {
   if (t.localName == "treecol") {
     HandleColumnClick(t.id);
     return;
   }
 
   if (t.localName != "treechildren")
     return;
 
-  let row = {};
-  let col = {};
-  let elt = {};
   let tree = GetThreadTree();
 
   // Figure out what cell the click was in.
-  tree.treeBoxObject.getCellAt(event.clientX, event.clientY, row, col, elt);
-  if (row.value == -1)
+  let treeCellInfo = tree.getCellAt(event.clientX, event.clientY);
+  if (treeCellInfo.row == -1)
    return;
 
   // Grouped By Sort dummy header row non cycler column doubleclick toggles the
   // thread's open/close state; tree.xml handles it. Cyclers are not currently
   // implemented in group header rows, a click/doubleclick there should
   // select/toggle thread state.
-  if (gFolderDisplay.view.isGroupedByHeaderAtIndex(row.value)) {
-    if (!col.value.cycler)
+  if (gFolderDisplay.view.isGroupedByHeaderAtIndex(treeCellInfo.row)) {
+    if (!treeCellInfo.col.cycler)
       return;
 
     if (event.detail == 1)
-      gFolderDisplay.selectViewIndex(row.value);
+      gFolderDisplay.selectViewIndex(treeCellInfo.row);
     if (event.detail == 2)
-      gFolderDisplay.view.dbView.toggleOpenState(row.value);
+      gFolderDisplay.view.dbView.toggleOpenState(treeCellInfo.row);
 
     event.stopPropagation();
     return;
   }
 
   // If the cell is in a cycler column or if the user doubleclicked on the
   // twisty, don't open the message in a new window.
-  if (event.detail == 2 && !col.value.cycler && elt.value != "twisty") {
+  if (event.detail == 2 && !treeCellInfo.col.cycler && treeCellInfo.childElt != "twisty") {
     ThreadPaneDoubleClick();
     // Doubleclicking should not toggle the open/close state of the thread.
     // This will happen if we don't prevent the event from bubbling to the
     // default handler in tree.xml.
     event.stopPropagation();
-  } else if (col.value.id == "junkStatusCol") {
+  } else if (treeCellInfo.col.id == "junkStatusCol") {
     MsgJunkMailInfo(true);
-  } else if (col.value.id == "threadCol" && !event.shiftKey && (event.ctrlKey || event.metaKey)) {
-    gDBView.ExpandAndSelectThreadByIndex(row.value, true);
+  } else if (treeCellInfo.col.id == "threadCol" && !event.shiftKey && (event.ctrlKey || event.metaKey)) {
+    gDBView.ExpandAndSelectThreadByIndex(treeCellInfo.row, true);
     event.stopPropagation();
   }
 }
 
 function HandleColumnClick(columnID) {
   if (gFolderDisplay.COLUMNS_MAP_NOSORT.has(columnID))
     return;
 
--- a/mail/components/addrbook/content/abCommon.js
+++ b/mail/components/addrbook/content/abCommon.js
@@ -626,17 +626,17 @@ function DirPaneClick(event) {
 }
 
 function DirPaneDoubleClick(event) {
   // We only care about left button events.
   if (event.button != 0)
     return;
 
   // Ignore double clicking on invalid rows.
-  let row = gDirTree.treeBoxObject.getRowAt(event.clientX, event.clientY);
+  let row = gDirTree.getRowAt(event.clientX, event.clientY);
   if (row == -1 || row > gDirTree.view.rowCount - 1)
     return;
 
   // Default action for double click is expand/collapse which ships with the tree.
   // For convenience, allow double-click to edit the properties of mailing
   // lists in directory tree.
   if (gDirTree && gDirTree.view.selection &&
       gDirTree.view.selection.count == 1 &&
--- a/mail/components/addrbook/content/abContactsPanel.js
+++ b/mail/components/addrbook/content/abContactsPanel.js
@@ -70,17 +70,17 @@ function contactsListOnClick(aEvent) {
   if (target.localName == "treecol" && aEvent.button == 0) {
     let sortDirection = target.getAttribute("sortDirection") == kDefaultDescending ?
                         kDefaultAscending : kDefaultDescending;
     SortAndUpdateIndicators(target.id, sortDirection);
     return;
   }
   // Any click on gAbResultsTree view (rows or blank space).
   if (target.localName == "treechildren") {
-    let row = gAbResultsTree.treeBoxObject.getRowAt(aEvent.clientX, aEvent.clientY);
+    let row = gAbResultsTree.getRowAt(aEvent.clientX, aEvent.clientY);
     if (row < 0 || row >= gAbResultsTree.view.rowCount) {
       // Any click on results tree whitespace.
       if ((aEvent.detail == 1 && aEvent.button == 0) || aEvent.button == 2) {
         // Single left click or any right click on results tree blank space:
         // Clear selection. This also triggers on the first click of any
         // double-click, but that's ok. MAC OS X doesn't return event.detail==1
         // for single right click, so we also let this trigger for the second
         // click of right double-click.
--- a/mail/components/extensions/test/browser/browser_ext_menus.js
+++ b/mail/components/extensions/test/browser/browser_ext_menus.js
@@ -1,16 +1,16 @@
 /* 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/. */
 
 let gAccount, gFolders;
 
 function treeClick(tree, row, column, event) {
-  let coords = tree.treeBoxObject.getCoordsForCellItem(row, tree.columns[column], "cell");
+  let coords = tree.getCoordsForCellItem(row, tree.columns[column], "cell");
   let treeChildren = tree.lastElementChild;
   EventUtils.synthesizeMouse(
     treeChildren,
     coords.x + (coords.width / 2),
     coords.y + (coords.height / 2),
     event,
     window
   );
--- a/mail/components/im/content/chat-messenger.js
+++ b/mail/components/im/content/chat-messenger.js
@@ -477,29 +477,29 @@ var chatHandler = {
       return true;
     }
     // Find the aShouldSelect log and select it.
     let logTime = aShouldSelect.time;
     for (let index = 0; index < treeView._rowMap.length; ++index) {
       if (!treeView.isContainer(index) &&
           treeView._rowMap[index].log.time == logTime) {
         logTree.view.selection.select(index);
-        logTree.treeBoxObject.ensureRowIsVisible(index);
+        logTree.ensureRowIsVisible(index);
         return true;
       }
       if (!treeView._rowMap[index].children.some(i => i.log.time == logTime))
         continue;
       treeView.toggleOpenState(index);
       ++index;
       while (index < treeView._rowMap.length &&
              treeView._rowMap[index].log.time != logTime)
         ++index;
       if (treeView._rowMap[index].log.time == logTime) {
         logTree.view.selection.select(index);
-        logTree.treeBoxObject.ensureRowIsVisible(index);
+        logTree.ensureRowIsVisible(index);
       }
       return true;
     }
     throw "Couldn't find the log to select among the set of logs passed.";
   },
 
   onLogSelect() {
     let selection = this._treeView.selection;
--- a/mail/components/preferences/cookies.js
+++ b/mail/components/preferences/cookies.js
@@ -32,17 +32,17 @@ var gCookiesWindow = {
 
   uninit() {
     Services.obs.removeObserver(this, "cookie-changed");
     Services.obs.removeObserver(this, "perm-changed");
   },
 
   _populateList(aInitialLoad) {
     this._loadCookies();
-    this._tree.treeBoxObject.view = this._view;
+    this._tree.view = this._view;
     if (aInitialLoad)
       this.sort("rawHost");
     if (this._view.rowCount > 0)
       this._tree.view.selection.select(0);
 
     if (aInitialLoad) {
       if (("arguments" in window) && window.arguments[2] &&
           window.arguments[2].filterString) {
@@ -74,17 +74,17 @@ var gCookiesWindow = {
       else if (aData == "added")
         this._handleCookieAdded(aCookie, strippedHost);
     } else if (aData == "cleared") {
       this._hosts = {};
       this._hostOrder = [];
 
       var oldRowCount = this._view._rowCount;
       this._view._rowCount = 0;
-      this._tree.treeBoxObject.rowCountChanged(0, -oldRowCount);
+      this._tree.rowCountChanged(0, -oldRowCount);
       this._view.selection.clearSelection();
     } else if (aData == "reload") {
       // first, clear any existing entries
       this.observe(aCookie, aTopic, "cleared");
 
       // then, reload the list
       this._populateList(false);
     }
@@ -132,17 +132,17 @@ var gCookiesWindow = {
           currCookie.expires  = changedCookie.expires;
           cookieItem = currCookie;
           break;
         }
       }
     }
 
     // Make sure the tree display is up to date...
-    this._tree.treeBoxObject.invalidateRow(rowIndex);
+    this._tree.invalidateRow(rowIndex);
     // ... and if the cookie is selected, update the displayed metadata too
     if (cookieItem != null && this._view.selection.currentIndex == rowIndex)
       this._updateCookieData(cookieItem);
   },
 
   _handleCookieAdded(changedCookie, strippedHost) {
     var rowCountImpact = 0;
     var addedHost = { value: 0 };
@@ -161,17 +161,17 @@ var gCookiesWindow = {
         this._view._filterSet.push(this._makeCookieObject(strippedHost, changedCookie));
         ++rowCountImpact;
       }
     }
     // Now update the tree display at the end (we could/should re run the sort
     // if any to get the position correct.)
     var oldRowCount = this._rowCount;
     this._view._rowCount += rowCountImpact;
-    this._tree.treeBoxObject.rowCountChanged(oldRowCount - 1, rowCountImpact);
+    this._tree.rowCountChanged(oldRowCount - 1, rowCountImpact);
 
     document.getElementById("removeAllCookies").disabled = this._view._filtered;
   },
 
   _view: {
     _filtered: false,
     _filterSet: [],
     _filterValue: "",
@@ -398,18 +398,18 @@ var gCookiesWindow = {
       if (!this._filtered) {
         var item = this._getItemAtIndex(aIndex);
         if (!item) return;
         this._invalidateCache(aIndex);
         var multiplier = item.open ? -1 : 1;
         var delta = multiplier * item.cookies.length;
         this._rowCount += delta;
         item.open = !item.open;
-        gCookiesWindow._tree.treeBoxObject.rowCountChanged(aIndex + 1, delta);
-        gCookiesWindow._tree.treeBoxObject.invalidateRow(aIndex);
+        gCookiesWindow._tree.rowCountChanged(aIndex + 1, delta);
+        gCookiesWindow._tree.invalidateRow(aIndex);
       }
     },
     cycleHeader(aColumn) {},
     selectionChanged() {},
     cycleCell(aIndex, aColumn) {},
     isEditable(aIndex, aColumn) {
       return false;
     },
@@ -603,17 +603,17 @@ var gCookiesWindow = {
     //    v goats.com
     //    //// goats.com /////////// flksjl33 ////
     //         goats.com             sldkkfjl
     //    > atwola.com
     //
     //    Before SelectedIndex: 1   Before RowCount: 4
     //    After  SelectedIndex: 1   After  RowCount: 3
     var seln = this._view.selection;
-    var tbo = this._tree.treeBoxObject;
+    var tbo = this._tree;
 
     if (seln.count < 1) return;
 
     var nextSelected = 0;
     var rowCountImpact = 0;
     var deleteItems = [];
     if (!this._view._filtered) {
       var ci = seln.currentIndex;
@@ -725,36 +725,36 @@ var gCookiesWindow = {
       this._view._filterSet.sort(sortByProperty);
       if (!ascending)
         this._view._filterSet.reverse();
     }
 
     this._view._invalidateCache(0);
     this._view.selection.clearSelection();
     this._view.selection.select(0);
-    this._tree.treeBoxObject.invalidate();
-    this._tree.treeBoxObject.ensureRowIsVisible(0);
+    this._tree.invalidate();
+    this._tree.ensureRowIsVisible(0);
 
     this._lastSortAscending = ascending;
     this._lastSortProperty = aProperty;
   },
 
   clearFilter() {
     // Revert to single-select in the tree
     this._tree.setAttribute("seltype", "single");
 
     // Clear the Tree Display
     this._view._filtered = false;
     this._view._rowCount = 0;
-    this._tree.treeBoxObject.rowCountChanged(0, -this._view._filterSet.length);
+    this._tree.rowCountChanged(0, -this._view._filterSet.length);
     this._view._filterSet = [];
 
     // Just reload the list to make sure deletions are respected
     this._loadCookies();
-    this._tree.treeBoxObject.view = this._view;
+    this._tree.view = this._view;
 
     // Restore sort order
     var sortby = this._lastSortProperty;
     if (sortby == "") {
       this._lastSortAscending = false;
       this.sort("rawHost");
     } else {
       this._lastSortAscending = !this._lastSortAscending;
@@ -835,20 +835,20 @@ var gCookiesWindow = {
       view._filtered = true;
     }
     // Move to multi-select in the tree
     gCookiesWindow._tree.setAttribute("seltype", "multiple");
 
     // Clear the display
     var oldCount = view._rowCount;
     view._rowCount = 0;
-    gCookiesWindow._tree.treeBoxObject.rowCountChanged(0, -oldCount);
+    gCookiesWindow._tree.rowCountChanged(0, -oldCount);
     // Set up the filtered display
     view._rowCount = view._filterSet.length;
-    gCookiesWindow._tree.treeBoxObject.rowCountChanged(0, view.rowCount);
+    gCookiesWindow._tree.rowCountChanged(0, view.rowCount);
 
     // if the view is not empty then select the first item
     if (view.rowCount > 0)
       view.selection.select(0);
 
     document.getElementById("cookiesIntro").value = gCookiesWindow._bundle.getString("cookiesFiltered");
   },
 
--- a/mail/components/preferences/permissions.js
+++ b/mail/components/preferences/permissions.js
@@ -170,23 +170,23 @@ var gPermissionManager = {
 
   _handleCapabilityChange() {
     // Re-do the sort, if the status changed from Block to Allow
     // or vice versa, since if we're sorted on status, we may no
     // longer be in order.
     if (this._lastPermissionSortColumn == "statusCol") {
       this._resortPermissions();
     }
-    this._tree.treeBoxObject.invalidate();
+    this._tree.invalidate();
   },
 
   _addPermission(aPermission) {
     this._addPermissionToList(aPermission);
     ++this._view._rowCount;
-    this._tree.treeBoxObject.rowCountChanged(this._view.rowCount - 1, 1);
+    this._tree.rowCountChanged(this._view.rowCount - 1, 1);
     // Re-do the sort, since we inserted this new item at the end.
     this._resortPermissions();
   },
 
   _resortPermissions() {
     gTreeUtils.sort(this._tree, this._view, this._permissions,
                     this._lastPermissionSortColumn,
                     this._permissionsComparator,
@@ -413,18 +413,18 @@ var gPermissionManager = {
   },
 
   _removePermissionFromList(aPrincipal) {
     for (let i = 0; i < this._permissions.length; ++i) {
       // Thunderbird compares origins, not principals here.
       if (this._permissions[i].principal.origin == aPrincipal.origin) {
         this._permissions.splice(i, 1);
         this._view._rowCount--;
-        this._tree.treeBoxObject.rowCountChanged(this._view.rowCount - 1, -1);
-        this._tree.treeBoxObject.invalidate();
+        this._tree.rowCountChanged(this._view.rowCount - 1, -1);
+        this._tree.invalidate();
         break;
       }
     }
   },
 
   setOrigin(aOrigin) {
     document.getElementById("url").value = aOrigin;
   },
--- a/mail/test/mozmill/folder-display/test-right-click-middle-click-messages.js
+++ b/mail/test/mozmill/folder-display/test-right-click-middle-click-messages.js
@@ -315,22 +315,22 @@ function _middle_click_on_existing_multi
  */
 function _middle_click_on_collapsed_thread_root_helper(aBackground) {
   be_in_folder(threadedFolder);
   make_display_threaded();
   collapse_all_threads();
 
   let folderTab = mc.tabmail.currentTabInfo;
 
-  let treeBox = mc.threadTree.treeBoxObject;
+  let tree = mc.threadTree;
   // Scroll to the top, then to the bottom
-  treeBox.ensureRowIsVisible(0);
-  treeBox.scrollByLines(mc.folderDisplay.view.dbView.rowCount);
+  tree.ensureRowIsVisible(0);
+  tree.scrollByLines(mc.folderDisplay.view.dbView.rowCount);
   // Note the first visible row
-  let preFirstRow = treeBox.getFirstVisibleRow();
+  let preFirstRow = tree.getFirstVisibleRow();
 
   // Since reflowing a tree (eg when switching tabs) ensures that the current
   // index is brought into view, we need to set the current index so that we
   // don't scroll because of it. So click on the first visible row.
   select_click_row(preFirstRow);
 
   // Middle-click on the root of the collapsed thread, which is also the last
   // row
@@ -339,41 +339,41 @@ function _middle_click_on_collapsed_thre
 
   if (!aBackground) {
     wait_for_message_display_completion();
     // Switch back to the folder tab
     switch_tab(folderTab);
   }
 
   // Make sure the first visible row is still the same
-  if (treeBox.getFirstVisibleRow() != preFirstRow)
+  if (tree.getFirstVisibleRow() != preFirstRow)
     throw new Error("The first visible row should have been " + preFirstRow +
-        ", but is actually " + treeBox.getFirstVisibleRow() + ".");
+        ", but is actually " + tree.getFirstVisibleRow() + ".");
 
   close_tab(tabMessage);
 }
 
 /**
  * Middle-click on the root of an expanded thread, making sure that we don't
  * jump around in the thread tree.
  */
 function _middle_click_on_expanded_thread_root_helper(aBackground) {
   be_in_folder(threadedFolder);
   make_display_threaded();
   expand_all_threads();
 
   let folderTab = mc.tabmail.currentTabInfo;
 
-  let treeBox = mc.threadTree.treeBoxObject;
+  let tree = mc.threadTree;
   // Scroll to the top, then to near (but not exactly) the bottom
-  treeBox.ensureRowIsVisible(0);
-  treeBox.scrollToRow(mc.folderDisplay.view.dbView.rowCount -
-      treeBox.getPageLength() - (NUM_MESSAGES_IN_THREAD / 2));
+  tree.ensureRowIsVisible(0);
+  tree.scrollToRow(mc.folderDisplay.view.dbView.rowCount -
+      tree.getPageLength() - (NUM_MESSAGES_IN_THREAD / 2));
   // Note the first visible row
-  let preFirstRow = treeBox.getFirstVisibleRow();
+  let preFirstRow = tree.getFirstVisibleRow();
 
   // Since reflowing a tree (eg when switching tabs) ensures that the current
   // index is brought into view, we need to set the current index so that we
   // don't scroll because of it. So click on the first visible row.
   select_click_row(preFirstRow);
 
   // Middle-click on the root of the expanded thread, which is the row with
   // index (number of rows - number of messages in thread).
@@ -382,19 +382,19 @@ function _middle_click_on_expanded_threa
 
   if (!aBackground) {
     wait_for_message_display_completion();
     // Switch back to the folder tab
     switch_tab(folderTab);
   }
 
   // Make sure the first visible row is still the same
-  if (treeBox.getFirstVisibleRow() != preFirstRow)
+  if (tree.getFirstVisibleRow() != preFirstRow)
     throw new Error("The first visible row should have been " + preFirstRow +
-        ", but is actually " + treeBox.getFirstVisibleRow() + ".");
+        ", but is actually " + tree.getFirstVisibleRow() + ".");
 
   close_tab(tabMessage);
 }
 
 /**
  * Generate background and foreground tests for each middle click test.
  *
  * @param aTests an array of test names
--- a/mail/test/mozmill/shared-modules/test-folder-display-helpers.js
+++ b/mail/test/mozmill/shared-modules/test-folder-display-helpers.js
@@ -956,21 +956,21 @@ function _normalize_view_index(aViewInde
  * @param aController  Controller object
  */
 function click_tree_row(aTree, aRowIndex, aController) {
   if (aRowIndex < 0 || aRowIndex >= aTree.view.rowCount)
     throw new Error("Row " + aRowIndex + " does not exist in the tree " + aTree.id + "!");
 
   let selection = aTree.view.selection;
   selection.select(aRowIndex);
-  aTree.treeBoxObject.ensureRowIsVisible(aRowIndex);
+  aTree.ensureRowIsVisible(aRowIndex);
 
   // get cell coordinates
   let column = aTree.columns[0];
-  let coords = aTree.treeBoxObject.getCoordsForCellItem(aRowIndex, column, "text");
+  let coords = aTree.getCoordsForCellItem(aRowIndex, column, "text");
 
   aController.sleep(0);
   EventUtils.synthesizeMouse(aTree.body, coords.x + 4, coords.y + 4,
                              {}, aTree.ownerDocument.defaultView);
   aController.sleep(0);
 }
 
 /**
@@ -1093,19 +1093,18 @@ function select_shift_click_row(aViewInd
 }
 
 /**
  * Helper function to click on a row with a given button.
  */
 function _row_click_helper(aController, aTree, aViewIndex, aButton, aExtra) {
   // Force-focus the tree
   aTree.focus();
-  let treeBox = aTree.treeBoxObject;
   // very important, gotta be able to see the row
-  treeBox.ensureRowIsVisible(aViewIndex);
+  aTree.ensureRowIsVisible(aViewIndex);
   // coordinates of the upper left of the entire tree widget (headers included)
   let tx = aTree.boxObject.x, ty = aTree.boxObject.y;
   // coordinates of the row display region of the tree (below the headers)
   let children = aController.e(aTree.id, {tagName: "treechildren"});
   let x = children.boxObject.x, y = children.boxObject.y;
   // Click in the middle of the row by default
   let rowX = children.boxObject.width / 2;
   // For the thread tree, Position our click on the subject column (which cannot
@@ -1113,22 +1112,22 @@ function _row_click_helper(aController, 
   // expand toggler unless that is explicitly requested.
   if (aTree.id == "threadTree") {
     let subjectCol = aController.e("subjectCol");
     rowX = subjectCol.boxObject.x - tx + 8;
     // click on the toggle if so requested
     if (aExtra !== "toggle")
       rowX += 32;
   }
-  let rowY = treeBox.rowHeight * (aViewIndex - treeBox.getFirstVisibleRow()) +
-    treeBox.rowHeight / 2;
-  if (treeBox.getRowAt(x + rowX, y + rowY) != aViewIndex) {
+  let rowY = aTree.rowHeight * (aViewIndex - aTree.getFirstVisibleRow()) +
+    aTree.rowHeight / 2;
+  if (aTree.getRowAt(x + rowX, y + rowY) != aViewIndex) {
     throw new Error("Thought we would find row " + aViewIndex + " at " +
                     rowX + "," + rowY + " but we found " +
-                    treeBox.getRowAt(rowX, rowY));
+                    aTree.getRowAt(rowX, rowY));
   }
   // Generate a mouse-down for all click types; the transient selection
   // logic happens on mousedown which our tests assume is happening.  (If you
   // are using a keybinding to trigger the event, that will not happen, but
   // we don't test that.)
   EventUtils.synthesizeMouse(aTree, x + rowX - tx, y + rowY - ty,
                              {type: "mousedown", button: aButton,
                               shiftKey: aExtra === "shift",
@@ -1184,20 +1183,20 @@ function middle_click_on_row(aViewIndex)
   return [mc.tabmail.tabInfo[mc.tabmail.tabContainer.childNodes.length - 1],
           msgHdr];
 }
 
 /**
  * Assert that the given row index is currently visible in the thread pane view.
  */
 function assert_row_visible(aViewIndex) {
-  let treeBox = mc.threadTree.treeBoxObject;
+  let tree = mc.threadTree;
 
-  if (treeBox.getFirstVisibleRow() > aViewIndex ||
-      treeBox.getLastVisibleRow() < aViewIndex)
+  if (tree.getFirstVisibleRow() > aViewIndex ||
+      tree.getLastVisibleRow() < aViewIndex)
     throw new Error("Row " + aViewIndex + " should currently be visible in " +
                     "the thread pane, but isn't.");
 }
 
 /**
  * Assert that the given folder mode is the current one.
  *
  * @param aMode The expected folder mode.
@@ -2222,22 +2221,22 @@ var assert_nothing_selected = assert_sel
  * Assert that the given view index or message is visible in the thread pane.
  */
 function assert_visible(aViewIndexOrMessage) {
   let viewIndex;
   if (typeof(aViewIndexOrMessage) == "number")
     viewIndex = _normalize_view_index(aViewIndexOrMessage);
   else
     viewIndex = mc.dbView.findIndexOfMsgHdr(aViewIndexOrMessage, false);
-  let treeBox = mc.threadTree.boxObject;
-  if (viewIndex < treeBox.getFirstVisibleRow() ||
-      viewIndex > treeBox.getLastVisibleRow())
+  let tree = mc.threadTree;
+  if (viewIndex < tree.getFirstVisibleRow() ||
+      viewIndex > tree.getLastVisibleRow())
     throw new Error("View index " + viewIndex + " is not visible! (" +
-                    treeBox.getFirstVisibleRow() + "-" +
-                    treeBox.getLastVisibleRow() + " are visible)");
+                    tree.getFirstVisibleRow() + "-" +
+                    tree.getLastVisibleRow() + " are visible)");
 }
 
 /**
  * Assert that the given message is now shown in the current view.
  */
 function assert_not_shown(aMessages) {
   aMessages.forEach(function(msg) {
     let viewIndex = mc.dbView.findIndexOfMsgHdr(msg, false);
--- a/mailnews/addrbook/content/abResultsPane.js
+++ b/mailnews/addrbook/content/abResultsPane.js
@@ -71,17 +71,17 @@ function SetAbView(aURI)
 
   if (!gAbView)
     gAbView = Cc["@mozilla.org/addressbook/abview;1"]
                 .createInstance(Ci.nsIAbView);
 
   var actualSortColumn = gAbView.setView(directory, GetAbViewListener(),
                                          sortColumn, sortDirection);
 
-  gAbResultsTree.treeBoxObject.view =
+  gAbResultsTree.view =
     gAbView.QueryInterface(Ci.nsITreeView);
 
   UpdateSortIndicators(actualSortColumn, sortDirection);
 
   // If the selected address book is LDAP and the search box is empty,
   // inform the user of the empty results pane.
   let abResultsTree = document.getElementById("abResultsTree");
   let cardViewOuterBox = document.getElementById("CardViewOuterBox");
@@ -284,18 +284,17 @@ function AbResultsPaneOnClick(event)
     // Revert the sort order. If none is set, use Ascending.
     sortDirection = currentDirection == kDefaultAscending ?
                                         kDefaultDescending : kDefaultAscending;
 
     SortAndUpdateIndicators(t.id, sortDirection);
   }
   else if (t.localName == "treechildren") {
     // figure out what row the click was in
-    var row = gAbResultsTree.treeBoxObject.getRowAt(event.clientX,
-                                                    event.clientY);
+    var row = gAbResultsTree.getRowAt(event.clientX, event.clientY);
     if (row == -1)
       return;
 
     if (event.detail == 2)
       AbResultsPaneDoubleClick(gAbView.getCardFromRow(row));
   }
 }
 
@@ -349,17 +348,17 @@ function UpdateSortIndicators(colID, sor
       currCol.removeAttribute("sortDirection");
     currCol = currCol.nextSibling;
   }
 }
 
 function InvalidateResultsPane()
 {
   if (gAbResultsTree)
-    gAbResultsTree.treeBoxObject.invalidate();
+    gAbResultsTree.invalidate();
 }
 
 // Controller object for Results Pane
 var ResultsPaneController =
 {
   supportsCommand: function(command)
   {
     switch (command) {
--- a/mailnews/base/content/msgSelectOfflineFolders.js
+++ b/mailnews/base/content/msgSelectOfflineFolders.js
@@ -63,25 +63,22 @@ var gSelectOffline = {
     }
   },
 
   onClick: function(aEvent) {
     // We only care about button 0 (left click) events.
     if (aEvent.button != 0)
       return;
 
-    let row = {};
-    let col = {};
-    this._treeElement.treeBoxObject
-        .getCellAt(aEvent.clientX, aEvent.clientY, row, col, {});
+    let treeCellInfo = this._treeElement.getCellAt(aEvent.clientX);
 
-    if (row.value == -1 || col.value.id != "syncCol")
+    if (treeCellInfo.row == -1 || treeCellInfo.col.id != "syncCol")
       return;
 
-    this._toggle(row.value);
+    this._toggle(treeCellInfo.row);
   },
 
   _toggle: function(aRow) {
     let folder = gFolderTreeView._rowMap[aRow]._folder;
 
     if (folder.isServer)
       return;
 
--- a/mailnews/base/content/msgSynchronize.js
+++ b/mailnews/base/content/msgSynchronize.js
@@ -123,29 +123,25 @@ function FindInWindow(currentWindow, id)
 
 
 function onSynchronizeClick(event)
 {
     // we only care about button 0 (left click) events
     if (event.button != 0)
       return;
 
-    var row = {}
-    var col = {}
-    var elt = {}
-
-    gSynchronizeTree.treeBoxObject.getCellAt(event.clientX, event.clientY, row, col, elt);
-    if (row.value == -1)
+    let treeCellInfo = gSynchronizeTree.getCellAt(event.clientX, event.clientY);
+    if (treeCellInfo.row == -1)
       return;
 
-    if (elt.value == "twisty") {
-        var folderResource = GetFolderResource(gSynchronizeTree, row.value);
+    if (treeCellInfo.childElt == "twisty") {
+        var folderResource = GetFolderResource(gSynchronizeTree, treeCellInfo.row);
         var folder = folderResource.QueryInterface(Ci.nsIMsgFolder);
 
-        if (!(gSynchronizeTree.treeBoxObject.view.isContainerOpen(row.value))) {
+        if (!(gSynchronizeTree.view.isContainerOpen(treeCellInfo.row))) {
             var serverType = folder.server.type;
             // imap is the only server type that does folder discovery
             if (serverType != "imap") return;
 
             if (folder.isServer) {
                 var server = folder.server;
                 server.performExpand(gMsgWindow);
             }
@@ -153,18 +149,18 @@ function onSynchronizeClick(event)
                 var imapFolder = folderResource.QueryInterface(Ci.nsIMsgImapMailFolder);
                 if (imapFolder) {
                   imapFolder.performExpand(gMsgWindow);
                 }
             }
         }
     }
     else {
-      if (col.value.id == "syncCol") {
-        UpdateNode(GetFolderResource(gSynchronizeTree, row.value), row.value);
+      if (treeCellInfo.col.id == "syncCol") {
+        UpdateNode(GetFolderResource(gSynchronizeTree, treeCellInfo.row), treeCellInfo.row);
       }
     }
 }
 
 function onSynchronizeTreeKeyPress(event)
 {
     // for now, only do something on space key
     if (event.charCode != KeyEvent.DOM_VK_SPACE)
--- a/mailnews/base/content/subscribe.js
+++ b/mailnews/base/content/subscribe.js
@@ -2,27 +2,26 @@
  * 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/. */
 
 ChromeUtils.import("resource:///modules/MailUtils.jsm");
 ChromeUtils.import("resource:///modules/iteratorUtils.jsm");
 
 var gSubscribeTree = null;
 var gSubscribeBody = null;
-var gSearchTree;
 var okCallback = null;
 var gChangeTable = {};
 var gServerURI = null;
 var gSubscribableServer = null;
 var gNameField = null;
 var gNameFieldLabel = null;
 var gStatusFeedback;
 var gSubscribeDeck = null;
 var gSearchView = null;
-var gSearchTreeBoxObject = null;
+var gSearchTree = null;
 var gSubscribeBundle;
 
 function Stop()
 {
   if (gSubscribableServer) {
     gSubscribableServer.stopPopulating(msgWindow);
   }
 }
@@ -143,17 +142,17 @@ function EnableSearchUI()
 
 function SubscribeOnLoad()
 {
   gSubscribeBundle = document.getElementById("bundle_subscribe");
 
   gSubscribeTree = document.getElementById("subscribeTree");
   gSubscribeBody = document.getElementById("subscribeTreeBody");
   gSearchTree = document.getElementById("searchTree");
-  gSearchTreeBoxObject = document.getElementById("searchTree").treeBoxObject;
+  gSearchTree = document.getElementById("searchTree");
   gNameField = document.getElementById("namefield");
   gNameFieldLabel = document.getElementById("namefieldlabel");
 
   gSubscribeDeck = document.getElementById("subscribedeck");
 
   msgWindow = Cc["@mozilla.org/messenger/msgwindow;1"]
                 .createInstance(Ci.nsIMsgWindow);
   msgWindow.domWindow = window;
@@ -265,35 +264,34 @@ function InSearchMode()
   return (gSubscribeDeck.getAttribute("selectedIndex") == "1");
 }
 
 function SearchOnClick(event)
 {
   // we only care about button 0 (left click) events
   if (event.button != 0 || event.originalTarget.localName != "treechildren") return;
 
-  var row = {}, col = {}, childElt = {};
-  gSearchTreeBoxObject.getCellAt(event.clientX, event.clientY, row, col, childElt);
-  if (row.value == -1 || row.value > gSearchView.rowCount-1)
+  let treeCellInfo = gSearchTree.getCellAt(event.clientX, event.clientY);
+  if (treeCellInfo.row == -1 || treeCellInfo.row > gSearchView.rowCount-1)
     return;
 
-  if (col.value.id == "subscribedColumn2") {
+  if (treeCellInfo.col.id == "subscribedColumn2") {
     if (event.detail != 2) {
       // single clicked on the check box
       // (in the "subscribedColumn2" column) reverse state
       // if double click, do nothing
-      ReverseStateFromRow(row.value);
+      ReverseStateFromRow(treeCellInfo.row);
     }
   } else if (event.detail == 2) {
     // double clicked on a row, reverse state
-    ReverseStateFromRow(row.value);
+    ReverseStateFromRow(treeCellInfo.row);
   }
 
   // invalidate the row
-  InvalidateSearchTreeRow(row.value);
+  InvalidateSearchTreeRow(treeCellInfo.row);
 }
 
 function ReverseStateFromRow(aRow)
 {
   // To determine if the row is subscribed or not,
   // we get the properties for the "subscribedColumn2" cell in the row
   // and look for the "subscribed" property.
   // If the "subscribed" string is in the list of properties
@@ -351,34 +349,33 @@ function ReverseStateFromNode(row)
 }
 
 function SubscribeOnClick(event)
 {
   // we only care about button 0 (left click) events
   if (event.button != 0 || event.originalTarget.localName != "treechildren")
    return;
 
-  var row = {}, col = {}, obj = {};
-  gSubscribeTree.treeBoxObject.getCellAt(event.clientX, event.clientY, row, col, obj);
-  if (row.value == -1 || row.value > (gSubscribeTree.view.rowCount - 1))
+  let treeCellInfo = gSubscribeTree.getCellAt(event.clientX, event.clientY);
+  if (treeCellInfo.row == -1 || treeCellInfo.row > (gSubscribeTree.view.rowCount - 1))
     return;
 
   if (event.detail == 2) {
     // only toggle subscribed state when double clicking something
     // that isn't a container
-    if (!gSubscribeTree.view.isContainer(row.value)) {
-      ReverseStateFromNode(row.value);
+    if (!gSubscribeTree.view.isContainer(treeCellInfo.row)) {
+      ReverseStateFromNode(treeCellInfo.row);
       return;
     }
   }
   else if (event.detail == 1)
   {
     // if the user single clicks on the subscribe check box, we handle it here
     if (col.value.id == "subscribedColumn")
-      ReverseStateFromNode(row.value);
+      ReverseStateFromNode(treeCellInfo.row);
   }
 }
 
 function Refresh()
 {
   // clear out the textfield's entry
   gNameField.value = "";
 
@@ -407,22 +404,22 @@ function ShowNewGroupsList()
   document.getElementById("subscribeTabs").selectedIndex = 1;
 
   // force it to talk to the server and get new groups
   SetUpTree(true, true);
 }
 
 function InvalidateSearchTreeRow(row)
 {
-    gSearchTreeBoxObject.invalidateRow(row);
+    gSearchTree.invalidateRow(row);
 }
 
 function InvalidateSearchTree()
 {
-    gSearchTreeBoxObject.invalidate();
+    gSearchTree.invalidate();
 }
 
 function SwitchToNormalView()
 {
   // the first card in the deck is the "normal" view
   gSubscribeDeck.setAttribute("selectedIndex","0");
 }
 
@@ -437,17 +434,17 @@ function Search()
   var searchValue = gNameField.value;
   if (searchValue.length && gSubscribableServer.supportsSubscribeSearch) {
     SwitchToSearchView();
     gSubscribableServer.setSearchValue(searchValue);
 
     if (!gSearchView && gSubscribableServer) {
     gSearchView = gSubscribableServer.QueryInterface(Ci.nsITreeView);
       gSearchView.selection = null;
-    gSearchTreeBoxObject.view = gSearchView;
+    gSearchTree.view = gSearchView;
   }
   }
   else {
     SwitchToNormalView();
   }
 }
 
 function CleanUpSearchView()
--- a/mailnews/base/content/virtualFolderListEdit.js
+++ b/mailnews/base/content/virtualFolderListEdit.js
@@ -68,24 +68,21 @@ var gSelectVirtual = {
     }
   },
 
   onClick: function(aEvent) {
     // We only care about button 0 (left click) events.
     if (aEvent.button != 0)
       return;
 
-    let row = {};
-    let col = {};
-    this._treeElement.treeBoxObject
-                     .getCellAt(aEvent.clientX, aEvent.clientY, row, col, {});
-    if (row.value == -1 || col.value.id != "selectedCol")
+    let treeCellInfo = this._treeElement.getCellAt(aEvent.clientX, aEvent.clientY);
+    if (treeCellInfo.row == -1 || treeCellInfo.col.id != "selectedCol")
       return;
 
-    this._toggle(row.value);
+    this._toggle(treeCellInfo.row);
   },
 
   _toggle: function(aRow) {
     let folder = gFolderTreeView._rowMap[aRow]._folder;
     if (this._selectedList.has(folder))
       this._selectedList.delete(folder);
     else
       this._selectedList.add(folder);
--- a/mailnews/base/prefs/content/AccountManager.js
+++ b/mailnews/base/prefs/content/AccountManager.js
@@ -192,23 +192,23 @@ function selectServer(server, selectPage
       // ... or one of its children.
       pageToSelect = accountNode.querySelector('[PageTag="' + selectPageId + '"]');
     }
   }
 
   let accountTree = document.getElementById("accounttree");
   let index = accountTree.view.getIndexOfItem(pageToSelect);
   accountTree.view.selection.select(index);
-  accountTree.treeBoxObject.ensureRowIsVisible(index);
+  accountTree.ensureRowIsVisible(index);
 
   let lastItem = accountNode.lastChild.lastChild;
   if (lastItem.localName == "treeitem")
     index = accountTree.view.getIndexOfItem(lastItem);
 
-  accountTree.treeBoxObject.ensureRowIsVisible(index);
+  accountTree.ensureRowIsVisible(index);
 }
 
 function replaceWithDefaultSmtpServer(deletedSmtpServerKey)
 {
   // First we replace the smtpserverkey in every identity.
   let am = MailServices.accounts;
   for (let identity of fixIterator(am.allIdentities,
                                    Ci.nsIMsgIdentity)) {
--- a/mailnews/base/util/jsTreeSelection.js
+++ b/mailnews/base/util/jsTreeSelection.js
@@ -32,31 +32,31 @@ ChromeUtils.import("resource://gre/modul
  *  documentation tool will copy-down that documentation.
  *
  * This implementation attempts to mimic the behavior of nsTreeSelection.  In
  *  a few cases, this leads to potentially confusing actions.  I attempt to note
  *  when we are doing this and why we do it.
  *
  * Unit test is in mailnews/base/util/test_jsTreeSelection.js
  */
-function JSTreeSelection(aTreeBoxObject) {
-  this._treeBoxObject = aTreeBoxObject;
+function JSTreeSelection(aTree) {
+  this._tree = aTree;
 
   this._currentIndex = null;
   this._shiftSelectPivot = null;
   this._ranges = [];
   this._count = 0;
 
   this._selectEventsSuppressed = false;
 }
 JSTreeSelection.prototype = {
   /**
-   * The current nsITreeBoxObject, appropriately QueryInterfaced.  May be null.
+   * The current XULTreeElement, appropriately QueryInterfaced. May be null.
    */
-  _treeBoxObject: null,
+  _tree: null,
 
   /**
    * Where the focus rectangle (that little dotted thing) shows up.  Just
    *  because something is focused does not mean it is actually selected.
    */
   _currentIndex: null,
   /**
    * The view index where the shift is anchored when it is not (conceptually)
@@ -78,20 +78,20 @@ JSTreeSelection.prototype = {
    */
   _count: 0,
 
   // In the case of the stand-alone message window, there's no tree, but
   // there's a view.
   _view: null,
 
   get tree() {
-    return this._treeBoxObject;
+    return this._tree;
   },
-  set tree(aTreeBoxObject) {
-    this._treeBoxObject = aTreeBoxObject;
+  set tree(aTree) {
+    this._tree = aTree;
   },
 
   set view(aView) {
     this._view = aView;
   },
   /**
    * Although the nsITreeSelection documentation doesn't say, what this method
    *  is supposed to do is check if the seltype attribute on the XUL tree is any
@@ -133,18 +133,18 @@ JSTreeSelection.prototype = {
     this.currentIndex = aViewIndex;
 
     if (this._count == 1 && this._ranges[0][0] == aViewIndex)
       return;
 
     this._count = 1;
     this._ranges = [[aViewIndex, aViewIndex]];
 
-    if (this._treeBoxObject)
-      this._treeBoxObject.invalidate();
+    if (this._tree)
+      this._tree.invalidate();
 
     this._fireSelectionChanged();
   },
 
   timedSelect: function JSTreeSelection_timedSelect(aIndex, aDelay) {
     throw new Error("We do not implement timed selection.");
   },
 
@@ -201,18 +201,18 @@ JSTreeSelection.prototype = {
         }
         // nope, no merge required, just update the range
         this._ranges[iTupe][1] = aIndex;
         break;
       }
       // otherwise we need to keep going
     }
 
-    if (this._treeBoxObject)
-      this._treeBoxObject.invalidateRow(aIndex);
+    if (this._tree)
+      this._tree.invalidateRow(aIndex);
     this._fireSelectionChanged();
   },
 
   /**
    * @param aRangeStart If omitted, it implies a shift-selection is happening,
    *     in which case we use _shiftSelectPivot as the start if we have it,
    *     _currentIndex if we don't, and if we somehow didn't have a
    *     _currentIndex, we use the range end.
@@ -237,18 +237,18 @@ JSTreeSelection.prototype = {
     // enforce our ordering constraint for our ranges
     if (aRangeStart > aRangeEnd)
       [aRangeStart, aRangeEnd] = [aRangeEnd, aRangeStart];
 
     // if we're not augmenting, then this is really easy.
     if (!aAugment) {
       this._count = aRangeEnd - aRangeStart + 1;
       this._ranges = [[aRangeStart, aRangeEnd]];
-      if (this._treeBoxObject)
-        this._treeBoxObject.invalidate();
+      if (this._tree)
+        this._tree.invalidate();
       this._fireSelectionChanged();
       return;
     }
 
     // Iterate over our existing set of ranges, finding the 'range' of ranges
     //  that our new range overlaps or simply obviates.
     // Overlap variables track blocks we need to keep some part of, Nuke
     //  variables are for blocks that get spliced out.  For our purposes, all
@@ -287,18 +287,18 @@ JSTreeSelection.prototype = {
       aRangeEnd = Math.max(aRangeEnd, this._ranges[highOverlap][1]);
     if (lowNuke != null)
       this._ranges.splice(lowNuke, highNuke - lowNuke + 1,
                           [aRangeStart, aRangeEnd]);
     else
       this._ranges.splice(insertionPoint, 0, [aRangeStart, aRangeEnd]);
 
     this._updateCount();
-    if (this._treeBoxObject)
-      this._treeBoxObject.invalidate();
+    if (this._tree)
+      this._tree.invalidate();
     this._fireSelectionChanged();
   },
 
   /**
    * This is basically RangedSelect but without insertion of a new range and we
    *  don't need to worry about adjacency.
    * Oddly, nsTreeSelection doesn't fire a selection changed event here...
    */
@@ -343,32 +343,32 @@ JSTreeSelection.prototype = {
     let args = [lowNuke, highNuke - lowNuke + 1];
     if (lowOverlap != null)
       args.push([this._ranges[lowOverlap][0], aRangeStart - 1]);
     if (highOverlap != null)
       args.push([aRangeEnd + 1, this._ranges[highOverlap][1]]);
     this._ranges.splice.apply(this._ranges, args);
 
     this._updateCount();
-    if (this._treeBoxObject)
-      this._treeBoxObject.invalidate();
+    if (this._tree)
+      this._tree.invalidate();
     // note! nsTreeSelection doesn't fire a selection changed event, so neither
     //  do we, but it seems like we should
   },
 
   /**
    * nsTreeSelection always fires a select notification when the range is
    *  cleared, even if there is no effective chance in selection.
    */
   clearSelection: function JSTreeSelection_clearSelection() {
     this._shiftSelectPivot = null;
     this._count = 0;
     this._ranges = [];
-    if (this._treeBoxObject)
-      this._treeBoxObject.invalidate();
+    if (this._tree)
+      this._tree.invalidate();
     this._fireSelectionChanged();
   },
 
   /**
    * Not even nsTreeSelection implements this.
    */
   invertSelection: function JSTreeSelection_invertSelection() {
     throw new Error("Who really was going to use this?");
@@ -386,34 +386,34 @@ JSTreeSelection.prototype = {
 
     // no-ops-ville
     if (!rowCount)
       return;
 
     this._count = rowCount;
     this._ranges = [[0, rowCount - 1]];
 
-    if (this._treeBoxObject)
-      this._treeBoxObject.invalidate();
+    if (this._tree)
+      this._tree.invalidate();
     this._fireSelectionChanged();
   },
 
   getRangeCount: function JSTreeSelection_getRangeCount() {
     return this._ranges.length;
   },
   getRangeAt: function JSTreeSelection_getRangeAt(aRangeIndex, aMinObj,
                                                   aMaxObj) {
     if (aRangeIndex < 0 || aRangeIndex > this._ranges.length)
       throw new Exception("Try a real range index next time.");
     [aMinObj.value, aMaxObj.value] = this._ranges[aRangeIndex];
   },
 
   invalidateSelection: function JSTreeSelection_invalidateSelection() {
-    if (this._treeBoxObject)
-      this._treeBoxObject.invalidate();
+    if (this._tree)
+      this._tree.invalidate();
   },
 
   /**
    * Helper method to adjust points in the face of row additions/removal.
    * @param aPoint The point, null if there isn't one, or an index otherwise.
    * @param aDeltaAt The row at which the change is happening.
    * @param aDelta The number of rows added if positive, or the (negative)
    *     number of rows removed.
@@ -518,18 +518,18 @@ JSTreeSelection.prototype = {
         }
       }
       // now translate everything from iInsert on up
       for (let iTrans = iInsert; iTrans < this._ranges.length; iTrans++) {
         let [low, high] = this._ranges[iTrans];
         this._ranges[iTrans] = [low + aCount, high + aCount];
       }
       // invalidate and fire selection change notice
-      if (this._treeBoxObject)
-        this._treeBoxObject.invalidate();
+      if (this._tree)
+        this._tree.invalidate();
       this._fireSelectionChanged();
       return;
     }
 
     // If we are removing rows, we are basically clearing the range that is
     //  getting deleted and translating everyone above the remaining point
     //  downwards.  The one trick is we may have to merge the lowest translated
     //  block.
@@ -548,18 +548,18 @@ JSTreeSelection.prototype = {
     // we may have to merge the lowest translated block because it may now be
     //  adjacent to the previous block
     if (iTrans > 0 && iTrans < this._ranges.length &&
         this._ranges[iTrans-1][1] == this_ranges[iTrans][0]) {
       this._ranges[iTrans-1][1] = this._ranges[iTrans][1];
       this._ranges.splice(iTrans, 1);
     }
 
-    if (this._treeBoxObject)
-      this._treeBoxObject.invalidate();
+    if (this._tree)
+      this._tree.invalidate();
     this.selectEventsSuppressed = saveSuppress;
   },
 
   get selectEventsSuppressed() {
     return this._selectEventsSuppressed;
   },
   /**
    * Control whether selection events are suppressed.  For consistency with
@@ -577,18 +577,18 @@ JSTreeSelection.prototype = {
    *  straight to the view.  If you have a tree, you shouldn't be using us,
    *  so this seems aboot right.
    */
   _fireSelectionChanged: function JSTreeSelection__fireSelectionChanged() {
     // don't fire if we are suppressed; we will fire when un-suppressed
     if (this.selectEventsSuppressed)
       return;
     let view;
-    if (this._treeBoxObject && this._treeBoxObject.view)
-      view = this._treeBoxObject.view;
+    if (this._tree && this._tree.view)
+      view = this._tree.view;
     else
       view = this._view;
 
     // We might not have a view if we're in the middle of setting up things
     if (view) {
       view = view.QueryInterface(Ci.nsITreeView);
       view.selectionChanged();
     }
@@ -604,18 +604,18 @@ JSTreeSelection.prototype = {
    *  invalidates the tree row if we have a tree.
    * The real selection object would send a DOM event we don't care about.
    */
   set currentIndex(aIndex) {
     if (aIndex == this.currentIndex)
       return;
 
     this._currentIndex = (aIndex != -1) ? aIndex : null;
-    if (this._treeBoxObject)
-      this._treeBoxObject.invalidateRow(aIndex);
+    if (this._tree)
+      this._tree.invalidateRow(aIndex);
   },
 
   currentColumn: null,
 
   get shiftSelectPivot() {
     return this._shiftSelectPivot != null ? this._shiftSelectPivot : -1;
   },
 
--- a/mailnews/extensions/newsblog/content/FeedUtils.jsm
+++ b/mailnews/extensions/newsblog/content/FeedUtils.jsm
@@ -863,17 +863,17 @@ var FeedUtils = {
       } else {
         let row = win.gFolderTreeView.getIndexOfFolder(aFolder);
         win.gFolderTreeView._tree.invalidateRow(row);
       }
     }
 
     win = Services.wm.getMostRecentWindow("Mail:News-BlogSubscriptions");
     if (win) {
-      win.FeedSubscriptions.mView.treeBox.invalidate();
+      win.FeedSubscriptions.mView.tree.invalidate();
     }
   },
 
   /**
    * Get the favicon for a feed folder subscription url (first one) or a feed
    * message url. The favicon service caches it in memory if places history is
    * not enabled.
    *
--- a/mailnews/extensions/newsblog/content/feed-subscriptions.js
+++ b/mailnews/extensions/newsblog/content/feed-subscriptions.js
@@ -104,17 +104,17 @@ var FeedSubscriptions = {
         }
       } else {
         let url = item.parentFolder == aSelectFolder ? aSelectFeedUrl :
                                                        item.url;
         this.selectFeed({ folder: rootFolder, url }, null);
       }
     }
 
-    this.mView.treeBox.ensureRowIsVisible(this.mView.selection.currentIndex);
+    this.mView.tree.ensureRowIsVisible(this.mView.selection.currentIndex);
     this.clearStatusInfo();
   },
 
   mView: {
     kRowIndexUndefined: -1,
 
     get currentItem() {
       // Get the current selection, if any.
@@ -125,26 +125,26 @@ var FeedSubscriptions = {
         item = this.getItemAtIndex(currentSelectionIndex);
       }
 
       return item;
     },
 
     /* nsITreeView */
     /* eslint-disable no-multi-spaces */
-    treeBox: null,
+    tree: null,
 
     mRowCount: 0,
     get rowCount()               { return this.mRowCount; },
 
     _selection:                  null,
     get selection()              { return this._selection; },
     set selection(val)           { return this._selection = val; },
 
-    setTree(aTreebox)            { this.treeBox = aTreebox; },
+    setTree(aTree)               { this.tree = aTree; },
     isSeparator(aRow)            { return false; },
     isSorted()                   { return false; },
     isEditable(aRow, aColumn)    { return false; },
 
     getProgressMode(aRow, aCol)  {},
     cycleHeader(aCol)            {},
     cycleCell(aRow, aCol)        {},
     selectionChanged()           {},
@@ -269,17 +269,17 @@ var FeedSubscriptions = {
         }
       }
 
       // Now remove it from our view.
       FeedSubscriptions.mFeedContainers.splice(aRow, 1);
 
       // Now invalidate the correct tree rows.
       this.mRowCount--;
-      this.treeBox.rowCountChanged(aRow, -1);
+      this.tree.rowCountChanged(aRow, -1);
 
       // Now update the selection position, unless noSelect (selection is
       // done later or not at all).  If the item is the last child, select the
       // parent.  Otherwise select the next sibling.
       if (!aNoSelect) {
         if (aRow <= FeedSubscriptions.mFeedContainers.length) {
           this.selection.select(hasNextSibling ? aRow : aRow - 1);
         } else {
@@ -570,17 +570,17 @@ var FeedSubscriptions = {
 
       let delta = multiplier * rowCount;
       this.mRowCount += delta;
 
       item.open = !item.open;
       // Suppress the select event caused by rowCountChanged.
       this.selection.selectEventsSuppressed = true;
       // Add or remove the children from our view.
-      this.treeBox.rowCountChanged(aRow, delta);
+      this.tree.rowCountChanged(aRow, delta);
       return delta;
     },
   },
 
   makeFolderObject(aFolder, aCurrentLevel) {
     let defaultQuickMode = aFolder.server.getBoolValue("quickMode");
     let optionsAcct = aFolder.isServer ? FeedUtils.getOptionsAcct(aFolder.server) :
                                          null;
@@ -719,18 +719,18 @@ var FeedSubscriptions = {
     let selectIt = aParms && ("select" in aParms) ? aParms.select : true;
     let openIt = aParms && ("open" in aParms) ? aParms.open : true;
     let removeIt = aParms && ("remove" in aParms) ? aParms.remove : false;
     let newFolder = aParms && ("newFolder" in aParms) ? aParms.newFolder : null;
     let startIndex, startItem;
     let found = false;
 
     let firstVisRow, curFirstVisRow, curLastVisRow;
-    if (this.mView.treeBox) {
-      firstVisRow = this.mView.treeBox.getFirstVisibleRow();
+    if (this.mView.tree) {
+      firstVisRow = this.mView.tree.getFirstVisibleRow();
     }
 
     if (parentIndex != null) {
       // Use the parentIndex if given.
       startIndex = parentIndex;
       if (aFolder.isServer) {
         // Fake item for account root folder.
         startItem = { name:     "AccountRoot",
@@ -854,23 +854,23 @@ var FeedSubscriptions = {
 
         this.mView.selection.select(index);
         found = true;
         break;
       }
     }
 
     // Ensure tree position does not jump unnecessarily.
-    curFirstVisRow = this.mView.treeBox.getFirstVisibleRow();
-    curLastVisRow = this.mView.treeBox.getLastVisibleRow();
+    curFirstVisRow = this.mView.tree.getFirstVisibleRow();
+    curLastVisRow = this.mView.tree.getLastVisibleRow();
     if (firstVisRow >= 0 &&
         this.mView.rowCount - curLastVisRow > firstVisRow - curFirstVisRow) {
-      this.mView.treeBox.scrollToRow(firstVisRow);
+      this.mView.tree.scrollToRow(firstVisRow);
     } else {
-      this.mView.treeBox.ensureRowIsVisible(this.mView.rowCount - 1);
+      this.mView.tree.ensureRowIsVisible(this.mView.rowCount - 1);
     }
 
     FeedUtils.log.debug("selectFolder: curIndex:firstVisRow:" +
                         "curFirstVisRow:curLastVisRow:rowCount - " +
                         this.mView.selection.currentIndex + ":" +
                         firstVisRow + ":" +
                         curFirstVisRow + ":" + curLastVisRow + ":" + this.mView.rowCount);
     return found;
@@ -900,17 +900,17 @@ var FeedSubscriptions = {
 
     if (this.selectFolder(folder, { parentIndex: aParentIndex })) {
       let seln = this.mView.selection;
       let item = this.mView.currentItem;
       if (item) {
         for (let i = seln.currentIndex + 1; i < this.mView.rowCount; i++) {
           if (this.mView.getItemAtIndex(i).url == aFeed.url) {
             this.mView.selection.select(i);
-            this.mView.treeBox.ensureRowIsVisible(i);
+            this.mView.tree.ensureRowIsVisible(i);
             found = true;
             break;
           }
         }
       }
     }
 
     return found;
@@ -1983,30 +1983,30 @@ var FeedSubscriptions = {
                           (parentFolder ? parentFolder.filePath.path : "(null)"));
 
       if (!parentFolder || !this.feedWindow) {
         return;
       }
 
       let feedWindow = this.feedWindow;
       let curSelItem = this.currentSelectedItem;
-      let firstVisRow = feedWindow.mView.treeBox.getFirstVisibleRow();
+      let firstVisRow = feedWindow.mView.tree.getFirstVisibleRow();
       let indexInView = feedWindow.mView.getItemInViewIndex(parentFolder);
       let open = indexInView != null;
 
       if (aFolder.isServer) {
         if (indexInView != null) {
           // Existing account root folder in the view.
           open = feedWindow.mView.getItemAtIndex(indexInView).open;
         } else {
           // Add the account root folder to the view.
           feedWindow.mFeedContainers.push(feedWindow.makeFolderObject(parentFolder, 0));
           feedWindow.mView.mRowCount++;
           feedWindow.mTree.view = feedWindow.mView;
-          feedWindow.mView.treeBox.scrollToRow(firstVisRow);
+          feedWindow.mView.tree.scrollToRow(firstVisRow);
           return;
         }
       }
 
       // Rebuild the added folder's parent item in the tree row cache.
       feedWindow.selectFolder(parentFolder, { select: false,
                                               open,
                                               newFolder: parentFolder });
@@ -2023,17 +2023,17 @@ var FeedSubscriptions = {
       }
 
       if (open) {
         // Close an open parent (or root) folder.
         feedWindow.mView.toggle(parentIndex);
         feedWindow.mView.toggleOpenState(parentIndex);
       }
 
-      feedWindow.mView.treeBox.scrollToRow(firstVisRow);
+      feedWindow.mView.tree.scrollToRow(firstVisRow);
 
       if (curSelItem.container) {
         feedWindow.selectFolder(curSelItem.folder, { open: curSelItem.open });
       } else {
         feedWindow.selectFeed({ folder: curSelItem.parentFolder,
                                 url: curSelItem.url },
                               parentIndex);
       }
@@ -2078,17 +2078,17 @@ var FeedSubscriptions = {
                           aOrigFolder.name + ":" + aNewFolder.name);
       if (!this.feedWindow) {
         return;
       }
 
       let feedWindow = this.feedWindow;
       let curSelIndex = this.currentSelectedIndex;
       let curSelItem = this.currentSelectedItem;
-      let firstVisRow = feedWindow.mView.treeBox.getFirstVisibleRow();
+      let firstVisRow = feedWindow.mView.tree.getFirstVisibleRow();
       let indexInView = feedWindow.mView.getItemInViewIndex(aOrigFolder);
       let open = indexInView != null;
 
       // Rebuild the renamed folder's item in the tree row cache.
       feedWindow.selectFolder(aOrigFolder, { select: false,
                                              open,
                                              newFolder: aNewFolder });
 
@@ -2104,17 +2104,17 @@ var FeedSubscriptions = {
       let parentIndex = feedWindow.mView.getParentIndex(indexInView);
       if (parentIndex == feedWindow.mView.kRowIndexUndefined) {
         // Root folder is its own parent.
         parentIndex = indexInView;
       }
 
       feedWindow.mView.toggle(parentIndex);
       feedWindow.mView.toggleOpenState(parentIndex);
-      feedWindow.mView.treeBox.scrollToRow(firstVisRow);
+      feedWindow.mView.tree.scrollToRow(firstVisRow);
 
       if (curSelItem.container) {
         if (curSelItem.folder == aOrigFolder) {
           feedWindow.selectFolder(aNewFolder, { open: curSelItem.open });
         } else if (select) {
           feedWindow.mView.selection.select(indexInView);
         } else {
           feedWindow.selectFolder(curSelItem.folder, { open: curSelItem.open });
@@ -2134,17 +2134,17 @@ var FeedSubscriptions = {
                           aMove + ":" + aSrcFolder.name + ":" + aDestFolder.name);
       if (!this.feedWindow) {
         return;
       }
 
       let feedWindow = this.feedWindow;
       let curSelIndex = this.currentSelectedIndex;
       let curSelItem = this.currentSelectedItem;
-      let firstVisRow = feedWindow.mView.treeBox.getFirstVisibleRow();
+      let firstVisRow = feedWindow.mView.tree.getFirstVisibleRow();
       let indexInView = feedWindow.mView.getItemInViewIndex(aSrcFolder);
       let destIndexInView = feedWindow.mView.getItemInViewIndex(aDestFolder);
       let open = indexInView != null || destIndexInView != null;
       let parentIndex = feedWindow.mView.getItemInViewIndex(aDestFolder.parent ||
                                                             aDestFolder);
       let select =
         indexInView == curSelIndex ||
         feedWindow.mView.isIndexChildOfParentIndex(indexInView, curSelIndex);
@@ -2164,17 +2164,17 @@ var FeedSubscriptions = {
 
         if (!open || !curSelItem) {
           // Folder isn't in the tree view, no need to update the view.
           return;
         }
 
         feedWindow.mView.toggle(parentIndex);
         feedWindow.mView.toggleOpenState(parentIndex);
-        feedWindow.mView.treeBox.scrollToRow(firstVisRow);
+        feedWindow.mView.tree.scrollToRow(firstVisRow);
 
         if (curSelItem.container) {
           if (curSelItem.folder == aSrcFolder || select) {
             feedWindow.selectFolder(aDestFolder, { open: true });
           } else {
             feedWindow.selectFolder(curSelItem.folder, { open: curSelItem.open });
           }
         } else {
--- a/mailnews/extensions/newsblog/content/newsblogOverlay.js
+++ b/mailnews/extensions/newsblog/content/newsblogOverlay.js
@@ -272,17 +272,17 @@ var FeedMessageHandler = {
 function openSubscriptionsDialog(aFolder) {
   // Check for an existing feed subscriptions window and focus it.
   let subscriptionsWindow =
     Services.wm.getMostRecentWindow("Mail:News-BlogSubscriptions");
 
   if (subscriptionsWindow) {
     if (aFolder) {
       subscriptionsWindow.FeedSubscriptions.selectFolder(aFolder);
-      subscriptionsWindow.FeedSubscriptions.mView.treeBox.ensureRowIsVisible(
+      subscriptionsWindow.FeedSubscriptions.mView.tree.ensureRowIsVisible(
         subscriptionsWindow.FeedSubscriptions.mView.selection.currentIndex);
     }
 
     subscriptionsWindow.focus();
   } else {
     window.openDialog("chrome://messenger-newsblog/content/feed-subscriptions.xul",
                       "", "centerscreen,chrome,dialog=no,resizable",
                       { folder: aFolder});