Bug 979835: Port BoxObject and its subclasses to WebIDL. r=khuey sr=bz
authorJon Morton <jonanin@gmail.com>
Tue, 14 Oct 2014 13:15:21 -0700
changeset 210449 8d3304b7e0e0b2b8fd607c8320436b415e8d4cae
parent 210448 944cba921a299f6f29c482652f5a0446189de6a3
child 210450 713b9fa30f62b47d811adc4f190b07b22cae2eb4
push idunknown
push userunknown
push dateunknown
reviewerskhuey, bz
bugs979835
milestone36.0a1
Bug 979835: Port BoxObject and its subclasses to WebIDL. r=khuey sr=bz
accessible/base/nsCoreUtils.cpp
accessible/base/nsCoreUtils.h
accessible/tests/mochitest/actions/test_treegrid.xul
accessible/tests/mochitest/hittest/test_zoom_tree.xul
accessible/tests/mochitest/name/test_tree.xul
accessible/tests/mochitest/selectable/test_tree.xul
accessible/tests/mochitest/states/test_tree.xul
accessible/tests/mochitest/tree/test_tree.xul
accessible/tests/mochitest/treeview.js
accessible/xul/XULTreeAccessible.cpp
accessible/xul/XULTreeGridAccessible.cpp
browser/base/content/browser-places.js
browser/base/content/pageinfo/pageInfo.js
browser/base/content/sync/quota.js
browser/components/feeds/FeedWriter.js
browser/components/places/content/sidebarUtils.js
browser/components/places/content/tree.xml
browser/components/places/tests/browser/browser_forgetthissite_single.js
browser/components/places/tests/browser/browser_library_infoBox.js
browser/components/places/tests/browser/browser_library_middleclick.js
browser/components/places/tests/browser/head.js
browser/components/preferences/cookies.js
browser/components/preferences/permissions.js
browser/components/preferences/tests/browser_bug705422.js
browser/components/preferences/translation.js
browser/components/search/test/browser_405664.js
browser/components/sessionstore/content/aboutSessionRestore.js
browser/components/sessionstore/test/browser_590563.js
browser/devtools/shared/widgets/FastListWidget.js
browser/devtools/shared/widgets/SideMenuWidget.jsm
browser/devtools/shared/widgets/SimpleListWidget.jsm
browser/devtools/shared/widgets/VariablesView.jsm
browser/metro/base/content/bindings/bindings.xml
browser/metro/base/content/input.js
browser/modules/UITour.jsm
content/base/public/nsIDocument.h
content/base/src/nsDocument.cpp
content/base/src/nsDocument.h
content/xul/content/src/nsXULElement.cpp
content/xul/content/src/nsXULElement.h
content/xul/document/src/XULDocument.cpp
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfoClasses.h
dom/bindings/Bindings.conf
dom/events/test/test_bug602962.xul
dom/tests/mochitest/general/test_interfaces.html
dom/webidl/BoxObject.webidl
dom/webidl/ContainerBoxObject.webidl
dom/webidl/LegacyQueryInterface.webidl
dom/webidl/ListBoxObject.webidl
dom/webidl/MenuBoxObject.webidl
dom/webidl/PopupBoxObject.webidl
dom/webidl/ScrollBoxObject.webidl
dom/webidl/TreeBoxObject.webidl
dom/webidl/TreeColumns.webidl
dom/webidl/XULDocument.webidl
dom/webidl/XULElement.webidl
dom/webidl/moz.build
dom/xslt/tests/buster/buster-handlers.js
editor/composer/test/test_bug434998.xul
editor/libeditor/tests/test_bug607584.xul
editor/libeditor/tests/test_bug616590.xul
editor/libeditor/tests/test_bug780908.xul
gfx/tests/unit/test_nsIScriptableRegion.js
js/xpconnect/src/dom_quickstubs.qsconf
layout/reftests/invalidation/540247-1-ref.xul
layout/reftests/invalidation/540247-1.xul
layout/xul/BoxObject.cpp
layout/xul/BoxObject.h
layout/xul/ContainerBoxObject.cpp
layout/xul/ContainerBoxObject.h
layout/xul/ListBoxObject.cpp
layout/xul/ListBoxObject.h
layout/xul/MenuBoxObject.cpp
layout/xul/MenuBoxObject.h
layout/xul/PopupBoxObject.cpp
layout/xul/PopupBoxObject.h
layout/xul/ScrollBoxObject.cpp
layout/xul/ScrollBoxObject.h
layout/xul/moz.build
layout/xul/nsBoxObject.cpp
layout/xul/nsBoxObject.h
layout/xul/nsContainerBoxObject.cpp
layout/xul/nsIBoxObject.idl
layout/xul/nsIBrowserBoxObject.idl
layout/xul/nsIContainerBoxObject.idl
layout/xul/nsIEditorBoxObject.idl
layout/xul/nsIIFrameBoxObject.idl
layout/xul/nsIListBoxObject.idl
layout/xul/nsIMenuBoxObject.idl
layout/xul/nsIPopupBoxObject.idl
layout/xul/nsIScrollBoxObject.idl
layout/xul/nsListBoxBodyFrame.cpp
layout/xul/nsListBoxBodyFrame.h
layout/xul/nsListBoxObject.cpp
layout/xul/nsMenuBoxObject.cpp
layout/xul/nsMenuPopupFrame.cpp
layout/xul/nsMenuPopupFrame.h
layout/xul/nsPopupBoxObject.cpp
layout/xul/nsScrollBoxObject.cpp
layout/xul/nsXULPopupManager.cpp
layout/xul/nsXULTooltipListener.cpp
layout/xul/tree/TreeBoxObject.cpp
layout/xul/tree/TreeBoxObject.h
layout/xul/tree/crashtests/585815-iframe.xul
layout/xul/tree/moz.build
layout/xul/tree/nsITreeBoxObject.idl
layout/xul/tree/nsTreeBodyFrame.cpp
layout/xul/tree/nsTreeBodyFrame.h
layout/xul/tree/nsTreeBoxObject.cpp
layout/xul/tree/nsTreeBoxObject.h
layout/xul/tree/nsTreeColFrame.cpp
layout/xul/tree/nsTreeColumns.cpp
layout/xul/tree/nsTreeColumns.h
layout/xul/tree/nsTreeSelection.cpp
security/manager/pki/resources/content/certManager.js
security/manager/pki/resources/content/viewCertDetails.js
services/sync/tps/extensions/mozmill/resource/driver/mozelement.js
testing/mochitest/browser-harness.xul
toolkit/components/filepicker/content/filepicker.js
toolkit/components/passwordmgr/content/passwordManager.js
toolkit/components/passwordmgr/content/passwordManagerExceptions.js
toolkit/components/passwordmgr/test/browser/browser_passwordmgrdlg.js
toolkit/content/tests/chrome/popup_trigger.js
toolkit/content/tests/chrome/test_contextmenu_list.xul
toolkit/content/tests/chrome/test_mousescroll.xul
toolkit/content/tests/chrome/test_popup_tree.xul
toolkit/content/tests/chrome/test_position.xul
toolkit/content/tests/chrome/window_largemenu.xul
toolkit/content/tests/fennec-tile-testapp/chrome/content/FooScript.js
toolkit/content/tests/fennec-tile-testapp/chrome/content/foo.xul
toolkit/content/tests/widgets/popup_shared.js
toolkit/content/tests/widgets/tree_shared.js
toolkit/content/widgets/autocomplete.xml
toolkit/content/widgets/button.xml
toolkit/content/widgets/datetimepicker.xml
toolkit/content/widgets/editor.xml
toolkit/content/widgets/general.xml
toolkit/content/widgets/listbox.xml
toolkit/content/widgets/menu.xml
toolkit/content/widgets/menulist.xml
toolkit/content/widgets/popup.xml
toolkit/content/widgets/richlistbox.xml
toolkit/content/widgets/scrollbox.xml
toolkit/content/widgets/tree.xml
toolkit/mozapps/extensions/content/extensions.js
toolkit/mozapps/extensions/test/browser/browser_inlinesettings.js
toolkit/mozapps/extensions/test/browser/browser_inlinesettings_info.js
toolkit/mozapps/extensions/test/browser/browser_select_selection.js
xpcom/reflect/xptinfo/ShimInterfaceInfo.cpp
xpfe/components/autocomplete/resources/content/autocomplete.xml
--- a/accessible/base/nsCoreUtils.cpp
+++ b/accessible/base/nsCoreUtils.cpp
@@ -52,17 +52,17 @@ nsCoreUtils::HasClickListener(nsIContent
     (listenerManager->HasListenersFor(nsGkAtoms::onclick) ||
      listenerManager->HasListenersFor(nsGkAtoms::onmousedown) ||
      listenerManager->HasListenersFor(nsGkAtoms::onmouseup));
 }
 
 void
 nsCoreUtils::DispatchClickEvent(nsITreeBoxObject *aTreeBoxObj,
                                 int32_t aRowIndex, nsITreeColumn *aColumn,
-                                const nsCString& aPseudoElt)
+                                const nsAString& aPseudoElt)
 {
   nsCOMPtr<nsIDOMElement> tcElm;
   aTreeBoxObj->GetTreeBody(getter_AddRefs(tcElm));
   if (!tcElm)
     return;
 
   nsCOMPtr<nsIContent> tcContent(do_QueryInterface(tcElm));
   nsIDocument *document = tcContent->GetCurrentDoc();
--- a/accessible/base/nsCoreUtils.h
+++ b/accessible/base/nsCoreUtils.h
@@ -39,17 +39,17 @@ public:
    * @param  aTreeBoxObj  [in] tree box object
    * @param  aRowIndex    [in] row index
    * @param  aColumn      [in] column object
    * @param  aPseudoElm   [in] pseudo elemenet inside the cell, see
    *                       nsITreeBoxObject for available values
    */
   static void DispatchClickEvent(nsITreeBoxObject *aTreeBoxObj,
                                  int32_t aRowIndex, nsITreeColumn *aColumn,
-                                 const nsCString& aPseudoElt = EmptyCString());
+                                 const nsAString& aPseudoElt = EmptyString());
 
   /**
    * Send mouse event to the given element.
    *
    * @param aEventType   [in] an event type (see BasicEvents.h for constants)
    * @param aX           [in] x coordinate in dev pixels
    * @param aY           [in] y coordinate in dev pixels
    * @param aContent     [in] the element
@@ -309,9 +309,8 @@ public:
   static bool IsWhitespace(char16_t aChar)
   {
     return aChar == ' ' || aChar == '\n' ||
       aChar == '\r' || aChar == '\t' || aChar == 0xa0;
   }
 };
 
 #endif
-
--- a/accessible/tests/mochitest/actions/test_treegrid.xul
+++ b/accessible/tests/mochitest/actions/test_treegrid.xul
@@ -150,18 +150,17 @@
     {
       var treeNode = getNode("tabletree");
       waitForEvent(EVENT_REORDER, treeNode, doTestActions);
       treeNode.view = new nsTreeTreeView();
     }
 
     function test1()
     {
-      var boxObj = getNode("tabletree").treeBoxObject;
-      boxObj.view.setCellValue(0, boxObj.columns.firstColumn, "false");
+      getNode("tabletree").view.setCellValue(0, boxObj.columns.firstColumn, "false");
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   ]]>
   </script>
 
   <hbox flex="1" style="overflow: auto;">
@@ -191,9 +190,8 @@
       </tree>
 
       <vbox id="debug"/>
       <button oncommand="test1();" label="uncheck"/>
     </vbox>
   </hbox>
 
 </window>
-
--- a/accessible/tests/mochitest/hittest/test_zoom_tree.xul
+++ b/accessible/tests/mochitest/hittest/test_zoom_tree.xul
@@ -35,26 +35,24 @@
       var treecol1 = tabDocument.getElementById("treecol1");
 
       // tree columns
       hitTest(tree, treecols, treecol1);
 
       // tree rows and cells
       var treeBoxObject = tree.treeBoxObject;
       var treeBodyBoxObj = tree.treeBoxObject.treeBody.boxObject;
-      var xObj = {}, yObj = {}, widthObj = {}, heightObj = {};
-      treeBoxObject.getCoordsForCellItem(1, tree.columns[0], "cell",
-                                         xObj, yObj, widthObj, heightObj);
+      var rect = treeBoxObject.getCoordsForCellItem(1, tree.columns[0], "cell");
 
       var treeAcc = getAccessible(tree, [nsIAccessibleTable]);
       var cellAcc = treeAcc.getCellAt(1, 0);
       var rowAcc = cellAcc.parent;
 
-      var cssX = xObj.value + treeBodyBoxObj.x;
-      var cssY = yObj.value + treeBodyBoxObj.y;
+      var cssX = rect.x + treeBodyBoxObj.x;
+      var cssY = rect.y + treeBodyBoxObj.y;
       var [x, y] = CSSToDevicePixels(tabWindow, cssX, cssY);
 
       testChildAtPoint(treeAcc, x, y, rowAcc, cellAcc);
       testChildAtPoint(rowAcc, x, y, cellAcc, cellAcc);
 
       // do zoom
       zoomDocument(tabDocument, 1.5);
 
@@ -95,9 +93,8 @@
       <div id="content" style="display: none">
       </div>
       <pre id="test">
       </pre>
     </body>
   </hbox>
 
 </window>
-
--- a/accessible/tests/mochitest/name/test_tree.xul
+++ b/accessible/tests/mochitest/name/test_tree.xul
@@ -27,17 +27,17 @@
   <script type="application/javascript">
   <![CDATA[
     function treeTester(aID)
     {
       this.DOMNode = getNode(aID);
 
       this.invoke = function treeTester_invoke()
       {
-        this.DOMNode.treeBoxObject.view = new nsTreeTreeView();
+        this.DOMNode.view = new nsTreeTreeView();
       }
 
       this.check = function treeTester_check(aEvent)
       {
         var tree = {
           role: ROLE_OUTLINE,
           children: [
             {
@@ -85,17 +85,17 @@
     }
 
     function tableTester(aID, aIsTable, aCol1ID, aCol2ID)
     {
       this.DOMNode = getNode(aID);
 
       this.invoke = function tableTester_invoke()
       {
-        this.DOMNode.treeBoxObject.view = new nsTableTreeView(2);
+        this.DOMNode.view = new nsTableTreeView(2);
       }
 
       this.check = function tableTester_check(aEvent)
       {
         var tree = {
           role: aIsTable ? ROLE_TABLE : ROLE_TREE_TABLE,
           children: [
             {
@@ -204,9 +204,8 @@
       <treecol id="tt_col2" flex="1" label="column 2"/>
     </treecols>
     <treechildren/>
   </tree>
 
   </vbox> <!-- close tests area -->
   </hbox> <!-- close main area -->
 </window>
-
--- a/accessible/tests/mochitest/selectable/test_tree.xul
+++ b/accessible/tests/mochitest/selectable/test_tree.xul
@@ -37,17 +37,17 @@
      * accessible.
      */
     function statesChecker(aTreeID, aView)
     {
       this.DOMNode = getNode(aTreeID);
       
       this.invoke = function invoke()
       {
-        this.DOMNode.treeBoxObject.view = aView;
+        this.DOMNode.view = aView;
       }
       this.check = function check()
       {
         var tree = getAccessible(this.DOMNode);
 
         var isTreeMultiSelectable = false;
         var seltype = this.DOMNode.getAttribute("seltype");
         if (seltype != "single" && seltype != "cell" && seltype != "text")
@@ -181,9 +181,8 @@
         <treechildren/>
       </tree>
 
       <vbox id="debug"/>
     </vbox>
   </hbox>
 
 </window>
-
--- a/accessible/tests/mochitest/states/test_tree.xul
+++ b/accessible/tests/mochitest/states/test_tree.xul
@@ -33,17 +33,17 @@
      * accessible.
      */
     function statesChecker(aTreeID, aView)
     {
       this.DOMNode = getNode(aTreeID);
 
       this.invoke = function statesChecker_invoke()
       {
-        this.DOMNode.treeBoxObject.view = aView;
+        this.DOMNode.view = aView;
       }
 
       this.check = function statesChecker_check()
       {
         var tree = getAccessible(this.DOMNode);
 
         // tree states
         testStates(tree, STATE_READONLY);
@@ -145,9 +145,8 @@
         <treechildren/>
       </tree>
 
       <vbox id="debug"/>
     </vbox>
   </hbox>
 
 </window>
-
--- a/accessible/tests/mochitest/tree/test_tree.xul
+++ b/accessible/tests/mochitest/tree/test_tree.xul
@@ -67,17 +67,17 @@
       var accTreeForTree = {
         role: aRole,
         children: [
           accTreeForColumns
         ]
       };
 
       var treeBoxObject = aTree.treeBoxObject;
-      var view = treeBoxObject.view;
+      var view = aTree.view;
       var columnCount = treeBoxObject.columns.count;
 
       for (var idx = 0; idx < columnCount; idx++)
         accTreeForColumns.children.push({ COLUMNHEADER: [ ] });
       if (!aTree.hasAttribute("hidecolumnpicker"))
         accTreeForColumns.children.push({ PUSHBUTTON: [ { MENUPOPUP: [] } ] });
 
       for (var idx = 0; idx < view.rowCount; idx++)
@@ -90,17 +90,17 @@
      * Event queue invoker object to test accessible tree for XUL tree element.
      */
     function treeChecker(aID, aView, aRole)
     {
       this.DOMNode = getNode(aID);
 
       this.invoke = function invoke()
       {
-        this.DOMNode.treeBoxObject.view = aView;
+        this.DOMNode.view = aView;
       }
       this.check = function check(aEvent)
       {
         testAccessibleTreeFor(this.DOMNode, aRole);
       }
       this.getID = function getID()
       {
         return "Tree testing of " + aID;
@@ -175,9 +175,8 @@
         <treechildren/>
       </tree>
 
       <vbox id="debug"/>
     </vbox>
   </hbox>
 
 </window>
-
--- a/accessible/tests/mochitest/treeview.js
+++ b/accessible/tests/mochitest/treeview.js
@@ -12,17 +12,17 @@ function loadXULTreeAndDoTest(aDoTestFun
     this.treeNode = getNode(aTreeID);
 
     this.eventSeq = [
       new invokerChecker(EVENT_REORDER, this.treeNode)
     ];
 
     this.invoke = function loadXULTree_invoke()
     {
-      this.treeNode.treeBoxObject.view = aTreeView;
+      this.treeNode.view = aTreeView;
     }
 
     this.getID = function loadXULTree_getID()
     {
       return "Load XUL tree " + prettyName(aTreeID);
     }
   }
 
--- a/accessible/xul/XULTreeAccessible.cpp
+++ b/accessible/xul/XULTreeAccessible.cpp
@@ -194,17 +194,17 @@ XULTreeAccessible::ChildAtPoint(int32_t 
 
   nsIntRect rootRect = rootFrame->GetScreenRect();
 
   int32_t clientX = presContext->DevPixelsToIntCSSPixels(aX) - rootRect.x;
   int32_t clientY = presContext->DevPixelsToIntCSSPixels(aY) - rootRect.y;
 
   int32_t row = -1;
   nsCOMPtr<nsITreeColumn> column;
-  nsAutoCString childEltUnused;
+  nsAutoString childEltUnused;
   mTree->GetCellAt(clientX, clientY, &row, getter_AddRefs(column),
                    childEltUnused);
 
   // If we failed to find tree cell for the given point then it might be
   // tree columns.
   if (row == -1 || !column)
     return AccessibleWrap::ChildAtPoint(aX, aY, aWhichChild);
 
@@ -741,17 +741,17 @@ XULTreeItemAccessibleBase::Bounds() cons
 
   nsCOMPtr<nsIBoxObject> boxObj = nsCoreUtils::GetTreeBodyBoxObject(mTree);
   if (!boxObj)
     return nsIntRect();
 
   nsCOMPtr<nsITreeColumn> column = nsCoreUtils::GetFirstSensibleColumn(mTree);
 
   int32_t x = 0, y = 0, width = 0, height = 0;
-  nsresult rv = mTree->GetCoordsForCellItem(mRow, column, EmptyCString(),
+  nsresult rv = mTree->GetCoordsForCellItem(mRow, column, EmptyString(),
                                             &x, &y, &width, &height);
   if (NS_FAILED(rv))
     return nsIntRect();
 
   boxObj->GetWidth(&width);
 
   int32_t tcX = 0, tcY = 0;
   boxObj->GetScreenX(&tcX);
@@ -991,25 +991,25 @@ XULTreeItemAccessibleBase::DispatchClick
 
   nsCOMPtr<nsITreeColumns> columns;
   mTree->GetColumns(getter_AddRefs(columns));
   if (!columns)
     return;
 
   // Get column and pseudo element.
   nsCOMPtr<nsITreeColumn> column;
-  nsAutoCString pseudoElm;
+  nsAutoString pseudoElm;
 
   if (aActionIndex == eAction_Click) {
     // Key column is visible and clickable.
     columns->GetKeyColumn(getter_AddRefs(column));
   } else {
     // Primary column contains a twisty we should click on.
     columns->GetPrimaryColumn(getter_AddRefs(column));
-    pseudoElm = NS_LITERAL_CSTRING("twisty");
+    pseudoElm = NS_LITERAL_STRING("twisty");
   }
 
   if (column)
     nsCoreUtils::DispatchClickEvent(mTree, mRow, column, pseudoElm);
 }
 
 Accessible*
 XULTreeItemAccessibleBase::GetSiblingAtOffset(int32_t aOffset,
@@ -1191,9 +1191,8 @@ XULTreeColumAccessible::GetSiblingAtOffs
         if (treeAcc)
           return treeAcc->GetTreeItemAccessible(aOffset - 1);
       }
     }
   }
 
   return nullptr;
 }
-
--- a/accessible/xul/XULTreeGridAccessible.cpp
+++ b/accessible/xul/XULTreeGridAccessible.cpp
@@ -336,17 +336,17 @@ XULTreeGridRowAccessible::ChildAtPoint(i
 
   nsIntRect rootRect = rootFrame->GetScreenRect();
 
   int32_t clientX = presContext->DevPixelsToIntCSSPixels(aX) - rootRect.x;
   int32_t clientY = presContext->DevPixelsToIntCSSPixels(aY) - rootRect.y;
 
   int32_t row = -1;
   nsCOMPtr<nsITreeColumn> column;
-  nsAutoCString childEltUnused;
+  nsAutoString childEltUnused;
   mTree->GetCellAt(clientX, clientY, &row, getter_AddRefs(column),
                    childEltUnused);
 
   // Return if we failed to find tree cell in the row for the given point.
   if (row != mRow || !column)
     return nullptr;
 
   return GetCellAccessible(column);
@@ -517,17 +517,17 @@ XULTreeGridCellAccessible::Bounds() cons
   // Get bounds for tree cell and add x and y of treechildren element to
   // x and y of the cell.
   nsCOMPtr<nsIBoxObject> boxObj = nsCoreUtils::GetTreeBodyBoxObject(mTree);
   if (!boxObj)
     return nsIntRect();
 
   int32_t x = 0, y = 0, width = 0, height = 0;
   nsresult rv = mTree->GetCoordsForCellItem(mRow, mColumn,
-                                            NS_LITERAL_CSTRING("cell"),
+                                            NS_LITERAL_STRING("cell"),
                                             &x, &y, &width, &height);
   if (NS_FAILED(rv))
     return nsIntRect();
 
   int32_t tcX = 0, tcY = 0;
   boxObj->GetScreenX(&tcX);
   boxObj->GetScreenY(&tcY);
   x += tcX;
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -703,23 +703,22 @@ var BookmarksEventHandler = {
 
   fillInBHTooltip: function BEH_fillInBHTooltip(aDocument, aEvent) {
     var node;
     var cropped = false;
     var targetURI;
 
     if (aDocument.tooltipNode.localName == "treechildren") {
       var tree = aDocument.tooltipNode.parentNode;
-      var row = {}, column = {};
       var tbo = tree.treeBoxObject;
-      tbo.getCellAt(aEvent.clientX, aEvent.clientY, row, column, {});
-      if (row.value == -1)
+      var cell = tbo.getCellAt(aEvent.clientX, aEvent.clientY);
+      if (cell.row == -1)
         return false;
-      node = tree.view.nodeForTreeIndex(row.value);
-      cropped = tbo.isCellCropped(row.value, column.value);
+      node = tree.view.nodeForTreeIndex(cell.row);
+      cropped = tbo.isCellCropped(cell.row, cell.col);
     }
     else {
       // Check whether the tooltipNode is a Places node.
       // In such a case use it, otherwise check for targetURI attribute.
       var tooltipNode = aDocument.tooltipNode;
       if (tooltipNode._placesNode)
         node = tooltipNode._placesNode;
       else {
--- a/browser/base/content/pageinfo/pageInfo.js
+++ b/browser/base/content/pageinfo/pageInfo.js
@@ -503,17 +503,17 @@ function makeGeneralTab()
     metaGroup.collapsed = true;
   else {
     var metaTagsCaption = document.getElementById("metaTagsCaption");
     if (length == 1)
       metaTagsCaption.label = gBundle.getString("generalMetaTag");
     else
       metaTagsCaption.label = gBundle.getFormattedString("generalMetaTags", [length]);
     var metaTree = document.getElementById("metatree");
-    metaTree.treeBoxObject.view = gMetaView;
+    metaTree.view = gMetaView;
 
     for (var i = 0; i < length; i++)
       gMetaView.addRow([metaNodes[i].name || metaNodes[i].httpEquiv, metaNodes[i].content]);
 
     metaGroup.collapsed = false;
   }
 
   // get the date of last modification
--- a/browser/base/content/sync/quota.js
+++ b/browser/base/content/sync/quota.js
@@ -156,20 +156,19 @@ let gUsageTreeView = {
 
   /*
    * Handle click events on the tree.
    */
   onTreeClick: function onTreeClick(event) {
     if (event.button == 2)
       return;
 
-    let row = {}, col = {};
-    this.treeBox.getCellAt(event.clientX, event.clientY, row, col, {});
-    if (col.value && col.value.id == "enabled")
-      this.toggle(row.value);
+    let cell = this.treeBox.getCellAt(event.clientX, event.clientY);
+    if (cell.col && cell.col.id == "enabled")
+      this.toggle(cell.row);
   },
 
   /*
    * Toggle enabled state of an engine.
    */
   toggle: function toggle(row) {
     // Update the tree
     let collection = this._collections[row];
--- a/browser/components/feeds/FeedWriter.js
+++ b/browser/components/feeds/FeedWriter.js
@@ -853,17 +853,16 @@ FeedWriter.prototype = {
            * Application" item is being selected with the keyboard. We do this
            * by ignoring command events while the dropdown is closed (user
            * arrowing through the combobox), but handling them while the
            * combobox dropdown is open (user pressed enter when an item was
            * selected). If we don't show the filepicker here, it will be shown
            * when clicking "Subscribe Now".
            */
           var popupbox = this._handlersMenuList.firstChild.boxObject;
-          popupbox.QueryInterface(Components.interfaces.nsIPopupBoxObject);
           if (popupbox.popupState == "hiding") {
             this._chooseClientApp(function(aResult) {
               if (!aResult) {
                 // Select the (per-prefs) selected handler if no application
                 // was selected
                 this._setSelectedHandler(this._getFeedType());
               }
             }.bind(this));
--- a/browser/components/places/content/sidebarUtils.js
+++ b/browser/components/places/content/sidebarUtils.js
@@ -5,66 +5,63 @@
 
 var SidebarUtils = {
   handleTreeClick: function SU_handleTreeClick(aTree, aEvent, aGutterSelect) {
     // right-clicks are not handled here
     if (aEvent.button == 2)
       return;
 
     var tbo = aTree.treeBoxObject;
-    var row = { }, col = { }, obj = { };
-    tbo.getCellAt(aEvent.clientX, aEvent.clientY, row, col, obj);
+    var cell = tbo.getCellAt(aEvent.clientX, aEvent.clientY);
 
-    if (row.value == -1 || obj.value == "twisty")
+    if (cell.row == -1 || cell.childElt == "twisty")
       return;
 
     var mouseInGutter = false;
     if (aGutterSelect) {
-      var x = { }, y = { }, w = { }, h = { };
-      tbo.getCoordsForCellItem(row.value, col.value, "image",
-                               x, y, w, h);
+      var rect = tbo.getCoordsForCellItem(cell.row, cell.col, "image");
       // getCoordsForCellItem returns the x coordinate in logical coordinates
       // (i.e., starting from the left and right sides in LTR and RTL modes,
       // respectively.)  Therefore, we make sure to exclude the blank area
       // before the tree item icon (that is, to the left or right of it in
       // LTR and RTL modes, respectively) from the click target area.
       var isRTL = window.getComputedStyle(aTree, null).direction == "rtl";
       if (isRTL)
-        mouseInGutter = aEvent.clientX > x.value;
+        mouseInGutter = aEvent.clientX > rect.x;
       else
-        mouseInGutter = aEvent.clientX < x.value;
+        mouseInGutter = aEvent.clientX < rect.y;
     }
 
 #ifdef XP_MACOSX
     var modifKey = aEvent.metaKey || aEvent.shiftKey;
 #else
     var modifKey = aEvent.ctrlKey || aEvent.shiftKey;
 #endif
 
-    var isContainer = tbo.view.isContainer(row.value);
+    var isContainer = tbo.view.isContainer(cell.row);
     var openInTabs = isContainer &&
                      (aEvent.button == 1 ||
                       (aEvent.button == 0 && modifKey)) &&
-                     PlacesUtils.hasChildURIs(tbo.view.nodeForTreeIndex(row.value), true);
+                     PlacesUtils.hasChildURIs(tbo.view.nodeForTreeIndex(cell.row), true);
 
     if (aEvent.button == 0 && isContainer && !openInTabs) {
-      tbo.view.toggleOpenState(row.value);
+      tbo.view.toggleOpenState(cell.row);
       return;
     }
     else if (!mouseInGutter && openInTabs &&
             aEvent.originalTarget.localName == "treechildren") {
-      tbo.view.selection.select(row.value);
+      tbo.view.selection.select(cell.row);
       PlacesUIUtils.openContainerNodeInTabs(aTree.selectedNode, aEvent, aTree);
     }
     else if (!mouseInGutter && !isContainer &&
              aEvent.originalTarget.localName == "treechildren") {
       // Clear all other selection since we're loading a link now. We must
       // do this *before* attempting to load the link since openURL uses
       // selection as an indication of which link to load.
-      tbo.view.selection.select(row.value);
+      tbo.view.selection.select(cell.row);
       PlacesUIUtils.openNodeWithEvent(aTree.selectedNode, aEvent, aTree);
     }
   },
 
   handleTreeKeyPress: function SU_handleTreeKeyPress(aEvent) {
     // XXX Bug 627901: Post Fx4, this method should take a tree parameter.
     let tree = aEvent.target;
     let node = tree.selectedNode;
@@ -79,24 +76,23 @@ var SidebarUtils = {
    * hovered over.
    */
   handleTreeMouseMove: function SU_handleTreeMouseMove(aEvent) {
     if (aEvent.target.localName != "treechildren")
       return;
 
     var tree = aEvent.target.parentNode;
     var tbo = tree.treeBoxObject;
-    var row = { }, col = { }, obj = { };
-    tbo.getCellAt(aEvent.clientX, aEvent.clientY, row, col, obj);
+    var cell = tbo.getCellAt(aEvent.clientX, aEvent.clientY);
 
-    // row.value is -1 when the mouse is hovering an empty area within the tree.
+    // cell.row is -1 when the mouse is hovering an empty area within the tree.
     // To avoid showing a URL from a previously hovered node for a currently
     // hovered non-url node, we must clear the moused-over URL in these cases.
-    if (row.value != -1) {
-      var node = tree.view.nodeForTreeIndex(row.value);
+    if (cell.row != -1) {
+      var node = tree.view.nodeForTreeIndex(cell.row);
       if (PlacesUtils.nodeIsURI(node))
         this.setMouseoverURL(node.uri);
       else
         this.setMouseoverURL("");
     }
     else
       this.setMouseoverURL("");
   },
--- a/browser/components/places/content/tree.xml
+++ b/browser/components/places/content/tree.xml
@@ -742,52 +742,50 @@
         this._controller.setDataTransfer(event);
         event.stopPropagation();
       ]]></handler>
 
       <handler event="dragover"><![CDATA[
         if (event.target.localName != "treechildren")
           return;
 
-        let row = { }, col = { }, child = { };
-        this.treeBoxObject.getCellAt(event.clientX, event.clientY,
-                                     row, col, child);
-        let node = row.value != -1 ?
-                   this.view.nodeForTreeIndex(row.value) :
+        let cell = this.treeBoxObject.getCellAt(event.clientX, event.clientY);
+        let node = cell.row != -1 ?
+                   this.view.nodeForTreeIndex(cell.row) :
                    this.result.root;
         // cache the dropTarget for the view
         PlacesControllerDragHelper.currentDropTarget = node;
 
         // We have to calculate the orientation since view.canDrop will use
         // it and we want to be consistent with the dropfeedback.
         let tbo = this.treeBoxObject;
         let rowHeight = tbo.rowHeight;
         let eventY = event.clientY - tbo.treeBody.boxObject.y -
-                     rowHeight * (row.value - tbo.getFirstVisibleRow());
+                     rowHeight * (cell.row - tbo.getFirstVisibleRow());
 
         let orientation = Ci.nsITreeView.DROP_BEFORE;
 
-        if (row.value == -1) {
+        if (cell.row == -1) {
           // If the row is not valid we try to insert inside the resultNode.
           orientation = Ci.nsITreeView.DROP_ON;
         }
         else if (PlacesUtils.nodeIsContainer(node) &&
                  eventY > rowHeight * 0.75) {
           // If we are below the 75% of a container the treeview we try
           // to drop after the node.
           orientation = Ci.nsITreeView.DROP_AFTER;
         }
         else if (PlacesUtils.nodeIsContainer(node) &&
                  eventY > rowHeight * 0.25) {
           // If we are below the 25% of a container the treeview we try
           // to drop inside the node.
           orientation = Ci.nsITreeView.DROP_ON;
         }
 
-        if (!this.view.canDrop(row.value, orientation, event.dataTransfer))
+        if (!this.view.canDrop(cell.row, orientation, event.dataTransfer))
           return;
 
         event.preventDefault();
         event.stopPropagation();
       ]]></handler>
 
       <handler event="dragend"><![CDATA[
         PlacesControllerDragHelper.currentDropTarget = null;
--- a/browser/components/places/tests/browser/browser_forgetthissite_single.js
+++ b/browser/components/places/tests/browser/browser_forgetthissite_single.js
@@ -57,17 +57,14 @@ function test() {
               organizer.removeEventListener("unload", arguments.callee, false);
               // Proceed
               funcNext();
             }, false);
             // Close Library window.
             organizer.close();
           }, true);
           // Get cell coordinates
-          var x = {}, y = {}, width = {}, height = {};
-          tree.treeBoxObject.getCoordsForCellItem(0, tree.columns[0], "text",
-                                                  x, y, width, height);
+          var rect = tree.treeBoxObject.getCoordsForCellItem(0, tree.columns[0], "text");
           // Initiate a context menu for the selected cell
-          EventUtils.synthesizeMouse(tree.body, x.value + width.value / 2, y.value + height.value / 2, {type: "contextmenu"}, organizer);
+          EventUtils.synthesizeMouse(tree.body, rect.x + rect.width / 2, rect.y + rect.height / 2, {type: "contextmenu"}, organizer);
     });
   }
 }
-
--- a/browser/components/places/tests/browser/browser_library_infoBox.js
+++ b/browser/components/places/tests/browser/browser_library_infoBox.js
@@ -47,17 +47,17 @@ gTests.push({
       isnot(childNode, null, "History node first child is not null.");
       PO._places.selectNode(childNode);
       checkInfoBoxSelected(PO);
       ok(infoBoxExpanderWrapper.hidden,
          "Expander button is hidden for history child node.");
       checkAddInfoFieldsCollapsed(PO);
 
       // open history item
-      var view = ContentTree.view.treeBoxObject.view;
+      var view = ContentTree.view.view;
       ok(view.rowCount > 0, "History item exists.");
       view.selection.select(0);
       ok(infoBoxExpanderWrapper.hidden,
          "Expander button is hidden for history item.");
       checkAddInfoFieldsCollapsed(PO);
 
       historyNode.containerOpen = false;
 
@@ -84,17 +84,17 @@ gTests.push({
          "Correctly selected recently bookmarked node.");
       PO._places.selectNode(childNode);
       checkInfoBoxSelected(PO);
       ok(!infoBoxExpanderWrapper.hidden,
          "Expander button is not hidden for recently bookmarked node.");
       checkAddInfoFieldsNotCollapsed(PO);
 
       // open first bookmark
-      var view = ContentTree.view.treeBoxObject.view;
+      var view = ContentTree.view.view;
       ok(view.rowCount > 0, "Bookmark item exists.");
       view.selection.select(0);
       checkInfoBoxSelected(PO);
       ok(!infoBoxExpanderWrapper.hidden,
          "Expander button is not hidden for bookmark item.");
       checkAddInfoFieldsNotCollapsed(PO);
       checkAddInfoFields(PO, "bookmark item");
 
--- a/browser/components/places/tests/browser/browser_library_middleclick.js
+++ b/browser/components/places/tests/browser/browser_library_middleclick.js
@@ -267,15 +267,13 @@ function runNextTest() {
 
 function mouseEventOnCell(aTree, aRowIndex, aColumnIndex, aEventDetails) {
   var selection = aTree.view.selection;
   selection.select(aRowIndex);
   aTree.treeBoxObject.ensureRowIsVisible(aRowIndex);
   var column = aTree.columns[aColumnIndex];
 
   // get cell coordinates
-  var x = {}, y = {}, width = {}, height = {};
-  aTree.treeBoxObject.getCoordsForCellItem(aRowIndex, column, "text",
-                                           x, y, width, height);
+  var rect = aTree.treeBoxObject.getCoordsForCellItem(aRowIndex, column, "text");
 
-  EventUtils.synthesizeMouse(aTree.body, x.value, y.value,
+  EventUtils.synthesizeMouse(aTree.body, rect.x, rect.y,
                              aEventDetails, gLibrary);
 }
--- a/browser/components/places/tests/browser/head.js
+++ b/browser/components/places/tests/browser/head.js
@@ -191,17 +191,15 @@ function synthesizeClickOnSelectedTreeCe
   if (tbo.view.selection.count != 1)
      throw new Error("The test node should be successfully selected");
   // Get selection rowID.
   let min = {}, max = {};
   tbo.view.selection.getRangeAt(0, min, max);
   let rowID = min.value;
   tbo.ensureRowIsVisible(rowID);
   // Calculate the click coordinates.
-  let x = {}, y = {}, width = {}, height = {};
-  tbo.getCoordsForCellItem(rowID, aTree.columns[0], "text",
-                           x, y, width, height);
-  x = x.value + width.value / 2;
-  y = y.value + height.value / 2;
+  var rect = tbo.getCoordsForCellItem(rowID, aTree.columns[0], "text");
+  var x = rect.x + rect.width / 2;
+  var y = rect.y + rect.height / 2;
   // Simulate the click.
   EventUtils.synthesizeMouse(aTree.body, x, y, aOptions || {},
                              aTree.ownerDocument.defaultView);
 }
--- a/browser/components/preferences/cookies.js
+++ b/browser/components/preferences/cookies.js
@@ -33,17 +33,17 @@ var gCookiesWindow = {
     var os = Components.classes["@mozilla.org/observer-service;1"]
                        .getService(Components.interfaces.nsIObserverService);
     os.removeObserver(this, "cookie-changed");
     os.removeObserver(this, "perm-changed");
   },
 
   _populateList: function (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[0] &&
@@ -785,17 +785,17 @@ var gCookiesWindow = {
     // Clear the Tree Display
     this._view._filtered = false;
     this._view._rowCount = 0;
     this._tree.treeBoxObject.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 {
--- a/browser/components/preferences/permissions.js
+++ b/browser/components/preferences/permissions.js
@@ -327,17 +327,17 @@ var gPermissionManager = {
     while (enumerator.hasMoreElements()) {
       var nextPermission = enumerator.getNext().QueryInterface(Components.interfaces.nsIPermission);
       this._addPermissionToList(nextPermission);
     }
    
     this._view._rowCount = this._permissions.length;
 
     // sort and display the table
-    this._tree.treeBoxObject.view = this._view;
+    this._tree.view = this._view;
     this.onPermissionSort("rawHost", false);
 
     // disable "remove all" button if there are none
     document.getElementById("removeAllPermissions").disabled = this._permissions.length == 0;
   },
   
   _addPermissionToList: function (aPermission)
   {
@@ -365,9 +365,8 @@ function setHost(aHost)
 {
   gPermissionManager.setHost(aHost);
 }
 
 function initWithParams(aParams)
 {
   gPermissionManager.init(aParams);
 }
-
--- a/browser/components/preferences/tests/browser_bug705422.js
+++ b/browser/components/preferences/tests/browser_bug705422.js
@@ -77,34 +77,33 @@ function runTest(win, searchTerm, cookie
 
     // "delete all cookies" should be enabled
     isDisabled(win, false);
 
 
     // select first cookie and delete
     var tree = win.document.getElementById("cookiesList");
     var deleteButton = win.document.getElementById("removeCookie");
-    var x = {}, y = {}, width = {}, height = {};
-    tree.treeBoxObject.getCoordsForCellItem(0, tree.columns[0], "cell", x, y, width, height);
-    EventUtils.synthesizeMouse(tree.body, x.value + width.value / 2, y.value + height.value / 2, {}, win);
+    var rect = tree.treeBoxObject.getCoordsForCellItem(0, tree.columns[0], "cell");
+    EventUtils.synthesizeMouse(tree.body, rect.x + rect.width / 2, rect.y + rect.height / 2, {}, win);
     EventUtils.synthesizeMouseAtCenter(deleteButton, {}, win);
 
     // count cookies should be matches-1
     is(win.gCookiesWindow._view.rowCount, matches-1, "Deleted selected cookie");
 
     // select two adjacent cells and delete
-    EventUtils.synthesizeMouse(tree.body, x.value + width.value / 2, y.value + height.value / 2, {}, win);
+    EventUtils.synthesizeMouse(tree.body, rect.x + rect.width / 2, rect.y + rect.height / 2, {}, win);
     deleteButton = win.document.getElementById("removeCookies"); 
     var eventObj = {};
     if (navigator.platform.indexOf("Mac") >= 0)
         eventObj.metaKey = true;
     else
         eventObj.ctrlKey = true;
-    tree.treeBoxObject.getCoordsForCellItem(1, tree.columns[0], "cell", x, y, width, height);
-    EventUtils.synthesizeMouse(tree.body, x.value + width.value / 2, y.value + height.value / 2, eventObj, win);
+    rect = tree.treeBoxObject.getCoordsForCellItem(1, tree.columns[0], "cell");
+    EventUtils.synthesizeMouse(tree.body, rect.x + rect.width / 2, rect.y + rect.height / 2, eventObj, win);
     EventUtils.synthesizeMouseAtCenter(deleteButton, {}, win);
 
     // count cookies should be matches-3
     is(win.gCookiesWindow._view.rowCount, matches-3, "Deleted selected two adjacent cookies");
 
     // "delete all cookies" should be enabled
     isDisabled(win, false);
 
--- a/browser/components/preferences/translation.js
+++ b/browser/components/preferences/translation.js
@@ -15,17 +15,17 @@ XPCOMUtils.defineLazyGetter(this, "gLang
 
 const kPermissionType = "translate";
 const kLanguagesPref = "browser.translation.neverForLanguages";
 
 function Tree(aId, aData)
 {
   this._data = aData;
   this._tree = document.getElementById(aId);
-  this._tree.treeBoxObject.view = this;
+  this._tree.view = this;
 }
 
 Tree.prototype = {
   get boxObject() this._tree.treeBoxObject,
   get isEmpty() !this._data.length,
   get hasSelection() this.selection.count > 0,
   getSelectedItems: function() {
     let result = [];
--- a/browser/components/search/test/browser_405664.js
+++ b/browser/components/search/test/browser_405664.js
@@ -1,16 +1,16 @@
 function test() {
   var searchBar = BrowserSearch.searchBar;
   ok(searchBar, "got search bar");
   
   searchBar.focus();
 
   var pbo = searchBar._popup.popupBoxObject;
-  ok(pbo, "popup is nsIPopupBoxObject");
+  ok(pbo, "popup is PopupBoxObject");
 
   EventUtils.synthesizeKey("VK_UP", { altKey: true });
   is(pbo.popupState, "showing", "popup is opening after Alt+Up");
 
   EventUtils.synthesizeKey("VK_ESCAPE", {});
   is(pbo.popupState, "closed", "popup is closed after ESC");
 
   EventUtils.synthesizeKey("VK_DOWN", { altKey: true });
--- a/browser/components/sessionstore/content/aboutSessionRestore.js
+++ b/browser/components/sessionstore/content/aboutSessionRestore.js
@@ -139,34 +139,33 @@ function startNewSession() {
     getBrowserWindow().BrowserHome();
 }
 
 function onListClick(aEvent) {
   // don't react to right-clicks
   if (aEvent.button == 2)
     return;
 
-  var row = {}, col = {};
-  treeView.treeBox.getCellAt(aEvent.clientX, aEvent.clientY, row, col, {});
-  if (col.value) {
+  var cell = treeView.treeBox.getCellAt(aEvent.clientX, aEvent.clientY);
+  if (cell.col) {
     // Restore this specific tab in the same window for middle/double/accel clicking
     // on a tab's title.
 #ifdef XP_MACOSX
     let accelKey = aEvent.metaKey;
 #else
     let accelKey = aEvent.ctrlKey;
 #endif
     if ((aEvent.button == 1 || aEvent.button == 0 && aEvent.detail == 2 || accelKey) &&
-        col.value.id == "title" &&
-        !treeView.isContainer(row.value)) {
-      restoreSingleTab(row.value, aEvent.shiftKey);
+        cell.col.id == "title" &&
+        !treeView.isContainer(cell.row)) {
+      restoreSingleTab(cell.row, aEvent.shiftKey);
       aEvent.stopPropagation();
     }
-    else if (col.value.id == "restore")
-      toggleRowChecked(row.value);
+    else if (cell.col.id == "restore")
+      toggleRowChecked(cell.row);
   }
 }
 
 function onListKeyDown(aEvent) {
   switch (aEvent.keyCode)
   {
   case KeyEvent.DOM_VK_SPACE:
     toggleRowChecked(document.getElementById("tabList").currentIndex);
--- a/browser/components/sessionstore/test/browser_590563.js
+++ b/browser/components/sessionstore/test/browser_590563.js
@@ -33,25 +33,23 @@ function test() {
   });
 }
 
 function middleClickTest(win) {
   let browser = win.gBrowser.selectedBrowser;
   let tree = browser.contentDocument.getElementById("tabList");
   is(tree.view.rowCount, 3, "There should be three items");
 
-  let x = {}, y = {}, width = {}, height = {};
-
   // click on the first tab item
-  tree.treeBoxObject.getCoordsForCellItem(1, tree.columns[1], "text", x, y, width, height);
-  EventUtils.synthesizeMouse(tree.body, x.value, y.value, { button: 1 },
+  var rect = tree.treeBoxObject.getCoordsForCellItem(1, tree.columns[1], "text");
+  EventUtils.synthesizeMouse(tree.body, rect.x, rect.y, { button: 1 },
                              browser.contentWindow);
   // click on the second tab item
-  tree.treeBoxObject.getCoordsForCellItem(2, tree.columns[1], "text", x, y, width, height);
-  EventUtils.synthesizeMouse(tree.body, x.value, y.value, { button: 1 },
+  rect = tree.treeBoxObject.getCoordsForCellItem(2, tree.columns[1], "text");
+  EventUtils.synthesizeMouse(tree.body, rect.x, rect.y, { button: 1 },
                              browser.contentWindow);
 
   is(win.gBrowser.tabs.length, 3,
      "The total number of tabs should be 3 after restoring 2 tabs by middle click.");
   is(win.gBrowser.visibleTabs.length, 3,
      "The total number of visible tabs should be 3 after restoring 2 tabs by middle click");
 }
 
--- a/browser/devtools/shared/widgets/FastListWidget.js
+++ b/browser/devtools/shared/widgets/FastListWidget.js
@@ -190,17 +190,17 @@ FastListWidget.prototype = {
    *        The element to make visible.
    */
   ensureElementIsVisible: function(element) {
     if (!element) {
       return;
     }
 
     // Ensure the element is visible but not scrolled horizontally.
-    let boxObject = this._list.boxObject.QueryInterface(Ci.nsIScrollBoxObject);
+    let boxObject = this._list.boxObject;
     boxObject.ensureElementIsVisible(element);
     boxObject.scrollBy(-this._list.clientWidth, 0);
   },
 
   /**
    * Sets the text displayed in this container when empty.
    * @param string aValue
    */
--- a/browser/devtools/shared/widgets/SideMenuWidget.jsm
+++ b/browser/devtools/shared/widgets/SideMenuWidget.jsm
@@ -209,17 +209,17 @@ SideMenuWidget.prototype = {
    *        The element to make visible.
    */
   ensureElementIsVisible: function(aElement) {
     if (!aElement) {
       return;
     }
 
     // Ensure the element is visible but not scrolled horizontally.
-    let boxObject = this._list.boxObject.QueryInterface(Ci.nsIScrollBoxObject);
+    let boxObject = this._list.boxObject;
     boxObject.ensureElementIsVisible(aElement);
     boxObject.scrollBy(-this._list.clientWidth, 0);
   },
 
   /**
    * Shows all the groups, even the ones with no visible children.
    */
   showEmptyGroups: function() {
--- a/browser/devtools/shared/widgets/SimpleListWidget.jsm
+++ b/browser/devtools/shared/widgets/SimpleListWidget.jsm
@@ -166,17 +166,17 @@ SimpleListWidget.prototype = {
    *        The element to make visible.
    */
   ensureElementIsVisible: function(aElement) {
     if (!aElement) {
       return;
     }
 
     // Ensure the element is visible but not scrolled horizontally.
-    let boxObject = this._list.boxObject.QueryInterface(Ci.nsIScrollBoxObject);
+    let boxObject = this._list.boxObject;
     boxObject.ensureElementIsVisible(aElement);
     boxObject.scrollBy(-this._list.clientWidth, 0);
   },
 
   /**
    * Sets the text displayed permanently in this container as a header.
    * @param string aValue
    */
--- a/browser/devtools/shared/widgets/VariablesView.jsm
+++ b/browser/devtools/shared/widgets/VariablesView.jsm
@@ -982,17 +982,17 @@ VariablesView.prototype = {
       this._parent.removeAttribute("actions-first");
     }
   },
 
   /**
    * Gets the parent node holding this view.
    * @return nsIDOMNode
    */
-  get boxObject() this._list.boxObject.QueryInterface(Ci.nsIScrollBoxObject),
+  get boxObject() this._list.boxObject,
 
   /**
    * Gets the parent node holding this view.
    * @return nsIDOMNode
    */
   get parentNode() this._parent,
 
   /**
--- a/browser/metro/base/content/bindings/bindings.xml
+++ b/browser/metro/base/content/bindings/bindings.xml
@@ -20,24 +20,21 @@
     <handlers>
       <handler event="scroll">
         <![CDATA[
           // if there no more items to insert, just return early
           if (this._items.length == 0)
             return;
 
           if (this._contentScrollHeight == -1) {
-            let scrollheight = {};
-            this.scrollBoxObject.getScrolledSize({}, scrollheight);
-            this._contentScrollHeight = scrollheight.value;
+            this._contentScrollHeight = this.scrollBoxObject.scrolledHeight;
           }
 
-          let y = {};
-          this.scrollBoxObject.getPosition({}, y);
-          let scrollRatio = (y.value + this._childrenHeight) / this._contentScrollHeight;
+          let y = this.scrollBoxObject.positionY;
+          let scrollRatio = (y + this._childrenHeight) / this._contentScrollHeight;
 
           // If we're scrolled 80% to the bottom of the list, append the next
           // set of items
           if (scrollRatio > 0.8)
             this._insertItems();
         ]]>
       </handler>
     </handlers>
--- a/browser/metro/base/content/input.js
+++ b/browser/metro/base/content/input.js
@@ -470,27 +470,27 @@ var ScrollUtils = {
     // if element is content or the startui page, get the browser scroll interface
     if (elem.ownerDocument == Browser.selectedBrowser.contentDocument) {
       elem = Browser.selectedBrowser;
     }
     for (; elem; elem = elem.parentNode) {
       try {
         if (elem.anonScrollBox) {
           scrollbox = elem.anonScrollBox;
-          qinterface = scrollbox.boxObject.QueryInterface(Ci.nsIScrollBoxObject);
+          qinterface = scrollbox.boxObject;
         } else if (elem.scrollBoxObject) {
           scrollbox = elem;
           qinterface = elem.scrollBoxObject;
           break;
         } else if (elem.customDragger) {
           scrollbox = elem;
           break;
         } else if (elem.boxObject) {
           let qi = (elem._cachedSBO) ? elem._cachedSBO
-                                     : elem.boxObject.QueryInterface(Ci.nsIScrollBoxObject);
+                                     : elem.boxObject;
           if (qi) {
             scrollbox = elem;
             scrollbox._cachedSBO = qinterface = qi;
             break;
           }
         }
       } catch (e) { /* we aren't here to deal with your exceptions, we'll just keep
                        traversing until we find something more well-behaved, as we
@@ -507,50 +507,43 @@ var ScrollUtils = {
 
   /**
    * The default dragger object used by TouchModule when dragging a scrollable
    * element that provides no customDragger.  Simply performs the expected
    * regular scrollBy calls on the scroller.
    */
   _defaultDragger: {
     isDraggable: function isDraggable(target, scroller) {
-      let sX = {}, sY = {},
-          pX = {}, pY = {};
-      scroller.getPosition(pX, pY);
-      scroller.getScrolledSize(sX, sY);
       let rect = target.getBoundingClientRect();
-      return { x: (sX.value > rect.width  || pX.value != 0),
-               y: (sY.value > rect.height || pY.value != 0) };
+      return { x: (scroller.scrolledWidth > rect.width   || scroller.positionX != 0),
+               y: (scroller.scrolledHeight > rect.height || scroller.positionY != 0) };
     },
 
     dragStart: function dragStart(cx, cy, target, scroller) {
       scroller.element.addEventListener("PanBegin", this._showScrollbars, false);
     },
 
     dragStop: function dragStop(dx, dy, scroller) {
       scroller.element.removeEventListener("PanBegin", this._showScrollbars, false);
       return this.dragMove(dx, dy, scroller);
     },
 
     dragMove: function dragMove(dx, dy, scroller) {
-      if (scroller.getPosition) {
         try {
-          let oldX = {}, oldY = {};
-          scroller.getPosition(oldX, oldY);
+        let oldX = scroller.positionX,
+            oldY = scroller.positionY;
 
           scroller.scrollBy(dx, dy);
 
-          let newX = {}, newY = {};
-          scroller.getPosition(newX, newY);
+        let newX = scroller.positionX,
+            newY = scroller.positionY;
 
-          return (newX.value != oldX.value) || (newY.value != oldY.value);
+        return (newX != oldX) || (newY != oldY);
 
         } catch (e) { /* we have no time for whiny scrollers! */ }
-      }
-
       return false;
     },
 
     _showScrollbars: function _showScrollbars(aEvent) {
       let scrollbox = aEvent.target;
       scrollbox.setAttribute("panning", "true");
 
       let hideScrollbars = function() {
--- a/browser/modules/UITour.jsm
+++ b/browser/modules/UITour.jsm
@@ -1016,17 +1016,17 @@ this.UITour = {
     function openMenuButton(aID) {
       let menuBtn = aWindow.document.getElementById(aID);
       if (!menuBtn || !menuBtn.boxObject) {
         aOpenCallback();
         return;
       }
       if (aOpenCallback)
         menuBtn.addEventListener("popupshown", onPopupShown);
-      menuBtn.boxObject.QueryInterface(Ci.nsIMenuBoxObject).openMenu(true);
+      menuBtn.boxObject.openMenu(true);
     }
     function onPopupShown(event) {
       this.removeEventListener("popupshown", onPopupShown);
       aOpenCallback(event);
     }
 
     if (aMenuName == "appMenu") {
       aWindow.PanelUI.panel.setAttribute("noautohide", "true");
@@ -1044,17 +1044,17 @@ this.UITour = {
       openMenuButton("bookmarks-menu-button");
     }
   },
 
   hideMenu: function(aWindow, aMenuName) {
     function closeMenuButton(aID) {
       let menuBtn = aWindow.document.getElementById(aID);
       if (menuBtn && menuBtn.boxObject)
-        menuBtn.boxObject.QueryInterface(Ci.nsIMenuBoxObject).openMenu(false);
+        menuBtn.boxObject.openMenu(false);
     }
 
     if (aMenuName == "appMenu") {
       aWindow.PanelUI.panel.removeAttribute("noautohide");
       aWindow.PanelUI.hide();
       this.recreatePopup(aWindow.PanelUI.panel);
     } else if (aMenuName == "bookmarks") {
       closeMenuButton("bookmarks-menu-button");
--- a/content/base/public/nsIDocument.h
+++ b/content/base/public/nsIDocument.h
@@ -33,17 +33,16 @@ class nsIDocShell;
 class nsDocShell;
 class nsDOMNavigationTiming;
 class nsFrameLoader;
 class nsHTMLCSSStyleSheet;
 class nsHTMLDocument;
 class nsHTMLStyleSheet;
 class nsIAtom;
 class nsIBFCacheEntry;
-class nsIBoxObject;
 class nsIChannel;
 class nsIContent;
 class nsIContentSink;
 class nsIDocShell;
 class nsIDocumentEncoder;
 class nsIDocumentObserver;
 class nsIDOMDocument;
 class nsIDOMDocumentFragment;
@@ -90,16 +89,17 @@ class SVGAttrAnimationRuleProcessor;
 namespace css {
 class Loader;
 class ImageLoader;
 } // namespace css
 
 namespace dom {
 class AnimationTimeline;
 class Attr;
+class BoxObject;
 class CDATASection;
 class Comment;
 struct CustomElementDefinition;
 class DocumentFragment;
 class DocumentType;
 class DOMImplementation;
 class DOMStringList;
 class Element;
@@ -1495,17 +1495,17 @@ public:
    * @param aElement canonical nsIContent pointer of the box object's element
    */
   virtual void ClearBoxObjectFor(nsIContent *aContent) = 0;
 
   /**
    * Get the box object for an element. This is not exposed through a
    * scriptable interface except for XUL documents.
    */
-  virtual already_AddRefed<nsIBoxObject>
+  virtual already_AddRefed<mozilla::dom::BoxObject>
     GetBoxObjectFor(mozilla::dom::Element* aElement,
                     mozilla::ErrorResult& aRv) = 0;
 
   /**
    * Get the compatibility mode for this document
    */
   nsCompatibility GetCompatibilityMode() const {
     return mCompatMode;
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -215,16 +215,17 @@
 #include "nsIDocumentActivity.h"
 #include "nsIStructuredCloneContainer.h"
 #include "nsIMutableArray.h"
 #include "nsContentPermissionHelper.h"
 #include "mozilla/dom/DOMStringList.h"
 #include "nsWindowMemoryReporter.h"
 #include "nsLocation.h"
 #include "mozilla/dom/FontFaceSet.h"
+#include "mozilla/dom/BoxObject.h"
 
 #ifdef MOZ_MEDIA_NAVIGATOR
 #include "mozilla/MediaManager.h"
 #endif // MOZ_MEDIA_NAVIGATOR
 #ifdef MOZ_WEBRTC
 #include "IPeerConnection.h"
 #endif // MOZ_WEBRTC
 
@@ -6942,17 +6943,17 @@ nsDocument::DoNotifyPossibleTitleChange(
   }
 
   // Fire a DOM event for the title change.
   nsContentUtils::DispatchChromeEvent(this, static_cast<nsIDocument*>(this),
                                       NS_LITERAL_STRING("DOMTitleChanged"),
                                       true, true);
 }
 
-already_AddRefed<nsIBoxObject>
+already_AddRefed<BoxObject>
 nsDocument::GetBoxObjectFor(Element* aElement, ErrorResult& aRv)
 {
   if (!aElement) {
     aRv.Throw(NS_ERROR_UNEXPECTED);
     return nullptr;
   }
 
   nsIDocument* doc = aElement->OwnerDoc();
@@ -6969,17 +6970,17 @@ nsDocument::GetBoxObjectFor(Element* aEl
                                     "UseOfGetBoxObjectForWarning");
   }
 
   if (!mBoxObjectTable) {
     mBoxObjectTable = new nsInterfaceHashtable<nsPtrHashKey<nsIContent>, nsPIBoxObject>(6);
   } else {
     nsCOMPtr<nsPIBoxObject> boxObject = mBoxObjectTable->Get(aElement);
     if (boxObject) {
-      return boxObject.forget();
+      return boxObject.forget().downcast<BoxObject>();
     }
   }
 
   int32_t namespaceID;
   nsCOMPtr<nsIAtom> tag = BindingManager()->ResolveTag(aElement, &namespaceID);
 
   nsAutoCString contractID("@mozilla.org/layout/xul-boxobject");
   if (namespaceID == kNameSpaceID_XUL) {
@@ -7010,17 +7011,17 @@ nsDocument::GetBoxObjectFor(Element* aEl
   }
 
   boxObject->Init(aElement);
 
   if (mBoxObjectTable) {
     mBoxObjectTable->Put(aElement, boxObject.get());
   }
 
-  return boxObject.forget();
+  return boxObject.forget().downcast<BoxObject>();
 }
 
 void
 nsDocument::ClearBoxObjectFor(nsIContent* aContent)
 {
   if (mBoxObjectTable) {
     nsPIBoxObject *boxObject = mBoxObjectTable->GetWeak(aContent);
     if (boxObject) {
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -25,18 +25,16 @@
 #include "nsStubDocumentObserver.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIContent.h"
 #include "nsIPrincipal.h"
 #include "nsIParser.h"
 #include "nsBindingManager.h"
 #include "nsInterfaceHashtable.h"
 #include "nsJSThingHashtable.h"
-#include "nsIBoxObject.h"
-#include "nsPIBoxObject.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsIURI.h"
 #include "nsScriptLoader.h"
 #include "nsIRadioGroupContainer.h"
 #include "nsILayoutHistoryState.h"
 #include "nsIRequest.h"
 #include "nsILoadGroup.h"
 #include "nsTObserverArray.h"
@@ -90,20 +88,22 @@ class nsChildContentList;
 class nsHTMLStyleSheet;
 class nsHTMLCSSStyleSheet;
 class nsDOMNavigationTiming;
 class nsWindowSizes;
 class nsHtml5TreeOpExecutor;
 class nsDocumentOnStack;
 class nsPointerLockPermissionRequest;
 class nsISecurityConsoleMessage;
+class nsPIBoxObject;
 
 namespace mozilla {
 class EventChainPreVisitor;
 namespace dom {
+class BoxObject;
 class UndoManager;
 struct LifecycleCallbacks;
 class CallbackFunction;
 }
 }
 
 /**
  * Right now our identifier map entries contain information for 'name'
@@ -997,18 +997,20 @@ public:
 
   virtual void BlockOnload();
   virtual void UnblockOnload(bool aFireSync);
 
   virtual void AddStyleRelevantLink(mozilla::dom::Link* aLink);
   virtual void ForgetLink(mozilla::dom::Link* aLink);
 
   void ClearBoxObjectFor(nsIContent* aContent);
-  already_AddRefed<nsIBoxObject> GetBoxObjectFor(mozilla::dom::Element* aElement,
-                                                 mozilla::ErrorResult& aRv) MOZ_OVERRIDE;
+
+  virtual already_AddRefed<mozilla::dom::BoxObject>
+  GetBoxObjectFor(mozilla::dom::Element* aElement,
+                  mozilla::ErrorResult& aRv) MOZ_OVERRIDE;
 
   virtual Element*
     GetAnonymousElementByAttribute(nsIContent* aElement,
                                    nsIAtom* aAttrName,
                                    const nsAString& aAttrValue) const;
 
   virtual Element* ElementFromPointHelper(float aX, float aY,
                                                       bool aIgnoreRootScrollFrame,
--- a/content/xul/content/src/nsXULElement.cpp
+++ b/content/xul/content/src/nsXULElement.cpp
@@ -68,17 +68,17 @@
 #include "nsXULControllers.h"
 #include "nsIBoxObject.h"
 #include "nsPIBoxObject.h"
 #include "XULDocument.h"
 #include "nsXULPopupListener.h"
 #include "nsRuleWalker.h"
 #include "nsIDOMCSSStyleDeclaration.h"
 #include "nsCSSParser.h"
-#include "nsIListBoxObject.h"
+#include "ListBoxObject.h"
 #include "nsContentUtils.h"
 #include "nsContentList.h"
 #include "mozilla/InternalMutationEvent.h"
 #include "mozilla/MouseEvents.h"
 #include "nsIDOMMutationEvent.h"
 #include "nsPIDOMWindow.h"
 #include "nsJSPrincipals.h"
 #include "nsDOMAttributeMap.h"
@@ -104,16 +104,17 @@
 #include "nsXBLBinding.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozAutoDocUpdate.h"
 #include "nsIDOMXULCommandEvent.h"
 #include "nsCCUncollectableMarker.h"
 #include "nsICSSDeclaration.h"
 
 #include "mozilla/dom/XULElementBinding.h"
+#include "mozilla/dom/BoxObject.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 #ifdef XUL_PROTOTYPE_ATTRIBUTE_METERING
 uint32_t             nsXULPrototypeAttribute::gNumElements;
 uint32_t             nsXULPrototypeAttribute::gNumAttributes;
 uint32_t             nsXULPrototypeAttribute::gNumCacheTests;
@@ -1500,17 +1501,17 @@ nsXULElement::GetControllers(ErrorResult
 NS_IMETHODIMP
 nsXULElement::GetBoxObject(nsIBoxObject** aResult)
 {
     ErrorResult rv;
     *aResult = GetBoxObject(rv).take();
     return rv.ErrorCode();
 }
 
-already_AddRefed<nsIBoxObject>
+already_AddRefed<BoxObject>
 nsXULElement::GetBoxObject(ErrorResult& rv)
 {
     // XXX sXBL/XBL2 issue! Owner or current document?
     return OwnerDoc()->GetBoxObjectFor(this, rv);
 }
 
 // Methods for setting/getting attributes from nsIDOMXULElement
 #define NS_IMPL_XUL_STRING_ATTR(_method, _atom)                     \
--- a/content/xul/content/src/nsXULElement.h
+++ b/content/xul/content/src/nsXULElement.h
@@ -21,17 +21,16 @@
 #include "nsIControllers.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMXULElement.h"
 #include "nsIDOMXULMultSelectCntrlEl.h"
 #include "nsIRDFCompositeDataSource.h"
 #include "nsIRDFResource.h"
 #include "nsIURI.h"
 #include "nsIXULTemplateBuilder.h"
-#include "nsIBoxObject.h"
 #include "nsLayoutCID.h"
 #include "nsAttrAndChildArray.h"
 #include "nsGkAtoms.h"
 #include "nsAutoPtr.h"
 #include "nsStyledElement.h"
 #include "nsIFrameLoader.h"
 #include "nsFrameLoader.h"
 #include "mozilla/dom/DOMRect.h"
@@ -49,16 +48,19 @@ class nsXULPrototypeNode;
 typedef nsTArray<nsRefPtr<nsXULPrototypeNode> > nsPrototypeArray;
 
 namespace mozilla {
 class EventChainPreVisitor;
 class EventListenerManager;
 namespace css {
 class StyleRule;
 }
+namespace dom {
+class BoxObject;
+}
 }
 
 namespace JS {
 class SourceBufferHolder;
 }
 
 ////////////////////////////////////////////////////////////////////////
 
@@ -582,17 +584,17 @@ public:
     bool AllowEvents() const
     {
         return BoolAttrIsTrue(nsGkAtoms::allowevents);
     }
     already_AddRefed<nsIRDFCompositeDataSource> GetDatabase();
     already_AddRefed<nsIXULTemplateBuilder> GetBuilder();
     already_AddRefed<nsIRDFResource> GetResource(mozilla::ErrorResult& rv);
     nsIControllers* GetControllers(mozilla::ErrorResult& rv);
-    already_AddRefed<nsIBoxObject> GetBoxObject(mozilla::ErrorResult& rv);
+    already_AddRefed<mozilla::dom::BoxObject> GetBoxObject(mozilla::ErrorResult& rv);
     void Focus(mozilla::ErrorResult& rv);
     void Blur(mozilla::ErrorResult& rv);
     void Click(mozilla::ErrorResult& rv);
     // The XPCOM DoCommand never fails, so it's OK for us.
     already_AddRefed<nsINodeList>
       GetElementsByAttribute(const nsAString& aAttribute,
                              const nsAString& aValue);
     already_AddRefed<nsINodeList>
--- a/content/xul/document/src/XULDocument.cpp
+++ b/content/xul/document/src/XULDocument.cpp
@@ -39,16 +39,17 @@
 #include "nsXMLContentSink.h"
 #include "nsXULContentSink.h"
 #include "nsXULContentUtils.h"
 #include "nsIXULOverlayProvider.h"
 #include "nsIStringEnumerator.h"
 #include "nsNetUtil.h"
 #include "nsParserCIID.h"
 #include "nsPIBoxObject.h"
+#include "mozilla/dom/BoxObject.h"
 #include "nsXPIDLString.h"
 #include "nsPIDOMWindow.h"
 #include "nsPIWindowRoot.h"
 #include "nsXULCommandDispatcher.h"
 #include "nsXULElement.h"
 #include "prlog.h"
 #include "rdf.h"
 #include "nsIFrame.h"
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -81,17 +81,16 @@
 #include "nsIDOMCSSSupportsRule.h"
 #include "nsIDOMMozCSSKeyframeRule.h"
 #include "nsIDOMMozCSSKeyframesRule.h"
 #include "nsIDOMCSSCounterStyleRule.h"
 #include "nsIDOMCSSPageRule.h"
 #include "nsIDOMCSSStyleRule.h"
 #include "nsIDOMXULCommandDispatcher.h"
 #include "nsIControllers.h"
-#include "nsIBoxObject.h"
 #ifdef MOZ_XUL
 #include "nsITreeSelection.h"
 #include "nsITreeContentView.h"
 #include "nsITreeView.h"
 #include "nsIXULTemplateBuilder.h"
 #include "nsITreeColumns.h"
 #endif
 #include "nsIDOMXPathNSResolver.h"
@@ -246,18 +245,16 @@ static nsDOMClassInfoData sClassInfoData
 
   // XUL classes
 #ifdef MOZ_XUL
   NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULCommandDispatcher, nsDOMGenericSH,
                                       DOM_DEFAULT_SCRIPTABLE_FLAGS)
 #endif
   NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(XULControllers, nsNonDOMObjectSH,
                                       DEFAULT_SCRIPTABLE_FLAGS)
-  NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(BoxObject, nsDOMGenericSH,
-                                      DEFAULT_SCRIPTABLE_FLAGS)
 #ifdef MOZ_XUL
   NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(TreeSelection, nsDOMGenericSH,
                                       DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CHROME_XBL_CLASSINFO_DATA(TreeContentView, nsDOMGenericSH,
                                       DEFAULT_SCRIPTABLE_FLAGS)
 #endif
 
 #ifdef MOZ_XUL
@@ -691,20 +688,16 @@ nsDOMClassInfo::Init()
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMXULCommandDispatcher)
   DOM_CLASSINFO_MAP_END
 #endif
 
   DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(XULControllers, nsIControllers)
     DOM_CLASSINFO_MAP_ENTRY(nsIControllers)
   DOM_CLASSINFO_MAP_END
 
-  DOM_CLASSINFO_MAP_BEGIN(BoxObject, nsIBoxObject)
-    DOM_CLASSINFO_MAP_ENTRY(nsIBoxObject)
-  DOM_CLASSINFO_MAP_END
-
 #ifdef MOZ_XUL
   DOM_CLASSINFO_MAP_BEGIN(TreeSelection, nsITreeSelection)
     DOM_CLASSINFO_MAP_ENTRY(nsITreeSelection)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(TreeContentView, nsITreeContentView)
     DOM_CLASSINFO_MAP_ENTRY(nsITreeContentView)
     DOM_CLASSINFO_MAP_ENTRY(nsITreeView)
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -14,17 +14,16 @@ DOMCI_CLASS(CSSImportRule)
 DOMCI_CLASS(CSSMediaRule)
 DOMCI_CLASS(CSSNameSpaceRule)
 
 // XUL classes
 #ifdef MOZ_XUL
 DOMCI_CLASS(XULCommandDispatcher)
 #endif
 DOMCI_CLASS(XULControllers)
-DOMCI_CLASS(BoxObject)
 #ifdef MOZ_XUL
 DOMCI_CLASS(TreeSelection)
 DOMCI_CLASS(TreeContentView)
 #endif
 
 #ifdef MOZ_XUL
 DOMCI_CLASS(XULTemplateBuilder)
 DOMCI_CLASS(XULTreeBuilder)
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -170,16 +170,20 @@ DOMInterfaces = {
     'nativeType': 'mozilla::dom::bluetooth::BluetoothPairingHandle',
 },
 
 'BluetoothPairingListener': {
     'nativeType':
       'mozilla::dom::bluetooth::BluetoothPairingListener',
 },
 
+'BoxObject': {
+    'resultNotAddRefed': ['element'],
+},
+
 'CameraCapabilities': {
     'nativeType': 'mozilla::dom::CameraCapabilities',
     'headerFile': 'DOMCameraCapabilities.h'
 },
 
 'CameraControl': {
     'nativeType': 'mozilla::nsDOMCameraControl',
     'headerFile': 'DOMCameraControl.h',
@@ -861,16 +865,20 @@ DOMInterfaces = {
     'headerFile' : 'nsPluginArray.h',
     'nativeType': 'nsPluginElement',
 },
 
 'PluginArray': {
     'nativeType': 'nsPluginArray',
 },
 
+'PopupBoxObject': {
+    'resultNotAddRefed': ['triggerNode', 'anchorNode'],
+},
+
 'Position': {
     'headerFile': 'nsGeoPosition.h'
 },
 
 'PositionError': {
     'headerFile': 'nsGeolocation.h'
 },
 
@@ -1797,31 +1805,30 @@ def addExternalIface(iface, nativeType=N
 addExternalIface('ApplicationCache', nativeType='nsIDOMOfflineResourceList')
 addExternalIface('Counter')
 addExternalIface('CSSRule')
 addExternalIface('RTCDataChannel', nativeType='nsIDOMDataChannel')
 addExternalIface('HitRegionOptions', nativeType='nsISupports')
 addExternalIface('imgINotificationObserver', nativeType='imgINotificationObserver')
 addExternalIface('imgIRequest', nativeType='imgIRequest', notflattened=True)
 addExternalIface('MenuBuilder', nativeType='nsIMenuBuilder', notflattened=True)
-addExternalIface('MozBoxObject', nativeType='nsIBoxObject')
 addExternalIface('MozControllers', nativeType='nsIControllers')
 addExternalIface('MozFrameLoader', nativeType='nsIFrameLoader', notflattened=True)
 addExternalIface('MozFrameRequestCallback', nativeType='nsIFrameRequestCallback',
                  notflattened=True)
 addExternalIface('MozMmsMessage')
 addExternalIface('MozObserver', nativeType='nsIObserver', notflattened=True)
 addExternalIface('MozRDFCompositeDataSource', nativeType='nsIRDFCompositeDataSource',
                  notflattened=True)
 addExternalIface('MozRDFResource', nativeType='nsIRDFResource', notflattened=True)
 addExternalIface('MozSmsMessage')
-addExternalIface('MozTreeBoxObject', nativeType='nsITreeBoxObject',
-                 notflattened=True)
 addExternalIface('MozTreeColumn', nativeType='nsITreeColumn',
                  headerFile='nsITreeColumns.h')
+addExternalIface('MozTreeView', nativeType='nsITreeView',
+                  headerFile='nsITreeView.h')
 addExternalIface('MozWakeLockListener', headerFile='nsIDOMWakeLockListener.h')
 addExternalIface('MozXULTemplateBuilder', nativeType='nsIXULTemplateBuilder')
 addExternalIface('nsIBrowserDOMWindow', nativeType='nsIBrowserDOMWindow',
                  notflattened=True)
 addExternalIface('nsIControllers', nativeType='nsIControllers')
 addExternalIface('nsIDOMCrypto', nativeType='nsIDOMCrypto',
                  headerFile='Crypto.h')
 addExternalIface('nsIInputStreamCallback', nativeType='nsIInputStreamCallback',
@@ -1830,16 +1837,17 @@ addExternalIface('nsIFile', nativeType='
 addExternalIface('nsIMessageBroadcaster', nativeType='nsIMessageBroadcaster',
                  headerFile='nsIMessageManager.h', notflattened=True)
 addExternalIface('nsISelectionListener', nativeType='nsISelectionListener')
 addExternalIface('nsIStreamListener', nativeType='nsIStreamListener', notflattened=True)
 addExternalIface('nsISupports', nativeType='nsISupports')
 addExternalIface('nsIDocShell', nativeType='nsIDocShell', notflattened=True)
 addExternalIface('nsIEditor', nativeType='nsIEditor', notflattened=True)
 addExternalIface('nsIVariant', nativeType='nsIVariant', notflattened=True)
+addExternalIface('nsIScriptableRegion', nativeType='nsIScriptableRegion', notflattened=True)
 addExternalIface('OutputStream', nativeType='nsIOutputStream',
                  notflattened=True)
 addExternalIface('Principal', nativeType='nsIPrincipal',
                  headerFile='nsIPrincipal.h', notflattened=True)
 addExternalIface('StackFrame', nativeType='nsIStackFrame',
                  headerFile='nsIException.h', notflattened=True)
 addExternalIface('URI', nativeType='nsIURI', headerFile='nsIURI.h',
                  notflattened=True)
--- a/dom/events/test/test_bug602962.xul
+++ b/dom/events/test/test_bug602962.xul
@@ -25,36 +25,35 @@ var oldWidth = 0, oldHeight = 0;
 var win = null;
 
 function openWindow() {
   win = window.open("chrome://mochitests/content/chrome/dom/events/test/bug602962.xul", "_blank", "width=600,height=600");
 }
 
 function doTest() {
   scrollbox = win.document.getElementById("page-scrollbox");
-  sbo = scrollbox.boxObject.QueryInterface(Components.interfaces.nsIScrollBoxObject);
+  sbo = scrollbox.boxObject;
   content = win.document.getElementById("page-box");
   content.style.width = 400 + "px";
   
   win.addEventListener("resize", function() {
     win.removeEventListener("resize", arguments.callee, false);
 
     sbo.scrollBy(200, 0);
     setTimeout(function() { resize(); }, 0);
   }, false);
 
   oldWidth = win.outerWidth;
   oldHeight = win.outerHeight;
   win.resizeTo(200, 400);
 }
 
 function resize() {
-  let x = {}, y = {};
-  sbo.getPosition(x, y);
-  scrollX = x.value, scrollY = y.value;
+  scrollX = sbo.positionX;
+  scrollY = sbo.positionY;
 
   win.addEventListener("resize", function() {
     content.style.width = (oldWidth + 400) + "px";
     win.removeEventListener("resize", arguments.callee, true);
     
     setTimeout(function() {
       finish();
     }, 0);
@@ -67,20 +66,18 @@ function finish() {
   if (win.outerWidth != oldWidth ||
       win.outerHeight != oldHeight) {
     // We should eventually get back to the original size.
     setTimeout(finish, 0);
     return;
   }
   sbo.scrollBy(scrollX, scrollY);
 
-  let x = {}, y = {};
-  sbo.getPosition(x, y);
-  is(x.value, 200, "Scroll X should have been restored to the value before the resize");
-  is(y.value, 0, "Scroll Y should have been restored to the value before the resize");
+  is(sbo.positionX, 200, "Scroll X should have been restored to the value before the resize");
+  is(sbo.positionY, 0, "Scroll Y should have been restored to the value before the resize");
 
   is(win.outerWidth, oldWidth, "Width should be resized");
   is(win.outerHeight, oldHeight, "Height should be resized");
   win.close();
   SimpleTest.finish();
 }
 
 SimpleTest.waitForExplicitFinish();
--- a/dom/tests/mochitest/general/test_interfaces.html
+++ b/dom/tests/mochitest/general/test_interfaces.html
@@ -668,16 +668,18 @@ var interfaceNamesInGlobalScope =
     "MediaStreamAudioSourceNode",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "MediaStreamEvent", pref: "media.peerconnection.enabled"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "MediaStreamTrackEvent", pref: "media.peerconnection.enabled"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "MediaStreamTrack",
 // IMPORTANT: Do not change this list without review from a DOM peer!
+    {name: "MenuBoxObject", xbl: true},
+// IMPORTANT: Do not change this list without review from a DOM peer!
     "MessageEvent",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "MessagePort",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "MimeType",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "MimeTypeArray",
 // IMPORTANT: Do not change this list without review from a DOM peer!
@@ -858,16 +860,18 @@ var interfaceNamesInGlobalScope =
     "PluginArray",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "PointerEvent", pref: "dom.w3c_pointer_events.enabled"},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "PopStateEvent",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "PopupBlockedEvent",
 // IMPORTANT: Do not change this list without review from a DOM peer!
+    {name: "PopupBoxObject", xbl: true},
+// IMPORTANT: Do not change this list without review from a DOM peer!
     "ProcessingInstruction",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "ProgressEvent",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "Promise",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "PropertyNodeList",
 // IMPORTANT: Do not change this list without review from a DOM peer!
new file mode 100644
--- /dev/null
+++ b/dom/webidl/BoxObject.webidl
@@ -0,0 +1,33 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/.
+ */
+
+[Func="IsChromeOrXBL"]
+interface BoxObject {
+  readonly attribute Element? element;
+
+  readonly attribute long x;
+  readonly attribute long y;
+  [Throws]
+  readonly attribute long screenX;
+  [Throws]
+  readonly attribute long screenY;
+  readonly attribute long width;
+  readonly attribute long height;
+
+  nsISupports? getPropertyAsSupports(DOMString propertyName);
+  void setPropertyAsSupports(DOMString propertyName, nsISupports value);
+  [Throws]
+  DOMString? getProperty(DOMString propertyName);
+  void setProperty(DOMString propertyName, DOMString propertyValue);
+  void removeProperty(DOMString propertyName);
+
+  // for stepping through content in the expanded dom with box-ordinal-group order
+  readonly attribute Element? parentBox;
+  readonly attribute Element? firstChild;
+  readonly attribute Element? lastChild;
+  readonly attribute Element? nextSibling;
+  readonly attribute Element? previousSibling;
+};
new file mode 100644
--- /dev/null
+++ b/dom/webidl/ContainerBoxObject.webidl
@@ -0,0 +1,12 @@
+
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/.
+ */
+
+[NoInterfaceObject]
+interface ContainerBoxObject : BoxObject {
+    [ChromeOnly]
+    readonly attribute nsIDocShell? docShell;
+};
--- a/dom/webidl/LegacyQueryInterface.webidl
+++ b/dom/webidl/LegacyQueryInterface.webidl
@@ -15,16 +15,17 @@ interface LegacyQueryInterface {
   // Legacy QueryInterface, only exposed to chrome or XBL code on the
   // main thread.
   [Exposed=Window]
   nsISupports queryInterface(IID iid);
 };
 
 Attr implements LegacyQueryInterface;
 BarProp implements LegacyQueryInterface;
+BoxObject implements LegacyQueryInterface;
 CaretPosition implements LegacyQueryInterface;
 Comment implements LegacyQueryInterface;
 Crypto implements LegacyQueryInterface;
 CSSPrimitiveValue implements LegacyQueryInterface;
 CSSStyleDeclaration implements LegacyQueryInterface;
 CSSValueList implements LegacyQueryInterface;
 DOMImplementation implements LegacyQueryInterface;
 DOMParser implements LegacyQueryInterface;
new file mode 100644
--- /dev/null
+++ b/dom/webidl/ListBoxObject.webidl
@@ -0,0 +1,21 @@
+
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/.
+ */
+
+[NoInterfaceObject]
+interface ListBoxObject : BoxObject {
+
+  long getRowCount();
+  long getNumberOfVisibleRows();
+  long getIndexOfFirstVisibleRow();
+
+  void ensureIndexIsVisible(long rowIndex);
+  void scrollToIndex(long rowIndex);
+  void scrollByLines(long numLines);
+
+  Element? getItemAtIndex(long index);
+  long getIndexOfItem(Element item);
+};
new file mode 100644
--- /dev/null
+++ b/dom/webidl/MenuBoxObject.webidl
@@ -0,0 +1,19 @@
+
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/.
+ */
+
+[Func="IsChromeOrXBL"]
+interface MenuBoxObject : BoxObject {
+
+  void openMenu(boolean openFlag);
+
+  attribute Element? activeChild;
+
+  boolean handleKeyPress(KeyboardEvent keyEvent);
+
+  readonly attribute boolean openedWithKey;
+
+};
rename from layout/xul/nsIPopupBoxObject.idl
rename to dom/webidl/PopupBoxObject.webidl
--- a/layout/xul/nsIPopupBoxObject.idl
+++ b/dom/webidl/PopupBoxObject.webidl
@@ -1,84 +1,77 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
-#include "nsISupports.idl"
-
-interface nsIDOMElement;
-interface nsIDOMNode;
-interface nsIDOMEvent;
-interface nsIDOMClientRect;
-
-[scriptable, uuid(492861e3-d168-410f-b2bb-6eb8ce503d4a)]
-interface nsIPopupBoxObject : nsISupports
+[Func="IsChromeOrXBL"]
+interface PopupBoxObject : BoxObject
 {
   /**
    *  This method is deprecated. Use openPopup or openPopupAtScreen instead.
    */
-  void showPopup(in nsIDOMElement srcContent, in nsIDOMElement popupContent,
-                 in long xpos, in long ypos,
-                 in wstring popupType, in wstring anchorAlignment, 
-                 in wstring popupAlignment);
+  void showPopup(Element? srcContent, Element popupContent,
+                 long xpos, long ypos,
+                 DOMString popupType, DOMString anchorAlignment,
+                 DOMString popupAlignment);
 
   /**
    *  Hide the popup if it is open. The cancel argument is used as a hint that
    *  the popup is being closed because it has been cancelled, rather than
    *  something being selected within the panel.
    *
    * @param cancel if true, then the popup is being cancelled.
    */
-  void hidePopup([optional] in bool cancel);
+  void hidePopup(optional boolean cancel = false);
 
-  /** 
+  /**
    * Allow the popup to automatically position itself.
    */
   attribute boolean autoPosition;
 
   /**
    * If keyboard navigation is enabled, the keyboard may be used to navigate
    * the menuitems on the popup. Enabling keyboard navigation is the default
    * behaviour and will install capturing key event listeners on the popup
    * that do not propagate key events to the contents. If you wish to place
    * elements in a popup which accept key events, such as textboxes, keyboard
    * navigation should be disabled.
    *
    * Setting ignorekeys="true" on the popup element also disables keyboard
    * navigation, and is recommended over calling this method.
    */
-  void enableKeyboardNavigator(in boolean enableKeyboardNavigator);
+  void enableKeyboardNavigator(boolean enableKeyboardNavigator);
 
-  /** 
+  /**
    * Enable automatic popup dismissal. This only has effect when called
    * on an open popup.
    */
-  void enableRollup(in boolean enableRollup);
+  void enableRollup(boolean enableRollup);
 
   /**
    * Control whether the event that caused the popup to be automatically
    * dismissed ("rolled up") should be consumed, or dispatched as a
    * normal event.  This should be set immediately before calling showPopup()
    * if non-default behavior is desired.
    */
-  const uint32_t ROLLUP_DEFAULT = 0;   /* widget/platform default */
-  const uint32_t ROLLUP_CONSUME = 1;   /* consume the rollup event */
-  const uint32_t ROLLUP_NO_CONSUME = 2; /* don't consume the rollup event */
-  void setConsumeRollupEvent(in uint32_t consume);
+  const unsigned long ROLLUP_DEFAULT = 0;   /* widget/platform default */
+  const unsigned long ROLLUP_CONSUME = 1;   /* consume the rollup event */
+  const unsigned long ROLLUP_NO_CONSUME = 2; /* don't consume the rollup event */
+  void setConsumeRollupEvent(unsigned long consume);
 
-  /** 
+  /**
    * Size the popup to the given dimensions
    */
-  void sizeTo(in long width, in long height);
+  void sizeTo(long width, long height);
 
   /**
    * Move the popup to a point on screen in CSS pixels.
    */
-  void moveTo(in long left, in long top);
+  void moveTo(long left, long top);
 
   /**
    * Open the popup relative to a specified node at a specific location.
    *
    * The popup may be either anchored to another node or opened freely.
    * To anchor a popup to a node, supply an anchor node and set the position
    * to a string indicating the manner in which the popup should be anchored.
    * Possible values for position are:
@@ -88,17 +81,17 @@ interface nsIPopupBoxObject : nsISupport
    *
    * The anchor node does not need to be in the same document as the popup.
    *
    * If the attributesOverride argument is true, the popupanchor, popupalign
    * and position attributes on the popup node override the position value
    * argument. If attributesOverride is false, the attributes are only used
    * if position is empty.
    *
-   * For an anchored popup, the x and y arguments may be used to offset the 
+   * For an anchored popup, the x and y arguments may be used to offset the
    * popup from its anchored position by some distance, measured in CSS pixels.
    * x increases to the right and y increases down. Negative values may also
    * be used to move to the left and upwards respectively.
    *
    * Unanchored popups may be created by supplying null as the anchor node.
    * An unanchored popup appears at the position specified by x and y,
    * relative to the viewport of the document containing the popup node. In
    * this case, position and attributesOverride are ignored.
@@ -106,82 +99,75 @@ interface nsIPopupBoxObject : nsISupport
    * @param anchorElement the node to anchor the popup to, may be null
    * @param position manner is which to anchor the popup to node
    * @param x horizontal offset
    * @param y vertical offset
    * @param isContextMenu true for context menus, false for other popups
    * @param attributesOverride true if popup node attributes override position
    * @param triggerEvent the event that triggered this popup (mouse click for example)
    */
-  void openPopup(in nsIDOMElement anchorElement,
-                 in AString position,
-                 in long x, in long y,
-                 in boolean isContextMenu,
-                 in boolean attributesOverride,
-                 in nsIDOMEvent triggerEvent);
+  void openPopup(Element? anchorElement,
+                 DOMString position,
+                 long x, long y,
+                 boolean isContextMenu,
+                 boolean attributesOverride,
+                 Event? triggerEvent);
 
   /**
    * Open the popup at a specific screen position specified by x and y. This
    * position may be adjusted if it would cause the popup to be off of the
    * screen. The x and y coordinates are measured in CSS pixels, and like all
    * screen coordinates, are given relative to the top left of the primary
    * screen.
    *
    * @param isContextMenu true for context menus, false for other popups
    * @param x horizontal screen position
    * @param y vertical screen position
    * @param triggerEvent the event that triggered this popup (mouse click for example)
    */
-  void openPopupAtScreen(in long x, in long y,
-                         in boolean isContextMenu,
-                         in nsIDOMEvent triggerEvent);
+  void openPopupAtScreen(long x, long y,
+                         boolean isContextMenu,
+                         Event? triggerEvent);
 
   /**
    * Returns the state of the popup:
    *   closed - the popup is closed
    *   open - the popup is open
    *   showing - the popup is in the process of being shown
    *   hiding - the popup is in the process of being hidden
    */
-  readonly attribute AString popupState;
+  readonly attribute DOMString popupState;
 
   /**
    * The node that triggered the popup. If the popup is not open, will return
    * null.
    */
-  readonly attribute nsIDOMNode triggerNode;
+  readonly attribute Node? triggerNode;
 
   /**
    * Retrieve the anchor that was specified to openPopup or for menupopups in a
    * menu, the parent menu.
    */
-  readonly attribute nsIDOMElement anchorNode;
+  readonly attribute Element? anchorNode;
 
   /**
    * Retrieve the screen rectangle of the popup, including the area occupied by
    * any titlebar or borders present.
    */
-  nsIDOMClientRect getOuterScreenRect();
+  DOMRect getOuterScreenRect();
 
   /**
    * Move an open popup to the given anchor position. The arguments have the same
    * meaning as the corresponding argument to openPopup. This method has no effect
    * on popups that are not open.
    */
-  void moveToAnchor(in nsIDOMElement anchorElement,
-                    in AString position,
-                    in long x, in long y,
-                    in boolean attributesOverride);
+  void moveToAnchor(Element? anchorElement,
+                    DOMString position,
+                    long x, long y,
+                    boolean attributesOverride);
 
   /** Returns the alignment position where the popup has appeared relative to its
    *  anchor node or point, accounting for any flipping that occurred.
    */
-  readonly attribute AString alignmentPosition;
+  readonly attribute DOMString alignmentPosition;
   readonly attribute long alignmentOffset;
-};
 
-%{C++
-class nsIBoxObject;
-
-nsresult
-NS_NewPopupBoxObject(nsIBoxObject** aResult);
-
-%}
+};
new file mode 100644
--- /dev/null
+++ b/dom/webidl/ScrollBoxObject.webidl
@@ -0,0 +1,70 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/.
+ */
+
+[NoInterfaceObject]
+interface ScrollBoxObject : BoxObject {
+
+  /**
+   * Scroll to the given coordinates, in css pixels.
+   * (0,0) will put the top left corner of the scrolled element's padding-box
+   * at the top left corner of the scrollport (which is its inner-border-box).
+   * Values will be clamped to legal values.
+   */
+  [Throws]
+  void scrollTo(long x, long y);
+
+  /**
+   * Scroll the given amount of device pixels to the right and down.
+   * Values will be clamped to make the resuling position legal.
+   */
+  [Throws]
+  void scrollBy(long dx, long dy);
+  [Throws]
+  void scrollByLine(long dlines);
+  [Throws]
+  void scrollByIndex(long dindexes);
+  [Throws]
+  void scrollToLine(long line);
+  [Throws]
+  void scrollToElement(Element child);
+  [Throws]
+  void scrollToIndex(long index);
+
+  /**
+   * Get the current scroll position in css pixels.
+   * @see scrollTo for the definition of x and y.
+   */
+  [Pure, Throws]
+  readonly attribute long positionX;
+  [Pure, Throws]
+  readonly attribute long positionY;
+  [Pure, Throws]
+  readonly attribute long scrolledWidth;
+  [Pure, Throws]
+  readonly attribute long scrolledHeight;
+
+  /**
+   * DEPRECATED: Please use positionX and positionY
+   *
+   * Get the current scroll position in css pixels.
+   * @see scrollTo for the definition of x and y.
+   */
+  [Throws]
+  void getPosition(object x, object y);
+
+  /**
+   * DEPRECATED: Please use scrolledWidth and scrolledHeight
+   */
+  [Throws]
+  void getScrolledSize(object width, object height);
+
+  [Throws]
+  void ensureElementIsVisible(Element child);
+  [Throws]
+  void ensureIndexIsVisible(long index);
+  [Throws]
+  void ensureLineIsVisible(long line);
+};
copy from layout/xul/tree/nsITreeBoxObject.idl
copy to dom/webidl/TreeBoxObject.webidl
--- a/layout/xul/tree/nsITreeBoxObject.idl
+++ b/dom/webidl/TreeBoxObject.webidl
@@ -1,64 +1,68 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/. */
 
-#include "nsISupports.idl"
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/.
+ */
 
-interface nsIDOMElement;
-interface nsITreeView;
-interface nsITreeSelection;
-interface nsITreeColumn;
-interface nsITreeColumns;
+interface MozTreeView;
+interface MozTreeColumn;
 interface nsIScriptableRegion;
 
-[scriptable, uuid(64BA5199-C4F4-4498-BBDC-F8E4C369086C)]
-interface nsITreeBoxObject : nsISupports
-{
+dictionary TreeCellInfo {
+    long row = 0;
+    MozTreeColumn? col = null;
+    DOMString childElt = "";
+};
+
+[NoInterfaceObject]
+interface TreeBoxObject : BoxObject {
+
   /**
    * Obtain the columns.
    */
-  readonly attribute nsITreeColumns columns;
+  readonly attribute TreeColumns? columns;
 
   /**
    * The view that backs the tree and that supplies it with its data.
    * It is dynamically settable, either using a view attribute on the
    * tree tag or by setting this attribute to a new value.
    */
-  attribute nsITreeView view;
+  [SetterThrows]
+  attribute MozTreeView? view;
 
   /**
    * Whether or not we are currently focused.
    */
   attribute boolean focused;
 
   /**
    * Obtain the treebody content node
    */
-  readonly attribute nsIDOMElement treeBody;
+  readonly attribute Element? treeBody;
 
   /**
    * Obtain the height of a row.
    */
   readonly attribute long rowHeight;
 
   /**
    * Obtain the width of a row.
    */
   readonly attribute long rowWidth;
 
   /**
-   * Get the pixel position of the horizontal scrollbar. 
+   * Get the pixel position of the horizontal scrollbar.
    */
   readonly attribute long horizontalPosition;
 
   /**
-   * Return the region for the visible parts of the selection, in device pixels.
+   * Return the region for the visible parts of the selection, in device pixels
    */
   readonly attribute nsIScriptableRegion selectionRegion;
 
   /**
    * Get the index of the first visible row.
    */
   long getFirstVisibleRow();
 
@@ -70,110 +74,125 @@ interface nsITreeBoxObject : nsISupports
   /**
    * Gets the number of possible visible rows.
    */
   long getPageLength();
 
   /**
    * Ensures that a row at a given index is visible.
    */
-  void ensureRowIsVisible(in long index);
+  void ensureRowIsVisible(long index);
 
   /**
    * Ensures that a given cell in the tree is visible.
    */
-  void ensureCellIsVisible(in long row, in nsITreeColumn col);
+  void ensureCellIsVisible(long row, MozTreeColumn? col);
 
   /**
    * Scrolls such that the row at index is at the top of the visible view.
    */
-  void scrollToRow(in long index);
+  void scrollToRow(long index);
 
   /**
    * Scroll the tree up or down by numLines lines. Positive
    * values move down in the tree. Prevents scrolling off the
-   * end of the tree. 
+   * end of the tree.
    */
-  void scrollByLines(in long numLines);
+  void scrollByLines(long numLines);
 
   /**
    * Scroll the tree up or down by numPages pages. A page
    * is considered to be the amount displayed by the tree.
    * Positive values move down in the tree. Prevents scrolling
    * off the end of the tree.
    */
-  void scrollByPages(in long numPages);
-  
-  /**
-   * Scrolls such that a given cell is visible (if possible) 
-   * at the top left corner of the visible view. 
-   */
-  void scrollToCell(in long row, in nsITreeColumn col);
+  void scrollByPages(long numPages);
 
   /**
-   * Scrolls horizontally so that the specified column is 
+   * Scrolls such that a given cell is visible (if possible)
+   * at the top left corner of the visible view.
+   */
+  void scrollToCell(long row, MozTreeColumn? col);
+
+  /**
+   * Scrolls horizontally so that the specified column is
    * at the left of the view (if possible).
    */
-  void scrollToColumn(in nsITreeColumn col);
+  void scrollToColumn(MozTreeColumn? col);
 
   /**
    * Scroll to a specific horizontal pixel position.
    */
-  void scrollToHorizontalPosition(in long horizontalPosition);
+  void scrollToHorizontalPosition(long horizontalPosition);
 
   /**
    * Invalidation methods for fine-grained painting control.
    */
   void invalidate();
-  void invalidateColumn(in nsITreeColumn col);
-  void invalidateRow(in long index);
-  void invalidateCell(in long row, in nsITreeColumn col);
-  void invalidateRange(in long startIndex, in long endIndex);
-  void invalidateColumnRange(in long startIndex, in long endIndex,
-                             in nsITreeColumn col);
+  void invalidateColumn(MozTreeColumn? col);
+  void invalidateRow(long index);
+  void invalidateCell(long row, MozTreeColumn? col);
+  void invalidateRange(long startIndex, long endIndex);
+  void invalidateColumnRange(long startIndex, long endIndex, MozTreeColumn? col);
 
   /**
    * A hit test that can tell you what row the mouse is over.
    * returns -1 for invalid mouse coordinates.
    *
    * The coordinate system is the client coordinate system for the
    * document this boxObject lives in, and the units are CSS pixels.
    */
-  long getRowAt(in long x, in long y);
+  long getRowAt(long x, long y);
 
   /**
-   * A hit test that can tell you what cell the mouse is over.  Row is the row index
-   * hit,  returns -1 for invalid mouse coordinates.  ColID is the column hit.
-   * ChildElt is the pseudoelement hit: this can have values of
+   * A hit test that can tell you what cell the mouse is over.
+   * TreeCellInfo.row is the row index hit,  returns -1 for invalid mouse
+   * coordinates.  TreeCellInfo.col is the column hit.
+   * TreeCellInfo.childElt is the pseudoelement hit: this can have values of
    * "cell", "twisty", "image", and "text".
    *
    * The coordinate system is the client coordinate system for the
    * document this boxObject lives in, and the units are CSS pixels.
    */
-  void getCellAt(in long x, in long y, out long row, out nsITreeColumn col, out ACString childElt);
+  [Throws]
+  TreeCellInfo getCellAt(long x, long y);
 
-  /** 
-   * Find the coordinates of an element within a specific cell. 
+  /**
+   * DEPRECATED: please use above version
+   */
+  [Throws]
+  void getCellAt(long x, long y, object row, object column, object childElt);
+
+  /**
+   * Find the coordinates of an element within a specific cell.
    */
-  void getCoordsForCellItem(in long row, in nsITreeColumn col, in ACString element, 
-                            out long x, out long y, out long width, out long height);
+  [Throws]
+  DOMRect? getCoordsForCellItem(long row, MozTreeColumn col, DOMString element);
 
-  /** 
+  /**
+   * DEPRECATED: Please use above version
+   */
+  [Throws]
+  void getCoordsForCellItem(long row, MozTreeColumn col, DOMString element,
+                            object x, object y, object width, object height);
+
+  /**
    * Determine if the text of a cell is being cropped or not.
    */
-  boolean isCellCropped(in long row, in nsITreeColumn col);
+  [Throws]
+  boolean isCellCropped(long row, MozTreeColumn? col);
 
   /**
    * The view is responsible for calling these notification methods when
    * rows are added or removed.  Index is the position at which the new
    * rows were added or at which rows were removed.  For
    * non-contiguous additions/removals, this method should be called multiple times.
    */
-  void rowCountChanged(in long index, in long count);
-  
+  void rowCountChanged(long index, long count);
+
   /**
    * Notify the tree that the view is about to perform a batch
    * update, that is, add, remove or invalidate several rows at once.
    * This must be followed by calling endUpdateBatch(), otherwise the tree
    * will get out of sync.
    */
   void beginUpdateBatch();
 
--- a/dom/webidl/TreeColumns.webidl
+++ b/dom/webidl/TreeColumns.webidl
@@ -1,21 +1,20 @@
 /* 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/. */
 
-interface MozTreeBoxObject;
 interface MozTreeColumn;
 
 [Func="IsChromeOrXBL"]
 interface TreeColumns {
   /**
    * The tree widget for these columns.
    */
-  readonly attribute MozTreeBoxObject? tree;
+  readonly attribute TreeBoxObject? tree;
 
   /**
    * The number of columns.
    */
   readonly attribute unsigned long count;
 
   /**
    * An alias for count (for the benefit of scripts which treat this as an
--- a/dom/webidl/XULDocument.webidl
+++ b/dom/webidl/XULDocument.webidl
@@ -3,17 +3,16 @@
  * 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/.
  *
  * The origin of this IDL file is:
  * dom/interfaces/xul/nsIDOMXULDocument.idl
  */
 
 interface XULCommandDispatcher;
-interface MozBoxObject;
 interface MozObserver;
 
 [Func="IsChromeOrXBL"]
 interface XULDocument : Document {
            attribute Node? popupNode;
 
   /**
    * These attributes correspond to trustedGetPopupNode().rangeOffset and
@@ -46,13 +45,13 @@ interface XULDocument : Document {
                                DOMString attr);
   void removeBroadcastListenerFor(Element broadcaster, Element observer,
                                   DOMString attr);
 
   [Throws]
   void persist([TreatNullAs=EmptyString] DOMString id, DOMString attr);
 
   [Throws]
-  MozBoxObject? getBoxObjectFor(Element? element);
+  BoxObject? getBoxObjectFor(Element? element);
 
   [Throws]
   void loadOverlay(DOMString url, MozObserver? observer);
 };
--- a/dom/webidl/XULElement.webidl
+++ b/dom/webidl/XULElement.webidl
@@ -1,15 +1,14 @@
 /* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/.
  */
 
-interface MozBoxObject;
 interface MozControllers;
 interface MozFrameLoader;
 interface MozRDFCompositeDataSource;
 interface MozRDFResource;
 interface MozXULTemplateBuilder;
 
 [Func="IsChromeOrXBL"]
 interface XULElement : Element {
@@ -90,17 +89,17 @@ interface XULElement : Element {
 
   readonly attribute MozRDFCompositeDataSource? database;
   readonly attribute MozXULTemplateBuilder?     builder;
   [Throws]
   readonly attribute MozRDFResource?            resource;
   [Throws]
   readonly attribute MozControllers             controllers;
   [Throws]
-  readonly attribute MozBoxObject?              boxObject;
+  readonly attribute BoxObject?                 boxObject;
 
   [Throws]
   void                      focus();
   [Throws]
   void                      blur();
   [Throws]
   void                      click();
   void                      doCommand();
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -48,16 +48,17 @@ WEBIDL_FILES = [
     'AudioTrackList.webidl',
     'AutocompleteInfo.webidl',
     'BarProp.webidl',
     'BatteryManager.webidl',
     'BeforeAfterKeyboardEvent.webidl',
     'BeforeUnloadEvent.webidl',
     'BiquadFilterNode.webidl',
     'Blob.webidl',
+    'BoxObject.webidl',
     'BrowserElementDictionaries.webidl',
     'CallsList.webidl',
     'CameraCapabilities.webidl',
     'CameraControl.webidl',
     'CameraManager.webidl',
     'CameraUtil.webidl',
     'CanvasRenderingContext2D.webidl',
     'CaretPosition.webidl',
@@ -69,16 +70,17 @@ WEBIDL_FILES = [
     'ChromeNotifications.webidl',
     'ClipboardEvent.webidl',
     'CommandEvent.webidl',
     'Comment.webidl',
     'CompositionEvent.webidl',
     'Console.webidl',
     'Constraints.webidl',
     'Contacts.webidl',
+    'ContainerBoxObject.webidl',
     'ConvolverNode.webidl',
     'Coordinates.webidl',
     'CSPReport.webidl',
     'CSS.webidl',
     'CSSPrimitiveValue.webidl',
     'CSSRuleList.webidl',
     'CSSStyleDeclaration.webidl',
     'CSSStyleSheet.webidl',
@@ -245,29 +247,31 @@ WEBIDL_FILES = [
     'InterAppConnection.webidl',
     'InterAppConnectionRequest.webidl',
     'InterAppMessagePort.webidl',
     'KeyAlgorithm.webidl',
     'KeyboardEvent.webidl',
     'KeyEvent.webidl',
     'LegacyQueryInterface.webidl',
     'LinkStyle.webidl',
+    'ListBoxObject.webidl',
     'LocalMediaStream.webidl',
     'Location.webidl',
     'MediaElementAudioSourceNode.webidl',
     'MediaError.webidl',
     'MediaList.webidl',
     'MediaQueryList.webidl',
     'MediaRecorder.webidl',
     'MediaSource.webidl',
     'MediaStream.webidl',
     'MediaStreamAudioDestinationNode.webidl',
     'MediaStreamAudioSourceNode.webidl',
     'MediaStreamTrack.webidl',
     'MediaTrackConstraintSet.webidl',
+    'MenuBoxObject.webidl',
     'MessageChannel.webidl',
     'MessageEvent.webidl',
     'MessagePort.webidl',
     'MessagePortList.webidl',
     'MimeType.webidl',
     'MimeTypeArray.webidl',
     'MouseEvent.webidl',
     'MouseScrollEvent.webidl',
@@ -315,16 +319,17 @@ WEBIDL_FILES = [
     'PerformanceResourceTiming.webidl',
     'PerformanceTiming.webidl',
     'PeriodicWave.webidl',
     'PermissionSettings.webidl',
     'PhoneNumberService.webidl',
     'Plugin.webidl',
     'PluginArray.webidl',
     'PointerEvent.webidl',
+    'PopupBoxObject.webidl',
     'Position.webidl',
     'PositionError.webidl',
     'ProcessingInstruction.webidl',
     'ProfileTimelineMarker.webidl',
     'Promise.webidl',
     'PromiseDebugging.webidl',
     'PushManager.webidl',
     'RadioNodeList.webidl',
@@ -342,16 +347,17 @@ WEBIDL_FILES = [
     'RTCPeerConnectionStatic.webidl',
     'RTCRtpReceiver.webidl',
     'RTCRtpSender.webidl',
     'RTCSessionDescription.webidl',
     'RTCStatsReport.webidl',
     'Screen.webidl',
     'ScriptProcessorNode.webidl',
     'ScrollAreaEvent.webidl',
+    'ScrollBoxObject.webidl',
     'Selection.webidl',
     'ServiceWorker.webidl',
     'ServiceWorkerContainer.webidl',
     'ServiceWorkerGlobalScope.webidl',
     'ServiceWorkerRegistration.webidl',
     'SettingChangeNotification.webidl',
     'SettingsManager.webidl',
     'ShadowRoot.webidl',
@@ -487,16 +493,17 @@ WEBIDL_FILES = [
     'TextTrackCueList.webidl',
     'TextTrackList.webidl',
     'TimeEvent.webidl',
     'TimeRanges.webidl',
     'Touch.webidl',
     'TouchEvent.webidl',
     'TouchList.webidl',
     'TransitionEvent.webidl',
+    'TreeBoxObject.webidl',
     'TreeColumns.webidl',
     'TreeWalker.webidl',
     'UDPMessageEvent.webidl',
     'UDPSocket.webidl',
     'UIEvent.webidl',
     'UndoManager.webidl',
     'URL.webidl',
     'URLSearchParams.webidl',
--- a/dom/xslt/tests/buster/buster-handlers.js
+++ b/dom/xslt/tests/buster/buster-handlers.js
@@ -3,17 +3,17 @@
  * 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/. */
 
 var xalan_field;
 
 function onLoad()
 {
     view.tree = document.getElementById('out');
-    view.boxObject = view.tree.boxObject.QueryInterface(Components.interfaces.nsITreeBoxObject);
+    view.boxObject = view.tree.boxObject;
     {  
         view.mIframe = document.getElementById('hiddenHtml');
         view.mIframe.webNavigation.allowPlugins = false;
         view.mIframe.webNavigation.allowJavascript = false;
         view.mIframe.webNavigation.allowMetaRedirects = false;
         view.mIframe.webNavigation.allowImages = false;
     }
     view.database = view.tree.database;
--- a/editor/composer/test/test_bug434998.xul
+++ b/editor/composer/test/test_bug434998.xul
@@ -93,17 +93,17 @@ https://bugzilla.mozilla.org/show_bug.cg
     mEditor: null
   };
 
   var progress, progressListener;
 
   function runTest() {
     var newEditorElement = document.getElementById("editor");
     newEditorElement.makeEditable("html", true);
-    var docShell = newEditorElement.boxObject.QueryInterface(Components.interfaces.nsIEditorBoxObject).docShell;
+    var docShell = newEditorElement.boxObject.docShell;
     progress = docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIWebProgress);
     progressListener = new EditorContentListener(newEditorElement);
     progress.addProgressListener(progressListener, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
     newEditorElement.setAttribute("src", "data:text/html,");
   }
 ]]>
 </script>
 </window>
--- a/editor/libeditor/tests/test_bug607584.xul
+++ b/editor/libeditor/tests/test_bug607584.xul
@@ -99,17 +99,17 @@ https://bugzilla.mozilla.org/show_bug.cg
       mEditor: null
   };
 
   var progress, progressListener;
 
   function runTest() {
     var newEditorElement = document.getElementById("editor");
     newEditorElement.makeEditable("html", true);
-    var docShell = newEditorElement.boxObject.QueryInterface(Components.interfaces.nsIEditorBoxObject).docShell;
+    var docShell = newEditorElement.boxObject.docShell;
     progress = docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIWebProgress);
     progressListener = new EditorContentListener(newEditorElement);
     progress.addProgressListener(progressListener, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
     newEditorElement.setAttribute("src", "data:text/html,");
   }
 ]]>
 </script>
 </window>
--- a/editor/libeditor/tests/test_bug616590.xul
+++ b/editor/libeditor/tests/test_bug616590.xul
@@ -89,17 +89,17 @@ https://bugzilla.mozilla.org/show_bug.cg
     mEditor: null
   };
 
   var progress, progressListener;
 
   function runTest() {
     var editorElement = document.getElementById("editor");
     editorElement.makeEditable("htmlmail", true);
-    var docShell = editorElement.boxObject.QueryInterface(Components.interfaces.nsIEditorBoxObject).docShell;
+    var docShell = editorElement.boxObject.docShell;
     progress = docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIWebProgress);
     progressListener = new EditorContentListener(editorElement);
     progress.addProgressListener(progressListener, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
     editorElement.setAttribute("src", "data:text/html,");
   }
 ]]>
 </script>
 </window>
--- a/editor/libeditor/tests/test_bug780908.xul
+++ b/editor/libeditor/tests/test_bug780908.xul
@@ -97,17 +97,17 @@ adapted from test_bug607584.xul by Kent 
       mEditor: null
   };
 
   var progress, progressListener;
 
   function runTest() {
     var newEditorElement = document.getElementById("editor");
     newEditorElement.makeEditable("html", true);
-    var docShell = newEditorElement.boxObject.QueryInterface(Components.interfaces.nsIEditorBoxObject).docShell;
+    var docShell = newEditorElement.boxObject.docShell;
     progress = docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIWebProgress);
     progressListener = new EditorContentListener(newEditorElement);
     progress.addProgressListener(progressListener, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
     newEditorElement.setAttribute("src", "data:text/html,");
   }
 ]]>
 </script>
 </window>
--- a/gfx/tests/unit/test_nsIScriptableRegion.js
+++ b/gfx/tests/unit/test_nsIScriptableRegion.js
@@ -1,16 +1,10 @@
 function run_test()
 {
-  // XXX Work around for the fact that for non-libxul builds loading gfx
-  // components doesn't call up the layout initialisation routine. This should
-  // be fixed/improved by bug 515595.
-  Components.classes["@mozilla.org/layout/xul-boxobject-tree;1"]
-            .createInstance(Components.interfaces.nsIBoxObject);
-
   let rgn = Components.classes["@mozilla.org/gfx/region;1"].createInstance(Components.interfaces.nsIScriptableRegion);
   do_check_true (rgn.getRects() === null)
   rgn.unionRect(0,0,80,60);
   do_check_true (rgn.getRects().toString() == "0,0,80,60")
   rgn.unionRect(90,70,1,1);
   do_check_true (rgn.getRects().toString() == "0,0,80,60,90,70,1,1")
 }
 
--- a/js/xpconnect/src/dom_quickstubs.qsconf
+++ b/js/xpconnect/src/dom_quickstubs.qsconf
@@ -26,24 +26,16 @@ members = [
     #   - nsIDOMJSWindow.{prompt,setTimeout,setInterval,open,openDialog}
     #
     # (And nsIDOMModalContentWindow.returnValue is an attribute of type
     # nsIVariant, which qsgen.py can't handle.)
 
     # dom/interfaces/xpath
     'nsIDOMXPathNSResolver.lookupNamespaceURI',
 
-    # layout/xul/base/public
-    'nsIBoxObject.x',
-    'nsIBoxObject.y',
-    'nsIBoxObject.screenX',
-    'nsIBoxObject.screenY',
-    'nsIBoxObject.width',
-    'nsIBoxObject.height',
-
     ]
 
 # Most interfaces can be found by searching the includePath; to find
 # nsIDOMEvent, for example, just look for nsIDOMEvent.idl.  But IDL filenames
 # for very long interface names are slightly abbreviated, and many interfaces
 # don't have their own files, just for extra wackiness.  So qsgen.py needs
 # a little help.
 #
--- a/layout/reftests/invalidation/540247-1-ref.xul
+++ b/layout/reftests/invalidation/540247-1-ref.xul
@@ -4,18 +4,17 @@
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
 
 <script><![CDATA[
 document.addEventListener("MozReftestInvalidate", runtest, false);
 
 function runtest() {
   document.getElementById('b').height = '100';
 
-  var sbo = document.getElementById('s').boxObject.
-              QueryInterface(Components.interfaces.nsIScrollBoxObject);
+  var sbo = document.getElementById('s').boxObject;
   sbo.scrollTo(0, 1000);
 
   document.documentElement.className = "";
 }
 ]]>
 </script>
 
   <scrollbox id="s" height="200" style="overflow: scroll;">
--- a/layout/reftests/invalidation/540247-1.xul
+++ b/layout/reftests/invalidation/540247-1.xul
@@ -5,18 +5,17 @@
 
 <script><![CDATA[
 document.addEventListener("MozReftestInvalidate", runtest, false);
 
 function runtest() {
   // Make sure that the effects of the scroll are painted to the screen before
   // shrinking the size of the scrolled frame.
   window.addEventListener("MozAfterPaint", finish, false);
-  var sbo = document.getElementById('s').boxObject.
-              QueryInterface(Components.interfaces.nsIScrollBoxObject);
+  var sbo = document.getElementById('s').boxObject;
   sbo.scrollTo(0, 1000);
 }
 
 function finish() {
   document.getElementById('b').height = '100';
   document.documentElement.className = "";
 }
 ]]>
rename from layout/xul/nsBoxObject.cpp
rename to layout/xul/BoxObject.cpp
--- a/layout/xul/nsBoxObject.cpp
+++ b/layout/xul/BoxObject.cpp
@@ -1,14 +1,14 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
-#include "nsBoxObject.h"
+#include "mozilla/dom/BoxObject.h"
 #include "nsCOMPtr.h"
 #include "nsIDocument.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsIContent.h"
 #include "nsContainerFrame.h"
 #include "nsIDocShell.h"
 #include "nsReadableUtils.h"
@@ -19,102 +19,107 @@
 #else
 #include "nsIDOMElement.h"
 #endif
 #include "nsLayoutUtils.h"
 #include "nsISupportsPrimitives.h"
 #include "nsSupportsPrimitives.h"
 #include "mozilla/dom/Element.h"
 #include "nsComponentManagerUtils.h"
-
-using namespace mozilla::dom;
+#include "mozilla/dom/BoxObjectBinding.h"
 
 // Implementation /////////////////////////////////////////////////////////////////
 
+namespace mozilla {
+namespace dom {
+
 // Static member variable initialization
 
 // Implement our nsISupports methods
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(nsBoxObject)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(nsBoxObject)
+NS_IMPL_CYCLE_COLLECTION_CLASS(BoxObject)
+NS_IMPL_CYCLE_COLLECTING_ADDREF(BoxObject)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(BoxObject)
 
-DOMCI_DATA(BoxObject, nsBoxObject)
-
-// QueryInterface implementation for nsBoxObject
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsBoxObject)
+// QueryInterface implementation for BoxObject
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(BoxObject)
+  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsIBoxObject)
   NS_INTERFACE_MAP_ENTRY(nsPIBoxObject)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(BoxObject)
 NS_INTERFACE_MAP_END
 
 static PLDHashOperator
 PropertyTraverser(const nsAString& aKey, nsISupports* aProperty, void* userArg)
 {
-  nsCycleCollectionTraversalCallback *cb = 
+  nsCycleCollectionTraversalCallback *cb =
     static_cast<nsCycleCollectionTraversalCallback*>(userArg);
 
   cb->NoteXPCOMChild(aProperty);
 
   return PL_DHASH_NEXT;
 }
 
-NS_IMPL_CYCLE_COLLECTION_CLASS(nsBoxObject)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(BoxObject)
+  // XXX jmorton: why aren't we unlinking mPropertyTable?
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
-NS_IMPL_CYCLE_COLLECTION_UNLINK_0(nsBoxObject)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsBoxObject)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(BoxObject)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
   if (tmp->mPropertyTable) {
     tmp->mPropertyTable->EnumerateRead(PropertyTraverser, &cb);
   }
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
+NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(BoxObject)
+
 // Constructors/Destructors
-nsBoxObject::nsBoxObject(void)
-  :mContent(nullptr)
+BoxObject::BoxObject()
+  : mContent(nullptr)
 {
 }
 
-nsBoxObject::~nsBoxObject(void)
+BoxObject::~BoxObject()
 {
 }
 
 NS_IMETHODIMP
-nsBoxObject::GetElement(nsIDOMElement** aResult)
+BoxObject::GetElement(nsIDOMElement** aResult)
 {
   if (mContent) {
     return CallQueryInterface(mContent, aResult);
   }
 
   *aResult = nullptr;
   return NS_OK;
 }
 
 // nsPIBoxObject //////////////////////////////////////////////////////////////////////////
 
 nsresult
-nsBoxObject::Init(nsIContent* aContent)
+BoxObject::Init(nsIContent* aContent)
 {
   mContent = aContent;
   return NS_OK;
 }
 
 void
-nsBoxObject::Clear()
+BoxObject::Clear()
 {
   mPropertyTable = nullptr;
   mContent = nullptr;
 }
 
 void
-nsBoxObject::ClearCachedValues()
+BoxObject::ClearCachedValues()
 {
 }
 
 nsIFrame*
-nsBoxObject::GetFrame(bool aFlushLayout)
+BoxObject::GetFrame(bool aFlushLayout)
 {
   nsIPresShell* shell = GetPresShell(aFlushLayout);
   if (!shell)
     return nullptr;
 
   if (!aFlushLayout) {
     // If we didn't flush layout when getting the presshell, we should at least
     // flush to make sure our frame model is up to date.
@@ -127,17 +132,17 @@ nsBoxObject::GetFrame(bool aFlushLayout)
   if (!mContent) {
     return nullptr;
   }
 
   return mContent->GetPrimaryFrame();
 }
 
 nsIPresShell*
-nsBoxObject::GetPresShell(bool aFlushLayout)
+BoxObject::GetPresShell(bool aFlushLayout)
 {
   if (!mContent) {
     return nullptr;
   }
 
   nsCOMPtr<nsIDocument> doc = mContent->GetCurrentDoc();
   if (!doc) {
     return nullptr;
@@ -145,21 +150,21 @@ nsBoxObject::GetPresShell(bool aFlushLay
 
   if (aFlushLayout) {
     doc->FlushPendingNotifications(Flush_Layout);
   }
 
   return doc->GetShell();
 }
 
-nsresult 
-nsBoxObject::GetOffsetRect(nsIntRect& aRect)
+nsresult
+BoxObject::GetOffsetRect(nsIntRect& aRect)
 {
   aRect.SetRect(0, 0, 0, 0);
- 
+
   if (!mContent)
     return NS_ERROR_NOT_INITIALIZED;
 
   // Get the Frame for our content
   nsIFrame* frame = GetFrame(true);
   if (frame) {
     // Get its origin
     nsPoint origin = frame->GetPositionIgnoringScrolling();
@@ -180,168 +185,165 @@ nsBoxObject::GetOffsetRect(nsIntRect& aR
         break;
       }
 
       // Add the parent's origin to our own to get to the
       // right coordinate system
       origin += next->GetPositionOfChildIgnoringScrolling(parent);
       parent = next;
     }
-  
+
     // For the origin, add in the border for the frame
     const nsStyleBorder* border = frame->StyleBorder();
     origin.x += border->GetComputedBorderWidth(NS_SIDE_LEFT);
     origin.y += border->GetComputedBorderWidth(NS_SIDE_TOP);
 
     // And subtract out the border for the parent
     const nsStyleBorder* parentBorder = parent->StyleBorder();
     origin.x -= parentBorder->GetComputedBorderWidth(NS_SIDE_LEFT);
     origin.y -= parentBorder->GetComputedBorderWidth(NS_SIDE_TOP);
 
     aRect.x = nsPresContext::AppUnitsToIntCSSPixels(origin.x);
     aRect.y = nsPresContext::AppUnitsToIntCSSPixels(origin.y);
-    
+
     // Get the union of all rectangles in this and continuation frames.
     // It doesn't really matter what we use as aRelativeTo here, since
     // we only care about the size. Using 'parent' might make things
     // a bit faster by speeding up the internal GetOffsetTo operations.
     nsRect rcFrame = nsLayoutUtils::GetAllInFlowRectsUnion(frame, parent);
     aRect.width = nsPresContext::AppUnitsToIntCSSPixels(rcFrame.width);
     aRect.height = nsPresContext::AppUnitsToIntCSSPixels(rcFrame.height);
   }
 
   return NS_OK;
 }
 
 nsresult
-nsBoxObject::GetScreenPosition(nsIntPoint& aPoint)
+BoxObject::GetScreenPosition(nsIntPoint& aPoint)
 {
   aPoint.x = aPoint.y = 0;
-  
+
   if (!mContent)
     return NS_ERROR_NOT_INITIALIZED;
 
   nsIFrame* frame = GetFrame(true);
   if (frame) {
     nsIntRect rect = frame->GetScreenRect();
     aPoint.x = rect.x;
     aPoint.y = rect.y;
   }
-  
+
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsBoxObject::GetX(int32_t* aResult)
+BoxObject::GetX(int32_t* aResult)
 {
   nsIntRect rect;
   GetOffsetRect(rect);
   *aResult = rect.x;
   return NS_OK;
 }
 
-NS_IMETHODIMP 
-nsBoxObject::GetY(int32_t* aResult)
+NS_IMETHODIMP
+BoxObject::GetY(int32_t* aResult)
 {
   nsIntRect rect;
   GetOffsetRect(rect);
   *aResult = rect.y;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsBoxObject::GetWidth(int32_t* aResult)
+BoxObject::GetWidth(int32_t* aResult)
 {
   nsIntRect rect;
   GetOffsetRect(rect);
   *aResult = rect.width;
   return NS_OK;
 }
 
-NS_IMETHODIMP 
-nsBoxObject::GetHeight(int32_t* aResult)
+NS_IMETHODIMP
+BoxObject::GetHeight(int32_t* aResult)
 {
   nsIntRect rect;
   GetOffsetRect(rect);
   *aResult = rect.height;
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsBoxObject::GetScreenX(int32_t *_retval)
+BoxObject::GetScreenX(int32_t *_retval)
 {
   nsIntPoint position;
   nsresult rv = GetScreenPosition(position);
   if (NS_FAILED(rv)) return rv;
-
   *_retval = position.x;
-
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsBoxObject::GetScreenY(int32_t *_retval)
+BoxObject::GetScreenY(int32_t *_retval)
 {
   nsIntPoint position;
   nsresult rv = GetScreenPosition(position);
   if (NS_FAILED(rv)) return rv;
-
   *_retval = position.y;
-
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsBoxObject::GetPropertyAsSupports(const char16_t* aPropertyName, nsISupports** aResult)
+BoxObject::GetPropertyAsSupports(const char16_t* aPropertyName, nsISupports** aResult)
 {
   NS_ENSURE_ARG(aPropertyName && *aPropertyName);
   if (!mPropertyTable) {
     *aResult = nullptr;
     return NS_OK;
   }
   nsDependentString propertyName(aPropertyName);
   mPropertyTable->Get(propertyName, aResult); // Addref here.
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsBoxObject::SetPropertyAsSupports(const char16_t* aPropertyName, nsISupports* aValue)
+BoxObject::SetPropertyAsSupports(const char16_t* aPropertyName, nsISupports* aValue)
 {
   NS_ENSURE_ARG(aPropertyName && *aPropertyName);
 
   if (!mPropertyTable) {
     mPropertyTable = new nsInterfaceHashtable<nsStringHashKey,nsISupports>(4);
   }
 
   nsDependentString propertyName(aPropertyName);
   mPropertyTable->Put(propertyName, aValue);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsBoxObject::GetProperty(const char16_t* aPropertyName, char16_t** aResult)
+BoxObject::GetProperty(const char16_t* aPropertyName, char16_t** aResult)
 {
   nsCOMPtr<nsISupports> data;
   nsresult rv = GetPropertyAsSupports(aPropertyName,getter_AddRefs(data));
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!data) {
     *aResult = nullptr;
     return NS_OK;
   }
 
   nsCOMPtr<nsISupportsString> supportsStr = do_QueryInterface(data);
-  if (!supportsStr)
+  if (!supportsStr) {
     return NS_ERROR_FAILURE;
+  }
 
   return supportsStr->ToString(aResult);
 }
 
 NS_IMETHODIMP
-nsBoxObject::SetProperty(const char16_t* aPropertyName, const char16_t* aPropertyValue)
+BoxObject::SetProperty(const char16_t* aPropertyName, const char16_t* aPropertyValue)
 {
   NS_ENSURE_ARG(aPropertyName && *aPropertyName);
 
   nsDependentString propertyName(aPropertyName);
   nsDependentString propertyValue;
   if (aPropertyValue) {
     propertyValue.Rebind(aPropertyValue);
   } else {
@@ -351,115 +353,270 @@ nsBoxObject::SetProperty(const char16_t*
   nsCOMPtr<nsISupportsString> supportsStr(do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
   NS_ENSURE_TRUE(supportsStr, NS_ERROR_OUT_OF_MEMORY);
   supportsStr->SetData(propertyValue);
 
   return SetPropertyAsSupports(aPropertyName,supportsStr);
 }
 
 NS_IMETHODIMP
-nsBoxObject::RemoveProperty(const char16_t* aPropertyName)
+BoxObject::RemoveProperty(const char16_t* aPropertyName)
 {
   NS_ENSURE_ARG(aPropertyName && *aPropertyName);
 
   if (!mPropertyTable) return NS_OK;
 
   nsDependentString propertyName(aPropertyName);
   mPropertyTable->Remove(propertyName);
   return NS_OK;
 }
 
-NS_IMETHODIMP 
-nsBoxObject::GetParentBox(nsIDOMElement * *aParentBox)
+NS_IMETHODIMP
+BoxObject::GetParentBox(nsIDOMElement * *aParentBox)
 {
   *aParentBox = nullptr;
   nsIFrame* frame = GetFrame(false);
   if (!frame) return NS_OK;
   nsIFrame* parent = frame->GetParent();
   if (!parent) return NS_OK;
 
   nsCOMPtr<nsIDOMElement> el = do_QueryInterface(parent->GetContent());
   *aParentBox = el;
   NS_IF_ADDREF(*aParentBox);
   return NS_OK;
 }
 
-NS_IMETHODIMP 
-nsBoxObject::GetFirstChild(nsIDOMElement * *aFirstVisibleChild)
+NS_IMETHODIMP
+BoxObject::GetFirstChild(nsIDOMElement * *aFirstVisibleChild)
 {
   *aFirstVisibleChild = nullptr;
   nsIFrame* frame = GetFrame(false);
   if (!frame) return NS_OK;
   nsIFrame* firstFrame = frame->GetFirstPrincipalChild();
   if (!firstFrame) return NS_OK;
   // get the content for the box and query to a dom element
   nsCOMPtr<nsIDOMElement> el = do_QueryInterface(firstFrame->GetContent());
   el.swap(*aFirstVisibleChild);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsBoxObject::GetLastChild(nsIDOMElement * *aLastVisibleChild)
+BoxObject::GetLastChild(nsIDOMElement * *aLastVisibleChild)
 {
   *aLastVisibleChild = nullptr;
   nsIFrame* frame = GetFrame(false);
   if (!frame) return NS_OK;
   return GetPreviousSibling(frame, nullptr, aLastVisibleChild);
 }
 
 NS_IMETHODIMP
-nsBoxObject::GetNextSibling(nsIDOMElement **aNextOrdinalSibling)
+BoxObject::GetNextSibling(nsIDOMElement **aNextOrdinalSibling)
 {
   *aNextOrdinalSibling = nullptr;
   nsIFrame* frame = GetFrame(false);
   if (!frame) return NS_OK;
   nsIFrame* nextFrame = frame->GetNextSibling();
   if (!nextFrame) return NS_OK;
   // get the content for the box and query to a dom element
   nsCOMPtr<nsIDOMElement> el = do_QueryInterface(nextFrame->GetContent());
   el.swap(*aNextOrdinalSibling);
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsBoxObject::GetPreviousSibling(nsIDOMElement **aPreviousOrdinalSibling)
+BoxObject::GetPreviousSibling(nsIDOMElement **aPreviousOrdinalSibling)
 {
   *aPreviousOrdinalSibling = nullptr;
   nsIFrame* frame = GetFrame(false);
   if (!frame) return NS_OK;
   nsIFrame* parentFrame = frame->GetParent();
   if (!parentFrame) return NS_OK;
   return GetPreviousSibling(parentFrame, frame, aPreviousOrdinalSibling);
 }
 
 nsresult
-nsBoxObject::GetPreviousSibling(nsIFrame* aParentFrame, nsIFrame* aFrame,
-                                nsIDOMElement** aResult)
+BoxObject::GetPreviousSibling(nsIFrame* aParentFrame, nsIFrame* aFrame,
+                              nsIDOMElement** aResult)
 {
   *aResult = nullptr;
   nsIFrame* nextFrame = aParentFrame->GetFirstPrincipalChild();
   nsIFrame* prevFrame = nullptr;
   while (nextFrame) {
     if (nextFrame == aFrame)
       break;
     prevFrame = nextFrame;
     nextFrame = nextFrame->GetNextSibling();
   }
-   
+
   if (!prevFrame) return NS_OK;
   // get the content for the box and query to a dom element
   nsCOMPtr<nsIDOMElement> el = do_QueryInterface(prevFrame->GetContent());
   el.swap(*aResult);
   return NS_OK;
 }
 
+nsIContent*
+BoxObject::GetParentObject() const
+{
+  return mContent;
+}
+
+JSObject*
+BoxObject::WrapObject(JSContext* aCx)
+{
+  return BoxObjectBinding::Wrap(aCx, this);
+}
+
+Element*
+BoxObject::GetElement() const
+{
+  return mContent && mContent->IsElement() ? mContent->AsElement() : nullptr;
+}
+
+int32_t
+BoxObject::X()
+{
+  int32_t ret = 0;
+  GetX(&ret);
+  return ret;
+}
+
+int32_t
+BoxObject::Y()
+{
+  int32_t ret = 0;
+  GetY(&ret);
+  return ret;
+}
+
+int32_t
+BoxObject::GetScreenX(ErrorResult& aRv)
+{
+  int32_t ret = 0;
+  aRv = GetScreenX(&ret);
+  return ret;
+}
+
+int32_t
+BoxObject::GetScreenY(ErrorResult& aRv)
+{
+  int32_t ret = 0;
+  aRv = GetScreenY(&ret);
+  return ret;
+}
+
+int32_t
+BoxObject::Width()
+{
+  int32_t ret = 0;
+  GetWidth(&ret);
+  return ret;
+}
+
+int32_t
+BoxObject::Height()
+{
+  int32_t ret = 0;
+  GetHeight(&ret);
+  return ret;
+}
+
+already_AddRefed<nsISupports>
+BoxObject::GetPropertyAsSupports(const nsAString& propertyName)
+{
+  nsCOMPtr<nsISupports> ret;
+  GetPropertyAsSupports(PromiseFlatString(propertyName).get(), getter_AddRefs(ret));
+  return ret.forget();
+}
+
+void
+BoxObject::SetPropertyAsSupports(const nsAString& propertyName, nsISupports* value)
+{
+  SetPropertyAsSupports(PromiseFlatString(propertyName).get(), value);
+}
+
+void
+BoxObject::GetProperty(const nsAString& propertyName, nsString& aRetVal, ErrorResult& aRv)
+{
+  nsCOMPtr<nsISupports> data(GetPropertyAsSupports(propertyName));
+  if (!data) {
+    return;
+  }
+
+  nsCOMPtr<nsISupportsString> supportsStr(do_QueryInterface(data));
+  if (!supportsStr) {
+    aRv.Throw(NS_ERROR_FAILURE);
+    return;
+  }
+
+  supportsStr->GetData(aRetVal);
+}
+
+void
+BoxObject::SetProperty(const nsAString& propertyName, const nsAString& propertyValue)
+{
+  SetProperty(PromiseFlatString(propertyName).get(), PromiseFlatString(propertyValue).get());
+}
+
+void
+BoxObject::RemoveProperty(const nsAString& propertyName)
+{
+  RemoveProperty(PromiseFlatString(propertyName).get());
+}
+
+already_AddRefed<Element>
+BoxObject::GetParentBox()
+{
+  nsCOMPtr<nsIDOMElement> el;
+  GetParentBox(getter_AddRefs(el));
+  nsCOMPtr<Element> ret(do_QueryInterface(el));
+  return ret.forget();
+}
+
+already_AddRefed<Element>
+BoxObject::GetFirstChild()
+{
+  nsCOMPtr<nsIDOMElement> el;
+  GetFirstChild(getter_AddRefs(el));
+  nsCOMPtr<Element> ret(do_QueryInterface(el));
+  return ret.forget();
+}
+
+already_AddRefed<Element>
+BoxObject::GetLastChild()
+{
+  nsCOMPtr<nsIDOMElement> el;
+  GetLastChild(getter_AddRefs(el));
+  nsCOMPtr<Element> ret(do_QueryInterface(el));
+  return ret.forget();
+}
+
+already_AddRefed<Element>
+BoxObject::GetNextSibling()
+{
+  nsCOMPtr<nsIDOMElement> el;
+  GetNextSibling(getter_AddRefs(el));
+  nsCOMPtr<Element> ret(do_QueryInterface(el));
+  return ret.forget();
+}
+
+already_AddRefed<Element>
+BoxObject::GetPreviousSibling()
+{
+  nsCOMPtr<nsIDOMElement> el;
+  GetPreviousSibling(getter_AddRefs(el));
+  nsCOMPtr<Element> ret(do_QueryInterface(el));
+  return ret.forget();
+}
+
+} // namespace dom
+} // namespace mozilla
+
 // Creation Routine ///////////////////////////////////////////////////////////////////////
 
+using namespace mozilla::dom;
+
 nsresult
 NS_NewBoxObject(nsIBoxObject** aResult)
 {
-  *aResult = new nsBoxObject;
-  if (!*aResult)
-    return NS_ERROR_OUT_OF_MEMORY;
-  NS_ADDREF(*aResult);
+  NS_ADDREF(*aResult = new BoxObject());
   return NS_OK;
 }
-
rename from layout/xul/nsBoxObject.h
rename to layout/xul/BoxObject.h
--- a/layout/xul/nsBoxObject.h
+++ b/layout/xul/BoxObject.h
@@ -1,55 +1,92 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
-#ifndef nsBoxObject_h_
-#define nsBoxObject_h_
+
+#ifndef mozilla_dom_BoxObject_h__
+#define mozilla_dom_BoxObject_h__
 
 #include "mozilla/Attributes.h"
+#include "mozilla/ErrorResult.h"
 #include "nsCOMPtr.h"
 #include "nsIBoxObject.h"
 #include "nsPIBoxObject.h"
 #include "nsPoint.h"
 #include "nsAutoPtr.h"
 #include "nsHashKeys.h"
 #include "nsInterfaceHashtable.h"
 #include "nsCycleCollectionParticipant.h"
+#include "nsWrapperCache.h"
 
 class nsIFrame;
 class nsIDocShell;
 struct nsIntRect;
 class nsIPresShell;
 
-class nsBoxObject : public nsPIBoxObject
+namespace mozilla {
+namespace dom {
+
+class Element;
+
+class BoxObject : public nsPIBoxObject,
+                  public nsWrapperCache
 {
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_CLASS(nsBoxObject)
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(BoxObject)
   NS_DECL_NSIBOXOBJECT
 
 public:
-  nsBoxObject();
+  BoxObject();
 
   // nsPIBoxObject
   virtual nsresult Init(nsIContent* aContent) MOZ_OVERRIDE;
   virtual void Clear() MOZ_OVERRIDE;
   virtual void ClearCachedValues() MOZ_OVERRIDE;
 
   nsIFrame* GetFrame(bool aFlushLayout);
   nsIPresShell* GetPresShell(bool aFlushLayout);
   nsresult GetOffsetRect(nsIntRect& aRect);
   nsresult GetScreenPosition(nsIntPoint& aPoint);
 
   // Given a parent frame and a child frame, find the frame whose
   // next sibling is the given child frame and return its element
   static nsresult GetPreviousSibling(nsIFrame* aParentFrame, nsIFrame* aFrame,
                                      nsIDOMElement** aResult);
 
+  // WebIDL (wraps old impls)
+  nsIContent* GetParentObject() const;
+  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+
+  Element* GetElement() const;
+
+  int32_t X();
+  int32_t Y();
+  int32_t GetScreenX(ErrorResult& aRv);
+  int32_t GetScreenY(ErrorResult& aRv);
+  int32_t Width();
+  int32_t Height();
+
+  already_AddRefed<nsISupports> GetPropertyAsSupports(const nsAString& propertyName);
+  void SetPropertyAsSupports(const nsAString& propertyName, nsISupports* value);
+  void GetProperty(const nsAString& propertyName, nsString& aRetVal, ErrorResult& aRv);
+  void SetProperty(const nsAString& propertyName, const nsAString& propertyValue);
+  void RemoveProperty(const nsAString& propertyName);
+
+  already_AddRefed<Element> GetParentBox();
+  already_AddRefed<Element> GetFirstChild();
+  already_AddRefed<Element> GetLastChild();
+  already_AddRefed<Element> GetNextSibling();
+  already_AddRefed<Element> GetPreviousSibling();
+
 protected:
-  virtual ~nsBoxObject();
+  virtual ~BoxObject();
 
   nsAutoPtr<nsInterfaceHashtable<nsStringHashKey,nsISupports> > mPropertyTable; //[OWNER]
 
   nsIContent* mContent; // [WEAK]
 };
 
+}
+}
+
 #endif
new file mode 100644
--- /dev/null
+++ b/layout/xul/ContainerBoxObject.cpp
@@ -0,0 +1,75 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/. */
+
+#include "mozilla/dom/ContainerBoxObject.h"
+#include "mozilla/dom/ContainerBoxObjectBinding.h"
+#include "nsCOMPtr.h"
+#include "nsIDocShell.h"
+#include "nsIContent.h"
+#include "nsIDocument.h"
+#include "nsIFrame.h"
+#include "nsSubDocumentFrame.h"
+
+namespace mozilla {
+namespace dom {
+  
+ContainerBoxObject::ContainerBoxObject()
+{
+}
+
+ContainerBoxObject::~ContainerBoxObject()
+{
+}
+
+JSObject*
+ContainerBoxObject::WrapObject(JSContext* aCx)
+{
+  return ContainerBoxObjectBinding::Wrap(aCx, this);
+}
+
+already_AddRefed<nsIDocShell>
+ContainerBoxObject::GetDocShell()
+{
+  nsSubDocumentFrame *subDocFrame = do_QueryFrame(GetFrame(false));
+  if (subDocFrame) {
+    // Ok, the frame for mContent is an nsSubDocumentFrame, it knows how
+    // to reach the docshell, so ask it...
+    nsCOMPtr<nsIDocShell> ret;
+    subDocFrame->GetDocShell(getter_AddRefs(ret));
+    return ret.forget();
+  }
+
+  if (!mContent) {
+    return nullptr;
+  }
+
+  // No nsSubDocumentFrame available for mContent, try if there's a mapping
+  // between mContent's document to mContent's subdocument.
+
+  nsIDocument *doc = mContent->GetComposedDoc();
+
+  if (!doc) {
+    return nullptr;
+  }
+
+  nsIDocument *sub_doc = doc->GetSubDocumentFor(mContent);
+
+  if (!sub_doc) {
+    return nullptr;
+  }
+
+  nsCOMPtr<nsIDocShell> result = sub_doc->GetDocShell();
+  return result.forget();
+}
+
+} // namespace dom
+} // namespace mozilla
+
+nsresult
+NS_NewContainerBoxObject(nsIBoxObject** aResult)
+{
+  NS_ADDREF(*aResult = new mozilla::dom::ContainerBoxObject());
+  return NS_OK;
+}
new file mode 100644
--- /dev/null
+++ b/layout/xul/ContainerBoxObject.h
@@ -0,0 +1,31 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* 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/. */
+
+#ifndef mozilla_dom_ContainerBoxObject_h
+#define mozilla_dom_ContainerBoxObject_h
+
+#include "mozilla/dom/BoxObject.h"
+
+namespace mozilla {
+namespace dom {
+
+class ContainerBoxObject MOZ_FINAL : public BoxObject
+{
+public:
+  ContainerBoxObject();
+
+  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+
+  already_AddRefed<nsIDocShell> GetDocShell();
+
+private:
+  ~ContainerBoxObject();
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_ContainerBoxObject_h
rename from layout/xul/nsListBoxObject.cpp
rename to layout/xul/ListBoxObject.cpp
--- a/layout/xul/nsListBoxObject.cpp
+++ b/layout/xul/ListBoxObject.cpp
@@ -1,130 +1,150 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
+#include "mozilla/dom/ListBoxObject.h"
 #include "nsCOMPtr.h"
-#include "nsPIListBoxObject.h"
-#include "nsBoxObject.h"
 #include "nsIFrame.h"
-#include "nsBindingManager.h"
-#include "nsIDOMElement.h"
-#include "nsIDOMNodeList.h"
 #include "nsGkAtoms.h"
 #include "nsIScrollableFrame.h"
 #include "nsListBoxBodyFrame.h"
 #include "ChildIterator.h"
-
-class nsListBoxObject MOZ_FINAL : public nsPIListBoxObject, public nsBoxObject
-{
-public:
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_NSILISTBOXOBJECT
-
-  // nsPIListBoxObject
-  virtual nsListBoxBodyFrame* GetListBoxBody(bool aFlush) MOZ_OVERRIDE;
-
-  nsListBoxObject();
+#include "mozilla/dom/Element.h"
+#include "mozilla/dom/ListBoxObjectBinding.h"
 
-  // nsPIBoxObject
-  virtual void Clear() MOZ_OVERRIDE;
-  virtual void ClearCachedValues() MOZ_OVERRIDE;
+namespace mozilla {
+namespace dom {
 
-protected:
-  virtual ~nsListBoxObject() {}
-
-  nsListBoxBodyFrame *mListBoxBody;
-};
-
-NS_IMPL_ISUPPORTS_INHERITED(nsListBoxObject, nsBoxObject, nsIListBoxObject,
+NS_IMPL_ISUPPORTS_INHERITED(ListBoxObject, BoxObject, nsIListBoxObject,
                             nsPIListBoxObject)
 
-nsListBoxObject::nsListBoxObject()
+ListBoxObject::ListBoxObject()
   : mListBoxBody(nullptr)
 {
 }
 
-//////////////////////////////////////////////////////////////////////////
-//// nsIListBoxObject
+ListBoxObject::~ListBoxObject()
+{
+}
 
+JSObject* ListBoxObject::WrapObject(JSContext* aCx)
+{
+  return ListBoxObjectBinding::Wrap(aCx, this);
+}
+
+// nsIListBoxObject
 NS_IMETHODIMP
-nsListBoxObject::GetRowCount(int32_t *aResult)
+ListBoxObject::GetRowCount(int32_t *aResult)
 {
-  nsListBoxBodyFrame* body = GetListBoxBody(true);
-  if (body)
-    return body->GetRowCount(aResult);
+  *aResult = GetRowCount();
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsListBoxObject::GetNumberOfVisibleRows(int32_t *aResult)
-{
-  nsListBoxBodyFrame* body = GetListBoxBody(true);
-  if (body)
-    return body->GetNumberOfVisibleRows(aResult);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsListBoxObject::GetIndexOfFirstVisibleRow(int32_t *aResult)
+ListBoxObject::GetItemAtIndex(int32_t index, nsIDOMElement **_retval)
 {
   nsListBoxBodyFrame* body = GetListBoxBody(true);
-  if (body)
-    return body->GetIndexOfFirstVisibleRow(aResult);
+  if (body) {
+    return body->GetItemAtIndex(index, _retval);
+  }
   return NS_OK;
-}
-
-NS_IMETHODIMP nsListBoxObject::EnsureIndexIsVisible(int32_t aRowIndex)
-{
-  nsListBoxBodyFrame* body = GetListBoxBody(true);
-  if (body)
-    return body->EnsureIndexIsVisible(aRowIndex);
-  return NS_OK;
-}
+ }
 
 NS_IMETHODIMP
-nsListBoxObject::ScrollToIndex(int32_t aRowIndex)
-{
-  nsListBoxBodyFrame* body = GetListBoxBody(true);
-  if (body)
-    return body->ScrollToIndex(aRowIndex);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsListBoxObject::ScrollByLines(int32_t aNumLines)
-{
-  nsListBoxBodyFrame* body = GetListBoxBody(true);
-  if (body)
-    return body->ScrollByLines(aNumLines);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsListBoxObject::GetItemAtIndex(int32_t index, nsIDOMElement **_retval)
-{
-  nsListBoxBodyFrame* body = GetListBoxBody(true);
-  if (body)
-    return body->GetItemAtIndex(index, _retval);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsListBoxObject::GetIndexOfItem(nsIDOMElement* aElement, int32_t *aResult)
+ListBoxObject::GetIndexOfItem(nsIDOMElement* aElement, int32_t *aResult)
 {
   *aResult = 0;
 
   nsListBoxBodyFrame* body = GetListBoxBody(true);
-  if (body)
+  if (body) {
     return body->GetIndexOfItem(aElement, aResult);
+  }
   return NS_OK;
 }
 
+// ListBoxObject
+
+int32_t
+ListBoxObject::GetRowCount()
+{
+  nsListBoxBodyFrame* body = GetListBoxBody(true);
+  if (body) {
+    return body->GetRowCount();
+  }
+  return 0;
+}
+
+int32_t
+ListBoxObject::GetNumberOfVisibleRows()
+{
+  nsListBoxBodyFrame* body = GetListBoxBody(true);
+  if (body) {
+    return body->GetNumberOfVisibleRows();
+  }
+  return 0;
+}
+
+int32_t
+ListBoxObject::GetIndexOfFirstVisibleRow()
+{
+  nsListBoxBodyFrame* body = GetListBoxBody(true);
+  if (body) {
+    return body->GetIndexOfFirstVisibleRow();
+  }
+  return 0;
+}
+
+void
+ListBoxObject::EnsureIndexIsVisible(int32_t aRowIndex)
+{
+  nsListBoxBodyFrame* body = GetListBoxBody(true);
+  if (body) {
+    body->EnsureIndexIsVisible(aRowIndex);
+  }
+}
+
+void
+ListBoxObject::ScrollToIndex(int32_t aRowIndex)
+{
+  nsListBoxBodyFrame* body = GetListBoxBody(true);
+  if (body) {
+    body->ScrollToIndex(aRowIndex);
+  }
+}
+
+void
+ListBoxObject::ScrollByLines(int32_t aNumLines)
+{
+  nsListBoxBodyFrame* body = GetListBoxBody(true);
+  if (body) {
+    body->ScrollByLines(aNumLines);
+  }
+}
+
+already_AddRefed<Element>
+ListBoxObject::GetItemAtIndex(int32_t index)
+{
+  nsCOMPtr<nsIDOMElement> el;
+  GetItemAtIndex(index, getter_AddRefs(el));
+  nsCOMPtr<Element> ret(do_QueryInterface(el));
+  return ret.forget();
+}
+
+int32_t
+ListBoxObject::GetIndexOfItem(Element& aElement)
+{
+  int32_t ret;
+  nsCOMPtr<nsIDOMElement> el(do_QueryInterface(&aElement));
+  GetIndexOfItem(el, &ret);
+  return ret;
+}
+
 //////////////////////
 
 static nsIContent*
 FindBodyContent(nsIContent* aParent)
 {
   if (aParent->Tag() == nsGkAtoms::listboxbody) {
     return aParent;
   }
@@ -136,78 +156,83 @@ FindBodyContent(nsIContent* aParent)
       return result;
     }
   }
 
   return nullptr;
 }
 
 nsListBoxBodyFrame*
-nsListBoxObject::GetListBoxBody(bool aFlush)
+ListBoxObject::GetListBoxBody(bool aFlush)
 {
   if (mListBoxBody) {
     return mListBoxBody;
   }
 
   nsIPresShell* shell = GetPresShell(false);
   if (!shell) {
     return nullptr;
   }
 
-  nsIFrame* frame = aFlush ? 
+  nsIFrame* frame = aFlush ?
                       GetFrame(false) /* does Flush_Frames */ :
                       mContent->GetPrimaryFrame();
-  if (!frame)
+  if (!frame) {
     return nullptr;
+  }
 
   // Iterate over our content model children looking for the body.
   nsCOMPtr<nsIContent> content = FindBodyContent(frame->GetContent());
 
-  if (!content)
+  if (!content) {
     return nullptr;
+  }
 
   // this frame will be a nsGFXScrollFrame
   frame = content->GetPrimaryFrame();
-  if (!frame)
+  if (!frame) {
      return nullptr;
+  }
+
   nsIScrollableFrame* scrollFrame = do_QueryFrame(frame);
-  if (!scrollFrame)
+  if (!scrollFrame) {
     return nullptr;
+  }
 
   // this frame will be the one we want
   nsIFrame* yeahBaby = scrollFrame->GetScrolledFrame();
-  if (!yeahBaby)
+  if (!yeahBaby) {
      return nullptr;
+  }
 
   // It's a frame. Refcounts are irrelevant.
   nsListBoxBodyFrame* listBoxBody = do_QueryFrame(yeahBaby);
   NS_ENSURE_TRUE(listBoxBody &&
                  listBoxBody->SetBoxObject(this),
                  nullptr);
   mListBoxBody = listBoxBody;
   return mListBoxBody;
 }
 
 void
-nsListBoxObject::Clear()
+ListBoxObject::Clear()
 {
   ClearCachedValues();
-
-  nsBoxObject::Clear();
+  BoxObject::Clear();
 }
 
 void
-nsListBoxObject::ClearCachedValues()
+ListBoxObject::ClearCachedValues()
 {
   mListBoxBody = nullptr;
 }
 
+}
+}
+
 // Creation Routine ///////////////////////////////////////////////////////////////////////
 
 nsresult
 NS_NewListBoxObject(nsIBoxObject** aResult)
 {
-  *aResult = new nsListBoxObject;
-  if (!*aResult)
-    return NS_ERROR_OUT_OF_MEMORY;
-  NS_ADDREF(*aResult);
+  NS_ADDREF(*aResult = new mozilla::dom::ListBoxObject());
   return NS_OK;
 }
new file mode 100644
--- /dev/null
+++ b/layout/xul/ListBoxObject.h
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* 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/. */
+
+#ifndef mozilla_dom_ListBoxObject_h
+#define mozilla_dom_ListBoxObject_h
+
+#include "mozilla/dom/BoxObject.h"
+#include "nsPIListBoxObject.h"
+
+namespace mozilla {
+namespace dom {
+
+class ListBoxObject MOZ_FINAL : public BoxObject,
+                                public nsPIListBoxObject
+{
+public:
+  NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_NSILISTBOXOBJECT
+
+  ListBoxObject();
+
+  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+
+  // nsPIListBoxObject
+  virtual nsListBoxBodyFrame* GetListBoxBody(bool aFlush) MOZ_OVERRIDE;
+
+  // nsPIBoxObject
+  virtual void Clear() MOZ_OVERRIDE;
+  virtual void ClearCachedValues() MOZ_OVERRIDE;
+
+  // ListBoxObject.webidl
+  int32_t GetRowCount();
+  int32_t GetNumberOfVisibleRows();
+  int32_t GetIndexOfFirstVisibleRow();
+  void EnsureIndexIsVisible(int32_t rowIndex);
+  void ScrollToIndex(int32_t rowIndex);
+  void ScrollByLines(int32_t numLines);
+  already_AddRefed<Element> GetItemAtIndex(int32_t index);
+  int32_t GetIndexOfItem(Element& item);
+
+protected:
+  nsListBoxBodyFrame *mListBoxBody;
+
+private:
+  ~ListBoxObject();
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_ListBoxObject_h
rename from layout/xul/nsMenuBoxObject.cpp
rename to layout/xul/MenuBoxObject.cpp
--- a/layout/xul/nsMenuBoxObject.cpp
+++ b/layout/xul/MenuBoxObject.cpp
@@ -1,46 +1,42 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
-#include "nsISupportsUtils.h"
-#include "nsIMenuBoxObject.h"
-#include "nsBoxObject.h"
+
+#include "mozilla/dom/MenuBoxObject.h"
+#include "mozilla/dom/MenuBoxObjectBinding.h"
+
+#include "mozilla/dom/KeyboardEvent.h"
+#include "mozilla/dom/Element.h"
 #include "nsIDOMKeyEvent.h"
 #include "nsIFrame.h"
 #include "nsMenuBarFrame.h"
 #include "nsMenuBarListener.h"
 #include "nsMenuFrame.h"
 #include "nsMenuPopupFrame.h"
 
-class nsMenuBoxObject : public nsIMenuBoxObject,
-                        public nsBoxObject
-{
-public:
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_NSIMENUBOXOBJECT
+namespace mozilla {
+namespace dom {
 
-  nsMenuBoxObject();
-protected:
-  virtual ~nsMenuBoxObject();
-};
-
-nsMenuBoxObject::nsMenuBoxObject()
+MenuBoxObject::MenuBoxObject()
 {
 }
 
-nsMenuBoxObject::~nsMenuBoxObject()
+MenuBoxObject::~MenuBoxObject()
 {
 }
 
-NS_IMPL_ISUPPORTS_INHERITED(nsMenuBoxObject, nsBoxObject, nsIMenuBoxObject)
+JSObject* MenuBoxObject::WrapObject(JSContext* aCx)
+{
+  return MenuBoxObjectBinding::Wrap(aCx, this);
+}
 
-/* void openMenu (in boolean openFlag); */
-NS_IMETHODIMP nsMenuBoxObject::OpenMenu(bool aOpenFlag)
+void MenuBoxObject::OpenMenu(bool aOpenFlag)
 {
   nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
   if (pm) {
     nsIFrame* frame = GetFrame(false);
     if (frame) {
       if (aOpenFlag) {
         nsCOMPtr<nsIContent> content = mContent;
         pm->ShowMenu(content, false, false);
@@ -50,111 +46,106 @@ NS_IMETHODIMP nsMenuBoxObject::OpenMenu(
         if (menu) {
           nsMenuPopupFrame* popupFrame = menu->GetPopup();
           if (popupFrame)
             pm->HidePopup(popupFrame->GetContent(), false, true, false, false);
         }
       }
     }
   }
-
-  return NS_OK;
 }
 
-NS_IMETHODIMP nsMenuBoxObject::GetActiveChild(nsIDOMElement** aResult)
+already_AddRefed<Element>
+MenuBoxObject::GetActiveChild()
 {
-  *aResult = nullptr;
   nsMenuFrame* menu = do_QueryFrame(GetFrame(false));
-  if (menu)
-    return menu->GetActiveChild(aResult);
-  return NS_OK;
+  if (menu) {
+    nsCOMPtr<nsIDOMElement> el;
+    menu->GetActiveChild(getter_AddRefs(el));
+    nsCOMPtr<Element> ret(do_QueryInterface(el));
+    return ret.forget();
+  }
+  return nullptr;
 }
 
-NS_IMETHODIMP nsMenuBoxObject::SetActiveChild(nsIDOMElement* aResult)
+void MenuBoxObject::SetActiveChild(Element* arg)
 {
   nsMenuFrame* menu = do_QueryFrame(GetFrame(false));
-  if (menu)
-    return menu->SetActiveChild(aResult);
-  return NS_OK;
+  if (menu) {
+    nsCOMPtr<nsIDOMElement> el(do_QueryInterface(arg));
+    menu->SetActiveChild(el);
+  }
 }
 
-/* boolean handleKeyPress (in nsIDOMKeyEvent keyEvent); */
-NS_IMETHODIMP nsMenuBoxObject::HandleKeyPress(nsIDOMKeyEvent* aKeyEvent, bool* aHandledFlag)
+bool MenuBoxObject::HandleKeyPress(KeyboardEvent& keyEvent)
 {
-  *aHandledFlag = false;
-  NS_ENSURE_ARG(aKeyEvent);
-
   nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
-  if (!pm)
-    return NS_OK;
+  if (!pm) {
+    return false;
+  }
 
   // if event has already been handled, bail
   bool eventHandled = false;
-  aKeyEvent->GetDefaultPrevented(&eventHandled);
-  if (eventHandled)
-    return NS_OK;
+  keyEvent.GetDefaultPrevented(&eventHandled);
+  if (eventHandled) {
+    return false;
+  }
 
-  if (nsMenuBarListener::IsAccessKeyPressed(aKeyEvent))
-    return NS_OK;
+  if (nsMenuBarListener::IsAccessKeyPressed(&keyEvent))
+    return false;
 
   nsMenuFrame* menu = do_QueryFrame(GetFrame(false));
-  if (!menu)
-    return NS_OK;
+  if (!menu) {
+    return false;
+  }
 
   nsMenuPopupFrame* popupFrame = menu->GetPopup();
-  if (!popupFrame)
-    return NS_OK;
+  if (!popupFrame) {
+    return false;
+  }
 
-  uint32_t keyCode;
-  aKeyEvent->GetKeyCode(&keyCode);
+  uint32_t keyCode = keyEvent.KeyCode();
   switch (keyCode) {
     case nsIDOMKeyEvent::DOM_VK_UP:
     case nsIDOMKeyEvent::DOM_VK_DOWN:
     case nsIDOMKeyEvent::DOM_VK_HOME:
     case nsIDOMKeyEvent::DOM_VK_END:
     {
       nsNavigationDirection theDirection;
       theDirection = NS_DIRECTION_FROM_KEY_CODE(popupFrame, keyCode);
-      *aHandledFlag =
-        pm->HandleKeyboardNavigationInPopup(popupFrame, theDirection);
-      return NS_OK;
+      return pm->HandleKeyboardNavigationInPopup(popupFrame, theDirection);
     }
     default:
-      *aHandledFlag = pm->HandleShortcutNavigation(aKeyEvent, popupFrame);
-      return NS_OK;
+      return pm->HandleShortcutNavigation(&keyEvent, popupFrame);
   }
 }
 
-NS_IMETHODIMP
-nsMenuBoxObject::GetOpenedWithKey(bool* aOpenedWithKey)
+bool MenuBoxObject::OpenedWithKey()
 {
-  *aOpenedWithKey = false;
-
   nsMenuFrame* menuframe = do_QueryFrame(GetFrame(false));
-  if (!menuframe)
-    return NS_OK;
+  if (!menuframe) {
+    return false;
+  }
 
   nsIFrame* frame = menuframe->GetParent();
   while (frame) {
     nsMenuBarFrame* menubar = do_QueryFrame(frame);
     if (menubar) {
-      *aOpenedWithKey = menubar->IsActiveByKeyboard();
-      return NS_OK;
+      return menubar->IsActiveByKeyboard();
     }
     frame = frame->GetParent();
   }
-
-  return NS_OK;
+  return false;
 }
 
+} // namespace dom
+} // namespace mozilla
 
 // Creation Routine ///////////////////////////////////////////////////////////////////////
 
+using namespace mozilla::dom;
+
 nsresult
 NS_NewMenuBoxObject(nsIBoxObject** aResult)
 {
-  *aResult = new nsMenuBoxObject;
-  if (!*aResult)
-    return NS_ERROR_OUT_OF_MEMORY;
-  NS_ADDREF(*aResult);
+  NS_ADDREF(*aResult = new MenuBoxObject());
   return NS_OK;
 }
-
new file mode 100644
--- /dev/null
+++ b/layout/xul/MenuBoxObject.h
@@ -0,0 +1,38 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* 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/. */
+
+#ifndef mozilla_dom_MenuBoxObject_h
+#define mozilla_dom_MenuBoxObject_h
+
+#include "mozilla/dom/BoxObject.h"
+
+namespace mozilla {
+namespace dom {
+
+class KeyboardEvent;
+
+class MenuBoxObject MOZ_FINAL : public BoxObject
+{
+public:
+
+  MenuBoxObject();
+
+  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+
+  void OpenMenu(bool aOpenFlag);
+  already_AddRefed<Element> GetActiveChild();
+  void SetActiveChild(Element* arg);
+  bool HandleKeyPress(KeyboardEvent& keyEvent);
+  bool OpenedWithKey();
+
+private:
+  ~MenuBoxObject();
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_MenuBoxObject_h
rename from layout/xul/nsPopupBoxObject.cpp
rename to layout/xul/PopupBoxObject.cpp
--- a/layout/xul/nsPopupBoxObject.cpp
+++ b/layout/xul/PopupBoxObject.cpp
@@ -1,229 +1,215 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
+
 #include "nsCOMPtr.h"
-#include "nsIPopupBoxObject.h"
 #include "nsIRootBox.h"
-#include "nsBoxObject.h"
 #include "nsIPresShell.h"
 #include "nsIContent.h"
-#include "nsIDOMElement.h"
 #include "nsNameSpaceManager.h"
 #include "nsGkAtoms.h"
 #include "nsMenuPopupFrame.h"
 #include "nsView.h"
 #include "mozilla/AppUnits.h"
 #include "mozilla/dom/DOMRect.h"
-
-using namespace mozilla::dom;
+#include "mozilla/dom/PopupBoxObject.h"
+#include "mozilla/dom/Element.h"
+#include "mozilla/dom/Event.h"
+#include "mozilla/dom/PopupBoxObjectBinding.h"
 
-class nsPopupBoxObject : public nsBoxObject,
-                         public nsIPopupBoxObject
+namespace mozilla {
+namespace dom {
+
+NS_IMPL_ADDREF_INHERITED(PopupBoxObject, BoxObject)
+NS_IMPL_RELEASE_INHERITED(PopupBoxObject, BoxObject)
+NS_INTERFACE_MAP_BEGIN(PopupBoxObject)
+NS_INTERFACE_MAP_END_INHERITING(BoxObject)
+
+PopupBoxObject::PopupBoxObject()
 {
-public:
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_NSIPOPUPBOXOBJECT
+}
+
+PopupBoxObject::~PopupBoxObject()
+{
+}
 
-  nsPopupBoxObject() {}
-protected:
-  virtual ~nsPopupBoxObject() {}
+nsIContent* PopupBoxObject::GetParentObject() const
+{
+  return BoxObject::GetParentObject();
+}
 
-  nsPopupSetFrame* GetPopupSetFrame();
-};
-
-NS_IMPL_ISUPPORTS_INHERITED(nsPopupBoxObject, nsBoxObject, nsIPopupBoxObject)
+JSObject* PopupBoxObject::WrapObject(JSContext* aCx)
+{
+  return PopupBoxObjectBinding::Wrap(aCx, this);
+}
 
 nsPopupSetFrame*
-nsPopupBoxObject::GetPopupSetFrame()
+PopupBoxObject::GetPopupSetFrame()
 {
   nsIRootBox* rootBox = nsIRootBox::GetRootBox(GetPresShell(false));
   if (!rootBox)
     return nullptr;
 
   return rootBox->GetPopupSetFrame();
 }
 
-NS_IMETHODIMP
-nsPopupBoxObject::HidePopup(bool aCancel)
+void
+PopupBoxObject::HidePopup(bool aCancel)
 {
   nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
-  if (pm && mContent)
+  if (pm && mContent) {
     pm->HidePopup(mContent, false, true, false, aCancel);
-
-  return NS_OK;
+  }
 }
 
-NS_IMETHODIMP
-nsPopupBoxObject::ShowPopup(nsIDOMElement* aAnchorElement,
-                            nsIDOMElement* aPopupElement,
-                            int32_t aXPos, int32_t aYPos,
-                            const char16_t *aPopupType,
-                            const char16_t *aAnchorAlignment,
-                            const char16_t *aPopupAlignment)
+void
+PopupBoxObject::ShowPopup(Element* aAnchorElement,
+                          Element& aPopupElement,
+                          int32_t aXPos, int32_t aYPos,
+                          const nsAString& aPopupType,
+                          const nsAString& aAnchorAlignment,
+                          const nsAString& aPopupAlignment)
 {
-  NS_ENSURE_TRUE(aPopupElement, NS_ERROR_INVALID_ARG);
-  // srcContent can be null.
-
   nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
   if (pm && mContent) {
     nsCOMPtr<nsIContent> anchorContent(do_QueryInterface(aAnchorElement));
     nsAutoString popupType(aPopupType);
     nsAutoString anchor(aAnchorAlignment);
     nsAutoString align(aPopupAlignment);
     pm->ShowPopupWithAnchorAlign(mContent, anchorContent, anchor, align,
-                                 aXPos, aYPos, popupType.EqualsLiteral("context"));
+                                 aXPos, aYPos,
+                                 popupType.EqualsLiteral("context"));
   }
-
-  return NS_OK;
 }
 
-NS_IMETHODIMP
-nsPopupBoxObject::OpenPopup(nsIDOMElement* aAnchorElement,
-                            const nsAString& aPosition,
-                            int32_t aXPos, int32_t aYPos,
-                            bool aIsContextMenu,
-                            bool aAttributesOverride,
-                            nsIDOMEvent* aTriggerEvent)
+void
+PopupBoxObject::OpenPopup(Element* aAnchorElement,
+                          const nsAString& aPosition,
+                          int32_t aXPos, int32_t aYPos,
+                          bool aIsContextMenu,
+                          bool aAttributesOverride,
+                          Event* aTriggerEvent)
 {
   nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
   if (pm && mContent) {
     nsCOMPtr<nsIContent> anchorContent(do_QueryInterface(aAnchorElement));
     pm->ShowPopup(mContent, anchorContent, aPosition, aXPos, aYPos,
                   aIsContextMenu, aAttributesOverride, false, aTriggerEvent);
   }
-
-  return NS_OK;
 }
 
-NS_IMETHODIMP
-nsPopupBoxObject::OpenPopupAtScreen(int32_t aXPos, int32_t aYPos,
-                                    bool aIsContextMenu,
-                                    nsIDOMEvent* aTriggerEvent)
+void
+PopupBoxObject::OpenPopupAtScreen(int32_t aXPos, int32_t aYPos,
+                                  bool aIsContextMenu,
+                                  Event* aTriggerEvent)
 {
   nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
   if (pm && mContent)
     pm->ShowPopupAtScreen(mContent, aXPos, aYPos, aIsContextMenu, aTriggerEvent);
-  return NS_OK;
 }
 
-NS_IMETHODIMP
-nsPopupBoxObject::MoveTo(int32_t aLeft, int32_t aTop)
+void
+PopupBoxObject::MoveTo(int32_t aLeft, int32_t aTop)
 {
   nsMenuPopupFrame *menuPopupFrame = mContent ? do_QueryFrame(mContent->GetPrimaryFrame()) : nullptr;
   if (menuPopupFrame) {
     menuPopupFrame->MoveTo(aLeft, aTop, true);
   }
-
-  return NS_OK;
 }
 
-NS_IMETHODIMP
-nsPopupBoxObject::MoveToAnchor(nsIDOMElement* aAnchorElement,
-                               const nsAString& aPosition,
-                               int32_t aXPos, int32_t aYPos,
-                               bool aAttributesOverride)
+void
+PopupBoxObject::MoveToAnchor(Element* aAnchorElement,
+                             const nsAString& aPosition,
+                             int32_t aXPos, int32_t aYPos,
+                             bool aAttributesOverride)
 {
   if (mContent) {
     nsCOMPtr<nsIContent> anchorContent(do_QueryInterface(aAnchorElement));
 
     nsMenuPopupFrame *menuPopupFrame = do_QueryFrame(mContent->GetPrimaryFrame());
     if (menuPopupFrame && menuPopupFrame->IsVisible()) {
       menuPopupFrame->MoveToAnchor(anchorContent, aPosition, aXPos, aYPos, aAttributesOverride);
     }
   }
-
-  return NS_OK;
 }
 
-NS_IMETHODIMP
-nsPopupBoxObject::SizeTo(int32_t aWidth, int32_t aHeight)
+void
+PopupBoxObject::SizeTo(int32_t aWidth, int32_t aHeight)
 {
   if (!mContent)
-    return NS_OK;
+    return;
 
   nsAutoString width, height;
   width.AppendInt(aWidth);
   height.AppendInt(aHeight);
 
   nsCOMPtr<nsIContent> content = mContent;
 
   // We only want to pass aNotify=true to SetAttr once, but must make sure
   // we pass it when a value is being changed.  Thus, we check if the height
   // is the same and if so, pass true when setting the width.
   bool heightSame = content->AttrValueIs(kNameSpaceID_None, nsGkAtoms::height, height, eCaseMatters);
 
   content->SetAttr(kNameSpaceID_None, nsGkAtoms::width, width, heightSame);
   content->SetAttr(kNameSpaceID_None, nsGkAtoms::height, height, true);
-
-  return NS_OK;
 }
 
-NS_IMETHODIMP
-nsPopupBoxObject::GetAutoPosition(bool* aShouldAutoPosition)
+bool
+PopupBoxObject::AutoPosition()
 {
-  *aShouldAutoPosition = true;
-
   nsMenuPopupFrame *menuPopupFrame = mContent ? do_QueryFrame(mContent->GetPrimaryFrame()) : nullptr;
   if (menuPopupFrame) {
-    *aShouldAutoPosition = menuPopupFrame->GetAutoPosition();
+    return menuPopupFrame->GetAutoPosition();
   }
-
-  return NS_OK;
+  return true;
 }
 
-NS_IMETHODIMP
-nsPopupBoxObject::SetAutoPosition(bool aShouldAutoPosition)
+void
+PopupBoxObject::SetAutoPosition(bool aShouldAutoPosition)
 {
   nsMenuPopupFrame *menuPopupFrame = mContent ? do_QueryFrame(mContent->GetPrimaryFrame()) : nullptr;
   if (menuPopupFrame) {
     menuPopupFrame->SetAutoPosition(aShouldAutoPosition);
   }
-
-  return NS_OK;
 }
 
-NS_IMETHODIMP
-nsPopupBoxObject::EnableRollup(bool aShouldRollup)
+void
+PopupBoxObject::EnableRollup(bool aShouldRollup)
 {
   // this does nothing now
-  return NS_OK;
 }
 
-NS_IMETHODIMP
-nsPopupBoxObject::SetConsumeRollupEvent(uint32_t aConsume)
+void
+PopupBoxObject::SetConsumeRollupEvent(uint32_t aConsume)
 {
   nsMenuPopupFrame *menuPopupFrame = do_QueryFrame(GetFrame(false));
   if (menuPopupFrame) {
     menuPopupFrame->SetConsumeRollupEvent(aConsume);
   }
-
-  return NS_OK;
 }
 
-NS_IMETHODIMP
-nsPopupBoxObject::EnableKeyboardNavigator(bool aEnableKeyboardNavigator)
+void
+PopupBoxObject::EnableKeyboardNavigator(bool aEnableKeyboardNavigator)
 {
   if (!mContent)
-    return NS_OK;
+    return;
 
   // Use ignorekeys="true" on the popup instead of using this function.
   if (aEnableKeyboardNavigator)
     mContent->UnsetAttr(kNameSpaceID_None, nsGkAtoms::ignorekeys, true);
   else
     mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::ignorekeys,
                       NS_LITERAL_STRING("true"), true);
-
-  return NS_OK;
 }
 
-NS_IMETHODIMP
-nsPopupBoxObject::GetPopupState(nsAString& aState)
+void
+PopupBoxObject::GetPopupState(nsString& aState)
 {
   // set this here in case there's no frame for the popup
   aState.AssignLiteral("closed");
 
   nsMenuPopupFrame *menuPopupFrame = mContent ? do_QueryFrame(mContent->GetPrimaryFrame()) : nullptr;
   if (menuPopupFrame) {
     switch (menuPopupFrame->PopupState()) {
       case ePopupShown:
@@ -240,85 +226,71 @@ nsPopupBoxObject::GetPopupState(nsAStrin
         break;
       case ePopupClosed:
         break;
       default:
         NS_NOTREACHED("Bad popup state");
         break;
     }
   }
-
-  return NS_OK;
 }
 
-NS_IMETHODIMP
-nsPopupBoxObject::GetTriggerNode(nsIDOMNode** aTriggerNode)
+nsINode*
+PopupBoxObject::GetTriggerNode() const
 {
-  *aTriggerNode = nullptr;
-
   nsMenuPopupFrame *menuPopupFrame = mContent ? do_QueryFrame(mContent->GetPrimaryFrame()) : nullptr;
-  nsIContent* triggerContent = nsMenuPopupFrame::GetTriggerContent(menuPopupFrame);
-  if (triggerContent)
-    CallQueryInterface(triggerContent, aTriggerNode);
-
-  return NS_OK;
+  return nsMenuPopupFrame::GetTriggerContent(menuPopupFrame);
 }
 
-NS_IMETHODIMP
-nsPopupBoxObject::GetAnchorNode(nsIDOMElement** aAnchor)
+Element*
+PopupBoxObject::GetAnchorNode() const
 {
-  *aAnchor = nullptr;
-
   nsMenuPopupFrame *menuPopupFrame = mContent ? do_QueryFrame(mContent->GetPrimaryFrame()) : nullptr;
-  if (!menuPopupFrame)
-    return NS_OK;
+  if (!menuPopupFrame) {
+    return nullptr;
+  }
 
   nsIContent* anchor = menuPopupFrame->GetAnchor();
-  if (anchor)
-    CallQueryInterface(anchor, aAnchor);
-
-  return NS_OK;
+  return anchor && anchor->IsElement() ? anchor->AsElement() : nullptr;
 }
 
-NS_IMETHODIMP
-nsPopupBoxObject::GetOuterScreenRect(nsIDOMClientRect** aRect)
+already_AddRefed<DOMRect>
+PopupBoxObject::GetOuterScreenRect()
 {
-  DOMRect* rect = new DOMRect(mContent);
-
-  NS_ADDREF(*aRect = rect);
+  nsRefPtr<DOMRect> rect = new DOMRect(mContent);
 
   // Return an empty rectangle if the popup is not open.
   nsMenuPopupFrame *menuPopupFrame = do_QueryFrame(GetFrame(false));
-  if (!menuPopupFrame || !menuPopupFrame->IsOpen())
-    return NS_OK;
+  if (!menuPopupFrame || !menuPopupFrame->IsOpen()) {
+    return rect.forget();
+  }
 
   nsView* view = menuPopupFrame->GetView();
   if (view) {
     nsIWidget* widget = view->GetWidget();
     if (widget) {
       nsIntRect screenRect;
       widget->GetScreenBounds(screenRect);
 
       int32_t pp = menuPopupFrame->PresContext()->AppUnitsPerDevPixel();
       rect->SetLayoutRect(screenRect.ToAppUnits(pp));
     }
   }
-
-  return NS_OK;
+  return rect.forget();
 }
 
-NS_IMETHODIMP
-nsPopupBoxObject::GetAlignmentPosition(nsAString& positionStr)
+void
+PopupBoxObject::GetAlignmentPosition(nsString& positionStr)
 {
   positionStr.Truncate();
 
   // This needs to flush layout.
   nsMenuPopupFrame *menuPopupFrame = do_QueryFrame(GetFrame(true));
   if (!menuPopupFrame)
-    return NS_OK;
+    return;
 
   int8_t position = menuPopupFrame->GetAlignmentPosition();
   switch (position) {
     case POPUPPOSITION_AFTERSTART:
       positionStr.AssignLiteral("after_start");
       break;
     case POPUPPOSITION_AFTEREND:
       positionStr.AssignLiteral("after_end");
@@ -346,40 +318,38 @@ nsPopupBoxObject::GetAlignmentPosition(n
       break;
     case POPUPPOSITION_AFTERPOINTER:
       positionStr.AssignLiteral("after_pointer");
       break;
     default:
       // Leave as an empty string.
       break;
   }
-
-  return NS_OK;
 }
 
-NS_IMETHODIMP
-nsPopupBoxObject::GetAlignmentOffset(int32_t *aAlignmentOffset)
+int32_t
+PopupBoxObject::AlignmentOffset()
 {
   nsMenuPopupFrame *menuPopupFrame = do_QueryFrame(GetFrame(false));
   if (!menuPopupFrame)
-    return NS_OK;
+    return 0;
 
   int32_t pp = mozilla::AppUnitsPerCSSPixel();
   // Note that the offset might be along either the X or Y axis, but for the
   // sake of simplicity we use a point with only the X axis set so we can
   // use ToNearestPixels().
   nsPoint appOffset(menuPopupFrame->GetAlignmentOffset(), 0);
   nsIntPoint popupOffset = appOffset.ToNearestPixels(pp);
-  *aAlignmentOffset = popupOffset.x;
-  return NS_OK;
+  return popupOffset.x;
 }
 
+} // namespace dom
+} // namespace mozilla
+
 // Creation Routine ///////////////////////////////////////////////////////////////////////
 
 nsresult
 NS_NewPopupBoxObject(nsIBoxObject** aResult)
 {
-  *aResult = new nsPopupBoxObject;
-  if (!*aResult)
-    return NS_ERROR_OUT_OF_MEMORY;
+  *aResult = new mozilla::dom::PopupBoxObject();
   NS_ADDREF(*aResult);
   return NS_OK;
 }
new file mode 100644
--- /dev/null
+++ b/layout/xul/PopupBoxObject.h
@@ -0,0 +1,106 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* 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/. */
+
+#ifndef mozilla_dom_PopupBoxObject_h
+#define mozilla_dom_PopupBoxObject_h
+
+#include "mozilla/Attributes.h"
+#include "mozilla/ErrorResult.h"
+#include "nsCycleCollectionParticipant.h"
+#include "nsWrapperCache.h"
+#include "mozilla/dom/BoxObject.h"
+#include "nsString.h"
+
+struct JSContext;
+class nsPopupSetFrame;
+
+namespace mozilla {
+namespace dom {
+
+class DOMRect;
+class Element;
+class Event;
+
+class PopupBoxObject MOZ_FINAL : public BoxObject
+{
+public:
+  NS_DECL_ISUPPORTS_INHERITED
+
+  // also in PopupBoxObject.webidl
+  static const uint32_t ROLLUP_DEFAULT = 0;   /* widget/platform default */
+  static const uint32_t ROLLUP_CONSUME = 1;   /* consume the rollup event */
+  static const uint32_t ROLLUP_NO_CONSUME = 2; /* don't consume the rollup event */
+
+  PopupBoxObject();
+
+  nsIContent* GetParentObject() const;
+  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+
+  void ShowPopup(Element* aAnchorElement,
+                 Element& aPopupElement,
+                 int32_t aXPos,
+                 int32_t aYPos,
+                 const nsAString& aPopupType,
+                 const nsAString& aAnchorAlignment,
+                 const nsAString& aPopupAlignment);
+
+  void HidePopup(bool aCancel);
+
+  bool AutoPosition();
+
+  void SetAutoPosition(bool aShouldAutoPosition);
+
+  void EnableKeyboardNavigator(bool aEnableKeyboardNavigator);
+
+  void EnableRollup(bool aShouldRollup);
+
+  void SetConsumeRollupEvent(uint32_t aConsume);
+
+  void SizeTo(int32_t aWidth, int32_t aHeight);
+
+  void MoveTo(int32_t aLeft, int32_t aTop);
+
+  void OpenPopup(Element* aAnchorElement,
+                 const nsAString& aPosition,
+                 int32_t aXPos,
+                 int32_t aYPos,
+                 bool aIsContextMenu, bool aAttributesOverride,
+                 Event* aTriggerEvent);
+
+  void OpenPopupAtScreen(int32_t aXPos,
+                         int32_t aYPos,
+                         bool aIsContextMenu,
+                         Event* aTriggerEvent);
+
+  void GetPopupState(nsString& aState);
+
+  nsINode* GetTriggerNode() const;
+
+  Element* GetAnchorNode() const;
+
+  already_AddRefed<DOMRect> GetOuterScreenRect();
+
+  void MoveToAnchor(Element* aAnchorElement,
+                    const nsAString& aPosition,
+                    int32_t aXPos,
+                    int32_t aYPos,
+                    bool aAttributesOverride);
+
+  void GetAlignmentPosition(nsString& positionStr);
+
+  int32_t AlignmentOffset();
+
+private:
+  ~PopupBoxObject();
+
+protected:
+  nsPopupSetFrame* GetPopupSetFrame();
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_PopupBoxObject_h
new file mode 100644
--- /dev/null
+++ b/layout/xul/ScrollBoxObject.cpp
@@ -0,0 +1,394 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/. */
+
+#include "mozilla/dom/ScrollBoxObject.h"
+#include "mozilla/dom/ScrollBoxObjectBinding.h"
+#include "mozilla/dom/Element.h"
+#include "mozilla/dom/ToJSValue.h"
+#include "nsCOMPtr.h"
+#include "nsIPresShell.h"
+#include "nsIContent.h"
+#include "nsIDOMElement.h"
+#include "nsPresContext.h"
+#include "nsBox.h"
+#include "nsIScrollableFrame.h"
+
+namespace mozilla {
+namespace dom {
+
+ScrollBoxObject::ScrollBoxObject()
+{
+}
+
+ScrollBoxObject::~ScrollBoxObject()
+{
+}
+
+JSObject* ScrollBoxObject::WrapObject(JSContext* aCx)
+{
+  return ScrollBoxObjectBinding::Wrap(aCx, this);
+}
+
+nsIScrollableFrame* ScrollBoxObject::GetScrollFrame()
+{
+  return do_QueryFrame(GetFrame(false));
+}
+
+/* void scrollTo (long x, long y); */
+void ScrollBoxObject::ScrollTo(int32_t x, int32_t y, ErrorResult& aRv)
+{
+  nsIScrollableFrame* sf = GetScrollFrame();
+  if (!sf) {
+    aRv.Throw(NS_ERROR_FAILURE);
+    return;
+  }
+
+  sf->ScrollToCSSPixels(CSSIntPoint(x, y));
+}
+
+/* void scrollBy (long dx, long dy); */
+void ScrollBoxObject::ScrollBy(int32_t dx, int32_t dy, ErrorResult& aRv)
+{
+  CSSIntPoint pt;
+  GetPosition(pt, aRv);
+
+  if (aRv.Failed()) {
+    return;
+  }
+
+  ScrollTo(pt.x + dx, pt.y + dy, aRv);
+}
+
+/* void scrollByLine (long dlines); */
+void ScrollBoxObject::ScrollByLine(int32_t dlines, ErrorResult& aRv)
+{
+  nsIScrollableFrame* sf = GetScrollFrame();
+  if (!sf) {
+    aRv.Throw(NS_ERROR_FAILURE);
+    return;
+  }
+
+  sf->ScrollBy(nsIntPoint(0, dlines), nsIScrollableFrame::LINES,
+               nsIScrollableFrame::SMOOTH);
+}
+
+// XUL <scrollbox> elements have a single box child element.
+// Get a pointer to that box.
+// Note that now that the <scrollbox> is just a regular box
+// with 'overflow:hidden', the boxobject's frame is an nsXULScrollFrame,
+// the <scrollbox>'s box frame is the scrollframe's "scrolled frame", and
+// the <scrollbox>'s child box is a child of that.
+static nsIFrame* GetScrolledBox(BoxObject* aScrollBox) {
+  nsIFrame* frame = aScrollBox->GetFrame(false);
+  if (!frame) {
+    return nullptr;
+  }
+
+  nsIScrollableFrame* scrollFrame = do_QueryFrame(frame);
+  if (!scrollFrame) {
+    NS_WARNING("ScrollBoxObject attached to something that's not a scroll frame!");
+    return nullptr;
+  }
+
+  nsIFrame* scrolledFrame = scrollFrame->GetScrolledFrame();
+  if (!scrolledFrame)
+    return nullptr;
+  return nsBox::GetChildBox(scrolledFrame);
+}
+
+/* void scrollByIndex (long dindexes); */
+void ScrollBoxObject::ScrollByIndex(int32_t dindexes, ErrorResult& aRv)
+{
+    nsIScrollableFrame* sf = GetScrollFrame();
+    if (!sf) {
+      aRv.Throw(NS_ERROR_FAILURE);
+      return;
+    }
+
+    nsIFrame* scrolledBox = GetScrolledBox(this);
+    if (!scrolledBox) {
+      aRv.Throw(NS_ERROR_FAILURE);
+      return;
+    }
+
+    nsRect rect;
+
+    // now get the scrolled boxes first child.
+    nsIFrame* child = nsBox::GetChildBox(scrolledBox);
+
+    bool horiz = scrolledBox->IsHorizontal();
+    nsPoint cp = sf->GetScrollPosition();
+    nscoord diff = 0;
+    int32_t curIndex = 0;
+    bool isLTR = scrolledBox->IsNormalDirection();
+
+    int32_t frameWidth = 0;
+    if (!isLTR && horiz) {
+      GetWidth(&frameWidth);
+      nsCOMPtr<nsIPresShell> shell = GetPresShell(false);
+      if (!shell) {
+        aRv.Throw(NS_ERROR_UNEXPECTED);
+        return;
+      }
+      frameWidth = nsPresContext::CSSPixelsToAppUnits(frameWidth);
+    }
+
+    // first find out what index we are currently at
+    while(child) {
+      rect = child->GetRect();
+      if (horiz) {
+        // In the left-to-right case we break from the loop when the center of
+        // the current child rect is greater than the scrolled position of
+        // the left edge of the scrollbox
+        // In the right-to-left case we break when the center of the current
+        // child rect is less than the scrolled position of the right edge of
+        // the scrollbox.
+        diff = rect.x + rect.width/2; // use the center, to avoid rounding errors
+        if ((isLTR && diff > cp.x) ||
+            (!isLTR && diff < cp.x + frameWidth)) {
+          break;
+        }
+      } else {
+        diff = rect.y + rect.height/2;// use the center, to avoid rounding errors
+        if (diff > cp.y) {
+          break;
+        }
+      }
+      child = nsBox::GetNextBox(child);
+      curIndex++;
+    }
+
+    int32_t count = 0;
+
+    if (dindexes == 0)
+      return;
+
+    if (dindexes > 0) {
+      while(child) {
+        child = nsBox::GetNextBox(child);
+        if (child) {
+          rect = child->GetRect();
+        }
+        count++;
+        if (count >= dindexes) {
+          break;
+        }
+      }
+
+   } else if (dindexes < 0) {
+      child = nsBox::GetChildBox(scrolledBox);
+      while(child) {
+        rect = child->GetRect();
+        if (count >= curIndex + dindexes) {
+          break;
+        }
+
+        count++;
+        child = nsBox::GetNextBox(child);
+
+      }
+   }
+
+   nscoord csspixel = nsPresContext::CSSPixelsToAppUnits(1);
+   if (horiz) {
+       // In the left-to-right case we scroll so that the left edge of the
+       // selected child is scrolled to the left edge of the scrollbox.
+       // In the right-to-left case we scroll so that the right edge of the
+       // selected child is scrolled to the right edge of the scrollbox.
+
+       nsPoint pt(isLTR ? rect.x : rect.x + rect.width - frameWidth,
+                  cp.y);
+
+       // Use a destination range that ensures the left edge (or right edge,
+       // for RTL) will indeed be visible. Also ensure that the top edge
+       // is visible.
+       nsRect range(pt.x, pt.y, csspixel, 0);
+       if (isLTR) {
+         range.x -= csspixel;
+       }
+       sf->ScrollTo(pt, nsIScrollableFrame::INSTANT, &range);
+   } else {
+       // Use a destination range that ensures the top edge will be visible.
+       nsRect range(cp.x, rect.y - csspixel, 0, csspixel);
+       sf->ScrollTo(nsPoint(cp.x, rect.y), nsIScrollableFrame::INSTANT, &range);
+   }
+}
+
+/* void scrollToLine (in long line); */
+void ScrollBoxObject::ScrollToLine(int32_t line, ErrorResult& aRv)
+{
+  nsIScrollableFrame* sf = GetScrollFrame();
+  if (!sf) {
+    aRv.Throw(NS_ERROR_FAILURE);
+    return;
+  }
+
+  nscoord y = sf->GetLineScrollAmount().height * line;
+  nsRect range(0, y - nsPresContext::CSSPixelsToAppUnits(1),
+               0, nsPresContext::CSSPixelsToAppUnits(1));
+  sf->ScrollTo(nsPoint(0, y), nsIScrollableFrame::INSTANT, &range);
+}
+
+/* void scrollToElement (Element child); */
+void ScrollBoxObject::ScrollToElement(Element& child, ErrorResult& aRv)
+{
+  nsCOMPtr<nsIPresShell> shell = GetPresShell(false);
+  if (!shell) {
+    aRv.Throw(NS_ERROR_UNEXPECTED);
+    return;
+  }
+
+  shell->ScrollContentIntoView(&child,
+                               nsIPresShell::ScrollAxis(
+                                 nsIPresShell::SCROLL_TOP,
+                                 nsIPresShell::SCROLL_ALWAYS),
+                               nsIPresShell::ScrollAxis(
+                                 nsIPresShell::SCROLL_LEFT,
+                                 nsIPresShell::SCROLL_ALWAYS),
+                               nsIPresShell::SCROLL_FIRST_ANCESTOR_ONLY |
+                               nsIPresShell::SCROLL_OVERFLOW_HIDDEN);
+}
+
+/* void scrollToIndex (long index); */
+void ScrollBoxObject::ScrollToIndex(int32_t index, ErrorResult& aRv)
+{
+  aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
+}
+
+int32_t ScrollBoxObject::GetPositionX(ErrorResult& aRv)
+{
+  CSSIntPoint pt;
+  GetPosition(pt, aRv);
+  return pt.x;
+}
+
+int32_t ScrollBoxObject::GetPositionY(ErrorResult& aRv)
+{
+  CSSIntPoint pt;
+  GetPosition(pt, aRv);
+  return pt.y;
+}
+
+int32_t ScrollBoxObject::GetScrolledWidth(ErrorResult& aRv)
+{
+  nsRect scrollRect;
+  GetScrolledSize(scrollRect, aRv);
+  return scrollRect.width;
+}
+
+int32_t ScrollBoxObject::GetScrolledHeight(ErrorResult& aRv)
+{
+  nsRect scrollRect;
+  GetScrolledSize(scrollRect, aRv);
+  return scrollRect.height;
+}
+
+/* private helper */
+void ScrollBoxObject::GetPosition(CSSIntPoint& aPos, ErrorResult& aRv)
+{
+  nsIScrollableFrame* sf = GetScrollFrame();
+  if (!sf) {
+    aRv.Throw(NS_ERROR_FAILURE);
+    return;
+  }
+
+  aPos = sf->GetScrollPositionCSSPixels();
+}
+
+/* private helper */
+void ScrollBoxObject::GetScrolledSize(nsRect& aRect, ErrorResult& aRv)
+{
+    nsIFrame* scrolledBox = GetScrolledBox(this);
+    if (!scrolledBox) {
+      aRv.Throw(NS_ERROR_FAILURE);
+      return;
+    }
+
+    aRect = scrolledBox->GetRect();
+    aRect.width  = nsPresContext::AppUnitsToIntCSSPixels(aRect.width);
+    aRect.height = nsPresContext::AppUnitsToIntCSSPixels(aRect.height);
+}
+
+void ScrollBoxObject::GetPosition(JSContext* cx,
+                                  JS::Handle<JSObject*> x,
+                                  JS::Handle<JSObject*> y,
+                                  ErrorResult& aRv)
+{
+  CSSIntPoint pt;
+  GetPosition(pt, aRv);
+  JS::Rooted<JS::Value> v(cx);
+  if (!ToJSValue(cx, pt.x, &v) ||
+      !JS_SetProperty(cx, x, "value", v)) {
+    aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL);
+    return;
+  }
+  if (!ToJSValue(cx, pt.y, &v) ||
+      !JS_SetProperty(cx, y, "value", v)) {
+    aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL);
+    return;
+  }
+}
+
+void ScrollBoxObject::GetScrolledSize(JSContext* cx,
+                                      JS::Handle<JSObject*> width,
+                                      JS::Handle<JSObject*> height,
+                                      ErrorResult& aRv)
+{
+  nsRect rect;
+  GetScrolledSize(rect, aRv);
+  JS::Rooted<JS::Value> v(cx);
+  if (!ToJSValue(cx, rect.width, &v) ||
+      !JS_SetProperty(cx, width, "value", v)) {
+    aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL);
+    return;
+  }
+  if (!ToJSValue(cx, rect.height, &v) ||
+      !JS_SetProperty(cx, height, "value", v)) {
+    aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL);
+    return;
+  }
+}
+
+/* void ensureElementIsVisible (in nsIDOMElement child); */
+void ScrollBoxObject::EnsureElementIsVisible(Element& child, ErrorResult& aRv)
+{
+    nsCOMPtr<nsIPresShell> shell = GetPresShell(false);
+    if (!shell) {
+      aRv.Throw(NS_ERROR_UNEXPECTED);
+      return;
+    }
+
+    shell->ScrollContentIntoView(&child,
+                                 nsIPresShell::ScrollAxis(),
+                                 nsIPresShell::ScrollAxis(),
+                                 nsIPresShell::SCROLL_FIRST_ANCESTOR_ONLY |
+                                 nsIPresShell::SCROLL_OVERFLOW_HIDDEN);
+}
+
+/* void ensureIndexIsVisible (long index); */
+void ScrollBoxObject::EnsureIndexIsVisible(int32_t index, ErrorResult& aRv)
+{
+  aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
+}
+
+/* void ensureLineIsVisible (long line); */
+void ScrollBoxObject::EnsureLineIsVisible(int32_t line, ErrorResult& aRv)
+{
+  aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
+}
+
+} // namespace dom
+} // namespace mozilla
+
+// Creation Routine ///////////////////////////////////////////////////////////////////////
+
+using namespace mozilla::dom;
+
+nsresult
+NS_NewScrollBoxObject(nsIBoxObject** aResult)
+{
+  NS_ADDREF(*aResult = new ScrollBoxObject());
+  return NS_OK;
+}
new file mode 100644
--- /dev/null
+++ b/layout/xul/ScrollBoxObject.h
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/. */
+
+#ifndef mozilla_dom_ScrollBoxObject_h
+#define mozilla_dom_ScrollBoxObject_h
+
+#include "mozilla/dom/BoxObject.h"
+#include "Units.h"
+
+class nsIScrollableFrame;
+struct nsRect;
+
+namespace mozilla {
+namespace dom {
+
+class ScrollBoxObject MOZ_FINAL : public BoxObject
+{
+public:
+  ScrollBoxObject();
+
+  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+
+  virtual nsIScrollableFrame* GetScrollFrame();
+
+  void ScrollTo(int32_t x, int32_t y, ErrorResult& aRv);
+  void ScrollBy(int32_t dx, int32_t dy, ErrorResult& aRv);
+  void ScrollByLine(int32_t dlines, ErrorResult& aRv);
+  void ScrollByIndex(int32_t dindexes, ErrorResult& aRv);
+  void ScrollToLine(int32_t line, ErrorResult& aRv);
+  void ScrollToElement(Element& child, ErrorResult& aRv);
+  void ScrollToIndex(int32_t index, ErrorResult& aRv);
+  int32_t GetPositionX(ErrorResult& aRv);
+  int32_t GetPositionY(ErrorResult& aRv);
+  int32_t GetScrolledWidth(ErrorResult& aRv);
+  int32_t GetScrolledHeight(ErrorResult& aRv);
+  void EnsureElementIsVisible(Element& child, ErrorResult& aRv);
+  void EnsureIndexIsVisible(int32_t index, ErrorResult& aRv);
+  void EnsureLineIsVisible(int32_t line, ErrorResult& aRv);
+
+  // Deprecated APIs from old IDL
+  void GetPosition(JSContext* cx,
+                   JS::Handle<JSObject*> x,
+                   JS::Handle<JSObject*> y,
+                   ErrorResult& aRv);
+
+  void GetScrolledSize(JSContext* cx,
+                       JS::Handle<JSObject*> width,
+                       JS::Handle<JSObject*> height,
+                       ErrorResult& aRv);
+
+protected:
+  void GetScrolledSize(nsRect& aRect, ErrorResult& aRv);
+  void GetPosition(CSSIntPoint& aPos, ErrorResult& aRv);
+
+private:
+  ~ScrollBoxObject();
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_ScrollBoxObject_h
--- a/layout/xul/moz.build
+++ b/layout/xul/moz.build
@@ -8,89 +8,95 @@ if CONFIG['ENABLE_TESTS']:
     MOCHITEST_MANIFESTS += ['test/mochitest.ini']
     MOCHITEST_CHROME_MANIFESTS += ['test/chrome.ini']
     BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
 
 XPIDL_SOURCES += [
     'nsIBoxObject.idl',
     'nsIBrowserBoxObject.idl',
     'nsIContainerBoxObject.idl',
-    'nsIEditorBoxObject.idl',
-    'nsIIFrameBoxObject.idl',
     'nsIListBoxObject.idl',
     'nsIMenuBoxObject.idl',
-    'nsIPopupBoxObject.idl',
     'nsIScrollBoxObject.idl',
     'nsISliderListener.idl',
 ]
 
 XPIDL_MODULE = 'layout_xul'
 
 EXPORTS += [
     'nsBox.h',
     'nsIScrollbarMediator.h',
     'nsPIBoxObject.h',
+    'nsPIListBoxObject.h',
     'nsXULPopupManager.h',
 ]
 
+EXPORTS.mozilla.dom += [
+    'BoxObject.h',
+    'ContainerBoxObject.h',
+    'ListBoxObject.h',
+    'MenuBoxObject.h',
+    'PopupBoxObject.h',
+    'ScrollBoxObject.h',
+]
+
 UNIFIED_SOURCES += [
+    'BoxObject.cpp',
     'nsBox.cpp',
     'nsBoxFrame.cpp',
     'nsBoxLayout.cpp',
     'nsBoxLayoutState.cpp',
-    'nsBoxObject.cpp',
     'nsButtonBoxFrame.cpp',
     'nsRepeatService.cpp',
     'nsRootBoxFrame.cpp',
     'nsScrollbarButtonFrame.cpp',
     'nsScrollbarFrame.cpp',
     'nsScrollBoxFrame.cpp',
     'nsSliderFrame.cpp',
     'nsSprocketLayout.cpp',
     'nsStackFrame.cpp',
     'nsStackLayout.cpp',
     'nsXULTooltipListener.cpp',
 ]
 
 if CONFIG['MOZ_XUL']:
     UNIFIED_SOURCES += [
-        'nsContainerBoxObject.cpp',
+        'ContainerBoxObject.cpp',
+        'ListBoxObject.cpp',
+        'MenuBoxObject.cpp',
         'nsDeckFrame.cpp',
         'nsDocElementBoxFrame.cpp',
         'nsGroupBoxFrame.cpp',
         'nsImageBoxFrame.cpp',
         'nsLeafBoxFrame.cpp',
         'nsListBoxBodyFrame.cpp',
         'nsListBoxLayout.cpp',
-        'nsListBoxObject.cpp',
         'nsListItemFrame.cpp',
         'nsMenuBarFrame.cpp',
         'nsMenuBarListener.cpp',
-        'nsMenuBoxObject.cpp',
         'nsMenuFrame.cpp',
         'nsMenuPopupFrame.cpp',
-        'nsPopupBoxObject.cpp',
         'nsPopupSetFrame.cpp',
         'nsProgressMeterFrame.cpp',
         'nsResizerFrame.cpp',
-        'nsScrollBoxObject.cpp',
         'nsSplitterFrame.cpp',
         'nsTextBoxFrame.cpp',
         'nsTitleBarFrame.cpp',
         'nsXULLabelFrame.cpp',
         'nsXULPopupManager.cpp',
+        'PopupBoxObject.cpp',
+        'ScrollBoxObject.cpp',
     ]
 
 if CONFIG['MOZ_XUL']:
     DIRS += ['tree', 'grid']
 
 FAIL_ON_WARNINGS = True
 
 MSVC_ENABLE_PGO = True
 
 FINAL_LIBRARY = 'xul'
 LOCAL_INCLUDES += [
     '../base',
     '../generic',
     '../style',
     '/content/base/src',
 ]
-
deleted file mode 100644
--- a/layout/xul/nsContainerBoxObject.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/. */
-
-#include "nsCOMPtr.h"
-#include "nsIContainerBoxObject.h"
-#include "nsIBrowserBoxObject.h"
-#include "nsIEditorBoxObject.h"
-#include "nsIIFrameBoxObject.h"
-#include "nsBoxObject.h"
-#include "nsIDocShell.h"
-#include "nsIContent.h"
-#include "nsIDocument.h"
-#include "nsIFrame.h"
-#include "nsSubDocumentFrame.h"
-
-/**
- * nsContainerBoxObject implements deprecated nsIBrowserBoxObject,
- * nsIEditorBoxObject and nsIIFrameBoxObject interfaces only because of the
- * backward compatibility.
- */
-
-class nsContainerBoxObject : public nsBoxObject,
-                             public nsIBrowserBoxObject,
-                             public nsIEditorBoxObject,
-                             public nsIIFrameBoxObject
-{
-protected:
-  virtual ~nsContainerBoxObject() {}
-public:
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_NSICONTAINERBOXOBJECT
-  NS_DECL_NSIBROWSERBOXOBJECT
-  NS_DECL_NSIEDITORBOXOBJECT
-  NS_DECL_NSIIFRAMEBOXOBJECT
-};
-
-NS_INTERFACE_MAP_BEGIN(nsContainerBoxObject)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIContainerBoxObject, nsIBrowserBoxObject)
-  NS_INTERFACE_MAP_ENTRY(nsIBrowserBoxObject)
-  NS_INTERFACE_MAP_ENTRY(nsIEditorBoxObject)
-  NS_INTERFACE_MAP_ENTRY(nsIIFrameBoxObject)
-NS_INTERFACE_MAP_END_INHERITING(nsBoxObject)
-
-NS_IMPL_ADDREF_INHERITED(nsContainerBoxObject, nsBoxObject)
-NS_IMPL_RELEASE_INHERITED(nsContainerBoxObject, nsBoxObject)
-
-NS_IMETHODIMP nsContainerBoxObject::GetDocShell(nsIDocShell** aResult)
-{
-  *aResult = nullptr;
-
-  nsSubDocumentFrame *subDocFrame = do_QueryFrame(GetFrame(false));
-  if (subDocFrame) {
-    // Ok, the frame for mContent is an nsSubDocumentFrame, it knows how
-    // to reach the docshell, so ask it...
-
-    return subDocFrame->GetDocShell(aResult);
-  }
-
-  if (!mContent) {
-    return NS_OK;
-  }
-  
-  // No nsSubDocumentFrame available for mContent, try if there's a mapping
-  // between mContent's document to mContent's subdocument.
-
-  nsIDocument *doc = mContent->GetComposedDoc();
-
-  if (!doc) {
-    return NS_OK;
-  }
-  
-  nsIDocument *sub_doc = doc->GetSubDocumentFor(mContent);
-
-  if (!sub_doc) {
-    return NS_OK;
-  }
-
-  NS_IF_ADDREF(*aResult = sub_doc->GetDocShell());
-  return NS_OK;
-}
-
-nsresult
-NS_NewContainerBoxObject(nsIBoxObject** aResult)
-{
-  *aResult = new nsContainerBoxObject();
-  if (!*aResult)
-    return NS_ERROR_OUT_OF_MEMORY;
-  NS_ADDREF(*aResult);
-  return NS_OK;
-}
-
--- a/layout/xul/nsIBoxObject.idl
+++ b/layout/xul/nsIBoxObject.idl
@@ -2,17 +2,17 @@
 /* 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/. */
 
 #include "nsISupports.idl"
 
 interface nsIDOMElement;
 
-[scriptable, uuid(ce572460-b0f2-4650-a9e7-c53a99d3b6ad)]
+[uuid(ce572460-b0f2-4650-a9e7-c53a99d3b6ad)]
 interface nsIBoxObject : nsISupports
 {
   readonly attribute nsIDOMElement element;
 
   readonly attribute long x;
   readonly attribute long y;
   readonly attribute long screenX;
   readonly attribute long screenY;
--- a/layout/xul/nsIBrowserBoxObject.idl
+++ b/layout/xul/nsIBrowserBoxObject.idl
@@ -1,16 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
 #include "nsIContainerBoxObject.idl"
 
 /**
- * @deprecated Please consider using nsIContainerBoxObject.
+ * @deprecated Please consider using ContainerBoxObject.
  */
 
-[scriptable, uuid(db436f2f-c656-4754-b0fa-99bc353bd63f)]
+[uuid(db436f2f-c656-4754-b0fa-99bc353bd63f)]
 interface nsIBrowserBoxObject : nsIContainerBoxObject
 {
 };
 
--- a/layout/xul/nsIContainerBoxObject.idl
+++ b/layout/xul/nsIContainerBoxObject.idl
@@ -1,20 +1,14 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
 #include "nsISupports.idl"
 
-interface nsIDocShell;
-interface nsIBoxObject;
+// DEPRECATED: This file exists for shim purposes only,
+// see ContainerBoxObject.webidl
 
-[scriptable, uuid(35d4c04b-3bd3-4375-92e2-a818b4b4acb6)]
+[uuid(35d4c04b-3bd3-4375-92e2-a818b4b4acb6)]
 interface nsIContainerBoxObject : nsISupports
 {
-  readonly attribute nsIDocShell docShell;
 };
-
-%{C++
-nsresult
-NS_NewContainerBoxObject(nsIBoxObject** aResult);
-%}
deleted file mode 100644
--- a/layout/xul/nsIEditorBoxObject.idl
+++ /dev/null
@@ -1,16 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/. */
-
-#include "nsIContainerBoxObject.idl"
-
-/**
- * @deprecated Please consider using nsIContainerBoxObject.
- */
-
-[scriptable, uuid(e3800a23-5b83-49aa-b18c-efa1ac5416e0)]
-interface nsIEditorBoxObject : nsIContainerBoxObject
-{
-};
-
deleted file mode 100644
--- a/layout/xul/nsIIFrameBoxObject.idl
+++ /dev/null
@@ -1,16 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/. */
-
-#include "nsIContainerBoxObject.idl"
-
-/**
- * @deprecated Please consider using nsIContainerBoxObject.
- */
-
-[scriptable, uuid(30114c44-d398-44a5-9e01-b48b711291cd)]
-interface nsIIFrameBoxObject : nsIContainerBoxObject
-{
-};
-
--- a/layout/xul/nsIListBoxObject.idl
+++ b/layout/xul/nsIListBoxObject.idl
@@ -1,31 +1,19 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
 #include "nsISupports.idl"
 
+// DEPRECATED: see ListBoxObject.webidl
+
 interface nsIDOMElement;
 
-[scriptable, uuid(AA9DEF4E-2E59-412d-A6DF-B76F52167795)]
+[uuid(AA9DEF4E-2E59-412d-A6DF-B76F52167795)]
 interface nsIListBoxObject : nsISupports
 {
   long getRowCount();
-  long getNumberOfVisibleRows();
-  long getIndexOfFirstVisibleRow();
-
-  void ensureIndexIsVisible(in long rowIndex);
-  void scrollToIndex(in long rowIndex);
-  void scrollByLines(in long numLines);
 
   nsIDOMElement getItemAtIndex(in long index);
   long getIndexOfItem(in nsIDOMElement item);
 };
-
-%{C++
-class nsIBoxObject;
-
-nsresult
-NS_NewListBoxObject(nsIBoxObject** aResult);
-
-%}
--- a/layout/xul/nsIMenuBoxObject.idl
+++ b/layout/xul/nsIMenuBoxObject.idl
@@ -1,30 +1,14 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
 #include "nsISupports.idl"
 
-interface nsIDOMElement;
-interface nsIDOMKeyEvent;
+// DEPRECATED: This file exists for shim purposes only,
+// see MenuBoxObject.webidl
 
-[scriptable, uuid(689ebf3d-0184-450a-9bfa-5a26be0e7a8c)]
+[uuid(689ebf3d-0184-450a-9bfa-5a26be0e7a8c)]
 interface nsIMenuBoxObject : nsISupports
 {
-  void openMenu(in boolean openFlag);
-
-  attribute nsIDOMElement activeChild;
-
-  boolean handleKeyPress(in nsIDOMKeyEvent keyEvent);
-
-  // true if the menu or menubar was opened via a keypress.
-  readonly attribute boolean openedWithKey;
 };
-
-%{C++
-class nsIBoxObject;
-
-nsresult
-NS_NewMenuBoxObject(nsIBoxObject** aResult);
-
-%}
--- a/layout/xul/nsIScrollBoxObject.idl
+++ b/layout/xul/nsIScrollBoxObject.idl
@@ -1,52 +1,12 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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/. */
 
 #include "nsISupports.idl"
 
-interface nsIDOMElement;
 
-
-[scriptable, uuid(56E2ADA8-4631-11d4-BA11-001083023C1E)]
+[uuid(56E2ADA8-4631-11d4-BA11-001083023C1E)]
 interface nsIScrollBoxObject : nsISupports
 {
-  /**
-   * Scroll to the given coordinates, in css pixels.
-   * (0,0) will put the top left corner of the scrolled element's padding-box
-   * at the top left corner of the scrollport (which is its inner-border-box).
-   * Values will be clamped to legal values.
-   */
-  void scrollTo(in long x, in long y);
-
-  /**
-   * Scroll the given amount of device pixels to the right and down.
-   * Values will be clamped to make the resuling position legal.
-   */
-  void scrollBy(in long dx, in long dy);
-
-  void scrollByLine(in long dlines);
-  void scrollByIndex(in long dindexes);
-  void scrollToLine(in long line);
-  void scrollToElement(in nsIDOMElement child);
-  void scrollToIndex(in long index);
-
-  /**
-   * Get the current scroll position in css pixels.
-   * @see scrollTo for the definition of x and y.
-   */
-  void getPosition(out long x, out long y);
-
-  void getScrolledSize(out long width, out long height);
-  void ensureElementIsVisible(in nsIDOMElement child);
-  void ensureIndexIsVisible(in long index);
-  void ensureLineIsVisible(in long line);
 };
-
-%{C++
-class nsIBoxObject;
-
-nsresult
-NS_NewScrollBoxObject(nsIBoxObject** aResult);
-
-%}
--- a/layout/xul/nsListBoxBodyFrame.cpp
+++ b/layout/xul/nsListBoxBodyFrame.cpp
@@ -490,37 +490,28 @@ nsListBoxBodyFrame::ReflowFinished()
 }
 
 void
 nsListBoxBodyFrame::ReflowCallbackCanceled()
 {
   mReflowCallbackPosted = false;
 }
 
-///////// nsIListBoxObject ///////////////
+///////// ListBoxObject ///////////////
 
-nsresult
-nsListBoxBodyFrame::GetRowCount(int32_t* aResult)
+int32_t
+nsListBoxBodyFrame::GetNumberOfVisibleRows()
 {
-  *aResult = GetRowCount();
-  return NS_OK;
+  return mRowHeight ? GetAvailableHeight() / mRowHeight : 0;
 }
 
-nsresult
-nsListBoxBodyFrame::GetNumberOfVisibleRows(int32_t *aResult)
+int32_t
+nsListBoxBodyFrame::GetIndexOfFirstVisibleRow()
 {
-  *aResult= mRowHeight ? GetAvailableHeight() / mRowHeight : 0;
-  return NS_OK;
-}
-
-nsresult
-nsListBoxBodyFrame::GetIndexOfFirstVisibleRow(int32_t *aResult)
-{
-  *aResult = mCurrentIndex;
-  return NS_OK;
+  return mCurrentIndex;
 }
 
 nsresult
 nsListBoxBodyFrame::EnsureIndexIsVisible(int32_t aRowIndex)
 {
   if (aRowIndex < 0)
     return NS_ERROR_ILLEGAL_VALUE;
 
@@ -556,19 +547,18 @@ nsListBoxBodyFrame::EnsureIndexIsVisible
   // box object.
   DoInternalPositionChangedSync(up, delta);
   return NS_OK;
 }
 
 nsresult
 nsListBoxBodyFrame::ScrollByLines(int32_t aNumLines)
 {
-  int32_t scrollIndex, visibleRows;
-  GetIndexOfFirstVisibleRow(&scrollIndex);
-  GetNumberOfVisibleRows(&visibleRows);
+  int32_t scrollIndex = GetIndexOfFirstVisibleRow(),
+    visibleRows = GetNumberOfVisibleRows();
 
   scrollIndex += aNumLines;
   
   if (scrollIndex < 0)
     scrollIndex = 0;
   else {
     int32_t numRows = GetRowCount();
     int32_t lastPageTopRow = numRows - visibleRows;
--- a/layout/xul/nsListBoxBodyFrame.h
+++ b/layout/xul/nsListBoxBodyFrame.h
@@ -4,17 +4,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsListBoxBodyFrame_h
 #define nsListBoxBodyFrame_h
 
 #include "mozilla/Attributes.h"
 #include "nsCOMPtr.h"
 #include "nsBoxFrame.h"
-#include "nsIListBoxObject.h"
 #include "nsIScrollbarMediator.h"
 #include "nsIReflowCallback.h"
 #include "nsBoxLayoutState.h"
 #include "nsThreadUtils.h"
 #include "nsPIBoxObject.h"
 
 class nsPresContext;
 class nsListScrollSmoother;
@@ -29,20 +28,19 @@ class nsListBoxBodyFrame MOZ_FINAL : pub
                      nsBoxLayout* aLayoutManager);
   virtual ~nsListBoxBodyFrame();
 
 public:
   NS_DECL_QUERYFRAME_TARGET(nsListBoxBodyFrame)
   NS_DECL_QUERYFRAME
   NS_DECL_FRAMEARENA_HELPERS
 
-  // non-virtual nsIListBoxObject
-  nsresult GetRowCount(int32_t *aResult);
-  nsresult GetNumberOfVisibleRows(int32_t *aResult);
-  nsresult GetIndexOfFirstVisibleRow(int32_t *aResult);
+  // non-virtual ListBoxObject
+  int32_t GetNumberOfVisibleRows();
+  int32_t GetIndexOfFirstVisibleRow();
   nsresult EnsureIndexIsVisible(int32_t aRowIndex);
   nsresult ScrollToIndex(int32_t aRowIndex);
   nsresult ScrollByLines(int32_t aNumLines);
   nsresult GetItemAtIndex(int32_t aIndex, nsIDOMElement **aResult);
   nsresult GetIndexOfItem(nsIDOMElement *aItem, int32_t *aResult);
 
   friend nsIFrame* NS_NewListBoxBodyFrame(nsIPresShell* aPresShell,
                                           nsStyleContext* aContext);
--- a/layout/xul/nsMenuPopupFrame.cpp
+++ b/layout/xul/nsMenuPopupFrame.cpp
@@ -29,17 +29,16 @@
 #include "nsIScrollableFrame.h"
 #include "nsIRootBox.h"
 #include "nsIDocShell.h"
 #include "nsReadableUtils.h"
 #include "nsUnicharUtils.h"
 #include "nsLayoutUtils.h"
 #include "nsContentUtils.h"
 #include "nsCSSFrameConstructor.h"
-#include "nsIPopupBoxObject.h"
 #include "nsPIWindowRoot.h"
 #include "nsIReflowCallback.h"
 #include "nsBindingManager.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsIBaseWindow.h"
 #include "nsISound.h"
 #include "nsIScreenManager.h"
 #include "nsIServiceManager.h"
@@ -48,19 +47,21 @@
 #include "nsDisplayList.h"
 #include "mozilla/EventDispatcher.h"
 #include "mozilla/EventStateManager.h"
 #include "mozilla/EventStates.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/LookAndFeel.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/dom/Element.h"
+#include "mozilla/dom/PopupBoxObject.h"
 #include <algorithm>
 
 using namespace mozilla;
+using mozilla::dom::PopupBoxObject;
 
 int8_t nsMenuPopupFrame::sDefaultLevelIsTop = -1;
 
 // NS_NewMenuPopupFrame
 //
 // Wrapper for creating a new menu popup container
 //
 nsIFrame*
@@ -83,17 +84,17 @@ nsMenuPopupFrame::nsMenuPopupFrame(nsIPr
   mCurrentMenu(nullptr),
   mPrefSize(-1, -1),
   mLastClientOffset(0, 0),
   mPopupType(ePopupTypePanel),
   mPopupState(ePopupClosed),
   mPopupAlignment(POPUPALIGNMENT_NONE),
   mPopupAnchor(POPUPALIGNMENT_NONE),
   mPosition(POPUPPOSITION_UNKNOWN),
-  mConsumeRollupEvent(nsIPopupBoxObject::ROLLUP_DEFAULT),
+  mConsumeRollupEvent(PopupBoxObject::ROLLUP_DEFAULT),
   mFlip(FlipType_Default),
   mIsOpenChanged(false),
   mIsContextMenu(false),
   mAdjustOffsetForContextMenu(false),
   mGeneratedChildren(false),
   mMenuCanOverlapOSBar(false),
   mShouldAutoPosition(true),
   mInContentShell(true),
@@ -1504,31 +1505,35 @@ void nsMenuPopupFrame::CanAdjustEdges(in
       aChange.y = 0;
     }
   }
 }
 
 bool nsMenuPopupFrame::ConsumeOutsideClicks()
 {
   // If the popup has explicitly set a consume mode, honor that.
-  if (mConsumeRollupEvent != nsIPopupBoxObject::ROLLUP_DEFAULT)
-    return (mConsumeRollupEvent == nsIPopupBoxObject::ROLLUP_CONSUME);
+  if (mConsumeRollupEvent != PopupBoxObject::ROLLUP_DEFAULT) {
+    return (mConsumeRollupEvent == PopupBoxObject::ROLLUP_CONSUME);
+  }
 
   if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::consumeoutsideclicks,
-                            nsGkAtoms::_true, eCaseMatters))
+                            nsGkAtoms::_true, eCaseMatters)) {
     return true;
+  }
   if (mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::consumeoutsideclicks,
-                            nsGkAtoms::_false, eCaseMatters))
+                            nsGkAtoms::_false, eCaseMatters)) {
     return false;
+  }
 
   nsCOMPtr<nsIContent> parentContent = mContent->GetParent();
   if (parentContent) {
     dom::NodeInfo *ni = parentContent->NodeInfo();
-    if (ni->Equals(nsGkAtoms::menulist, kNameSpaceID_XUL))
+    if (ni->Equals(nsGkAtoms::menulist, kNameSpaceID_XUL)) {
       return true;  // Consume outside clicks for combo boxes on all platforms
+    }
 #if defined(XP_WIN)
     // Don't consume outside clicks for menus in Windows
     if (ni->Equals(nsGkAtoms::menu, kNameSpaceID_XUL) ||
         ni->Equals(nsGkAtoms::splitmenu, kNameSpaceID_XUL) ||
         ni->Equals(nsGkAtoms::popupset, kNameSpaceID_XUL) ||
         ((ni->Equals(nsGkAtoms::button, kNameSpaceID_XUL) ||
           ni->Equals(nsGkAtoms::toolbarbutton, kNameSpaceID_XUL)) &&
          (parentContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
@@ -1536,18 +1541,19 @@ bool nsMenuPopupFrame::ConsumeOutsideCli
           parentContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
                                      nsGkAtoms::menuButton, eCaseMatters)))) {
       return false;
     }
 #endif
     if (ni->Equals(nsGkAtoms::textbox, kNameSpaceID_XUL)) {
       // Don't consume outside clicks for autocomplete widget
       if (parentContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
-                                     nsGkAtoms::autocomplete, eCaseMatters))
+                                     nsGkAtoms::autocomplete, eCaseMatters)) {
         return false;
+      }
     }
   }
 
   return true;
 }
 
 // XXXroc this is megalame. Fossicking around for a frame of the right
 // type is a recipe for disaster in the long term.
@@ -1858,17 +1864,17 @@ nsMenuPopupFrame::GetWidget()
     return nullptr;
 
   return view->GetWidget();
 }
 
 void
 nsMenuPopupFrame::AttachedDismissalListener()
 {
-  mConsumeRollupEvent = nsIPopupBoxObject::ROLLUP_DEFAULT;
+  mConsumeRollupEvent = PopupBoxObject::ROLLUP_DEFAULT;
 }
 
 // helpers /////////////////////////////////////////////////////////////
 
 nsresult 
 nsMenuPopupFrame::AttributeChanged(int32_t aNameSpaceID,
                                    nsIAtom* aAttribute,
                                    int32_t aModType)
@@ -1899,17 +1905,17 @@ nsMenuPopupFrame::AttributeChanged(int32
 }
 
 void
 nsMenuPopupFrame::MoveToAttributePosition()
 {
   // Move the widget around when the user sets the |left| and |top| attributes. 
   // Note that this is not the best way to move the widget, as it results in lots
   // of FE notifications and is likely to be slow as molasses. Use |moveTo| on
-  // nsIPopupBoxObject if possible. 
+  // PopupBoxObject if possible.
   nsAutoString left, top;
   mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::left, left);
   mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::top, top);
   nsresult err1, err2;
   int32_t xpos = left.ToInteger(&err1);
   int32_t ypos = top.ToInteger(&err2);
 
   if (NS_SUCCEEDED(err1) && NS_SUCCEEDED(err2))
--- a/layout/xul/nsMenuPopupFrame.h
+++ b/layout/xul/nsMenuPopupFrame.h
@@ -511,18 +511,18 @@ protected:
   nsPopupType mPopupType; // type of popup
   nsPopupState mPopupState; // open state of the popup
 
   // popup alignment relative to the anchor node
   int8_t mPopupAlignment;
   int8_t mPopupAnchor;
   int8_t mPosition;
 
-  // One of nsIPopupBoxObject::ROLLUP_DEFAULT/ROLLUP_CONSUME/ROLLUP_NO_CONSUME
-  int8_t mConsumeRollupEvent;
+  // One of PopupBoxObject::ROLLUP_DEFAULT/ROLLUP_CONSUME/ROLLUP_NO_CONSUME
+  uint8_t mConsumeRollupEvent;
   FlipType mFlip; // Whether to flip
 
   bool mIsOpenChanged; // true if the open state changed since the last layout
   bool mIsContextMenu; // true for context menus
   // true if we need to offset the popup to ensure it's not under the mouse
   bool mAdjustOffsetForContextMenu;
   bool mGeneratedChildren; // true if the contents have been created
 
deleted file mode 100644
--- a/layout/xul/nsScrollBoxObject.cpp
+++ /dev/null
@@ -1,331 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/. */
-
-#include "nsCOMPtr.h"
-#include "nsIScrollBoxObject.h"
-#include "nsBoxObject.h"
-#include "nsIPresShell.h"
-#include "nsIContent.h"
-#include "nsIDOMElement.h"
-#include "nsPresContext.h"
-#include "nsBox.h"
-#include "nsIScrollableFrame.h"
-
-using namespace mozilla;
-
-class nsScrollBoxObject MOZ_FINAL : public nsIScrollBoxObject,
-                                    public nsBoxObject
-{
-public:
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_NSISCROLLBOXOBJECT
-
-  nsScrollBoxObject();
-
-  virtual nsIScrollableFrame* GetScrollFrame() {
-    return do_QueryFrame(GetFrame(false));
-  }
-
-protected:
-  virtual ~nsScrollBoxObject();
-};
-
-/* Implementation file */
-
-NS_INTERFACE_MAP_BEGIN(nsScrollBoxObject)
-  NS_INTERFACE_MAP_ENTRY(nsIScrollBoxObject)
-NS_INTERFACE_MAP_END_INHERITING(nsBoxObject)
-
-NS_IMPL_ADDREF_INHERITED(nsScrollBoxObject, nsBoxObject)
-NS_IMPL_RELEASE_INHERITED(nsScrollBoxObject, nsBoxObject)
-
-nsScrollBoxObject::nsScrollBoxObject()
-{
-  /* member initializers and constructor code */
-}
-
-nsScrollBoxObject::~nsScrollBoxObject()
-{
-  /* destructor code */
-}
-
-/* void scrollTo (in long x, in long y); */
-NS_IMETHODIMP nsScrollBoxObject::ScrollTo(int32_t x, int32_t y)
-{
-  nsIScrollableFrame* sf = GetScrollFrame();
-  if (!sf)
-    return NS_ERROR_FAILURE;
-  sf->ScrollToCSSPixels(CSSIntPoint(x, y));
-  return NS_OK;
-}
-
-/* void scrollBy (in long dx, in long dy); */
-NS_IMETHODIMP nsScrollBoxObject::ScrollBy(int32_t dx, int32_t dy)
-{
-  int32_t x, y;
-  nsresult rv = GetPosition(&x, &y);
-  if (NS_FAILED(rv))
-    return rv;
-
-  return ScrollTo(x + dx, y + dy);
-}
-
-/* void scrollByLine (in long dlines); */
-NS_IMETHODIMP nsScrollBoxObject::ScrollByLine(int32_t dlines)
-{
-  nsIScrollableFrame* sf = GetScrollFrame();
-  if (!sf)
-    return NS_ERROR_FAILURE;
-
-  sf->ScrollBy(nsIntPoint(0, dlines), nsIScrollableFrame::LINES,
-               nsIScrollableFrame::SMOOTH);
-  return NS_OK;
-}
-
-// XUL <scrollbox> elements have a single box child element.
-// Get a pointer to that box.
-// Note that now that the <scrollbox> is just a regular box
-// with 'overflow:hidden', the boxobject's frame is an nsXULScrollFrame,
-// the <scrollbox>'s box frame is the scrollframe's "scrolled frame", and
-// the <scrollbox>'s child box is a child of that.
-static nsIFrame* GetScrolledBox(nsBoxObject* aScrollBox) {
-  nsIFrame* frame = aScrollBox->GetFrame(false);
-  if (!frame) 
-    return nullptr;
-  nsIScrollableFrame* scrollFrame = do_QueryFrame(frame);
-  if (!scrollFrame) {
-    NS_WARNING("nsIScrollBoxObject attached to something that's not a scroll frame!");
-    return nullptr;
-  }
-  nsIFrame* scrolledFrame = scrollFrame->GetScrolledFrame();
-  if (!scrolledFrame)
-    return nullptr;
-  return nsBox::GetChildBox(scrolledFrame);
-}
-
-/* void scrollByIndex (in long dindexes); */
-NS_IMETHODIMP nsScrollBoxObject::ScrollByIndex(int32_t dindexes)
-{
-    nsIScrollableFrame* sf = GetScrollFrame();
-    if (!sf)
-       return NS_ERROR_FAILURE;
-    nsIFrame* scrolledBox = GetScrolledBox(this);
-    if (!scrolledBox)
-       return NS_ERROR_FAILURE;
-
-    nsRect rect;
-
-    // now get the scrolled boxes first child.
-    nsIFrame* child = nsBox::GetChildBox(scrolledBox);
-
-    bool horiz = scrolledBox->IsHorizontal();
-    nsPoint cp = sf->GetScrollPosition();
-    nscoord diff = 0;
-    int32_t curIndex = 0;
-    bool isLTR = scrolledBox->IsNormalDirection();
-
-    int32_t frameWidth = 0;
-    if (!isLTR && horiz) {
-      GetWidth(&frameWidth);
-      nsCOMPtr<nsIPresShell> shell = GetPresShell(false);
-      if (!shell) {
-        return NS_ERROR_UNEXPECTED;
-      }
-      frameWidth = nsPresContext::CSSPixelsToAppUnits(frameWidth);
-    }
-
-    // first find out what index we are currently at
-    while(child) {
-      rect = child->GetRect();
-      if (horiz) {
-        // In the left-to-right case we break from the loop when the center of
-        // the current child rect is greater than the scrolled position of
-        // the left edge of the scrollbox
-        // In the right-to-left case we break when the center of the current
-        // child rect is less than the scrolled position of the right edge of
-        // the scrollbox.
-        diff = rect.x + rect.width/2; // use the center, to avoid rounding errors
-        if ((isLTR && diff > cp.x) ||
-            (!isLTR && diff < cp.x + frameWidth)) {
-          break;
-        }
-      } else {
-        diff = rect.y + rect.height/2;// use the center, to avoid rounding errors
-        if (diff > cp.y) {
-          break;
-        }
-      }
-      child = nsBox::GetNextBox(child);
-      curIndex++;
-    }
-
-    int32_t count = 0;
-
-    if (dindexes == 0)
-       return NS_OK;
-
-    if (dindexes > 0) {
-      while(child) {
-        child = nsBox::GetNextBox(child);
-        if (child)
-          rect = child->GetRect();
-        count++;
-        if (count >= dindexes)
-          break;
-      }
-
-   } else if (dindexes < 0) {
-      child = nsBox::GetChildBox(scrolledBox);
-      while(child) {
-        rect = child->GetRect();
-        if (count >= curIndex + dindexes)
-          break;
-
-        count++;
-        child = nsBox::GetNextBox(child);
-
-      }
-   }
-
-   nscoord csspixel = nsPresContext::CSSPixelsToAppUnits(1);
-   if (horiz) {
-       // In the left-to-right case we scroll so that the left edge of the
-       // selected child is scrolled to the left edge of the scrollbox.
-       // In the right-to-left case we scroll so that the right edge of the
-       // selected child is scrolled to the right edge of the scrollbox.
-
-       nsPoint pt(isLTR ? rect.x : rect.x + rect.width - frameWidth,
-                  cp.y);
-
-       // Use a destination range that ensures the left edge (or right edge,
-       // for RTL) will indeed be visible. Also ensure that the top edge
-       // is visible.
-       nsRect range(pt.x, pt.y, csspixel, 0);
-       if (isLTR) {
-         range.x -= csspixel;
-       }
-       sf->ScrollTo(pt, nsIScrollableFrame::INSTANT, &range);
-   } else {
-       // Use a destination range that ensures the top edge will be visible.
-       nsRect range(cp.x, rect.y - csspixel, 0, csspixel);
-       sf->ScrollTo(nsPoint(cp.x, rect.y), nsIScrollableFrame::INSTANT, &range);
-   }
-
-   return NS_OK;
-}
-
-/* void scrollToLine (in long line); */
-NS_IMETHODIMP nsScrollBoxObject::ScrollToLine(int32_t line)
-{
-  nsIScrollableFrame* sf = GetScrollFrame();
-  if (!sf)
-     return NS_ERROR_FAILURE;
-  
-  nscoord y = sf->GetLineScrollAmount().height * line;
-  nsRect range(0, y - nsPresContext::CSSPixelsToAppUnits(1),
-               0, nsPresContext::CSSPixelsToAppUnits(1));
-  sf->ScrollTo(nsPoint(0, y), nsIScrollableFrame::INSTANT, &range);
-  return NS_OK;
-}
-
-/* void scrollToElement (in nsIDOMElement child); */
-NS_IMETHODIMP nsScrollBoxObject::ScrollToElement(nsIDOMElement *child)
-{
-    NS_ENSURE_ARG_POINTER(child);
-
-    nsCOMPtr<nsIPresShell> shell = GetPresShell(false);
-    if (!shell) {
-      return NS_ERROR_UNEXPECTED;
-    }
-
-    nsCOMPtr<nsIContent> content = do_QueryInterface(child);
-    shell->ScrollContentIntoView(content,
-                                 nsIPresShell::ScrollAxis(
-                                   nsIPresShell::SCROLL_TOP,
-                                   nsIPresShell::SCROLL_ALWAYS),
-                                 nsIPresShell::ScrollAxis(
-                                   nsIPresShell::SCROLL_LEFT,
-                                   nsIPresShell::SCROLL_ALWAYS),
-                                 nsIPresShell::SCROLL_FIRST_ANCESTOR_ONLY |
-                                 nsIPresShell::SCROLL_OVERFLOW_HIDDEN);
-    return NS_OK;
-}
-
-/* void scrollToIndex (in long index); */
-NS_IMETHODIMP nsScrollBoxObject::ScrollToIndex(int32_t index)
-{
-    return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-/* void getPosition (out long x, out long y); */
-NS_IMETHODIMP nsScrollBoxObject::GetPosition(int32_t *x, int32_t *y)
-{
-  nsIScrollableFrame* sf = GetScrollFrame();
-  if (!sf)
-     return NS_ERROR_FAILURE;
-
-  CSSIntPoint pt = sf->GetScrollPositionCSSPixels();
-  *x = pt.x;
-  *y = pt.y;
-
-  return NS_OK;  
-}
-
-/* void getScrolledSize (out long width, out long height); */
-NS_IMETHODIMP nsScrollBoxObject::GetScrolledSize(int32_t *width, int32_t *height)
-{
-    nsIFrame* scrolledBox = GetScrolledBox(this);
-    if (!scrolledBox)
-        return NS_ERROR_FAILURE;
-        	
-    nsRect scrollRect = scrolledBox->GetRect();
-
-    *width  = nsPresContext::AppUnitsToIntCSSPixels(scrollRect.width);
-    *height = nsPresContext::AppUnitsToIntCSSPixels(scrollRect.height);
-
-    return NS_OK;
-}
-
-/* void ensureElementIsVisible (in nsIDOMElement child); */
-NS_IMETHODIMP nsScrollBoxObject::EnsureElementIsVisible(nsIDOMElement *child)
-{
-    NS_ENSURE_ARG_POINTER(child);
-
-    nsCOMPtr<nsIPresShell> shell = GetPresShell(false);
-    if (!shell) {
-      return NS_ERROR_UNEXPECTED;
-    }
-
-    nsCOMPtr<nsIContent> content = do_QueryInterface(child);
-    shell->ScrollContentIntoView(content,
-                                 nsIPresShell::ScrollAxis(),
-                                 nsIPresShell::ScrollAxis(),
-                                 nsIPresShell::SCROLL_FIRST_ANCESTOR_ONLY |
-                                 nsIPresShell::SCROLL_OVERFLOW_HIDDEN);
-    return NS_OK;
-}
-
-/* void ensureIndexIsVisible (in long index); */
-NS_IMETHODIMP nsScrollBoxObject::EnsureIndexIsVisible(int32_t index)
-{
-    return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-/* void ensureLineIsVisible (in long line); */
-NS_IMETHODIMP nsScrollBoxObject::EnsureLineIsVisible(int32_t line)
-{
-    return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-nsresult
-NS_NewScrollBoxObject(nsIBoxObject** aResult)
-{
-  *aResult = new nsScrollBoxObject;
-  if (!*aResult)
-    return NS_ERROR_OUT_OF_MEMORY;
-  NS_ADDREF(*aResult);
-  return NS_OK;
-}
-
--- a/layout/xul/nsXULPopupManager.cpp
+++ b/layout/xul/nsXULPopupManager.cpp
@@ -3,17 +3,16 @@
  * 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/. */
 
 #include "nsGkAtoms.h"
 #include "nsXULPopupManager.h"
 #include "nsMenuFrame.h"
 #include "nsMenuPopupFrame.h"
 #include "nsMenuBarFrame.h"
-#include "nsIPopupBoxObject.h"
 #include "nsMenuBarListener.h"
 #include "nsContentUtils.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMXULElement.h"
 #include "nsIXULDocument.h"
 #include "nsIXULTemplateBuilder.h"
 #include "nsCSSFrameConstructor.h"
--- a/layout/xul/nsXULTooltipListener.cpp
+++ b/layout/xul/nsXULTooltipListener.cpp
@@ -5,17 +5,16 @@
 
 #include "nsXULTooltipListener.h"
 
 #include "nsIDOMMouseEvent.h"
 #include "nsIDOMXULDocument.h"
 #include "nsIDOMXULElement.h"
 #include "nsIDocument.h"
 #include "nsGkAtoms.h"
-#include "nsIPopupBoxObject.h"
 #include "nsMenuPopupFrame.h"
 #include "nsIServiceManager.h"
 #include "nsIDragService.h"
 #include "nsIDragSession.h"
 #ifdef MOZ_XUL
 #include "nsITreeView.h"
 #endif
 #include "nsIScriptContext.h"
@@ -24,16 +23,17 @@
 #include "nsXULPopupManager.h"
 #endif
 #include "nsIRootBox.h"
 #include "nsIBoxObject.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/LookAndFeel.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/Event.h" // for nsIDOMEvent::InternalDOMEvent()
+#include "mozilla/dom/BoxObject.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 nsXULTooltipListener* nsXULTooltipListener::mInstance = nullptr;
 
 //////////////////////////////////////////////////////////////////////////
 //// nsISupports
@@ -341,17 +341,17 @@ nsXULTooltipListener::CheckTreeBodyMove(
   GetSourceTreeBoxObject(getter_AddRefs(obx));
   if (bx && obx) {
     int32_t x, y;
     aMouseEvent->GetScreenX(&x);
     aMouseEvent->GetScreenY(&y);
 
     int32_t row;
     nsCOMPtr<nsITreeColumn> col;
-    nsAutoCString obj;
+    nsAutoString obj;
 
     // subtract off the documentElement's boxObject
     int32_t boxX, boxY;
     bx->GetScreenX(&boxX);
     bx->GetScreenY(&boxY);
     x -= boxX;
     y -= boxY;
 
new file mode 100644
--- /dev/null
+++ b/layout/xul/tree/TreeBoxObject.cpp
@@ -0,0 +1,693 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/. */
+
+#include "mozilla/dom/TreeBoxObject.h"
+#include "nsCOMPtr.h"
+#include "nsIDOMXULElement.h"
+#include "nsIScriptableRegion.h"
+#include "nsIXULTemplateBuilder.h"
+#include "nsTreeContentView.h"
+#include "nsITreeSelection.h"
+#include "ChildIterator.h"
+#include "nsContentUtils.h"
+#include "nsError.h"
+#include "nsTreeBodyFrame.h"
+#include "mozilla/dom/TreeBoxObjectBinding.h"
+#include "nsITreeColumns.h"
+#include "mozilla/dom/DOMRect.h"
+#include "mozilla/dom/BindingUtils.h"
+#include "mozilla/dom/Element.h"
+#include "mozilla/dom/ToJSValue.h"
+
+namespace mozilla {
+namespace dom {
+
+NS_IMPL_CYCLE_COLLECTION_INHERITED(TreeBoxObject, BoxObject,
+                                   mView)
+
+NS_IMPL_ADDREF_INHERITED(TreeBoxObject, BoxObject)
+NS_IMPL_RELEASE_INHERITED(TreeBoxObject, BoxObject)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TreeBoxObject)
+  NS_INTERFACE_MAP_ENTRY(nsITreeBoxObject)
+NS_INTERFACE_MAP_END_INHERITING(BoxObject)
+
+void
+TreeBoxObject::Clear()
+{
+  ClearCachedValues();
+
+  // Drop the view's ref to us.
+  if (mView) {
+    nsCOMPtr<nsITreeSelection> sel;
+    mView->GetSelection(getter_AddRefs(sel));
+    if (sel)
+      sel->SetTree(nullptr);
+    mView->SetTree(nullptr); // Break the circular ref between the view and us.
+  }
+  mView = nullptr;
+
+  BoxObject::Clear();
+}
+
+
+TreeBoxObject::TreeBoxObject()
+  : mTreeBody(nullptr)
+{
+}
+
+TreeBoxObject::~TreeBoxObject()
+{
+}
+
+static nsIContent* FindBodyElement(nsIContent* aParent)
+{
+  mozilla::dom::FlattenedChildIterator iter(aParent);
+  for (nsIContent* content = iter.GetNextChild(); content; content = iter.GetNextChild()) {
+    mozilla::dom::NodeInfo *ni = content->NodeInfo();
+    if (ni->Equals(nsGkAtoms::treechildren, kNameSpaceID_XUL)) {
+      return content;
+    } else if (ni->Equals(nsGkAtoms::tree, kNameSpaceID_XUL)) {
+      // There are nesting tree elements. Only the innermost should
+      // find the treechilren.
+      return nullptr;
+    } else if (content->IsElement() &&
+               !ni->Equals(nsGkAtoms::_template, kNameSpaceID_XUL)) {
+      nsIContent* result = FindBodyElement(content);
+      if (result)
+        return result;
+    }
+  }
+
+  return nullptr;
+}
+
+nsTreeBodyFrame*
+TreeBoxObject::GetTreeBodyFrame(bool aFlushLayout)
+{
+  // Make sure our frames are up to date, and layout as needed.  We
+  // have to do this before checking for our cached mTreeBody, since
+  // it might go away on style flush, and in any case if aFlushLayout
+  // is true we need to make sure to flush no matter what.
+  // XXXbz except that flushing style when we were not asked to flush
+  // layout here breaks things.  See bug 585123.
+  nsIFrame* frame;
+  if (aFlushLayout) {
+    frame = GetFrame(aFlushLayout);
+    if (!frame)
+      return nullptr;
+  }
+
+  if (mTreeBody) {
+    // Have one cached already.
+    return mTreeBody;
+  }
+
+  if (!aFlushLayout) {
+    frame = GetFrame(aFlushLayout);
+    if (!frame)
+      return nullptr;
+  }
+
+  // Iterate over our content model children looking for the body.
+  nsCOMPtr<nsIContent> content = FindBodyElement(frame->GetContent());
+  if (!content)
+    return nullptr;
+
+  frame = content->GetPrimaryFrame();
+  if (!frame)
+     return nullptr;
+
+  // Make sure that the treebodyframe has a pointer to |this|.
+  nsTreeBodyFrame *treeBody = do_QueryFrame(frame);
+  NS_ENSURE_TRUE(treeBody && treeBody->GetTreeBoxObject() == this, nullptr);
+
+  mTreeBody = treeBody;
+  return mTreeBody;
+}
+
+NS_IMETHODIMP
+TreeBoxObject::GetView(nsITreeView * *aView)
+{
+  if (!mTreeBody) {
+    if (!GetTreeBodyFrame()) {
+      // Don't return an uninitialised view
+      *aView = nullptr;
+      return NS_OK;
+    }
+
+    if (mView)
+      // Our new frame needs to initialise itself
+      return mTreeBody->GetView(aView);
+  }
+  if (!mView) {
+    nsCOMPtr<nsIDOMXULElement> xulele = do_QueryInterface(mContent);
+    if (xulele) {
+      // See if there is a XUL tree builder associated with the element
+      nsCOMPtr<nsIXULTemplateBuilder> builder;
+      xulele->GetBuilder(getter_AddRefs(builder));
+      mView = do_QueryInterface(builder);
+
+      if (!mView) {
+        // No tree builder, create a tree content view.
+        nsresult rv = NS_NewTreeContentView(getter_AddRefs(mView));
+        NS_ENSURE_SUCCESS(rv, rv);
+      }
+
+      // Initialise the frame and view
+      mTreeBody->SetView(mView);
+    }
+  }
+  NS_IF_ADDREF(*aView = mView);
+  return NS_OK;
+}
+
+already_AddRefed<nsITreeView>
+TreeBoxObject::GetView() {
+  nsCOMPtr<nsITreeView> view;
+  GetView(getter_AddRefs(view));
+  return view.forget();
+}
+
+static bool
+CanTrustView(nsISupports* aValue)
+{
+  // Untrusted content is only allowed to specify known-good views
+  if (nsContentUtils::IsCallerChrome())
+    return true;
+  nsCOMPtr<nsINativeTreeView> nativeTreeView = do_QueryInterface(aValue);
+  if (!nativeTreeView || NS_FAILED(nativeTreeView->EnsureNative())) {
+    // XXX ERRMSG need a good error here for developers
+    return false;
+  }
+  return true;
+}
+
+NS_IMETHODIMP TreeBoxObject::SetView(nsITreeView * aView)
+{
+  if (!CanTrustView(aView))
+    return NS_ERROR_DOM_SECURITY_ERR;
+
+  mView = aView;
+  nsTreeBodyFrame* body = GetTreeBodyFrame();
+  if (body)
+    body->SetView(aView);
+
+  return NS_OK;
+}
+
+void TreeBoxObject::SetView(nsITreeView* aView, ErrorResult& aRv)
+{
+  aRv = SetView(aView);
+}
+
+bool TreeBoxObject::Focused()
+{
+  nsTreeBodyFrame* body = GetTreeBodyFrame();
+  if (body)
+    return body->GetFocused();
+  return false;
+}
+
+NS_IMETHODIMP TreeBoxObject::GetFocused(bool* aFocused)
+{
+  *aFocused = Focused();
+  return NS_OK;
+}
+
+NS_IMETHODIMP TreeBoxObject::SetFocused(bool aFocused)
+{
+  nsTreeBodyFrame* body = GetTreeBodyFrame();
+  if (body)
+    return body->SetFocused(aFocused);
+  return NS_OK;
+}
+
+NS_IMETHODIMP TreeBoxObject::GetTreeBody(nsIDOMElement** aElement)
+{
+  *aElement = nullptr;
+  nsTreeBodyFrame* body = GetTreeBodyFrame();
+  if (body)
+    return body->GetTreeBody(aElement);
+  return NS_OK;
+}
+
+already_AddRefed<Element>
+TreeBoxObject::GetTreeBody()
+{
+  nsCOMPtr<nsIDOMElement> el;
+  GetTreeBody(getter_AddRefs(el));
+  nsCOMPtr<Element> ret(do_QueryInterface(el));
+  return ret.forget();
+}
+
+already_AddRefed<nsTreeColumns>
+TreeBoxObject::GetColumns()
+{
+  nsTreeBodyFrame* body = GetTreeBodyFrame();
+  if (body)
+    return body->Columns();
+  return nullptr;
+}
+
+NS_IMETHODIMP TreeBoxObject::GetColumns(nsITreeColumns** aColumns)
+{
+  *aColumns = GetColumns().take();
+  return NS_OK;
+}
+
+int32_t TreeBoxObject::RowHeight()
+{
+  nsTreeBodyFrame* body = GetTreeBodyFrame();
+  if (body)
+    return body->RowHeight();
+  return 0;
+}
+
+int32_t TreeBoxObject::RowWidth()
+{
+  nsTreeBodyFrame* body = GetTreeBodyFrame();
+  if (body)
+    return body->RowWidth();
+  return 0;
+}
+
+NS_IMETHODIMP TreeBoxObject::GetRowHeight(int32_t* aRowHeight)
+{
+  *aRowHeight = RowHeight();
+  return NS_OK;
+}
+
+NS_IMETHODIMP TreeBoxObject::GetRowWidth(int32_t *aRowWidth)
+{
+  *aRowWidth = RowWidth();
+  return NS_OK;
+}
+
+int32_t TreeBoxObject::GetFirstVisibleRow()
+{
+  nsTreeBodyFrame* body = GetTreeBodyFrame();
+  if (body)
+    return body->FirstVisibleRow();
+  return 0;
+}
+
+NS_IMETHODIMP TreeBoxObject::GetFirstVisibleRow(int32_t *aFirstVisibleRow)
+{
+  *aFirstVisibleRow = GetFirstVisibleRow();
+  return NS_OK;
+}
+
+int32_t TreeBoxObject::GetLastVisibleRow()
+{
+  nsTreeBodyFrame* body = GetTreeBodyFrame();
+  if (body)
+    return body->LastVisibleRow();
+  return 0;
+}
+
+NS_IMETHODIMP TreeBoxObject::GetLastVisibleRow(int32_t *aLastVisibleRow)
+{
+  *aLastVisibleRow = GetLastVisibleRow();
+  return NS_OK;
+}
+
+int32_t TreeBoxObject::HorizontalPosition()
+{
+  nsTreeBodyFrame* body = GetTreeBodyFrame();
+  if (body)
+    return body->GetHorizontalPosition();
+  return 0;
+}
+
+NS_IMETHODIMP TreeBoxObject::GetHorizontalPosition(int32_t *aHorizontalPosition)
+{
+  *aHorizontalPosition = HorizontalPosition();
+  return NS_OK;
+}
+
+int32_t TreeBoxObject::GetPageLength()
+{
+  nsTreeBodyFrame* body = GetTreeBodyFrame();
+  if (body)
+    return body->PageLength();
+  return 0;
+}
+
+NS_IMETHODIMP TreeBoxObject::GetPageLength(int32_t *aPageLength)
+{
+  *aPageLength = GetPageLength();
+  return NS_OK;
+}
+
+NS_IMETHODIMP TreeBoxObject::GetSelectionRegion(nsIScriptableRegion **aRegion)
+{
+  *aRegion = nullptr;
+  nsTreeBodyFrame* body = GetTreeBodyFrame();
+  if (body)
+    return body->GetSelectionRegion(aRegion);
+  return NS_OK;
+}
+
+already_AddRefed<nsIScriptableRegion>
+TreeBoxObject::SelectionRegion()
+{
+  nsCOMPtr<nsIScriptableRegion> region;
+  GetSelectionRegion(getter_AddRefs(region));
+  return region.forget();
+}
+
+NS_IMETHODIMP
+TreeBoxObject::EnsureRowIsVisible(int32_t aRow)
+{
+  nsTreeBodyFrame* body = GetTreeBodyFrame();
+  if (body)
+    return body->EnsureRowIsVisible(aRow);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+TreeBoxObject::EnsureCellIsVisible(int32_t aRow, nsITreeColumn* aCol)
+{
+  nsTreeBodyFrame* body = GetTreeBodyFrame();
+  if (body)
+    return body->EnsureCellIsVisible(aRow, aCol);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+TreeBoxObject::ScrollToRow(int32_t aRow)
+{
+  nsTreeBodyFrame* body = GetTreeBodyFrame(true);
+  if (body)
+    return body->ScrollToRow(aRow);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+TreeBoxObject::ScrollByLines(int32_t aNumLines)
+{
+  nsTreeBodyFrame* body = GetTreeBodyFrame();
+  if (body)
+    return body->ScrollByLines(aNumLines);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+TreeBoxObject::ScrollByPages(int32_t aNumPages)
+{
+  nsTreeBodyFrame* body = GetTreeBodyFrame();
+  if (body)
+    return body->ScrollByPages(aNumPages);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+TreeBoxObject::ScrollToCell(int32_t aRow, nsITreeColumn* aCol)
+{
+  nsTreeBodyFrame* body = GetTreeBodyFrame();
+  if (body)
+    return body->ScrollToCell(aRow, aCol);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+TreeBoxObject::ScrollToColumn(nsITreeColumn* aCol)
+{
+  nsTreeBodyFrame* body = GetTreeBodyFrame();
+  if (body)
+    return body->ScrollToColumn(aCol);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+TreeBoxObject::ScrollToHorizontalPosition(int32_t aHorizontalPosition)
+{
+  nsTreeBodyFrame* body = GetTreeBodyFrame();
+  if (body)
+    return body->ScrollToHorizontalPosition(aHorizontalPosition);
+  return NS_OK;
+}
+
+NS_IMETHODIMP TreeBoxObject::Invalidate()
+{
+  nsTreeBodyFrame* body = GetTreeBodyFrame();
+  if (body)
+    return body->Invalidate();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+TreeBoxObject::InvalidateColumn(nsITreeColumn* aCol)
+{
+  nsTreeBodyFrame* body = GetTreeBodyFrame();
+  if (body)
+    return body->InvalidateColumn(aCol);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+TreeBoxObject::InvalidateRow(int32_t aIndex)
+{
+  nsTreeBodyFrame* body = GetTreeBodyFrame();
+  if (body)
+    return body->InvalidateRow(aIndex);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+TreeBoxObject::InvalidateCell(int32_t aRow, nsITreeColumn* aCol)
+{
+  nsTreeBodyFrame* body = GetTreeBodyFrame();
+  if (body)
+    return body->InvalidateCell(aRow, aCol);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+TreeBoxObject::InvalidateRange(int32_t aStart, int32_t aEnd)
+{
+  nsTreeBodyFrame* body = GetTreeBodyFrame();
+  if (body)
+    return body->InvalidateRange(aStart, aEnd);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+TreeBoxObject::InvalidateColumnRange(int32_t aStart, int32_t aEnd, nsITreeColumn* aCol)
+{
+  nsTreeBodyFrame* body = GetTreeBodyFrame();
+  if (body)
+    return body->InvalidateColumnRange(aStart, aEnd, aCol);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+TreeBoxObject::GetRowAt(int32_t x, int32_t y, int32_t *aRow)
+{
+  *aRow = 0;
+  nsTreeBodyFrame* body = GetTreeBodyFrame();
+  if (body)
+    return body->GetRowAt(x, y, aRow);
+  return NS_OK;
+}
+
+int32_t
+TreeBoxObject::GetRowAt(int32_t x, int32_t y)
+{
+  int32_t row;
+  GetRowAt(x, y, &row);
+  return row;
+}
+
+NS_IMETHODIMP
+TreeBoxObject::GetCellAt(int32_t aX, int32_t aY, int32_t *aRow,
+                         nsITreeColumn** aCol, nsAString& aChildElt)
+{
+  *aRow = 0;
+  *aCol = nullptr;
+  nsTreeBodyFrame* body = GetTreeBodyFrame();
+  if (body) {
+    nsAutoCString element;
+    nsresult retval = body->GetCellAt(aX, aY, aRow, aCol, element);
+    CopyUTF8toUTF16(element, aChildElt);
+    return retval;
+  }
+  return NS_OK;
+}
+
+void
+TreeBoxObject::GetCellAt(int32_t x, int32_t y, TreeCellInfo& aRetVal, ErrorResult& aRv)
+{
+  GetCellAt(x, y, &aRetVal.mRow, getter_AddRefs(aRetVal.mCol), aRetVal.mChildElt);
+}
+
+void
+TreeBoxObject::GetCellAt(JSContext* cx,
+                         int32_t x, int32_t y,
+                         JS::Handle<JSObject*> rowOut,
+                         JS::Handle<JSObject*> colOut,
+                         JS::Handle<JSObject*> childEltOut,
+                         ErrorResult& aRv)
+{
+  int32_t row;
+  nsITreeColumn* col;
+  nsAutoString childElt;
+  GetCellAt(x, y, &row, &col, childElt);
+
+  JS::Rooted<JS::Value> v(cx);
+
+  if (!ToJSValue(cx, row, &v) ||
+      !JS_SetProperty(cx, rowOut, "value", v)) {
+    aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL);
+    return;
+  }
+  if (!dom::WrapObject(cx, col, &v) ||
+      !JS_SetProperty(cx, colOut, "value", v)) {
+    aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL);
+    return;
+  }
+  if (!ToJSValue(cx, childElt, &v) ||
+      !JS_SetProperty(cx, childEltOut, "value", v)) {
+    aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL);
+    return;
+  }
+}
+
+NS_IMETHODIMP
+TreeBoxObject::GetCoordsForCellItem(int32_t aRow, nsITreeColumn* aCol, const nsAString& aElement,
+                                      int32_t *aX, int32_t *aY, int32_t *aWidth, int32_t *aHeight)
+{
+  *aX = *aY = *aWidth = *aHeight = 0;
+  nsTreeBodyFrame* body = GetTreeBodyFrame();
+  NS_ConvertUTF16toUTF8 element(aElement);
+  if (body)
+    return body->GetCoordsForCellItem(aRow, aCol, element, aX, aY, aWidth, aHeight);
+  return NS_OK;
+}
+
+already_AddRefed<DOMRect>
+TreeBoxObject::GetCoordsForCellItem(int32_t row, nsITreeColumn* col, const nsAString& element, ErrorResult& aRv)
+{
+  int32_t x, y, w, h;
+  GetCoordsForCellItem(row, col, element, &x, &y, &w, &h);
+  nsRefPtr<DOMRect> rect = new DOMRect(mContent, x, y, w, h);
+  return rect.forget();
+}
+
+void
+TreeBoxObject::GetCoordsForCellItem(JSContext* cx,
+                                    int32_t row,
+                                    nsITreeColumn* col,
+                                    const nsAString& element,
+                                    JS::Handle<JSObject*> xOut,
+                                    JS::Handle<JSObject*> yOut,
+                                    JS::Handle<JSObject*> widthOut,
+                                    JS::Handle<JSObject*> heightOut,
+                                    ErrorResult& aRv)
+{
+  int32_t x, y, w, h;
+  GetCoordsForCellItem(row, col, element, &x, &y, &w, &h);
+  JS::Rooted<JS::Value> v(cx, INT_TO_JSVAL(x));
+  if (!JS_SetProperty(cx, xOut, "value", v)) {
+    aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL);
+    return;
+  }
+  v = INT_TO_JSVAL(y);
+  if (!JS_SetProperty(cx, yOut, "value", v)) {
+    aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL);
+    return;
+  }
+  v = INT_TO_JSVAL(w);
+  if (!JS_SetProperty(cx, widthOut, "value", v)) {
+    aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL);
+    return;
+  }
+  v = INT_TO_JSVAL(h);
+  if (!JS_SetProperty(cx, heightOut, "value", v)) {
+    aRv.Throw(NS_ERROR_XPC_CANT_SET_OUT_VAL);
+    return;
+  }
+}
+
+NS_IMETHODIMP
+TreeBoxObject::IsCellCropped(int32_t aRow, nsITreeColumn* aCol, bool *aIsCropped)
+{
+  *aIsCropped = false;
+  nsTreeBodyFrame* body = GetTreeBodyFrame();
+  if (body)
+    return body->IsCellCropped(aRow, aCol, aIsCropped);
+  return NS_OK;
+}
+
+bool
+TreeBoxObject::IsCellCropped(int32_t row, nsITreeColumn* col, ErrorResult& aRv)
+{
+  bool ret;
+  aRv = IsCellCropped(row, col, &ret);
+  return ret;
+}
+
+NS_IMETHODIMP
+TreeBoxObject::RowCountChanged(int32_t aIndex, int32_t aDelta)
+{
+  nsTreeBodyFrame* body = GetTreeBodyFrame();
+  if (body)
+    return body->RowCountChanged(aIndex, aDelta);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+TreeBoxObject::BeginUpdateBatch()
+{
+  nsTreeBodyFrame* body = GetTreeBodyFrame();
+  if (body)
+    return body->BeginUpdateBatch();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+TreeBoxObject::EndUpdateBatch()
+{
+  nsTreeBodyFrame* body = GetTreeBodyFrame();
+  if (body)
+    return body->EndUpdateBatch();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+TreeBoxObject::ClearStyleAndImageCaches()
+{
+  nsTreeBodyFrame* body = GetTreeBodyFrame();
+  if (body)
+    return body->ClearStyleAndImageCaches();
+  return NS_OK;
+}
+
+void
+TreeBoxObject::ClearCachedValues()
+{
+  mTreeBody = nullptr;
+}
+
+JSObject*
+TreeBoxObject::WrapObject(JSContext* aCx)
+{
+  return TreeBoxObjectBinding::Wrap(aCx, this);
+}
+
+} // namespace dom
+} // namespace mozilla
+
+// Creation Routine ///////////////////////////////////////////////////////////////////////
+
+using namespace mozilla::dom;
+
+nsresult
+NS_NewTreeBoxObject(nsIBoxObject** aResult)
+{
+  NS_ADDREF(*aResult = new TreeBoxObject());
+  return NS_OK;
+}
new file mode 100644
--- /dev/null
+++ b/layout/xul/tree/TreeBoxObject.h
@@ -0,0 +1,127 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/. */
+
+#ifndef mozilla_dom_TreeBoxObject_h
+#define mozilla_dom_TreeBoxObject_h
+
+#include "mozilla/dom/BoxObject.h"
+#include "nsITreeView.h"
+#include "nsITreeBoxObject.h"
+
+class nsTreeBodyFrame;
+class nsTreeColumns;
+
+namespace mozilla {
+namespace dom {
+
+struct TreeCellInfo;
+class DOMRect;
+
+class TreeBoxObject MOZ_FINAL : public BoxObject,
+                                public nsITreeBoxObject
+{
+public:
+  NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(TreeBoxObject, BoxObject)
+  NS_DECL_NSITREEBOXOBJECT
+
+  TreeBoxObject();
+
+  nsTreeBodyFrame* GetTreeBodyFrame(bool aFlushLayout = false);
+  nsTreeBodyFrame* GetCachedTreeBodyFrame() { return mTreeBody; }
+
+  //NS_PIBOXOBJECT interfaces
+  virtual void Clear() MOZ_OVERRIDE;
+  virtual void ClearCachedValues() MOZ_OVERRIDE;
+
+  // WebIDL
+  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+
+  already_AddRefed<nsTreeColumns> GetColumns();
+
+  already_AddRefed<nsITreeView> GetView();
+
+  void SetView(nsITreeView* arg, ErrorResult& aRv);
+
+  bool Focused();
+
+  already_AddRefed<Element> GetTreeBody();
+
+  int32_t RowHeight();
+
+  int32_t RowWidth();
+
+  int32_t HorizontalPosition();
+
+  already_AddRefed<nsIScriptableRegion> SelectionRegion();
+
+  int32_t GetFirstVisibleRow();
+
+  int32_t GetLastVisibleRow();
+
+  int32_t GetPageLength();
+
+  int32_t GetRowAt(int32_t x, int32_t y);
+
+  void GetCellAt(int32_t x, int32_t y, TreeCellInfo& aRetVal, ErrorResult& aRv);
+
+  already_AddRefed<DOMRect> GetCoordsForCellItem(int32_t row,
+                                                 nsITreeColumn* col,
+                                                 const nsAString& element,
+                                                 ErrorResult& aRv);
+
+  bool IsCellCropped(int32_t row, nsITreeColumn* col, ErrorResult& aRv);
+
+  // Deprecated APIs from old IDL
+  void GetCellAt(JSContext* cx,
+                 int32_t x, int32_t y,
+                 JS::Handle<JSObject*> rowOut,
+                 JS::Handle<JSObject*> colOut,
+                 JS::Handle<JSObject*> childEltOut,
+                 ErrorResult& aRv);
+
+  void GetCoordsForCellItem(JSContext* cx,
+                            int32_t row,
+                            nsITreeColumn* col,
+                            const nsAString& element,
+                            JS::Handle<JSObject*> xOut,
+                            JS::Handle<JSObject*> yOut,
+                            JS::Handle<JSObject*> widthOut,
+                            JS::Handle<JSObject*> heightOut,
+                            ErrorResult& aRv);
+
+  // Same signature (except for nsresult return type) as the XPIDL impls
+  // void Invalidate();
+  // void BeginUpdateBatch();
+  // void EndUpdateBatch();
+  // void ClearStyleAndImageCaches();
+  // void SetFocused(bool arg);
+  // void EnsureRowIsVisible(int32_t index);
+  // void EnsureCellIsVisible(int32_t row, nsITreeColumn* col);
+  // void ScrollToRow(int32_t index);
+  // void ScrollByLines(int32_t numLines);
+  // void ScrollByPages(int32_t numPages);
+  // void ScrollToCell(int32_t row, nsITreeColumn* col);
+  // void ScrollToColumn(nsITreeColumn* col);
+  // void ScrollToHorizontalPosition(int32_t horizontalPosition);
+  // void InvalidateColumn(nsITreeColumn* col);
+  // void InvalidateRow(int32_t index);
+  // void InvalidateCell(int32_t row, nsITreeColumn* col);
+  // void InvalidateRange(int32_t startIndex, int32_t endIndex);
+  // void InvalidateColumnRange(int32_t startIndex, int32_t endIndex, nsITreeColumn* col);
+  // void RowCountChanged(int32_t index, int32_t count);
+
+protected:
+  nsTreeBodyFrame* mTreeBody;
+  nsCOMPtr<nsITreeView> mView;
+
+private:
+  ~TreeBoxObject();
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif
--- a/layout/xul/tree/crashtests/585815-iframe.xul
+++ b/layout/xul/tree/crashtests/585815-iframe.xul
@@ -57,17 +57,16 @@
       </treerow>  
     </treeitem> 
   </treechildren>
 </tree>
 
 <script type="text/javascript"><![CDATA[
 function run() {
   var tree = document.getElementsByTagName("tree")[0];
-  var sel = tree.treeBoxObject.view.selection;
+  var sel = tree.view.selection;
   sel.rangedSelect(0, 0, true);
   sel.rangedSelect(1000, 1001, true);
   sel.adjustSelection(1, 0x7fffffff);
 }
 ]]></script>
 
 </window>
-
--- a/layout/xul/tree/moz.build
+++ b/layout/xul/tree/moz.build
@@ -14,32 +14,35 @@ XPIDL_SOURCES += [
 
 XPIDL_MODULE = 'layout_xul_tree'
 
 EXPORTS += [
     'nsTreeColFrame.h',
     'nsTreeUtils.h',
 ]
 
+EXPORTS.mozilla.dom += [
+    'TreeBoxObject.h'
+]
+
 UNIFIED_SOURCES += [
     'nsTreeBodyFrame.cpp',
-    'nsTreeBoxObject.cpp',
     'nsTreeColFrame.cpp',
     'nsTreeColumns.cpp',
     'nsTreeContentView.cpp',
     'nsTreeImageListener.cpp',
     'nsTreeSelection.cpp',
     'nsTreeStyleCache.cpp',
     'nsTreeUtils.cpp',
+    'TreeBoxObject.cpp',
 ]
 
 FAIL_ON_WARNINGS = True
 
 FINAL_LIBRARY = 'xul'
 LOCAL_INCLUDES += [
     '..',
     '../../base',
     '../../forms',
     '../../generic',
     '../../style',
     '/content/base/src',
 ]
-
--- a/layout/xul/tree/nsITreeBoxObject.idl
+++ b/layout/xul/tree/nsITreeBoxObject.idl
@@ -7,17 +7,17 @@
 
 interface nsIDOMElement;
 interface nsITreeView;
 interface nsITreeSelection;
 interface nsITreeColumn;
 interface nsITreeColumns;
 interface nsIScriptableRegion;
 
-[scriptable, uuid(64BA5199-C4F4-4498-BBDC-F8E4C369086C)]
+[uuid(64BA5199-C4F4-4498-BBDC-F8E4C369086C)]
 interface nsITreeBoxObject : nsISupports
 {
   /**
    * Obtain the columns.
    */
   readonly attribute nsITreeColumns columns;
 
   /**
@@ -143,22 +143,22 @@ interface nsITreeBoxObject : nsISupports
    * A hit test that can tell you what cell the mouse is over.  Row is the row index
    * hit,  returns -1 for invalid mouse coordinates.  ColID is the column hit.
    * ChildElt is the pseudoelement hit: this can have values of
    * "cell", "twisty", "image", and "text".
    *
    * The coordinate system is the client coordinate system for the
    * document this boxObject lives in, and the units are CSS pixels.
    */
-  void getCellAt(in long x, in long y, out long row, out nsITreeColumn col, out ACString childElt);
+  void getCellAt(in long x, in long y, out long row, out nsITreeColumn col, out AString childElt);
 
   /** 
    * Find the coordinates of an element within a specific cell. 
    */
-  void getCoordsForCellItem(in long row, in nsITreeColumn col, in ACString element, 
+  void getCoordsForCellItem(in long row, in nsITreeColumn col, in AString element,
                             out long x, out long y, out long width, out long height);
 
   /** 
    * Determine if the text of a cell is being cropped or not.
    */
   boolean isCellCropped(in long row, in nsITreeColumn col);
 
   /**
--- a/layout/xul/tree/nsTreeBodyFrame.cpp
+++ b/layout/xul/tree/nsTreeBodyFrame.cpp
@@ -37,32 +37,31 @@
 #include "nsCSSRendering.h"
 #include "nsIXULTemplateBuilder.h"
 #include "nsXPIDLString.h"
 #include "nsContainerFrame.h"
 #include "nsView.h"
 #include "nsViewManager.h"
 #include "nsWidgetsCID.h"
 #include "nsBoxFrame.h"
-#include "nsBoxObject.h"
 #include "nsIURL.h"
 #include "nsNetUtil.h"
 #include "nsBoxLayoutState.h"
 #include "nsTreeContentView.h"
 #include "nsTreeUtils.h"
 #include "nsITheme.h"
 #include "imgIRequest.h"
 #include "imgIContainer.h"
 #include "imgILoader.h"
 #include "mozilla/dom/NodeInfo.h"
 #include "nsContentUtils.h"
 #include "nsLayoutUtils.h"
 #include "nsIScrollableFrame.h"
 #include "nsDisplayList.h"
-#include "nsTreeBoxObject.h"
+#include "mozilla/dom/TreeBoxObject.h"
 #include "nsRenderingContext.h"
 #include "nsIScriptableRegion.h"
 #include <algorithm>
 #include "ScrollbarActivity.h"
 
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
 #include "nsIWritablePropertyBag2.h"
@@ -327,18 +326,18 @@ nsTreeBodyFrame::EnsureBoxObject()
       nsCOMPtr<nsIBoxObject> box =
         nsDoc->GetBoxObjectFor(parent->AsElement(), ignored);
       // Ensure that we got a native box object.
       nsCOMPtr<nsPIBoxObject> pBox = do_QueryInterface(box);
       if (pBox) {
         nsCOMPtr<nsITreeBoxObject> realTreeBoxObject = do_QueryInterface(pBox);
         if (realTreeBoxObject) {
           nsTreeBodyFrame* innerTreeBoxObject =
-            static_cast<nsTreeBoxObject*>(realTreeBoxObject.get())
-              ->GetCachedTreeBody();
+            static_cast<dom::TreeBoxObject*>(realTreeBoxObject.get())
+              ->GetCachedTreeBodyFrame();
           ENSURE_TRUE(!innerTreeBoxObject || innerTreeBoxObject == this);
           mTreeBoxObject = realTreeBoxObject;
         }
       }
     }
   }
 }
 
@@ -534,23 +533,16 @@ nsTreeBodyFrame::SetView(nsITreeView * a
       PresContext()->PresShell()->PostReflowCallback(this);
     }
   }
  
   return NS_OK;
 }
 
 nsresult
-nsTreeBodyFrame::GetFocused(bool* aFocused)
-{
-  *aFocused = mFocused;
-  return NS_OK;
-}
-
-nsresult
 nsTreeBodyFrame::SetFocused(bool aFocused)
 {
   if (mFocused != aFocused) {
     mFocused = aFocused;
     if (mView) {
       nsCOMPtr<nsITreeSelection> sel;
       mView->GetSelection(getter_AddRefs(sel));
       if (sel)
@@ -565,35 +557,32 @@ nsTreeBodyFrame::GetTreeBody(nsIDOMEleme
 {
   //NS_ASSERTION(mContent, "no content, see bug #104878");
   if (!mContent)
     return NS_ERROR_NULL_POINTER;
 
   return mContent->QueryInterface(NS_GET_IID(nsIDOMElement), (void**)aElement);
 }
 
-nsresult
-nsTreeBodyFrame::GetRowHeight(int32_t* _retval)
-{
-  *_retval = nsPresContext::AppUnitsToIntCSSPixels(mRowHeight);
-  return NS_OK;
-}
-
-nsresult
-nsTreeBodyFrame::GetRowWidth(int32_t *aRowWidth)
+int32_t
+nsTreeBodyFrame::RowHeight() const
 {
-  *aRowWidth = nsPresContext::AppUnitsToIntCSSPixels(CalcHorzWidth(GetScrollParts()));
-  return NS_OK;
+  return nsPresContext::AppUnitsToIntCSSPixels(mRowHeight);
 }
 
-nsresult
-nsTreeBodyFrame::GetHorizontalPosition(int32_t *aHorizontalPosition)
+int32_t
+nsTreeBodyFrame::RowWidth()
 {
-  *aHorizontalPosition = nsPresContext::AppUnitsToIntCSSPixels(mHorzPosition); 
-  return NS_OK;
+  return nsPresContext::AppUnitsToIntCSSPixels(CalcHorzWidth(GetScrollParts()));
+}
+
+int32_t
+nsTreeBodyFrame::GetHorizontalPosition() const
+{
+  return nsPresContext::AppUnitsToIntCSSPixels(mHorzPosition);
 }
 
 nsresult
 nsTreeBodyFrame::GetSelectionRegion(nsIScriptableRegion **aRegion)
 {
   *aRegion = nullptr;
 
   nsCOMPtr<nsITreeSelection> selection;
--- a/layout/xul/tree/nsTreeBodyFrame.h
+++ b/layout/xul/tree/nsTreeBodyFrame.h
@@ -75,22 +75,22 @@ public:
   }
   already_AddRefed<nsITreeView> GetExistingView() const
   {
     nsCOMPtr<nsITreeView> view = mView;
     return view.forget();
   }
   nsresult GetView(nsITreeView **aView);
   nsresult SetView(nsITreeView *aView);
-  nsresult GetFocused(bool *aFocused);
+  bool GetFocused() const { return mFocused; }
   nsresult SetFocused(bool aFocused);
   nsresult GetTreeBody(nsIDOMElement **aElement);
-  nsresult GetRowHeight(int32_t *aValue);
-  nsresult GetRowWidth(int32_t *aValue);
-  nsresult GetHorizontalPosition(int32_t *aValue);
+  int32_t RowHeight() const;
+  int32_t RowWidth();
+  int32_t GetHorizontalPosition() const;
   nsresult GetSelectionRegion(nsIScriptableRegion **aRegion);
   int32_t FirstVisibleRow() const { return mTopRowIndex; }
   int32_t LastVisibleRow() const { return mTopRowIndex + mPageLength; }
   int32_t PageLength() const { return mPageLength; }
   nsresult EnsureRowIsVisible(int32_t aRow);
   nsresult EnsureCellIsVisible(int32_t aRow, nsITreeColumn *aCol);
   nsresult ScrollToRow(int32_t aRow);
   nsresult ScrollByLines(int32_t aNumLines);
deleted file mode 100644
--- a/layout/xul/tree/nsTreeBoxObject.cpp
+++ /dev/null
@@ -1,493 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/. */
-
-#include "nsTreeBoxObject.h"
-#include "nsCOMPtr.h"
-#include "nsIDOMXULElement.h"
-#include "nsIXULTemplateBuilder.h"
-#include "nsTreeContentView.h"
-#include "nsITreeSelection.h"
-#include "ChildIterator.h"
-#include "nsContentUtils.h"
-#include "nsError.h"
-#include "nsTreeBodyFrame.h"
-
-NS_IMPL_CYCLE_COLLECTION_INHERITED(nsTreeBoxObject, nsBoxObject,
-                                   mView)
-
-NS_IMPL_ADDREF_INHERITED(nsTreeBoxObject, nsBoxObject)
-NS_IMPL_RELEASE_INHERITED(nsTreeBoxObject, nsBoxObject)
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsTreeBoxObject)
-  NS_INTERFACE_MAP_ENTRY(nsITreeBoxObject)
-NS_INTERFACE_MAP_END_INHERITING(nsBoxObject)
-
-void
-nsTreeBoxObject::Clear()
-{
-  ClearCachedValues();
-
-  // Drop the view's ref to us.
-  if (mView) {
-    nsCOMPtr<nsITreeSelection> sel;
-    mView->GetSelection(getter_AddRefs(sel));
-    if (sel)
-      sel->SetTree(nullptr);
-    mView->SetTree(nullptr); // Break the circular ref between the view and us.
-  }
-  mView = nullptr;
-
-  nsBoxObject::Clear();
-}
-
-
-nsTreeBoxObject::nsTreeBoxObject()
-  : mTreeBody(nullptr)
-{
-}
-
-nsTreeBoxObject::~nsTreeBoxObject()
-{
-  /* destructor code */
-}
-
-static nsIContent* FindBodyElement(nsIContent* aParent)
-{
-  mozilla::dom::FlattenedChildIterator iter(aParent);
-  for (nsIContent* content = iter.GetNextChild(); content; content = iter.GetNextChild()) {
-    mozilla::dom::NodeInfo *ni = content->NodeInfo();
-    if (ni->Equals(nsGkAtoms::treechildren, kNameSpaceID_XUL)) {
-      return content;
-    } else if (ni->Equals(nsGkAtoms::tree, kNameSpaceID_XUL)) {
-      // There are nesting tree elements. Only the innermost should
-      // find the treechilren.
-      return nullptr;
-    } else if (content->IsElement() &&
-               !ni->Equals(nsGkAtoms::_template, kNameSpaceID_XUL)) {
-      nsIContent* result = FindBodyElement(content);
-      if (result)
-        return result;
-    }
-  }
-
-  return nullptr;
-}
-
-nsTreeBodyFrame*
-nsTreeBoxObject::GetTreeBody(bool aFlushLayout)
-{
-  // Make sure our frames are up to date, and layout as needed.  We
-  // have to do this before checking for our cached mTreeBody, since
-  // it might go away on style flush, and in any case if aFlushLayout
-  // is true we need to make sure to flush no matter what.
-  // XXXbz except that flushing style when we were not asked to flush
-  // layout here breaks things.  See bug 585123.
-  nsIFrame* frame;
-  if (aFlushLayout) {
-    frame = GetFrame(aFlushLayout);
-    if (!frame)
-      return nullptr;
-  }
-
-  if (mTreeBody) {
-    // Have one cached already.
-    return mTreeBody;
-  }
-
-  if (!aFlushLayout) {
-    frame = GetFrame(aFlushLayout);
-    if (!frame)
-      return nullptr;
-  }
-
-  // Iterate over our content model children looking for the body.
-  nsCOMPtr<nsIContent> content = FindBodyElement(frame->GetContent());
-  if (!content)
-    return nullptr;
-
-  frame = content->GetPrimaryFrame();
-  if (!frame)
-     return nullptr;
-
-  // Make sure that the treebodyframe has a pointer to |this|.
-  nsTreeBodyFrame *treeBody = do_QueryFrame(frame);
-  NS_ENSURE_TRUE(treeBody && treeBody->GetTreeBoxObject() == this, nullptr);
-
-  mTreeBody = treeBody;
-  return mTreeBody;
-}
-
-NS_IMETHODIMP nsTreeBoxObject::GetView(nsITreeView * *aView)
-{
-  if (!mTreeBody) {
-    if (!GetTreeBody()) {
-      // Don't return an uninitialised view
-      *aView = nullptr;
-      return NS_OK;
-    }
-
-    if (mView)
-      // Our new frame needs to initialise itself
-      return mTreeBody->GetView(aView);
-  }
-  if (!mView) {
-    nsCOMPtr<nsIDOMXULElement> xulele = do_QueryInterface(mContent);
-    if (xulele) {
-      // See if there is a XUL tree builder associated with the element
-      nsCOMPtr<nsIXULTemplateBuilder> builder;
-      xulele->GetBuilder(getter_AddRefs(builder));
-      mView = do_QueryInterface(builder);
-
-      if (!mView) {
-        // No tree builder, create a tree content view.
-        nsresult rv = NS_NewTreeContentView(getter_AddRefs(mView));
-        NS_ENSURE_SUCCESS(rv, rv);
-      }
-
-      // Initialise the frame and view
-      mTreeBody->SetView(mView);
-    }
-  }
-  NS_IF_ADDREF(*aView = mView);
-  return NS_OK;
-}
-
-static bool
-CanTrustView(nsISupports* aValue)
-{
-  // Untrusted content is only allowed to specify known-good views
-  if (nsContentUtils::IsCallerChrome())
-    return true;
-  nsCOMPtr<nsINativeTreeView> nativeTreeView = do_QueryInterface(aValue);
-  if (!nativeTreeView || NS_FAILED(nativeTreeView->EnsureNative())) {
-    // XXX ERRMSG need a good error here for developers
-    return false;
-  }
-  return true;
-}
-
-NS_IMETHODIMP nsTreeBoxObject::SetView(nsITreeView * aView)
-{
-  if (!CanTrustView(aView))
-    return NS_ERROR_DOM_SECURITY_ERR;
-  
-  mView = aView;
-  nsTreeBodyFrame* body = GetTreeBody();
-  if (body)
-    body->SetView(aView);
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsTreeBoxObject::GetFocused(bool* aFocused)
-{
-  *aFocused = false;
-  nsTreeBodyFrame* body = GetTreeBody();
-  if (body)
-    return body->GetFocused(aFocused);
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsTreeBoxObject::SetFocused(bool aFocused)
-{
-  nsTreeBodyFrame* body = GetTreeBody();
-  if (body)
-    return body->SetFocused(aFocused);
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsTreeBoxObject::GetTreeBody(nsIDOMElement** aElement)
-{
-  *aElement = nullptr;
-  nsTreeBodyFrame* body = GetTreeBody();
-  if (body) 
-    return body->GetTreeBody(aElement);
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsTreeBoxObject::GetColumns(nsITreeColumns** aColumns)
-{
-  *aColumns = nullptr;
-  nsTreeBodyFrame* body = GetTreeBody();
-  if (body) 
-    *aColumns = body->Columns().take();
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsTreeBoxObject::GetRowHeight(int32_t* aRowHeight)
-{
-  *aRowHeight = 0;
-  nsTreeBodyFrame* body = GetTreeBody();
-  if (body) 
-    return body->GetRowHeight(aRowHeight);
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsTreeBoxObject::GetRowWidth(int32_t *aRowWidth)
-{
-  *aRowWidth = 0;
-  nsTreeBodyFrame* body = GetTreeBody();
-  if (body) 
-    return body->GetRowWidth(aRowWidth);
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsTreeBoxObject::GetFirstVisibleRow(int32_t *aFirstVisibleRow)
-{
-  *aFirstVisibleRow = 0;
-  nsTreeBodyFrame* body = GetTreeBody();
-  if (body)
-    *aFirstVisibleRow = body->FirstVisibleRow();
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsTreeBoxObject::GetLastVisibleRow(int32_t *aLastVisibleRow)
-{
-  *aLastVisibleRow = 0;
-  nsTreeBodyFrame* body = GetTreeBody();
-  if (body)
-    *aLastVisibleRow = body->LastVisibleRow();
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsTreeBoxObject::GetHorizontalPosition(int32_t *aHorizontalPosition)
-{
-  *aHorizontalPosition = 0;
-  nsTreeBodyFrame* body = GetTreeBody();
-  if (body)
-    return body->GetHorizontalPosition(aHorizontalPosition);
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsTreeBoxObject::GetPageLength(int32_t *aPageLength)
-{
-  *aPageLength = 0;
-  nsTreeBodyFrame* body = GetTreeBody();
-  if (body)
-    *aPageLength = body->PageLength();
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsTreeBoxObject::GetSelectionRegion(nsIScriptableRegion **aRegion)
-{
- *aRegion = nullptr;
-  nsTreeBodyFrame* body = GetTreeBody();
-  if (body)
-    return body->GetSelectionRegion(aRegion);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsTreeBoxObject::EnsureRowIsVisible(int32_t aRow)
-{
-  nsTreeBodyFrame* body = GetTreeBody();
-  if (body)
-    return body->EnsureRowIsVisible(aRow);
-  return NS_OK;
-}
-
-NS_IMETHODIMP 
-nsTreeBoxObject::EnsureCellIsVisible(int32_t aRow, nsITreeColumn* aCol)
-{
-  nsTreeBodyFrame* body = GetTreeBody();
-  if (body)
-    return body->EnsureCellIsVisible(aRow, aCol);
-  return NS_OK;
-    return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-nsTreeBoxObject::ScrollToRow(int32_t aRow)
-{
-  nsTreeBodyFrame* body = GetTreeBody(true);
-  if (body)
-    return body->ScrollToRow(aRow);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsTreeBoxObject::ScrollByLines(int32_t aNumLines)
-{
-  nsTreeBodyFrame* body = GetTreeBody();
-  if (body)
-    return body->ScrollByLines(aNumLines);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsTreeBoxObject::ScrollByPages(int32_t aNumPages)
-{
-  nsTreeBodyFrame* body = GetTreeBody();
-  if (body)
-    return body->ScrollByPages(aNumPages);
-  return NS_OK;
-}
-
-NS_IMETHODIMP 
-nsTreeBoxObject::ScrollToCell(int32_t aRow, nsITreeColumn* aCol)
-{
-  nsTreeBodyFrame* body = GetTreeBody();
-  if (body)
-    return body->ScrollToCell(aRow, aCol);
-  return NS_OK;
-}
-
-NS_IMETHODIMP 
-nsTreeBoxObject::ScrollToColumn(nsITreeColumn* aCol)
-{
-  nsTreeBodyFrame* body = GetTreeBody();
-  if (body)
-    return body->ScrollToColumn(aCol);
-  return NS_OK;
-}
-
-NS_IMETHODIMP 
-nsTreeBoxObject::ScrollToHorizontalPosition(int32_t aHorizontalPosition)
-{
-  nsTreeBodyFrame* body = GetTreeBody();
-  if (body)
-    return body->ScrollToHorizontalPosition(aHorizontalPosition);
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsTreeBoxObject::Invalidate()
-{
-  nsTreeBodyFrame* body = GetTreeBody();
-  if (body)
-    return body->Invalidate();
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsTreeBoxObject::InvalidateColumn(nsITreeColumn* aCol)
-{
-  nsTreeBodyFrame* body = GetTreeBody();
-  if (body)
-    return body->InvalidateColumn(aCol);
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsTreeBoxObject::InvalidateRow(int32_t aIndex)
-{
-  nsTreeBodyFrame* body = GetTreeBody();
-  if (body)
-    return body->InvalidateRow(aIndex);
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsTreeBoxObject::InvalidateCell(int32_t aRow, nsITreeColumn* aCol)
-{
-  nsTreeBodyFrame* body = GetTreeBody();
-  if (body)
-    return body->InvalidateCell(aRow, aCol);
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsTreeBoxObject::InvalidateRange(int32_t aStart, int32_t aEnd)
-{
-  nsTreeBodyFrame* body = GetTreeBody();
-  if (body)
-    return body->InvalidateRange(aStart, aEnd);
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsTreeBoxObject::InvalidateColumnRange(int32_t aStart, int32_t aEnd, nsITreeColumn* aCol)
-{
-  nsTreeBodyFrame* body = GetTreeBody();
-  if (body)
-    return body->InvalidateColumnRange(aStart, aEnd, aCol);
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsTreeBoxObject::GetRowAt(int32_t x, int32_t y, int32_t *aRow)
-{
-  *aRow = 0;
-  nsTreeBodyFrame* body = GetTreeBody();
-  if (body)
-    return body->GetRowAt(x, y, aRow);
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsTreeBoxObject::GetCellAt(int32_t aX, int32_t aY, int32_t *aRow, nsITreeColumn** aCol,
-                                         nsACString& aChildElt)
-{
-  *aRow = 0;
-  *aCol = nullptr;
-  nsTreeBodyFrame* body = GetTreeBody();
-  if (body)
-    return body->GetCellAt(aX, aY, aRow, aCol, aChildElt);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsTreeBoxObject::GetCoordsForCellItem(int32_t aRow, nsITreeColumn* aCol, const nsACString& aElement, 
-                                      int32_t *aX, int32_t *aY, int32_t *aWidth, int32_t *aHeight)
-{
-  *aX = *aY = *aWidth = *aHeight = 0;
-  nsTreeBodyFrame* body = GetTreeBody();
-  if (body)
-    return body->GetCoordsForCellItem(aRow, aCol, aElement, aX, aY, aWidth, aHeight);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsTreeBoxObject::IsCellCropped(int32_t aRow, nsITreeColumn* aCol, bool *aIsCropped)
-{  
-  *aIsCropped = false;
-  nsTreeBodyFrame* body = GetTreeBody();
-  if (body)
-    return body->IsCellCropped(aRow, aCol, aIsCropped);
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsTreeBoxObject::RowCountChanged(int32_t aIndex, int32_t aDelta)
-{
-  nsTreeBodyFrame* body = GetTreeBody();
-  if (body)
-    return body->RowCountChanged(aIndex, aDelta);
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsTreeBoxObject::BeginUpdateBatch()
-{
-  nsTreeBodyFrame* body = GetTreeBody();
-  if (body)
-    return body->BeginUpdateBatch();
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsTreeBoxObject::EndUpdateBatch()
-{
-  nsTreeBodyFrame* body = GetTreeBody();
-  if (body)
-    return body->EndUpdateBatch();
-  return NS_OK;
-}
-
-NS_IMETHODIMP nsTreeBoxObject::ClearStyleAndImageCaches()
-{
-  nsTreeBodyFrame* body = GetTreeBody();
-  if (body)
-    return body->ClearStyleAndImageCaches();
-  return NS_OK;
-}
-
-void
-nsTreeBoxObject::ClearCachedValues()
-{
-  mTreeBody = nullptr;
-}    
-
-// Creation Routine ///////////////////////////////////////////////////////////////////////
-
-nsresult
-NS_NewTreeBoxObject(nsIBoxObject** aResult)
-{
-  *aResult = new nsTreeBoxObject;
-  if (!*aResult)
-    return NS_ERROR_OUT_OF_MEMORY;
-  NS_ADDREF(*aResult);
-  return NS_OK;
-}
-
deleted file mode 100644
--- a/layout/xul/tree/nsTreeBoxObject.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* 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/. */
-
-#ifndef nsTreeBoxObject_h___
-#define nsTreeBoxObject_h___
-
-#include "mozilla/Attributes.h"
-#include "nsBoxObject.h"
-#include "nsITreeView.h"
-#include "nsITreeBoxObject.h"
-
-class nsTreeBodyFrame;
-
-class nsTreeBoxObject : public nsITreeBoxObject, public nsBoxObject
-{
-public:
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsTreeBoxObject, nsBoxObject)
-  NS_DECL_NSITREEBOXOBJECT
-
-  nsTreeBoxObject();
-
-  nsTreeBodyFrame* GetTreeBody(bool aFlushLayout = false);
-  nsTreeBodyFrame* GetCachedTreeBody() { return mTreeBody; }
-
-  //NS_PIBOXOBJECT interfaces
-  virtual void Clear() MOZ_OVERRIDE;
-  virtual void ClearCachedValues() MOZ_OVERRIDE;
-
-protected:
-  ~nsTreeBoxObject();
-  nsTreeBodyFrame* mTreeBody;
-  nsCOMPtr<nsITreeView> mView;
-};
-
-#endif
--- a/layout/xul/tree/nsTreeColFrame.cpp
+++ b/layout/xul/tree/nsTreeColFrame.cpp
@@ -5,19 +5,18 @@
 
 #include "nsCOMPtr.h"
 #include "nsTreeColFrame.h"
 #include "nsGkAtoms.h"
 #include "nsIContent.h"
 #include "nsStyleContext.h"
 #include "nsNameSpaceManager.h"
 #include "nsIBoxObject.h"
-#include "nsTreeBoxObject.h"
+#include "mozilla/dom/TreeBoxObject.h"
 #include "nsIDOMElement.h"
-#include "nsITreeBoxObject.h"
 #include "nsITreeColumns.h"
 #include "nsIDOMXULTreeElement.h"
 #include "nsDisplayList.h"
 #include "nsTreeBodyFrame.h"
 
 //
 // NS_NewTreeColFrame
 //
@@ -183,17 +182,18 @@ nsTreeColFrame::InvalidateColumns(bool a
 {
   nsITreeBoxObject* treeBoxObject = GetTreeBoxObject();
   if (treeBoxObject) {
     nsCOMPtr<nsITreeColumns> columns;
 
     if (aCanWalkFrameTree) {
       treeBoxObject->GetColumns(getter_AddRefs(columns));
     } else {
-      nsTreeBodyFrame* body = static_cast<nsTreeBoxObject*>(treeBoxObject)->GetCachedTreeBody();
+      nsTreeBodyFrame* body = static_cast<mozilla::dom::TreeBoxObject*>
+        (treeBoxObject)->GetCachedTreeBodyFrame();
       if (body) {
         columns = body->Columns();
       }
     }
 
     if (columns)
       columns->InvalidateColumns();
   }
--- a/layout/xul/tree/nsTreeColumns.cpp
+++ b/layout/xul/tree/nsTreeColumns.cpp
@@ -9,16 +9,17 @@
 #include "nsIBoxObject.h"
 #include "nsTreeColumns.h"
 #include "nsTreeUtils.h"
 #include "nsStyleContext.h"
 #include "nsDOMClassInfoID.h"
 #include "nsContentUtils.h"
 #include "nsTreeBodyFrame.h"
 #include "mozilla/dom/Element.h"
+#include "mozilla/dom/TreeBoxObject.h"
 #include "mozilla/dom/TreeColumnsBinding.h"
 
 using namespace mozilla;
 
 // Column class that caches all the info about our column.
 nsTreeColumn::nsTreeColumn(nsTreeColumns* aColumns, nsIContent* aContent)
   : mContent(aContent),
     mColumns(aColumns),
@@ -374,20 +375,20 @@ nsTreeColumns::GetParentObject() const
 }
 
 /* virtual */ JSObject*
 nsTreeColumns::WrapObject(JSContext* aCx)
 {
   return dom::TreeColumnsBinding::Wrap(aCx, this);
 }
 
-nsITreeBoxObject*
+dom::TreeBoxObject*
 nsTreeColumns::GetTree() const
 {
-  return mTree ? mTree->GetTreeBoxObject() : nullptr;
+  return mTree ? static_cast<mozilla::dom::TreeBoxObject*>(mTree->GetTreeBoxObject()) : nullptr;
 }
 
 NS_IMETHODIMP
 nsTreeColumns::GetTree(nsITreeBoxObject** _retval)
 {
   NS_IF_ADDREF(*_retval = GetTree());
   return NS_OK;
 }
--- a/layout/xul/tree/nsTreeColumns.h
+++ b/layout/xul/tree/nsTreeColumns.h
@@ -19,16 +19,17 @@ class nsTreeBodyFrame;
 class nsTreeColumns;
 class nsIFrame;
 class nsIContent;
 struct nsRect;
 
 namespace mozilla {
 namespace dom {
 class Element;
+class TreeBoxObject;
 } // namespace dom
 } // namespace mozilla
 
 #define NS_TREECOLUMN_IMPL_CID                       \
 { /* 02cd1963-4b5d-4a6c-9223-814d3ade93a3 */         \
     0x02cd1963,                                      \
     0x4b5d,                                          \
     0x4a6c,                                          \
@@ -135,17 +136,17 @@ public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsTreeColumns)
   NS_DECL_NSITREECOLUMNS
 
   nsIContent* GetParentObject() const;
   virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
 
   // WebIDL
-  nsITreeBoxObject* GetTree() const;
+  mozilla::dom::TreeBoxObject* GetTree() const;
   uint32_t Count();
   uint32_t Length()
   {
     return Count();
   }
 
   nsTreeColumn* GetFirstColumn() { EnsureColumns(); return mFirstColumn; }
   nsTreeColumn* GetLastColumn();
--- a/layout/xul/tree/nsTreeSelection.cpp
+++ b/layout/xul/tree/nsTreeSelection.cpp
@@ -260,17 +260,16 @@ nsTreeSelection::~nsTreeSelection()
 
 NS_IMPL_CYCLE_COLLECTION(nsTreeSelection, mTree, mCurrentColumn)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsTreeSelection)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsTreeSelection)
 
 DOMCI_DATA(TreeSelection, nsTreeSelection)
 
-// QueryInterface implementation for nsBoxObject
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsTreeSelection)
   NS_INTERFACE_MAP_ENTRY(nsITreeSelection)
   NS_INTERFACE_MAP_ENTRY(nsINativeTreeSelection)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(TreeSelection)
 NS_INTERFACE_MAP_END
 
 NS_IMETHODIMP nsTreeSelection::GetTree(nsITreeBoxObject * *aTree)
--- a/security/manager/pki/resources/content/certManager.js
+++ b/security/manager/pki/resources/content/certManager.js
@@ -52,42 +52,37 @@ function LoadCerts()
   certdb = Components.classes[nsX509CertDB].getService(nsIX509CertDB);
   var certcache = Components.classes[nsNSSCertCache].createInstance(nsINSSCertCache);
   
   certcache.cacheAllCerts();
 
   caTreeView = Components.classes[nsCertTree]
                     .createInstance(nsICertTree);
   caTreeView.loadCertsFromCache(certcache, nsIX509Cert.CA_CERT);
-  document.getElementById('ca-tree')
-   .treeBoxObject.view = caTreeView;
+  document.getElementById('ca-tree').view = caTreeView;
 
   serverTreeView = Components.classes[nsCertTree]
                         .createInstance(nsICertTree);
   serverTreeView.loadCertsFromCache(certcache, nsIX509Cert.SERVER_CERT);
-  document.getElementById('server-tree')
-   .treeBoxObject.view = serverTreeView;
+  document.getElementById('server-tree').view = serverTreeView;
 
   emailTreeView = Components.classes[nsCertTree]
                        .createInstance(nsICertTree);
   emailTreeView.loadCertsFromCache(certcache, nsIX509Cert.EMAIL_CERT);
-  document.getElementById('email-tree')
-   .treeBoxObject.view = emailTreeView; 
+  document.getElementById('email-tree').view = emailTreeView;
 
   userTreeView = Components.classes[nsCertTree]
                       .createInstance(nsICertTree);
   userTreeView.loadCertsFromCache(certcache, nsIX509Cert.USER_CERT);
-  document.getElementById('user-tree')
-   .treeBoxObject.view = userTreeView;
+  document.getElementById('user-tree').view = userTreeView;
 
   orphanTreeView = Components.classes[nsCertTree]
                       .createInstance(nsICertTree);
   orphanTreeView.loadCertsFromCache(certcache, nsIX509Cert.UNKNOWN_CERT);
-  document.getElementById('orphan-tree')
-   .treeBoxObject.view = orphanTreeView;
+  document.getElementById('orphan-tree').view = orphanTreeView;
 
   enableBackupAllButton();
 }
 
 function enableBackupAllButton()
 {
   var rowCnt = userTreeView.rowCount;
   var backupAllButton=document.getElementById('mine_backupAllButton');
--- a/security/manager/pki/resources/content/viewCertDetails.js
+++ b/security/manager/pki/resources/content/viewCertDetails.js
@@ -118,35 +118,34 @@ function addTreeItemToTreeChild(treeChil
     treeCell.setAttribute("display",value);
   treeRow.appendChild(treeCell);
   treeElem1.appendChild(treeRow);
   treeChild.appendChild(treeElem1);
   return treeElem1;
 }
 
 function displaySelected() {
-  var asn1Tree = document.getElementById('prettyDumpTree').
-                     treeBoxObject.view.QueryInterface(nsIASN1Tree);
+  var asn1Tree = document.getElementById('prettyDumpTree')
+          .view.QueryInterface(nsIASN1Tree);
   var items = asn1Tree.selection;
   var certDumpVal = document.getElementById('certDumpVal');
   if (items.currentIndex != -1) {
     var value = asn1Tree.getDisplayData(items.currentIndex);
     certDumpVal.value = value;
   } else {
     certDumpVal.value ="";
   }
 }
 
 function BuildPrettyPrint(cert)
 {
   var certDumpTree = Components.classes[nsASN1Tree].
                           createInstance(nsIASN1Tree);
   certDumpTree.loadASN1Structure(cert.ASN1Structure);
-  document.getElementById('prettyDumpTree').
-           treeBoxObject.view =  certDumpTree;
+  document.getElementById('prettyDumpTree').view = certDumpTree;
 }
 
 function addAttributeFromCert(nodeName, value)
 {
   var node = document.getElementById(nodeName);
   if (!value) {
     value = bundle.getString('notPresent');
   }
@@ -251,18 +250,18 @@ function DisplayGeneralDataFromCert(cert
   issuerOrgUnit = cert.issuerOrganizationUnit;
   addAttributeFromCert('issuercommonname', issuerCommonname);
   addAttributeFromCert('issuerorganization', issuerOrg);
   addAttributeFromCert('issuerorgunit', issuerOrgUnit);
 }
 
 function updateCertDump()
 {
-  var asn1Tree = document.getElementById('prettyDumpTree').
-                     treeBoxObject.view.QueryInterface(nsIASN1Tree);
+  var asn1Tree = document.getElementById('prettyDumpTree')
+          .view.QueryInterface(nsIASN1Tree);
 
   var tree = document.getElementById('treesetDump');
   if (tree.currentIndex < 0) {
     doPrompt("No items are selected."); //This should never happen.
   } else {
     var item = tree.contentView.getItemAtIndex(tree.currentIndex);
     var dbKey = item.firstChild.firstChild.getAttribute('display');
     //  Get the cert from the cert database
--- a/services/sync/tps/extensions/mozmill/resource/driver/mozelement.js
+++ b/services/sync/tps/extensions/mozmill/resource/driver/mozelement.js
@@ -1007,17 +1007,17 @@ MozMillDropList.prototype = Object.creat
                         getElementsByTagNameNS(NAMESPACE_XUL, "menupopup")[0].
                         getElementsByTagNameNS(NAMESPACE_XUL, "menuitem");
 
         var item = null;
 
         if (index != undefined) {
           if (index == -1) {
             this.dispatchEvent('focus', false);
-            this.element.boxObject.QueryInterface(Ci.nsIMenuBoxObject).activeChild = null;
+            this.element.boxObject.activeChild = null;
             this.dispatchEvent('change', true);
 
             broker.pass({'function':'MozMillDropList.select()'});
 
             return true;
           } else {
             item = menuitems[index];
           }
--- a/testing/mochitest/browser-harness.xul
+++ b/testing/mochitest/browser-harness.xul
@@ -303,17 +303,16 @@
     }
 
     function scrollTo(id) {
       var line = document.getElementById(id);
       if (!line)
         return;
 
       var boxObject = document.getElementById("results").parentNode.boxObject;
-      boxObject.QueryInterface(Components.interfaces.nsIScrollBoxObject);
       boxObject.scrollToElement(line);
     }
   ]]></script>
   <button id="runTestsButton" oncommand="runTests();" label="Run All Tests"/>
   <label id="status"/>
   <scrollbox flex="1" style="overflow: auto" align="stretch">
     <div id="results" xmlns="http://www.w3.org/1999/xhtml" flex="1"/>
   </scrollbox>
--- a/toolkit/components/filepicker/content/filepicker.js
+++ b/toolkit/components/filepicker/content/filepicker.js
@@ -3,17 +3,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/. */
 
 const nsIFilePicker       = Components.interfaces.nsIFilePicker;
 const nsIProperties       = Components.interfaces.nsIProperties;
 const NS_DIRECTORYSERVICE_CONTRACTID = "@mozilla.org/file/directory_service;1";
 const NS_IOSERVICE_CONTRACTID = "@mozilla.org/network/io-service;1";
-const nsITreeBoxObject = Components.interfaces.nsITreeBoxObject;
 const nsIFileView = Components.interfaces.nsIFileView;
 const NS_FILEVIEW_CONTRACTID = "@mozilla.org/filepicker/fileview;1";
 const nsITreeView = Components.interfaces.nsITreeView;
 const nsILocalFile = Components.interfaces.nsILocalFile;
 const nsIFile = Components.interfaces.nsIFile;
 const NS_LOCAL_FILE_CONTRACTID = "@mozilla.org/file/local;1";
 const NS_PROMPTSERVICE_CONTRACTID = "@mozilla.org/embedcomp/prompt-service;1";
 
@@ -120,17 +119,17 @@ function filepickerLoad() {
 
   // setup the dialogOverlay.xul button handlers
   retvals.buttonStatus = nsIFilePicker.returnCancel;
 
   var tree = document.getElementById("directoryTree");
   if (filePickerMode == nsIFilePicker.modeOpenMultiple)
     tree.removeAttribute("seltype");
 
-  tree.treeBoxObject.view = treeView;
+  tree.view = treeView;
 
   // Start out with the ok button disabled since nothing will be
   // selected and nothing will be in the text field.
   okButton.disabled = filePickerMode != nsIFilePicker.modeGetFolder;
 
   // This allows the window to show onscreen before we begin
   // loading the file list
 
--- a/toolkit/components/passwordmgr/content/passwordManager.js
+++ b/toolkit/components/passwordmgr/content/passwordManager.js
@@ -93,17 +93,17 @@ function LoadSignons() {
     signons = passwordmanager.getAllLogins();
   } catch (e) {
     signons = [];
   }
   signons.forEach(login => login.QueryInterface(Components.interfaces.nsILoginMetaInfo));
   signonsTreeView.rowCount = signons.length;
 
   // sort and display the table
-  signonsTree.treeBoxObject.view = signonsTreeView;
+  signonsTree.view = signonsTreeView;
   // The sort column didn't change. SortTree (called by
   // SignonColumnSort) assumes we want to toggle the sort
   // direction but here we don't so we have to trick it
   lastSignonSortAscending = !lastSignonSortAscending;
   SignonColumnSort(lastSignonSortColumn);
 
   // disable "remove all signons" button if there are no signons
   var element = document.getElementById("removeAllSignons");
--- a/toolkit/components/passwordmgr/content/passwordManagerExceptions.js
+++ b/toolkit/components/passwordmgr/content/passwordManagerExceptions.js
@@ -43,17 +43,17 @@ function Reject(number, host) {
 }
 
 function LoadRejects() {
   var hosts = passwordmanager.getAllDisabledHosts();
   rejects = hosts.map(function(host, i) { return new Reject(i, host); });
   rejectsTreeView.rowCount = rejects.length;
 
   // sort and display the table
-  rejectsTree.treeBoxObject.view = rejectsTreeView;
+  rejectsTree.view = rejectsTreeView;
   RejectColumnSort(lastRejectSortColumn);
 
   var element = document.getElementById("removeAllRejects");
   if (rejects.length == 0) {
     element.setAttribute("disabled","true");
   } else {
     element.removeAttribute("disabled");
   }
--- a/toolkit/components/passwordmgr/test/browser/browser_passwordmgrdlg.js
+++ b/toolkit/components/passwordmgr/test/browser/browser_passwordmgrdlg.js
@@ -44,17 +44,17 @@ function test() {
     SimpleTest.waitForFocus(doTest, pwmgrdlg);
 
     // the meat of the test
     function doTest() {
         let doc = pwmgrdlg.document;
         let win = doc.defaultView;
         let filter = doc.getElementById("filter");
         let tree = doc.getElementById("signonsTree");
-        let view = tree.treeBoxObject.view;
+        let view = tree.view;
 
         is(filter.value, "", "Filter box should initially be empty");
         is(view.rowCount, 10, "There should be 10 passwords initially");
 
         // Prepare a set of tests
         //   filter: the text entered in the filter search box
         //   count: the number of logins which should match the respective filter
         //   count2: the number of logins which should match the respective filter
--- a/toolkit/content/tests/chrome/popup_trigger.js
+++ b/toolkit/content/tests/chrome/popup_trigger.js
@@ -24,17 +24,17 @@ function runTests()
 {
   if (screen.height < 768) {
     ok(false, "popup tests are likely to fail for screen heights less than 768 pixels");
   }
 
   gMenuPopup = document.getElementById("thepopup");
   gTrigger = document.getElementById("trigger");
 
-  gIsMenu = gTrigger.boxObject instanceof Components.interfaces.nsIMenuBoxObject;
+  gIsMenu = gTrigger.boxObject instanceof MenuBoxObject;
 
   // a hacky way to get the screen position of the document. Cache the event
   // so that we can use it in calls to openPopup.
   gCachedEvent = cacheEvent({ shiftKey: true });
   gScreenX = gCachedEvent.screenX;
   gScreenY = gCachedEvent.screenY;
   gCachedEvent2 = cacheEvent({ altKey: true, ctrlKey: true, shiftKey: true, metaKey: true });
 
--- a/toolkit/content/tests/chrome/test_contextmenu_list.xul
+++ b/toolkit/content/tests/chrome/test_contextmenu_list.xul
@@ -101,17 +101,17 @@ function startTest()
 function menuTests()
 {
   gSelectionStep = 0;
   var element = $("menu");
   synthesizeMouse(element, 0, 0, { type : "contextmenu", button: 0 });
   is(gContextMenuFired, true, "context menu fired when menu open");
 
   gSelectionStep = 1;
-  $("menu").boxObject.QueryInterface(Components.interfaces.nsIMenuBoxObject).activeChild = $("menu2");
+  $("menu").boxObject.activeChild = $("menu2");
   synthesizeMouse(element, 0, 0, { type : "contextmenu", button: 0 });
 
   $("menu").open = false;
 }
 
 function nextTest()
 {
   gTestId++;
--- a/toolkit/content/tests/chrome/test_mousescroll.xul
+++ b/toolkit/content/tests/chrome/test_mousescroll.xul
@@ -138,16 +138,17 @@ function testRichListbox(id, andThen)
   var winUtils = SpecialPowers.getDOMWindowUtils(window);
   winUtils.advanceTimeAndRefresh(100);
 
   function helper()
   {
     var [aStart, aDelta, aIntDelta, aDeltaMode] = tests[0];
     tests.shift();
     listbox.scrollToIndex(aStart);
+
     synthesizeWheel(listbox, 10, 10,
                     { deltaMode: aDeltaMode, deltaY: aDelta,
                       lineOrPageDeltaY: aIntDelta });
 
     winUtils.advanceTimeAndRefresh(100);
 
     var change = listbox.getIndexOfFirstVisibleRow() - aStart;
     var direction = (change > 0) - (change < 0);
@@ -195,59 +196,59 @@ function testRichListbox(id, andThen)
 function testArrowScrollbox(id)
 {
   var scrollbox = document.getElementById(id);
   var scrollBoxObject = scrollbox.scrollBoxObject;
   var orient = scrollbox.getAttribute("orient");
 
   function helper(aStart, aDelta, aIntDelta, aDeltaMode, aExpected)
   {
-    var xpos = {};
-    var ypos = {};
     var orientIsHorizontal = (orient == "horizontal");
-    var pos = orientIsHorizontal ? xpos : ypos;
 
     scrollBoxObject.scrollTo(aStart, aStart);
 
     for (var i = orientIsHorizontal ? 2 : 0; i >= 0; i--) {
       synthesizeWheel(scrollbox, 5, 5,
                       { deltaMode: aDeltaMode, deltaY: aDelta,
                         lineOrPageDeltaY: aIntDelta });
-      scrollBoxObject.getPosition(xpos, ypos);
+
+      var pos = orientIsHorizontal ? scrollBoxObject.positionX :
+                                     scrollBoxObject.positionY;
+
       // Note, vertical mouse scrolling is allowed to scroll horizontal
       // arrowscrollboxes, because many users have no horizontal mouse scroll
       // capability
       let expected = !i ? aExpected : aStart;
-      is(pos.value, expected,
+      is(pos, expected,
          "testArrowScrollbox(" + id +  "): vertical, starting " + aStart +
            " delta " + aDelta + " lineOrPageDelta " + aIntDelta +
            " aDeltaMode " + aDeltaMode);
     }
 
     scrollBoxObject.scrollTo(aStart, aStart);
     for (var i = orientIsHorizontal ? 2 : 0; i >= 0; i--) {
       synthesizeWheel(scrollbox, 5, 5,
                       { deltaMode: aDeltaMode, deltaX: aDelta,
                         lineOrPageDeltaX: aIntDelta });
       // horizontal mouse scrolling is never allowed to scroll vertical
       // arrowscrollboxes
-      scrollBoxObject.getPosition(xpos, ypos);
+      var pos = orientIsHorizontal ? scrollBoxObject.positionX :
+                                     scrollBoxObject.positionY;
       let expected = (!i && orientIsHorizontal) ? aExpected : aStart;
-      is(pos.value, expected,
+      is(pos, expected,
          "testArrowScrollbox(" + id +  "): horizontal, starting " + aStart +
            " delta " + aDelta + " lineOrPageDelta " + aIntDelta +
            " aDeltaMode " + aDeltaMode);
     }
   }
 
-  var scrolledWidth = {};
-  var scrolledHeight = {};
-  scrollBoxObject.getScrolledSize(scrolledWidth, scrolledHeight);
-  var scrollMaxX = scrolledWidth.value - scrollBoxObject.width;
-  var scrollMaxY = scrolledHeight.value - scrollBoxObject.height;
+  var scrolledWidth = scrollBoxObject.scrolledWidth;
+  var scrolledHeight = scrollBoxObject.scrolledHeight;
+  var scrollMaxX = scrolledWidth - scrollBoxObject.width;
+  var scrollMaxY = scrolledHeight - scrollBoxObject.height;
   var scrollMax = orient == "horizontal" ? scrollMaxX : scrollMaxY;
 
   deltaModes.forEach(function(aDeltaMode) {
     // These lineOrPageDelta values are not realistic.  However, it's enough to
     // test if it's scrolled by the lineOrPageDelta value.
     let delta = (aDeltaMode == WheelEvent.DOM_DELTA_PIXEL) ? 5.0 : 0.3;
     helper(50, -delta, -100, aDeltaMode, 0);
     helper(50,  delta,  100, aDeltaMode, scrollMax);
--- a/toolkit/content/tests/chrome/test_popup_tree.xul
+++ b/toolkit/content/tests/chrome/test_popup_tree.xul
@@ -44,21 +44,20 @@ function runTests()
 
 function treeClick()
 {
   var tree = $("tree");
   is(tree.currentIndex, -1, "selectedIndex before click");
   synthesizeMouseExpectEvent($("treechildren"), 2, 2, { }, $("treechildren"), "click", "");
   is(tree.currentIndex, 0, "selectedIndex after click");
 
-  var x = { }, y = { }, width = { }, height = { };
-  tree.treeBoxObject.getCoordsForCellItem(1, tree.columns.address, "", x, y, width, height);
-  synthesizeMouseExpectEvent($("treechildren"), x.value, y.value + 2,
+  var rect = tree.treeBoxObject.getCoordsForCellItem(1, tree.columns.address, "");
+  synthesizeMouseExpectEvent($("treechildren"), rect.x, rect.y + 2,
                              { }, $("treechildren"), "click", "");
-  is(tree.currentIndex, 1, "selectedIndex after second click " + x.value + "," + y.value);
+  is(tree.currentIndex, 1, "selectedIndex after second click " + rect.x + "," + rect.y);
 
   $("panel").hidePopup();
 }
 
 ]]>
 </script>
 
 <body xmlns="http://www.w3.org/1999/xhtml">
--- a/toolkit/content/tests/chrome/test_position.xul
+++ b/toolkit/content/tests/chrome/test_position.xul
@@ -70,24 +70,24 @@ function runTest()
 
   var box2 = $("box2");
   checkPosition("box2", box2, 2, 46, winwidth, 96);
 
   // height is height(box1) = 46 + margin-top(box3) = 1 + margin-top(button1) = 5
   var button1 = $("button1");
   checkPosition("button1", button1, 9, 53, 99, 88);
 
-  var sbo = box2.boxObject.QueryInterface(Components.interfaces.nsIScrollBoxObject);
+  var sbo = box2.boxObject;
   sbo.scrollTo(7, 16);
 
   // clientRect height is offset from root so is 16 pixels vertically less
   checkPosition("button1 scrolled", button1, 9, 37, 99, 72);
 
   var box3 = $("box3");
-  sbo = box3.boxObject.QueryInterface(Components.interfaces.nsIScrollBoxObject);
+  sbo = box3.boxObject;
   sbo.scrollTo(1, 2);
 
   checkPosition("button1 scrolled", button1, 9, 35, 99, 70);
 
   $("menu").open = true;
 }
 
 function menuOpened()
--- a/toolkit/content/tests/chrome/window_largemenu.xul
+++ b/toolkit/content/tests/chrome/window_largemenu.xul
@@ -140,19 +140,17 @@ function popupShown()
     // down when we pass the fractional value to openPopupAtScreen above.
     is(Math.round(rect.top) + gScreenY, Math.floor(screen.height / 2),
                               gTests[gTestIndex] + " top");
     ok(Math.round(rect.bottom) + gScreenY < screen.height,
                                 gTests[gTestIndex] + " bottom");
     ok(!gOverflowed && gUnderflowed, gTests[gTestIndex] + " overflow")
   }
 
-  var sx = { }, sy = { };
-  sbo.getPosition(sx, sy);
-  is(sy.value, expectedScrollPos, "menu scroll position");
+  is(sbo.positionY, expectedScrollPos, "menu scroll position");
 
   hidePopup();
 }
 
 function is(l, r, n) { window.opener.wrappedJSObject.SimpleTest.is(l,r,n); }
 function ok(v, n) { window.opener.wrappedJSObject.SimpleTest.ok(v,n); }
 
 var oldx, oldy, waitSteps = 0;
--- a/toolkit/content/tests/fennec-tile-testapp/chrome/content/FooScript.js
+++ b/toolkit/content/tests/fennec-tile-testapp/chrome/content/FooScript.js
@@ -53,19 +53,17 @@ BrowserView.prototype = {
   //   _viewportRect
   //   _viewportInnerBoundsRect
   //
 
   get tileManager() { return this._tileManager; },
   get scrollbox() { return this._scrollbox; },
 
   init: function init() {
-    let scrollbox = document.getElementById("scrollbox")
-			.boxObject
-			.QueryInterface(Components.interfaces.nsIScrollBoxObject);
+    let scrollbox = document.getElementById("scrollbox").boxObject;
     this._scrollbox = scrollbox;
 
     let leftbar  = document.getElementById("left_sidebar");
     let rightbar = document.getElementById("right_sidebar");
     let topbar   = document.getElementById("top_urlbar");
     this._leftbar = leftbar;
     this._rightbar = rightbar;
     this._topbar = topbar;
@@ -123,20 +121,17 @@ BrowserView.prototype = {
     // way this function is used
     rect.x = (clip) ? Math.max(x, 0) : x;
     rect.y = (clip) ? Math.max(y, 0) : y;
 
     return rect;
   },
 
   getScrollboxPosition: function getScrollboxPosition() {
-    let x = {};
-    let y = {};
-    this._scrollbox.getPosition(x, y);
-    return [x.value, y.value];
+    return [this._scrollbox.positionX, this._scrollbox.positionY];
   },
 
   getViewportInnerBoundsRect: function getViewportInnerBoundsRect(dx, dy) {
     if (!dx) dx = 0;
     if (!dy) dy = 0;
 
     let w = window.innerWidth;
     let h = window.innerHeight;
@@ -308,36 +303,34 @@ function onMouseUp() {
 
   bv.tileManager.endPanning();
 }
 
 function onMouseMove(e) {
   if (window._isDragging) {
     let scrollbox = bv.scrollbox;
 
-    let x = {};
-    let y = {};
-    let w = {};
-    let h = {};
-    scrollbox.getPosition(x, y);
-    scrollbox.getScrolledSize(w, h);
+    let x = scrollbox.positionX;
+    let y = scrollbox.positionY;
+    let w = scrollbox.scrolledWidth;
+    let h = scrollbox.scrolledHeight;
 
     let dx = window._dragStart.x - e.clientX;
     let dy = window._dragStart.y - e.clientY;
 
     // XXX if max(x, 0) > scrollwidth we shouldn't do anything (same for y/height)
-    let newX = Math.max(x.value + dx, 0);
-    let newY = Math.max(y.value + dy, 0);
+    let newX = Math.max(x + dx, 0);
+    let newY = Math.max(y + dy, 0);
 
-    if (newX < w.value || newY < h.value) {
+    if (newX < w || newY < h) {
       // clip dx and dy to prevent us from going below 0
-      dx = Math.max(dx, -x.value);
-      dy = Math.max(dy, -y.value);
+      dx = Math.max(dx, -x);
+      dy = Math.max(dy, -y);
 
-      bv.onBeforeScroll(x.value, y.value, dx, dy);
+      bv.onBeforeScroll(x, y, dx, dy);
 
       /*dump("==========scroll==========" + endl);
       dump("delta: " + dx + "," + dy + endl);
       let xx = {};
       let yy = {};
       scrollbox.getPosition(xx, yy);
       dump(xx.value + "," + yy.value + endl);*/
 
--- a/toolkit/content/tests/fennec-tile-testapp/chrome/content/foo.xul
+++ b/toolkit/content/tests/fennec-tile-testapp/chrome/content/foo.xul
@@ -18,22 +18,20 @@
 // environment.  What could possibly go wrong? ...
 let bv        = null;
 let scrollbox = null;
 let leftbar   = null;
 let rightbar  = null;
 let topbar    = null;
 
 function debug() {
-  let w = {};
-  let h = {};
-  scrollbox.getScrolledSize(w, h);
+  let w = scrollbox.scrolledWidth;
+  let h = scrollbox.scrolledHeight;
   let container = document.getElementById("tile_container");
   let [x, y] = getScrollboxPosition();
-  let [w, h] = [w.value, h.value];
   if (bv) {
     dump('----------------------DEBUG!-------------------------\n');
     dump(bv._browserViewportState.toString() + endl);
 
     dump(endl);
 
     let cr = bv._tileManager._criticalRect;
     dump('criticalRect from BV: ' + (cr ? cr.toString() : null) + endl);
@@ -180,37 +178,35 @@ function onMouseDown(e) {
 
 function onMouseUp() {
   window._isDragging = false;
   bv.resumeRendering();
 }
 
 function onMouseMove(e) {
   if (window._isDragging) {
-    let x = {};
-    let y = {};
-    let w = {};
-    let h = {};
-    scrollbox.getPosition(x, y);
-    scrollbox.getScrolledSize(w, h);
+    let x = scrollbox.positionX;
+    let y = scrollbox.positionY;
+    let w = scrollbox.scrolledWidth;
+    let h = scrollbox.scrolledHeight;
 
     let dx = window._dragStart.x - e.clientX;
     let dy = window._dragStart.y - e.clientY;
 
     // XXX if max(x, 0) > scrollwidth we shouldn't do anything (same for y/height)
-    let newX = Math.max(x.value + dx, 0);
-    let newY = Math.max(y.value + dy, 0);
+    let newX = Math.max(x + dx, 0);
+    let newY = Math.max(y + dy, 0);
 
-    if (newX < w.value || newY < h.value) {
+    if (newX < w || newY < h) {
       // clip dx and dy to prevent us from going below 0
-      dx = Math.max(dx, -x.value);
-      dy = Math.max(dy, -y.value);
+      dx = Math.max(dx, -x);
+      dy = Math.max(dy, -y);
 
-      let oldx = x.value;
-      let oldy = y.value;
+      let oldx = x;
+      let oldy = y;
 
       bv.onBeforeVisibleMove(dx, dy);
 
       updateBars(oldx, oldy, dx, dy);
       scrollbox.scrollBy(dx, dy);
       
       let [newx, newy] = getScrollboxPosition();
       let realdx = newx - oldx;
@@ -226,19 +222,17 @@ function onMouseMove(e) {
 function onAlmostLoad() {
   window._isDragging = false;
   window.infoMode = false;
   window.setTimeout(onLoad, 1500);
 }
 
 function onLoad() {
   // ----------------------------------------------------
-  scrollbox = document.getElementById("scrollbox")
-		.boxObject
-		.QueryInterface(Components.interfaces.nsIScrollBoxObject);
+  scrollbox = document.getElementById("scrollbox").boxObject;
   leftbar  = document.getElementById("left_sidebar");
   rightbar = document.getElementById("right_sidebar");
   topbar   = document.getElementById("top_urlbar");
   // ----------------------------------------------------
 
   let initX = Math.round(leftbar.getBoundingClientRect().right);
   dump('scrolling to ' + initX + endl);
   scrollbox.scrollTo(initX, 0);
@@ -306,20 +300,17 @@ function scrollboxToViewportRect(rect) {
   let ytrans = -topbarcr.height;
 
   rect.translate(xtrans, ytrans);
 
   return rect;
 }
 
 function getScrollboxPosition() {
-  let x = {};
-  let y = {};
-  scrollbox.getPosition(x, y);
-  return [x.value, y.value];
+  return [scrollbox.positionX, scrollbox.positionY];
 }
 
 function getContentScrollValues(browser) {
   let cwu = getBrowserDOMWindowUtils(browser);
   let scrollX = {};
   let scrollY = {};
   cwu.getScrollXY(false, scrollX, scrollY);
 
--- a/toolkit/content/tests/widgets/popup_shared.js
+++ b/toolkit/content/tests/widgets/popup_shared.js
@@ -257,31 +257,31 @@ function goNextStepSync()
 
 function openMenu(menu)
 {
   if ("open" in menu) {
     menu.open = true;
   }
   else {
     var bo = menu.boxObject;
-    if (bo instanceof SpecialPowers.Ci.nsIMenuBoxObject)
+    if (bo instanceof MenuBoxObject)
       bo.openMenu(true);
     else
       synthesizeMouse(menu, 4, 4, { });
   }
 }
 
 function closeMenu(menu, popup)
 {
   if ("open" in menu) {
     menu.open = false;
   }
   else {
     var bo = menu.boxObject;
-    if (bo instanceof SpecialPowers.Ci.nsIMenuBoxObject)
+    if (bo instanceof MenuBoxObject)
       bo.openMenu(false);
     else
       popup.hidePopup();
   }
 }
 
 function checkActive(popup, id, testname)
 {
@@ -298,26 +298,26 @@ function checkActive(popup, id, testname
   ok(activeok, testname + " item " + (id ? id : "none") + " active");
 }
 
 function checkOpen(menuid, testname)
 {
   var menu = document.getElementById(menuid);
   if ("open" in menu)
     ok(menu.open, testname + " " + menuid + " menu is open");
-  else if (menu.boxObject instanceof SpecialPowers.Ci.nsIMenuBoxObject)
+  else if (menu.boxObject instanceof MenuBoxObject)
     ok(menu.getAttribute("open") == "true", testname + " " + menuid + " menu is open");
 }
 
 function checkClosed(menuid, testname)
 {
   var menu = document.getElementById(menuid);
   if ("open" in menu)
     ok(!menu.open, testname + " " + menuid + " menu is open");
-  else if (menu.boxObject instanceof SpecialPowers.Ci.nsIMenuBoxObject)
+  else if (menu.boxObject instanceof MenuBoxObject)
     ok(!menu.hasAttribute("open"), testname + " " + menuid + " menu is closed");
 }
 
 function convertPosition(anchor, align)
 {
   if (anchor == "topleft" && align == "topleft") return "overlap";
   if (anchor == "topleft" && align == "topright") return "start_before";
   if (anchor == "topleft" && align == "bottomleft") return "before_start";
--- a/toolkit/content/tests/widgets/tree_shared.js
+++ b/toolkit/content/tests/widgets/tree_shared.js
@@ -1287,20 +1287,19 @@ function checkColumns(aTree, aReference,
   columns.forEach(function(e) {
     ids.push(e.element.id);
   });
   is(compareArrays(ids, aReference), true, aMessage);
 }
 
 function mouseOnCell(tree, row, column, testname)
 {
-  var x = {}, y = {}, width = {}, height = {};
-  tree.boxObject.getCoordsForCellItem(row, column, "text", x, y, width, height);
+  var rect = tree.boxObject.getCoordsForCellItem(row, column, "text");
 
-  synthesizeMouseExpectEvent(tree.body, x.value, y.value, {}, tree, "select", testname);
+  synthesizeMouseExpectEvent(tree.body, rect.x, rect.y, {}, tree, "select", testname);
 }
 
 function mouseClickOnColumnHeader(aColumns, aColumnIndex, aButton, aClickCount)
 {
   var columnHeader = aColumns[aColumnIndex].element;
   var columnHeaderRect = columnHeader.getBoundingClientRect();
   var columnWidth = columnHeaderRect.right - columnHeaderRect.left;
   // For multiple click we send separate click events, with increasing
@@ -1316,20 +1315,19 @@ function mouseClickOnColumnHeader(aColum
 function mouseDblClickOnCell(tree, row, column, testname)
 {
   // select the row we will edit
   var selection = tree.view.selection;
   selection.select(row);
   tree.treeBoxObject.ensureRowIsVisible(row);
 
   // get cell coordinates
-  var x = {}, y = {}, width = {}, height = {};
-  tree.treeBoxObject.getCoordsForCellItem(row, column, "text", x, y, width, height);
+  var rect = tree.treeBoxObject.getCoordsForCellItem(row, column, "text");
 
-  synthesizeMouse(tree.body, x.value, y.value, { clickCount: 2 }, null);
+  synthesizeMouse(tree.body, rect.x, rect.y, { clickCount: 2 }, null);
 }
 
 function compareArrays(arr1, arr2)
 {
   if (arr1.length != arr2.length)
     return false;
 
   for (var i = 0; i < arr1.length; i++) {
--- a/toolkit/content/widgets/autocomplete.xml
+++ b/toolkit/content/widgets/autocomplete.xml
@@ -790,19 +790,17 @@
         document.getAnonymousElementByAttribute(this, "anonid", "treecols");
       </field>
 
       <property name="view"
                 onget="return this.mView;">
         <setter><![CDATA[
           // We must do this by hand because the tree binding may not be ready yet
           this.mView = val;
-          var bx = this.tree.boxObject;
-          bx = bx.QueryInterface(Components.interfaces.nsITreeBoxObject);
-          bx.view = val;
+          this.tree.boxObject.view = val;
         ]]></setter>
       </property>
 
     </implementation>
   </binding>
 
   <binding id="autocomplete-base-popup" role="none"
 extends="chrome://global/content/bindings/popup.xml#popup">
--- a/toolkit/content/widgets/button.xml
+++ b/toolkit/content/widgets/button.xml
@@ -20,18 +20,17 @@
                 onset="this.setAttribute('dlgtype', val); return val;"/>
 
       <property name="group"
                 onget="return this.getAttribute('group');"
                 onset="this.setAttribute('group', val); return val;"/>
 
       <property name="open" onget="return this.hasAttribute('open');">
         <setter><![CDATA[
-          if (this.boxObject instanceof
-              Components.interfaces.nsIMenuBoxObject) {
+          if (this.boxObject instanceof MenuBoxObject) {
             this.boxObject.openMenu(val);
           } else {
             // Fall back to just setting the attribute
             if (val) {
               this.setAttribute('open', 'true');
             } else {
               this.removeAttribute('open');
             }
@@ -142,17 +141,17 @@
            because any external oncommand handlers might get called before ours,
            and then they would see the incorrect value of checked. Additionally
            a command attribute would redirect the command events anyway.-->
       <handler event="click" button="0" action="this._handleClick();"/>
       <handler event="keypress" key=" " action="this._handleClick();"/>
 
       <handler event="keypress">
       <![CDATA[
-        if (this.boxObject instanceof Components.interfaces.nsIMenuBoxObject) {
+        if (this.boxObject instanceof MenuBoxObject) {
           if (this.open)
             return;
         } else {
           if (event.keyCode == KeyEvent.DOM_VK_UP ||
               (event.keyCode == KeyEvent.DOM_VK_LEFT &&
                 document.defaultView.getComputedStyle(this.parentNode, "")
                         .direction == "ltr") ||
               (event.keyCode == KeyEvent.DOM_VK_RIGHT &&
--- a/toolkit/content/widgets/datetimepicker.xml
+++ b/toolkit/content/widgets/datetimepicker.xml
@@ -1253,17 +1253,17 @@
         var grid = document.getAnonymousElementByAttribute(this, "anonid", "grid");
         this.attachedControl = grid;
         grid.attachedControl = this;
         grid._setValueNoSync(this._dateValue);
       </constructor>
       <property name="open" onget="return this.hasAttribute('open');">
         <setter>
           <![CDATA[
-            if (this.boxObject instanceof Components.interfaces.nsIMenuBoxObject)
+            if (this.boxObject instanceof MenuBoxObject)
               this.boxObject.openMenu(val);
             return val;
           ]]>
         </setter>
       </property>
       <property name="displayedMonth">
         <getter>
           return document.getAnonymousElementByAttribute(this, "anonid", "grid").displayedMonth;
--- a/toolkit/content/widgets/editor.xml
+++ b/toolkit/content/widgets/editor.xml
@@ -130,17 +130,17 @@
                 onget="return this.getAttribute('editortype');"
                 onset="this.setAttribute('editortype', val); return val;"/>
       <property name="webNavigation"
                 onget="return this.docShell.QueryInterface(Components.interfaces.nsIWebNavigation);"
                 readonly="true"/>
       <property name="contentDocument" readonly="true"
                 onget="return this.webNavigation.document;"/>
       <property name="docShell"
-                onget="return this.boxObject.QueryInterface(Components.interfaces.nsIContainerBoxObject).docShell;"
+                onget="return this.boxObject.docShell;"
                 readonly="true"/>
       <property name="currentURI"
                 readonly="true"
                 onget="return this.webNavigation.currentURI;"/>
       <property name="contentWindow"
                 readonly="true"
                 onget="return this.docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIDOMWindow);"/>
       <property name="webBrowserFind"
@@ -163,9 +163,8 @@
                 onset="this.markupDocumentViewer.textZoom = val;"/>
       <property name="isSyntheticDocument"
                 onget="return this.contentDocument.isSyntheticDocument;"
                 readonly="true"/>
     </implementation>
   </binding>
 
 </bindings>
-
--- a/toolkit/content/widgets/general.xml
+++ b/toolkit/content/widgets/general.xml
@@ -82,17 +82,17 @@
       ]]></destructor>
     </implementation>
   </binding>
 
   <binding id="iframe" role="outerdoc">
     <implementation>
       <property name="docShell"
                 readonly="true"
-                onget="return this.boxObject.QueryInterface(Components.interfaces.nsIContainerBoxObject).docShell"/>
+                onget="return this.boxObject.docShell"/>
       <property name="contentWindow"
                 readonly="true"
                 onget="return this.docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIDOMWindow);"/>
       <property name="webNavigation"
                 onget="return this.docShell.QueryInterface(Components.interfaces.nsIWebNavigation);"
                 readonly="true"/>
       <property name="contentDocument" readonly="true"
                 onget="return this.webNavigation.document;"/>
--- a/toolkit/content/widgets/listbox.xml
+++ b/toolkit/content/widgets/listbox.xml
@@ -672,17 +672,17 @@
       </xul:listrows>
     </content>
 
     <implementation>
 
       <!-- ///////////////// public listbox members ///////////////// -->
 
       <property name="listBoxObject"
-                onget="return this.boxObject.QueryInterface(Components.interfaces.nsIListBoxObject);"
+                onget="return this.boxObject;"
                 readonly="true"/>
 
       <!-- ///////////////// private listbox members ///////////////// -->
 
       <method name="_fireOnSelect">
         <body>
         <![CDATA[
           if (!this._suppressOnSelect && !this.suppressOnSelect) {
@@ -1137,9 +1137,8 @@
     <content>
       <xul:image class="listheader-icon"/>
       <xul:label class="listheader-label" xbl:inherits="value=label,crop" flex="1" crop="right"/>
       <xul:image class="listheader-sortdirection" xbl:inherits="sortDirection"/>
     </content>
   </binding>
 
 </bindings>
-
--- a/toolkit/content/widgets/menu.xml
+++ b/toolkit/content/widgets/menu.xml
@@ -44,26 +44,24 @@
   </binding>
 
   <binding id="menu-base"
            extends="chrome://global/content/bindings/menu.xml#menuitem-base">
 
     <implementation implements="nsIDOMXULContainerElement">
       <property name="open" onget="return this.hasAttribute('open');">
         <setter><![CDATA[
-          this.boxObject.QueryInterface(Components.interfaces.nsIMenuBoxObject)
-              .openMenu(val);
+          this.boxObject.openMenu(val);
           return val;
         ]]></setter>
       </property>
 
       <property name="openedWithKey" readonly="true">
         <getter><![CDATA[
-          return this.boxObject.QueryInterface(Components.interfaces.nsIMenuBoxObject)
-              .openedWithKey;
+          return this.boxObject.openedWithKey;
         ]]></getter>
       </property>
 
       <!-- nsIDOMXULContainerElement interface -->
       <method name="appendItem">
         <parameter name="aLabel"/>
         <parameter name="aValue"/>
         <body>
--- a/toolkit/content/widgets/menulist.xml
+++ b/toolkit/content/widgets/menulist.xml
@@ -65,17 +65,17 @@
         ]]>
       </handler>
     </handlers>
 
     <implementation implements="nsIDOMXULMenuListElement, nsIDOMEventListener">
       <constructor>
         this.mInputField = null;
         this.mSelectedInternal = null;
-        this.menuBoxObject = this.boxObject.QueryInterface(Components.interfaces.nsIMenuBoxObject);
+        this.menuBoxObject = this.boxObject;
         this.setInitialSelection();
       </constructor>
 
       <method name="setInitialSelection">
         <body>
           <![CDATA[
             var popup = this.menupopup;
             if (popup) {
--- a/toolkit/content/widgets/popup.xml
+++ b/toolkit/content/widgets/popup.xml
@@ -16,17 +16,17 @@
 
     <implementation implements="nsIDOMXULPopupElement">
       <property name="label" onget="return this.getAttribute('label');"
                              onset="this.setAttribute('label', val); return val;"/>
       <property name="position" onget="return this.getAttribute('position');"
                                 onset="this.setAttribute('position', val); return val;"/>
       <property name="popupBoxObject">
         <getter>
-          return this.boxObject.QueryInterface(Components.interfaces.nsIPopupBoxObject);
+          return this.boxObject;
         </getter>
       </property>
 
       <property name="state" readonly="true"
                 onget="return this.popupBoxObject.popupState"/>
 
       <property name="triggerNode" readonly="true"
                 onget="return this.popupBoxObject.triggerNode"/>
@@ -82,39 +82,39 @@
           var popupBox = null;
           var menuBox = null;
           try {
             popupBox = this.popupBoxObject;
           } catch(e) {}
           try {
             menuBox = this.parentNode.boxObject;
           } catch(e) {}
-          if (menuBox instanceof Components.interfaces.nsIMenuBoxObject)
+          if (menuBox instanceof MenuBoxObject)
             menuBox.openMenu(true);
           else if (popupBox)
             popupBox.showPopup(element, this, xpos, ypos, popuptype, anchoralignment, popupalignment);
         ]]>
         </body>
       </method>
       
       <method name="hidePopup">
         <parameter name="cancel"/>
         <body>
         <![CDATA[
           var popupBox = null;
           var menuBox = null;
           try {
-            popupBox = this.boxObject.QueryInterface(Components.interfaces.nsIPopupBoxObject);
+            popupBox = this.popupBoxObject;
           } catch(e) {}
           try {
             menuBox = this.parentNode.boxObject;
           } catch(e) {}
-          if (menuBox instanceof Components.interfaces.nsIMenuBoxObject)
+          if (menuBox instanceof MenuBoxObject)
             menuBox.openMenu(false);
-          else if (popupBox)
+          else if (popupBox instanceof PopupBoxObject)
             popupBox.hidePopup(cancel);
         ]]>
         </body>
       </method>
 
       <property name="autoPosition">
         <getter>
         <![CDATA[
--- a/toolkit/content/widgets/richlistbox.xml
+++ b/toolkit/content/widgets/richlistbox.xml
@@ -23,17 +23,17 @@
       </xul:scrollbox>
     </content>
 
     <implementation>
       <field name="_scrollbox">
         document.getAnonymousElementByAttribute(this, "anonid", "main-box");
       </field>
       <field name="scrollBoxObject">
-        this._scrollbox.boxObject.QueryInterface(Components.interfaces.nsIScrollBoxObject);
+        this._scrollbox.boxObject;
       </field>
       <constructor>
         <![CDATA[
           // add a template build listener
           if (this.builder)
             this.builder.addListener(this._builderListener);
           else
             this._refreshSelection();
@@ -429,23 +429,21 @@
 
       <method name="_isItemVisible">
         <parameter name="aItem"/>
         <body>
           <![CDATA[
             if (!aItem)
               return false;
 
-            var y = {};
-            this.scrollBoxObject.getPosition({}, y);
-            y.value += this.scrollBoxObject.y;
+            var y = this.scrollBoxObject.positionY + this.scrollBoxObject.y;
 
             // Partially visible items are also considered visible
-            return (aItem.boxObject.y + aItem.boxObject.height > y.value) &&
-                   (aItem.boxObject.y < y.value + this.scrollBoxObject.height);
+            return (aItem.boxObject.y + aItem.boxObject.height > y) &&
+                   (aItem.boxObject.y < y + this.scrollBoxObject.height);
           ]]>
         </body>
       </method>
 
       <field name="_currentIndex">null</field>
 
       <!-- For backwards-compatibility and for convenience.
         Use getIndexOfItem instead. -->
@@ -580,9 +578,8 @@
               this.removeAttribute("searchlabel");
             return val;
           ]]>
         </setter>
       </property>
     </implementation>
   </binding>
 </bindings>
-
--- a/toolkit/content/widgets/scrollbox.xml
+++ b/toolkit/content/widgets/scrollbox.xml
@@ -115,19 +115,17 @@
           return val;
         ]]></setter>
       </property>
 
       <field name="_scrollBoxObject">null</field>
       <property name="scrollBoxObject" readonly="true">
         <getter><![CDATA[
           if (!this._scrollBoxObject) {
-            this._scrollBoxObject =
-              this._scrollbox.boxObject
-                             .QueryInterface(Components.interfaces.nsIScrollBoxObject);
+            this._scrollBoxObject = this._scrollbox.boxObject;
           }
           return this._scrollBoxObject;
         ]]></getter>
       </property>
 
       <property name="scrollClientRect" readonly="true">
         <getter><![CDATA[
           return this._scrollbox.getBoundingClientRect();
--- a/toolkit/content/widgets/tree.xml
+++ b/toolkit/content/widgets/tree.xml
@@ -51,17 +51,19 @@
     <implementation implements="nsIDOMXULTreeElement, nsIDOMXULMultiSelectControlElement">
 
       <!-- ///////////////// nsIDOMXULTreeElement ///////////////// -->
 
       <property name="columns"
                 onget="return this.treeBoxObject.columns;"/>
 
       <property name="view"
-                onget="return this.treeBoxObject.view;"
+                onget="return this.treeBoxObject.view ?
+                       this.treeBoxObject.view.QueryInterface(Components.interfaces.nsITreeView) :
+                       null;"
                 onset="return this.treeBoxObject.view = val;"/>
 
       <property name="body"
                 onget="return this.treeBoxObject.treeBody;"/>
 
       <property name="editable"
                 onget="return this.getAttribute('editable') == 'true';"
                 onset="if (val) this.setAttribute('editable', 'true');
@@ -75,17 +77,17 @@
                 onget="return this.getAttribute('seltype')"
                 onset="this.setAttribute('seltype', val); return val;"/>
 
       <property name="currentIndex"