Bug 1456611 - Remove insertItemAt and removeItemAt methods from XUL widgets. r=enn
authorDão Gottwald <dao@mozilla.com>
Tue, 24 Apr 2018 21:42:26 +0200
changeset 473009 d0ea1b6b6dfb1e1e5e5edaa64bbf09bee22367c2
parent 473008 67d5b919af152c3f2cb1c29e008cead6f47ecbbd
child 473010 426038e8d7577f4a2b02435e27d2cddbdbab98bb
push id1728
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:12:27 +0000
treeherdermozilla-release@c296fde26f5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersenn
bugs1456611
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1456611 - Remove insertItemAt and removeItemAt methods from XUL widgets. r=enn MozReview-Commit-ID: BaChYp8bBbI
browser/components/preferences/applicationManager.js
browser/components/preferences/sitePermissions.js
dom/interfaces/xul/nsIDOMXULSelectCntrlEl.idl
toolkit/content/tests/chrome/test_menu.xul
toolkit/content/tests/chrome/test_popupincontent.xul
toolkit/content/tests/chrome/xul_selectcontrol.js
toolkit/content/widgets/listbox.xml
toolkit/content/widgets/menu.xml
toolkit/content/widgets/menulist.xml
toolkit/content/widgets/radio.xml
toolkit/content/widgets/richlistbox.xml
toolkit/content/widgets/tabbox.xml
toolkit/mozapps/extensions/content/extensions.js
--- a/browser/components/preferences/applicationManager.js
+++ b/browser/components/preferences/applicationManager.js
@@ -70,17 +70,17 @@ var gAppManagerDialog = {
   onCancel: function appManager_onCancel() {
     // do nothing
   },
 
   remove: function appManager_remove() {
     var list = document.getElementById("appList");
     this._removed.push(list.selectedItem.app);
     var index = list.selectedIndex;
-    list.removeItemAt(index);
+    list.selectedItem.remove();
     if (list.getRowCount() == 0) {
       // The list is now empty, make the bottom part disappear
       document.getElementById("appDetails").hidden = true;
     } else {
       // Select the item at the same index, if we removed the last
       // item of the list, select the previous item
       if (index == list.getRowCount())
         --index;
--- a/browser/components/preferences/sitePermissions.js
+++ b/browser/components/preferences/sitePermissions.js
@@ -145,17 +145,19 @@ var gSitePermissionsManager = {
     let p = new Permission(perm.principal, perm.type, perm.capability,
                            capabilityString);
     this._permissions.set(p.origin, p);
   },
 
   _removePermissionFromList(origin) {
     this._permissions.delete(origin);
     let permissionlistitem = document.getElementsByAttribute("origin", origin)[0];
-    this._list.removeItemAt(this._list.getIndexOfItem(permissionlistitem));
+    if (permissionlistitem) {
+      permissionlistitem.remove();
+    }
   },
 
   _loadPermissions() {
     // load permissions into a table.
     let enumerator = Services.perms.enumerator;
     while (enumerator.hasMoreElements()) {
       let nextPermission = enumerator.getNext().QueryInterface(Ci.nsIPermission);
       this._addPermissionToList(nextPermission);
--- a/dom/interfaces/xul/nsIDOMXULSelectCntrlEl.idl
+++ b/dom/interfaces/xul/nsIDOMXULSelectCntrlEl.idl
@@ -9,16 +9,14 @@ interface nsIDOMXULSelectControlItemElem
 [scriptable, uuid(9bf188a7-d6f9-431b-b5c7-118013998e8b)]
 interface nsIDOMXULSelectControlElement : nsIDOMXULControlElement {
   attribute nsIDOMXULSelectControlItemElement selectedItem;
   attribute long selectedIndex;
 
   attribute DOMString value;
   
   nsIDOMXULSelectControlItemElement appendItem(in DOMString label, in DOMString value);
-  nsIDOMXULSelectControlItemElement insertItemAt(in long index, in DOMString label, in DOMString value);
-  nsIDOMXULSelectControlItemElement removeItemAt(in long index);
 
   readonly attribute unsigned long itemCount;
   long getIndexOfItem(in nsIDOMXULSelectControlItemElement item);
   nsIDOMXULSelectControlItemElement getItemAtIndex(in long index);
 };
 
--- a/toolkit/content/tests/chrome/test_menu.xul
+++ b/toolkit/content/tests/chrome/test_menu.xul
@@ -51,26 +51,16 @@
     is(menu.parentContainer, topmenu,
         "nsIDOMXULContainerElement::parentContainer failed.");
 
     // nsIDOMXULContainerElement::appendItem();
     var item = menu.appendItem("item3");
     is(menu.getIndexOfItem(item), 2,
        "nsIDOMXULContainerElement::appendItem() failed.");
 
-    // nsIDOMXULContainerElement::insertItemAt();
-    var item = menu.insertItemAt(0, "itemZero");
-    is(item, menu.getItemAtIndex(0),
-        "nsIDOMXULContainerElement::insertItemAt() failed.");
-
-    // nsIDOMXULContainerElement::removeItemAt();
-    var item = menu.removeItemAt(0);
-    is(3, menu.itemCount,
-       "nsIDOMXULContainerElement::removeItemAt() failed.");
-
     SimpleTest.finish();
   }
 
   ]]>
   </script>
 
   <body xmlns="http://www.w3.org/1999/xhtml">
     <p id="display">
--- a/toolkit/content/tests/chrome/test_popupincontent.xul
+++ b/toolkit/content/tests/chrome/test_popupincontent.xul
@@ -70,17 +70,17 @@ function nextTest()
       popup.removeAttribute("top");
       for (var i = 0; i < 80; i++)
         menu.appendItem("Test", "");
       synthesizeMouse(menu, 2, 2, { });
       break;
     case "large menu":
       step = "shorter menu again";
       for (var i = 0; i < 80; i++)
-        menu.removeItemAt(menu.itemCount - 1);
+        popup.lastChild.remove();
       synthesizeMouse(menu, 2, 2, { });
       break;
     case "shorter menu again":
       SimpleTest.finish();
       break;
   }
 }
 
--- a/toolkit/content/tests/chrome/xul_selectcontrol.js
+++ b/toolkit/content/tests/chrome/xul_selectcontrol.js
@@ -114,93 +114,31 @@ function test_nsIDOMXULSelectControlElem
   var otherValueClearsSelection = behaviourContains(element.localName, "other-value-clears-selection");
   test_nsIDOMXULSelectControlElement_States(element, testid + "set value other", 2,
                                             otherValueClearsSelection ? null : seconditem,
                                             otherValueClearsSelection ? -1 : 1,
                                             allowOtherValue ? "other" : secondvalue);
   if (allowOtherValue)
     element.value = "";
 
-  // 'removeItemAt' - check if removeItemAt removes the right item
-  if (selectionRequired)
-    element.value = secondvalue;
-  else
-    element.selectedIndex = -1;
-
-  var removeditem = element.removeItemAt(0);
-  is(removeditem, firstitem, testid + "removeItemAt return value");
-  test_nsIDOMXULSelectControlElement_States(element, testid + "removeItemAt", 1,
-        selectionRequired ? seconditem : null, selectionRequired ? 0 : -1,
-        selectionRequired ? secondvalue : "");
-
-  is(removeditem.control, undefined, testid + "control not set");
-
-  var thirditem = element.appendItem("Third Item", "third");
   var fourthitem = element.appendItem("Fourth Item", fourthvalue);
-  var fifthitem = element.appendItem("Fifth Item", "fifth");
-
-  // 'removeItemAt 2' - check if removeItemAt removes the selected item and
-  //                    adjusts the selection to the next item
-  element.selectedItem = thirditem;
-  is(element.removeItemAt(1), thirditem, testid + "removeItemAt 2 return value");
-
-  // radio buttons don't handle removing quite right due to XBL issues,
-  // so disable testing some of these remove tests for now - bug 367400
-  var isnotradio = (element.localName != "radiogroup");
-  // XXXndeakin disable these tests for all widgets for now. They require bug 331513.
-  isnotradio = false;
-  if (isnotradio)
-    test_nsIDOMXULSelectControlElement_States(element, testid + "removeItemAt 2", 3, fourthitem, 1, fourthvalue);
-
-  // 'removeItemAt 3' - check if removeItemAt adjusts the selection
-  //                    if an earlier item is removed
-  element.selectedItem = fourthitem;
-  element.removeItemAt(0);
-  test_nsIDOMXULSelectControlElement_States(element, testid + "removeItemAt 3", 2, fourthitem, 0, fourthvalue);
-
-  // 'removeItemAt 4' - check if removeItemAt adjusts the selection if the
-  //                    last item is selected and removed
-  element.selectedItem = fifthitem;
-  element.removeItemAt(1);
-  if (isnotradio)
-    test_nsIDOMXULSelectControlElement_States(element, testid + "removeItemAt 4", 1, fourthitem, 0, fourthvalue);
-
-  // 'removeItemAt 5' - check that removeItemAt doesn't fail when removing invalid items
-  is(element.removeItemAt(-1), null, testid + "removeItemAt 5 return value");
-  if (isnotradio)
-    test_nsIDOMXULSelectControlElement_States(element, testid + "removeItemAt 5", 1, fourthitem, 0, fourthvalue);
-
-  // 'removeItemAt 6' - check that removeItemAt doesn't fail when removing invalid items
-  is(element.removeItemAt(1), null, testid + "removeItemAt 6 return value");
-  is("item removed", "item removed", testid + "removeItemAt 6");
-  if (isnotradio)
-    test_nsIDOMXULSelectControlElement_States(element, testid + "removeItemAt 6", 1, fourthitem, 0, fourthvalue);
-
-  // 'insertItemAt' - check if insertItemAt inserts items at the right locations
-  element.selectedIndex = 0;
-  test_nsIDOMXULSelectControlElement_insertItemAt(element, 0, 0, testid, 5);
-  test_nsIDOMXULSelectControlElement_insertItemAt(element, 2, 2, testid, 6);
-  test_nsIDOMXULSelectControlElement_insertItemAt(element, -1, 3, testid, 7);
-  test_nsIDOMXULSelectControlElement_insertItemAt(element, 6, 4, testid, 8);
-
   element.selectedIndex = 0;
   fourthitem.disabled = true;
-  element.selectedIndex = 1;
-  test_nsIDOMXULSelectControlElement_States(element, testid + "selectedIndex disabled", 5, fourthitem, 1, fourthvalue);
+  element.selectedIndex = 2;
+  test_nsIDOMXULSelectControlElement_States(element, testid + "selectedIndex disabled", 3, fourthitem, 2, fourthvalue);
 
   element.selectedIndex = 0;
   element.selectedItem = fourthitem;
-  test_nsIDOMXULSelectControlElement_States(element, testid + "selectedIndex disabled", 5, fourthitem, 1, fourthvalue);
+  test_nsIDOMXULSelectControlElement_States(element, testid + "selectedItem disabled", 3, fourthitem, 2, fourthvalue);
 
-  // 'removeall' - check if all items are removed
-  while (element.itemCount)
-    element.removeItemAt(0);
-  if (isnotradio)
-    test_nsIDOMXULSelectControlElement_States(element, testid + "remove all", 0, null, -1,
-                                              allowOtherValue ? "number8" : "");
+  if (element.menupopup) {
+    element.menupopup.textContent = "";
+  } else {
+    element.textContent = "";
+  }
 }
 
 function test_nsIDOMXULSelectControlElement_init(element, testprefix) {
   // editable menulists use the label as the value
   var isEditable = (element.localName == "menulist" && element.editable);
 
   var id = element.id;
   element = document.getElementById(id + "-initwithvalue");
@@ -230,48 +168,32 @@ function test_nsIDOMXULSelectControlElem
   is(element.selectedIndex, expectedindex, testid + " selectedIndex");
   is(element.value, expectedvalue, testid + " value");
   if (element.selectedItem) {
     is(element.selectedItem.selected, true,
                   testid + " selectedItem marked as selected");
   }
 }
 
-function test_nsIDOMXULSelectControlElement_insertItemAt(element, index, expectedindex, testid, number) {
-  var expectedCount = element.itemCount;
-  var expectedSelItem = element.selectedItem;
-  var expectedSelIndex = element.selectedIndex;
-  var expectedSelValue = element.value;
-
-  var newitem = element.insertItemAt(index, "Item " + number, "number" + number);
-  is(element.getIndexOfItem(newitem), expectedindex,
-                testid + "insertItemAt " + expectedindex + " - get inserted item");
-  expectedCount++;
-  if (expectedSelIndex >= expectedindex)
-    expectedSelIndex++;
-
-  test_nsIDOMXULSelectControlElement_States(element, testid + "insertItemAt " + index,
-                                           expectedCount, expectedSelItem,
-                                           expectedSelIndex, expectedSelValue);
-  return newitem;
-}
-
 /** test_nsIDOMXULSelectControlElement_UI
   *
   * Test the UI aspects of an element which implements nsIDOMXULSelectControlElement
   *
   * Parameters:
   *   element - element to test
   */
 function test_nsIDOMXULSelectControlElement_UI(element, testprefix) {
   var testid = (testprefix) ? testprefix + " " : "";
   testid += element.localName + " nsIDOMXULSelectControlElement UI ";
 
-  while (element.itemCount)
-    element.removeItemAt(0);
+  if (element.menupopup) {
+    element.menupopup.textContent = "";
+  } else {
+    element.textContent = "";
+  }
 
   var firstitem = element.appendItem("First Item", "first");
   var seconditem = element.appendItem("Second Item", "second");
 
   // 'mouse select' - check if clicking an item selects it
   synthesizeMouseExpectEvent(firstitem, 2, 2, {}, element, "select", testid + "mouse select");
   test_nsIDOMXULSelectControlElement_States(element, testid + "mouse select", 2, firstitem, 0, "first");
 
@@ -327,18 +249,18 @@ function test_nsIDOMXULSelectControlElem
     synthesizeKeyExpectEvent("VK_PAGE_DOWN", {}, element, "select", testid + "key page down to end");
     test_nsIDOMXULSelectControlElement_States(element, testid + "key page down to end", 6, sixthitem, 5, "sixth");
 
     synthesizeKeyExpectEvent("VK_PAGE_UP", {}, element, "select", testid + "key page up");
     test_nsIDOMXULSelectControlElement_States(element, testid + "key page up", 6, thirditem, 2, "third");
     synthesizeKeyExpectEvent("VK_PAGE_UP", {}, element, "select", testid + "key page up to start");
     test_nsIDOMXULSelectControlElement_States(element, testid + "key page up to start", 6, firstitem, 0, "first");
 
-    element.removeItemAt(5);
-    element.removeItemAt(4);
+    element.getItemAtIndex(5).remove();
+    element.getItemAtIndex(4).remove();
   }
 
   // now test whether a disabled item works.
   element.selectedIndex = 0;
   seconditem.disabled = true;
 
   var dontSelectDisabled = (behaviourContains(element.localName, "dont-select-disabled"));
 
--- a/toolkit/content/widgets/listbox.xml
+++ b/toolkit/content/widgets/listbox.xml
@@ -55,22 +55,16 @@
      */
     scrollToIndex(aIndex)
 
     /** Create item element and append it to the end of listbox
      * @param aLabel - label of new item element
      * @param aValue - value of new item element */
     appendItem(aLabel, aValue)
 
-    /** Create item element and insert it to given position
-     * @param aIndex - insertion position
-     * @param aLabel - label of new item element
-     * @param aValue - value of new item element */
-    insertItemAt(aIndex, aLabel, aValue)
-
     /** Scroll up/down one page
      * @param aDirection - specifies scrolling direction, should be either -1 or 1
      * @return the number of elements the selection scrolled
      */
     scrollOnePage(aDirection)
 
     /** Fire "select" event */
     _fireOnSelect()
@@ -133,28 +127,16 @@
           var kids = this.getElementsByAttribute("value", val);
           if (kids && kids.item(0))
             this.selectItem(kids[0]);
           return val;
         ]]>
         </setter>
       </property>
 
-      <method name="removeItemAt">
-        <parameter name="index"/>
-        <body>
-        <![CDATA[
-          var remove = this.getItemAtIndex(index);
-          if (remove)
-            this.removeChild(remove);
-          return remove;
-        ]]>
-        </body>
-      </method>
-
     <!-- nsIDOMXULMultiSelectControlElement -->
       <property name="selType"
                 onget="return this.getAttribute('seltype');"
                 onset="this.setAttribute('seltype', val); return val;"/>
 
       <property name="currentItem" onget="return this._currentItem;">
         <setter>
           if (this._currentItem == val)
@@ -724,36 +706,16 @@
           var item = this.ownerDocument.createElementNS(XULNS, "listitem");
           item.setAttribute("label", aLabel);
           item.setAttribute("value", aValue);
           this.appendChild(item);
           return item;
         </body>
       </method>
 
-      <method name="insertItemAt">
-        <parameter name="aIndex"/>
-        <parameter name="aLabel"/>
-        <parameter name="aValue"/>
-        <body>
-          const XULNS =
-            "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
-
-          var item = this.ownerDocument.createElementNS(XULNS, "listitem");
-          item.setAttribute("label", aLabel);
-          item.setAttribute("value", aValue);
-          var before = this.getItemAtIndex(aIndex);
-          if (before)
-            this.insertBefore(item, before);
-          else
-            this.appendChild(item);
-          return item;
-        </body>
-      </method>
-
       <property name="itemCount" readonly="true"
                 onget="return this.listBoxObject.getRowCount()"/>
 
       <!-- ///////////////// nsIListBoxObject ///////////////// -->
       <method name="getIndexOfItem">
         <parameter name="item"/>
         <body>
           <![CDATA[
--- a/toolkit/content/widgets/menu.xml
+++ b/toolkit/content/widgets/menu.xml
@@ -59,60 +59,33 @@
         ]]></getter>
       </property>
 
       <!-- nsIDOMXULContainerElement interface -->
       <method name="appendItem">
         <parameter name="aLabel"/>
         <parameter name="aValue"/>
         <body>
-          return this.insertItemAt(-1, aLabel, aValue);
-        </body>
-      </method>
-
-      <method name="insertItemAt">
-        <parameter name="aIndex"/>
-        <parameter name="aLabel"/>
-        <parameter name="aValue"/>
-        <body>
           const XUL_NS =
             "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
 
           var menupopup = this.menupopup;
           if (!menupopup) {
             menupopup = this.ownerDocument.createElementNS(XUL_NS, "menupopup");
             this.appendChild(menupopup);
           }
 
           var menuitem = this.ownerDocument.createElementNS(XUL_NS, "menuitem");
           menuitem.setAttribute("label", aLabel);
           menuitem.setAttribute("value", aValue);
 
-          var before = this.getItemAtIndex(aIndex);
-          if (before)
-            return menupopup.insertBefore(menuitem, before);
           return menupopup.appendChild(menuitem);
         </body>
       </method>
 
-      <method name="removeItemAt">
-        <parameter name="aIndex"/>
-        <body>
-        <![CDATA[
-          var menupopup = this.menupopup;
-          if (menupopup) {
-            var item = this.getItemAtIndex(aIndex);
-            if (item)
-              return menupopup.removeChild(item);
-          }
-          return null;
-        ]]>
-        </body>
-      </method>
-
       <property name="itemCount" readonly="true">
         <getter>
           var menupopup = this.menupopup;
           return menupopup ? menupopup.childNodes.length : 0;
         </getter>
       </property>
 
       <method name="getIndexOfItem">
--- a/toolkit/content/widgets/menulist.xml
+++ b/toolkit/content/widgets/menulist.xml
@@ -328,56 +328,16 @@
             item.setAttribute("description", description);
 
           popup.appendChild(item);
           return item;
         ]]>
         </body>
       </method>
 
-      <method name="insertItemAt">
-        <parameter name="index"/>
-        <parameter name="label"/>
-        <parameter name="value"/>
-        <parameter name="description"/>
-        <body>
-        <![CDATA[
-          const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
-          var popup = this.menupopup ||
-                      this.appendChild(document.createElementNS(XULNS, "menupopup"));
-          var item = document.createElementNS(XULNS, "menuitem");
-          item.setAttribute("label", label);
-          item.setAttribute("value", value);
-          if (description)
-            item.setAttribute("description", description);
-
-          if (index >= 0 && index < popup.childNodes.length)
-            popup.insertBefore(item, popup.childNodes[index]);
-          else
-            popup.appendChild(item);
-          return item;
-        ]]>
-        </body>
-      </method>
-
-      <method name="removeItemAt">
-        <parameter name="index"/>
-        <body>
-        <![CDATA[
-          var popup = this.menupopup;
-          if (popup && 0 <= index && index < popup.childNodes.length) {
-            var remove = popup.childNodes[index];
-            popup.removeChild(remove);
-            return remove;
-          }
-          return null;
-        ]]>
-        </body>
-      </method>
-
       <method name="removeAllItems">
         <body>
         <![CDATA[
           this.selectedItem = null;
           var popup = this.menupopup;
           if (popup)
             this.removeChild(popup);
         ]]>
--- a/toolkit/content/widgets/radio.xml
+++ b/toolkit/content/widgets/radio.xml
@@ -311,51 +311,16 @@
           radio.setAttribute("label", label);
           radio.setAttribute("value", value);
           this.appendChild(radio);
           this._radioChildren = null;
           return radio;
         ]]>
         </body>
       </method>
-
-      <method name="insertItemAt">
-        <parameter name="index"/>
-        <parameter name="label"/>
-        <parameter name="value"/>
-        <body>
-        <![CDATA[
-          var XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
-          var radio = document.createElementNS(XULNS, "radio");
-          radio.setAttribute("label", label);
-          radio.setAttribute("value", value);
-          var before = this.getItemAtIndex(index);
-          if (before)
-            before.parentNode.insertBefore(radio, before);
-          else
-            this.appendChild(radio);
-          this._radioChildren = null;
-          return radio;
-        ]]>
-        </body>
-      </method>
-
-      <method name="removeItemAt">
-        <parameter name="index"/>
-        <body>
-        <![CDATA[
-          var remove = this.getItemAtIndex(index);
-          if (remove) {
-            remove.remove();
-            this._radioChildren = null;
-          }
-          return remove;
-        ]]>
-        </body>
-      </method>
     </implementation>
 
     <handlers>
       <handler event="mousedown">
         if (this.disabled)
           event.preventDefault();
        </handler>
 
--- a/toolkit/content/widgets/richlistbox.xml
+++ b/toolkit/content/widgets/richlistbox.xml
@@ -128,43 +128,30 @@
         ]]>
         </body>
       </method>
 
       <method name="appendItem">
         <parameter name="aLabel"/>
         <parameter name="aValue"/>
         <body>
-          return this.insertItemAt(-1, aLabel, aValue);
-        </body>
-      </method>
-
-      <method name="insertItemAt">
-        <parameter name="aIndex"/>
-        <parameter name="aLabel"/>
-        <parameter name="aValue"/>
-        <body>
           const XULNS =
             "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
 
           var item =
             this.ownerDocument.createElementNS(XULNS, "richlistitem");
           item.setAttribute("value", aValue);
 
           var label = this.ownerDocument.createElementNS(XULNS, "label");
           label.setAttribute("value", aLabel);
           label.setAttribute("flex", "1");
           label.setAttribute("crop", "end");
           item.appendChild(label);
 
-          var before = this.getItemAtIndex(aIndex);
-          if (!before)
-            this.appendChild(item);
-          else
-            this.insertBefore(item, before);
+          this.appendChild(item);
 
           return item;
         </body>
       </method>
 
       <property name="itemCount" readonly="true"
                 onget="return this.children.length"/>
 
--- a/toolkit/content/widgets/tabbox.xml
+++ b/toolkit/content/widgets/tabbox.xml
@@ -522,48 +522,16 @@
           var tab = document.createElementNS(XULNS, "tab");
           tab.setAttribute("label", label);
           tab.setAttribute("value", value);
           this.appendChild(tab);
           return tab;
         ]]>
         </body>
       </method>
-
-      <method name="insertItemAt">
-        <parameter name="index"/>
-        <parameter name="label"/>
-        <parameter name="value"/>
-        <body>
-        <![CDATA[
-          var XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
-          var tab = document.createElementNS(XULNS, "tab");
-          tab.setAttribute("label", label);
-          tab.setAttribute("value", value);
-          var before = this.getItemAtIndex(index);
-          if (before)
-            this.insertBefore(tab, before);
-          else
-            this.appendChild(tab);
-          return tab;
-        ]]>
-        </body>
-      </method>
-
-      <method name="removeItemAt">
-        <parameter name="index"/>
-        <body>
-        <![CDATA[
-          var remove = this.getItemAtIndex(index);
-          if (remove)
-            this.removeChild(remove);
-          return remove;
-        ]]>
-        </body>
-      </method>
     </implementation>
 
 #ifdef MOZ_WIDGET_GTK
     <handlers>
       <handler event="DOMMouseScroll">
       <![CDATA[
         if (event.detail > 0)
           this.advanceSelectedTab(1, false);
--- a/toolkit/mozapps/extensions/content/extensions.js
+++ b/toolkit/mozapps/extensions/content/extensions.js
@@ -2234,18 +2234,17 @@ var gLegacyView = {
     this.refreshVisibility();
   },
 
   async show(type, request) {
     let addons = await AddonManager.getAddonsByTypes(["extension", "theme"]);
     addons = addons.filter(a => !a.hidden &&
                               (isDisabledLegacy(a) || isDisabledUnsigned(a)));
 
-    while (this._listBox.itemCount > 0)
-      this._listBox.removeItemAt(0);
+    this._listBox.textContent = "";
 
     let elements = addons.map(a => createItem(a));
     if (elements.length == 0) {
       gViewController.loadView("addons://list/extension");
       return;
     }
 
     sortElements(elements, ["uiState", "name"], true);
@@ -2370,18 +2369,17 @@ var gListView = {
 
     if (!(aType in AddonManager.addonTypes))
       throw Components.Exception("Attempting to show unknown type " + aType, Cr.NS_ERROR_INVALID_ARG);
 
     this._type = aType;
     this.node.setAttribute("type", aType);
     this.showEmptyNotice(false);
 
-    while (this._listBox.itemCount > 0)
-      this._listBox.removeItemAt(0);
+    this._listBox.textContent = "";
 
     if (aType == "plugin") {
       navigator.plugins.refresh(false);
     }
 
     getAddonsAndInstalls(aType, (aAddonsList, aInstallsList) => {
       if (gViewController && aRequest != gViewController.currentViewRequest)
         return;
@@ -3261,18 +3259,17 @@ var gUpdatesView = {
     AddonManager.removeInstallListener(this);
   },
 
   show(aType, aRequest) {
     document.getElementById("empty-availableUpdates-msg").hidden = aType != "available";
     document.getElementById("empty-recentUpdates-msg").hidden = aType != "recent";
     this.showEmptyNotice(false);
 
-    while (this._listBox.itemCount > 0)
-      this._listBox.removeItemAt(0);
+    this._listBox.textContent = "";
 
     this.node.setAttribute("updatetype", aType);
     if (aType == "recent")
       this._showRecentUpdates(aRequest);
     else
       this._showAvailableUpdates(false, aRequest);
   },