Bug 1408186 - Remove nsIDOMHTMLSelectElement and nsIDOMHTMLOptionsCollection; r=bz
authorKyle Machulis <kyle@nonpolynomial.com>
Thu, 12 Oct 2017 16:32:25 -0700
changeset 428606 68970144c5df771ce74c5bc3185bc6d32bc672fa
parent 428605 dfd49bfe648886bfbf0ae0deb1891a0dc8da0ded
child 428607 b12daff50304db61d4250754c58b7250778b141c
push idunknown
push userunknown
push dateunknown
reviewersbz
bugs1408186
milestone58.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 1408186 - Remove nsIDOMHTMLSelectElement and nsIDOMHTMLOptionsCollection; r=bz MozReview-Commit-ID: Gh3JwLUtmz9
browser/extensions/formautofill/FormAutofillHandler.jsm
browser/extensions/formautofill/FormAutofillHeuristics.jsm
browser/extensions/formautofill/test/unit/test_onFormSubmitted.js
dom/html/HTMLOptionElement.cpp
dom/html/HTMLOptionsCollection.cpp
dom/html/HTMLOptionsCollection.h
dom/html/HTMLSelectElement.cpp
dom/html/HTMLSelectElement.h
dom/html/test/test_bug389797.html
dom/interfaces/html/moz.build
dom/interfaces/html/nsIDOMHTMLOptionsCollection.idl
dom/interfaces/html/nsIDOMHTMLSelectElement.idl
dom/webidl/HTMLOptionsCollection.webidl
dom/webidl/HTMLSelectElement.webidl
layout/forms/nsListControlFrame.cpp
security/manager/ssl/nsKeygenHandler.cpp
toolkit/modules/FormLikeFactory.jsm
xpcom/reflect/xptinfo/ShimInterfaceInfo.cpp
--- a/browser/extensions/formautofill/FormAutofillHandler.jsm
+++ b/browser/extensions/formautofill/FormAutofillHandler.jsm
@@ -370,17 +370,17 @@ FormAutofillHandler.prototype = {
 
     for (let fieldName in profile) {
       let fieldDetail = this.getFieldDetailByName(fieldName);
       if (!fieldDetail) {
         continue;
       }
 
       let element = fieldDetail.elementWeakRef.get();
-      if (!(element instanceof Ci.nsIDOMHTMLSelectElement)) {
+      if (ChromeUtils.getClassName(element) !== "HTMLSelectElement") {
         continue;
       }
 
       let cache = this._cacheValue.matchingSelectOption.get(element) || {};
       let value = profile[fieldName];
       if (cache[value] && cache[value].get()) {
         continue;
       }
@@ -510,17 +510,17 @@ FormAutofillHandler.prototype = {
         if (element == focusedInput ||
             (element != focusedInput && !element.value)) {
           element.setUserInput(value);
           this.changeFieldState(fieldDetail, "AUTO_FILLED");
           continue;
         }
       }
 
-      if (element instanceof Ci.nsIDOMHTMLSelectElement) {
+      if (ChromeUtils.getClassName(element) === "HTMLSelectElement") {
         let cache = this._cacheValue.matchingSelectOption.get(element) || {};
         let option = cache[value] && cache[value].get();
         if (!option) {
           continue;
         }
         // Do not change value or dispatch events if the option is already selected.
         // Use case for multiple select is not considered here.
         if (!option.selected) {
@@ -590,17 +590,17 @@ FormAutofillHandler.prototype = {
       let element = fieldDetail.elementWeakRef.get();
       let value = profile[fieldDetail.fieldName] || "";
 
       // Skip the field that is null
       if (!element) {
         continue;
       }
 
-      if (element instanceof Ci.nsIDOMHTMLSelectElement) {
+      if (ChromeUtils.getClassName(element) === "HTMLSelectElement") {
         // Unlike text input, select element is always previewed even if
         // the option is already selected.
         if (value) {
           let cache = this._cacheValue.matchingSelectOption.get(element) || {};
           let option = cache[value] && cache[value].get();
           if (option) {
             value = option.text || "";
           } else {
@@ -740,17 +740,17 @@ FormAutofillHandler.prototype = {
       details.forEach(detail => {
         let element = detail.elementWeakRef.get();
         // Remove the unnecessary spaces
         let value = element && element.value.trim();
 
         // Try to abbreviate the value of select element.
         if (type == "address" &&
             detail.fieldName == "address-level1" &&
-            element instanceof Ci.nsIDOMHTMLSelectElement) {
+            ChromeUtils.getClassName(element) === "HTMLSelectElement") {
           // Don't save the record when the option value is empty *OR* there
           // are multiple options being selected. The empty option is usually
           // assumed to be default along with a meaningless text to users.
           if (!value || element.selectedOptions.length != 1) {
             // Keep the property and preserve more information for address updating
             data[type].record[detail.fieldName] = "";
             return;
           }
--- a/browser/extensions/formautofill/FormAutofillHeuristics.jsm
+++ b/browser/extensions/formautofill/FormAutofillHeuristics.jsm
@@ -305,17 +305,17 @@ this.FormAutofillHeuristics = {
    * Try to find the field that is look like a month select.
    *
    * @param {DOMElement} element
    * @returns {boolean}
    *          Return true if we observe the trait of month select in
    *          the current element.
    */
   _isExpirationMonthLikely(element) {
-    if (!(element instanceof Ci.nsIDOMHTMLSelectElement)) {
+    if (ChromeUtils.getClassName(element) !== "HTMLSelectElement") {
       return false;
     }
 
     const options = [...element.options];
     const desiredValues = Array(12).fill(1).map((v, i) => v + i);
 
     // The number of month options shouldn't be less than 12 or larger than 13
     // including the default option.
@@ -332,17 +332,17 @@ this.FormAutofillHeuristics = {
    * Try to find the field that is look like a year select.
    *
    * @param {DOMElement} element
    * @returns {boolean}
    *          Return true if we observe the trait of year select in
    *          the current element.
    */
   _isExpirationYearLikely(element) {
-    if (!(element instanceof Ci.nsIDOMHTMLSelectElement)) {
+    if (ChromeUtils.getClassName(element) !== "HTMLSelectElement") {
       return false;
     }
 
     const options = [...element.options];
     // A normal expiration year select should contain at least the last three years
     // in the list.
     const curYear = new Date().getFullYear();
     const desiredValues = Array(3).fill(0).map((v, i) => v + curYear + i);
--- a/browser/extensions/formautofill/test/unit/test_onFormSubmitted.js
+++ b/browser/extensions/formautofill/test/unit/test_onFormSubmitted.js
@@ -546,17 +546,17 @@ TESTCASES.forEach(testcase => {
     do_print("Starting testcase: " + testcase.description);
 
     let form = MOCK_DOC.getElementById("form1");
     form.reset();
     for (let key in testcase.formValue) {
       let input = MOCK_DOC.getElementById(key);
       let value = testcase.formValue[key];
 
-      if (input instanceof Ci.nsIDOMHTMLSelectElement && value) {
+      if (ChromeUtils.getClassName(input) === "HTMLSelectElement" && value) {
         input.multiple = Array.isArray(value);
         [...input.options].forEach(option => {
           option.selected = value.includes(option.value);
         });
       } else {
         input.value = testcase.formValue[key];
       }
     }
--- a/dom/html/HTMLOptionElement.cpp
+++ b/dom/html/HTMLOptionElement.cpp
@@ -14,17 +14,16 @@
 #include "nsIForm.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMHTMLCollection.h"
 #include "nsISelectControlFrame.h"
 
 // Notify/query select frame for selected state
 #include "nsIFormControlFrame.h"
 #include "nsIDocument.h"
-#include "nsIDOMHTMLSelectElement.h"
 #include "nsNodeInfoManager.h"
 #include "nsCOMPtr.h"
 #include "mozilla/EventStates.h"
 #include "nsContentCreatorFunctions.h"
 #include "mozAutoDocUpdate.h"
 #include "nsTextNode.h"
 
 /**
--- a/dom/html/HTMLOptionsCollection.cpp
+++ b/dom/html/HTMLOptionsCollection.cpp
@@ -92,48 +92,46 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(HT
 
 // nsISupports
 
 // QueryInterface implementation for HTMLOptionsCollection
 NS_INTERFACE_TABLE_HEAD(HTMLOptionsCollection)
   NS_WRAPPERCACHE_INTERFACE_TABLE_ENTRY
   NS_INTERFACE_TABLE(HTMLOptionsCollection,
                      nsIHTMLCollection,
-                     nsIDOMHTMLOptionsCollection,
                      nsIDOMHTMLCollection)
   NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(HTMLOptionsCollection)
 NS_INTERFACE_MAP_END
 
-
 NS_IMPL_CYCLE_COLLECTING_ADDREF(HTMLOptionsCollection)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(HTMLOptionsCollection)
 
-
 JSObject*
 HTMLOptionsCollection::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
   return HTMLOptionsCollectionBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMETHODIMP
 HTMLOptionsCollection::GetLength(uint32_t* aLength)
 {
   *aLength = mElements.Length();
 
   return NS_OK;
 }
 
-NS_IMETHODIMP
-HTMLOptionsCollection::SetLength(uint32_t aLength)
+void
+HTMLOptionsCollection::SetLength(uint32_t aLength, ErrorResult& aError)
 {
   if (!mSelect) {
-    return NS_ERROR_UNEXPECTED;
+    aError.Throw(NS_ERROR_UNEXPECTED);
+    return;
   }
 
-  return mSelect->SetLength(aLength);
+  mSelect->SetLength(aLength, aError);
 }
 
 void
 HTMLOptionsCollection::IndexedSetter(uint32_t aIndex,
                                      HTMLOptionElement* aOption,
                                      ErrorResult& aError)
 {
   if (!mSelect) {
@@ -148,21 +146,18 @@ HTMLOptionsCollection::IndexedSetter(uin
     // We're done.
     return;
   }
 
   // Now we're going to be setting an option in our collection
   if (aIndex > mElements.Length()) {
     // Fill our array with blank options up to (but not including, since we're
     // about to change it) aIndex, for compat with other browsers.
-    nsresult rv = SetLength(aIndex);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      aError.Throw(rv);
-      return;
-    }
+    SetLength(aIndex, aError);
+    ENSURE_SUCCESS_VOID(aError);
   }
 
   NS_ASSERTION(aIndex <= mElements.Length(), "SetLength lied");
 
   if (aIndex == mElements.Length()) {
     mSelect->AppendChild(*aOption, aError);
     return;
   }
@@ -186,47 +181,29 @@ HTMLOptionsCollection::IndexedSetter(uin
 int32_t
 HTMLOptionsCollection::GetSelectedIndex(ErrorResult& aError)
 {
   if (!mSelect) {
     aError.Throw(NS_ERROR_UNEXPECTED);
     return 0;
   }
 
-  int32_t selectedIndex;
-  aError = mSelect->GetSelectedIndex(&selectedIndex);
-  return selectedIndex;
-}
-
-NS_IMETHODIMP
-HTMLOptionsCollection::GetSelectedIndex(int32_t* aSelectedIndex)
-{
-  ErrorResult rv;
-  *aSelectedIndex = GetSelectedIndex(rv);
-  return rv.StealNSResult();
+  return mSelect->SelectedIndex();
 }
 
 void
 HTMLOptionsCollection::SetSelectedIndex(int32_t aSelectedIndex,
                                         ErrorResult& aError)
 {
   if (!mSelect) {
     aError.Throw(NS_ERROR_UNEXPECTED);
     return;
   }
 
-  aError = mSelect->SetSelectedIndex(aSelectedIndex);
-}
-
-NS_IMETHODIMP
-HTMLOptionsCollection::SetSelectedIndex(int32_t aSelectedIndex)
-{
-  ErrorResult rv;
-  SetSelectedIndex(aSelectedIndex, rv);
-  return rv.StealNSResult();
+  mSelect->SetSelectedIndex(aSelectedIndex, aError);
 }
 
 NS_IMETHODIMP
 HTMLOptionsCollection::Item(uint32_t aIndex, nsIDOMNode** aReturn)
 {
   nsISupports* item = GetElementAt(aIndex);
   if (!item) {
     *aReturn = nullptr;
@@ -305,39 +282,16 @@ HTMLOptionsCollection::GetSupportedNames
 
   uint32_t atomsLen = atoms.Length();
   nsString* names = aNames.AppendElements(atomsLen);
   for (uint32_t i = 0; i < atomsLen; ++i) {
     atoms[i]->ToString(names[i]);
   }
 }
 
-NS_IMETHODIMP
-HTMLOptionsCollection::GetSelect(nsIDOMHTMLSelectElement** aReturn)
-{
-  NS_IF_ADDREF(*aReturn = mSelect);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-HTMLOptionsCollection::Add(nsIDOMHTMLOptionElement* aOption,
-                           nsIVariant* aBefore)
-{
-  if (!aOption) {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  if (!mSelect) {
-    return NS_ERROR_NOT_INITIALIZED;
-  }
-
-  nsCOMPtr<nsIDOMHTMLElement> elem = do_QueryInterface(aOption);
-  return mSelect->Add(elem, aBefore);
-}
-
 void
 HTMLOptionsCollection::Add(const HTMLOptionOrOptGroupElement& aElement,
                            const Nullable<HTMLElementOrLong>& aBefore,
                            ErrorResult& aError)
 {
   if (!mSelect) {
     aError.Throw(NS_ERROR_NOT_INITIALIZED);
     return;
@@ -349,26 +303,17 @@ HTMLOptionsCollection::Add(const HTMLOpt
 void
 HTMLOptionsCollection::Remove(int32_t aIndex, ErrorResult& aError)
 {
   if (!mSelect) {
     aError.Throw(NS_ERROR_UNEXPECTED);
     return;
   }
 
-  uint32_t len = 0;
-  mSelect->GetLength(&len);
+  uint32_t len = mSelect->Length();
   if (aIndex < 0 || (uint32_t)aIndex >= len)
     aIndex = 0;
 
-  aError = mSelect->Remove(aIndex);
-}
-
-NS_IMETHODIMP
-HTMLOptionsCollection::Remove(int32_t aIndex)
-{
-  ErrorResult rv;
-  Remove(aIndex, rv);
-  return rv.StealNSResult();
+  mSelect->Remove(aIndex);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/html/HTMLOptionsCollection.h
+++ b/dom/html/HTMLOptionsCollection.h
@@ -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/. */
 #ifndef mozilla_dom_HTMLOptionsCollection_h
 #define mozilla_dom_HTMLOptionsCollection_h
 
 #include "mozilla/Attributes.h"
 #include "nsIHTMLCollection.h"
-#include "nsIDOMHTMLOptionsCollection.h"
 #include "nsWrapperCache.h"
 
 #include "mozilla/dom/HTMLOptionElement.h"
 #include "mozilla/ErrorResult.h"
 #include "nsCOMPtr.h"
 #include "nsError.h"
 #include "nsGenericHTMLElement.h"
 #include "nsTArray.h"
@@ -27,24 +26,24 @@ class HTMLElementOrLong;
 class HTMLOptionElementOrHTMLOptGroupElement;
 class HTMLSelectElement;
 
 /**
  * The collection of options in the select (what you get back when you do
  * select.options in DOM)
  */
 class HTMLOptionsCollection final : public nsIHTMLCollection
-                                  , public nsIDOMHTMLOptionsCollection
                                   , public nsWrapperCache
 {
   typedef HTMLOptionElementOrHTMLOptGroupElement HTMLOptionOrOptGroupElement;
 public:
   explicit HTMLOptionsCollection(HTMLSelectElement* aSelect);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_NSIDOMHTMLCOLLECTION
 
   // nsWrapperCache
   using nsWrapperCache::GetWrapperPreserveColor;
   using nsWrapperCache::GetWrapper;
   using nsWrapperCache::PreserveWrapper;
   virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 protected:
   virtual ~HTMLOptionsCollection();
@@ -54,22 +53,16 @@ protected:
     return nsWrapperCache::GetWrapperPreserveColor();
   }
   virtual void PreserveWrapperInternal(nsISupports* aScriptObjectHolder) override
   {
     nsWrapperCache::PreserveWrapper(aScriptObjectHolder);
   }
 public:
 
-  // nsIDOMHTMLOptionsCollection interface
-  NS_DECL_NSIDOMHTMLOPTIONSCOLLECTION
-
-  // nsIDOMHTMLCollection interface, all its methods are defined in
-  // nsIDOMHTMLOptionsCollection
-
   virtual Element* GetElementAt(uint32_t aIndex) override;
   virtual nsINode* GetParentObject() override;
 
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(HTMLOptionsCollection,
                                                          nsIHTMLCollection)
 
   // Helpers for HTMLSelectElement
   /**
@@ -142,26 +135,26 @@ public:
     return NamedGetter(aName, dummy);
   }
   HTMLOptionElement* NamedGetter(const nsAString& aName, bool& aFound);
   virtual Element*
   GetFirstNamedElement(const nsAString& aName, bool& aFound) override
   {
     return NamedGetter(aName, aFound);
   }
-
   void Add(const HTMLOptionOrOptGroupElement& aElement,
            const Nullable<HTMLElementOrLong>& aBefore,
            ErrorResult& aError);
   void Remove(int32_t aIndex, ErrorResult& aError);
   int32_t GetSelectedIndex(ErrorResult& aError);
   void SetSelectedIndex(int32_t aSelectedIndex, ErrorResult& aError);
   void IndexedSetter(uint32_t aIndex, HTMLOptionElement* aOption,
                      ErrorResult& aError);
   virtual void GetSupportedNames(nsTArray<nsString>& aNames) override;
+  void SetLength(uint32_t aLength, ErrorResult& aError);
 
 private:
   /** The list of options (holds strong references).  This is infallible, so
    * various members such as InsertOptionAt are also infallible. */
   nsTArray<RefPtr<mozilla::dom::HTMLOptionElement> > mElements;
   /** The select element that contains this array */
   HTMLSelectElement* mSelect;
 };
--- a/dom/html/HTMLSelectElement.cpp
+++ b/dom/html/HTMLSelectElement.cpp
@@ -162,17 +162,16 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLSelectElement,
                                                 nsGenericHTMLFormElementWithState)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mValidity)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mSelectedOptions)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED(HTMLSelectElement,
                                              nsGenericHTMLFormElementWithState,
-                                             nsIDOMHTMLSelectElement,
                                              nsIConstraintValidation)
 
 
 // nsIDOMHTMLSelectElement
 
 
 NS_IMPL_ELEMENT_CLONE(HTMLSelectElement)
 
@@ -199,22 +198,16 @@ HTMLSelectElement::GetAutocompleteInfo(A
 {
   const nsAttrValue* attributeVal = GetParsedAttr(nsGkAtoms::autocomplete);
   mAutocompleteInfoState =
     nsContentUtils::SerializeAutocompleteAttribute(attributeVal, aInfo,
                                                    mAutocompleteInfoState,
                                                    true);
 }
 
-NS_IMETHODIMP
-HTMLSelectElement::GetForm(nsIDOMHTMLFormElement** aForm)
-{
-  return nsGenericHTMLFormElementWithState::GetForm(aForm);
-}
-
 nsresult
 HTMLSelectElement::InsertChildAt(nsIContent* aKid,
                                  uint32_t aIndex,
                                  bool aNotify)
 {
   SafeOptionListMutation safeMutation(this, this, aKid, aIndex, aNotify);
   nsresult rv = nsGenericHTMLFormElementWithState::InsertChildAt(aKid, aIndex,
                                                                  aNotify);
@@ -600,120 +593,48 @@ HTMLSelectElement::Add(nsGenericHTMLElem
   }
 
   // If the before parameter is not null, we are equivalent to the
   // insertBefore method on the parent of before.
   nsCOMPtr<nsINode> refNode = aBefore;
   parent->InsertBefore(aElement, refNode, aError);
 }
 
-NS_IMETHODIMP
-HTMLSelectElement::Add(nsIDOMHTMLElement* aElement,
-                       nsIVariant* aBefore)
-{
-  uint16_t dataType;
-  nsresult rv = aBefore->GetDataType(&dataType);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsIContent> element = do_QueryInterface(aElement);
-  nsGenericHTMLElement* htmlElement =
-    nsGenericHTMLElement::FromContentOrNull(element);
-  if (!htmlElement) {
-    return NS_ERROR_NULL_POINTER;
-  }
-
-  // aBefore is omitted, undefined or null
-  if (dataType == nsIDataType::VTYPE_EMPTY ||
-      dataType == nsIDataType::VTYPE_VOID) {
-    ErrorResult error;
-    Add(*htmlElement, (nsGenericHTMLElement*)nullptr, error);
-    return error.StealNSResult();
-  }
-
-  nsCOMPtr<nsISupports> supports;
-
-  // whether aBefore is nsIDOMHTMLElement...
-  if (NS_SUCCEEDED(aBefore->GetAsISupports(getter_AddRefs(supports)))) {
-    nsCOMPtr<nsIContent> beforeElement = do_QueryInterface(supports);
-    nsGenericHTMLElement* beforeHTMLElement =
-      nsGenericHTMLElement::FromContentOrNull(beforeElement);
-
-    NS_ENSURE_TRUE(beforeHTMLElement, NS_ERROR_DOM_SYNTAX_ERR);
-
-    ErrorResult error;
-    Add(*htmlElement, beforeHTMLElement, error);
-    return error.StealNSResult();
-  }
-
-  // otherwise, whether aBefore is long
-  int32_t index;
-  NS_ENSURE_SUCCESS(aBefore->GetAsInt32(&index), NS_ERROR_DOM_SYNTAX_ERR);
-
-  ErrorResult error;
-  Add(*htmlElement, index, error);
-  return error.StealNSResult();
-}
-
-NS_IMETHODIMP
+void
 HTMLSelectElement::Remove(int32_t aIndex)
 {
   nsCOMPtr<nsINode> option = Item(static_cast<uint32_t>(aIndex));
   if (!option) {
-    return NS_OK;
+    return;
   }
 
   option->Remove();
-  return NS_OK;
 }
 
-NS_IMETHODIMP
-HTMLSelectElement::GetOptions(nsIDOMHTMLOptionsCollection** aValue)
-{
-  NS_IF_ADDREF(*aValue = GetOptions());
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
+void
 HTMLSelectElement::GetType(nsAString& aType)
 {
   if (HasAttr(kNameSpaceID_None, nsGkAtoms::multiple)) {
     aType.AssignLiteral("select-multiple");
   }
   else {
     aType.AssignLiteral("select-one");
   }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-HTMLSelectElement::GetLength(uint32_t* aLength)
-{
-  return mOptions->GetLength(aLength);
 }
 
 #define MAX_DYNAMIC_SELECT_LENGTH 10000
 
-NS_IMETHODIMP
-HTMLSelectElement::SetLength(uint32_t aLength)
-{
-  ErrorResult rv;
-  SetLength(aLength, rv);
-  return rv.StealNSResult();
-}
-
 void
 HTMLSelectElement::SetLength(uint32_t aLength, ErrorResult& aRv)
 {
   uint32_t curlen = Length();
 
   if (curlen > aLength) { // Remove extra options
     for (uint32_t i = curlen; i > aLength; --i) {
-      MOZ_ALWAYS_SUCCEEDS(Remove(i - 1));
+      Remove(i - 1);
     }
   } else if (aLength > curlen) {
     if (aLength > MAX_DYNAMIC_SELECT_LENGTH) {
       aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
       return;
     }
 
     RefPtr<mozilla::dom::NodeInfo> nodeInfo;
@@ -763,33 +684,16 @@ HTMLSelectElement::SelectedOptions()
 {
   if (!mSelectedOptions) {
     mSelectedOptions = new nsContentList(this, MatchSelectedOptions, nullptr,
                                          nullptr, /* deep */ true);
   }
   return mSelectedOptions;
 }
 
-NS_IMETHODIMP
-HTMLSelectElement::GetSelectedOptions(nsIDOMHTMLCollection** aSelectedOptions)
-{
-  NS_ADDREF(*aSelectedOptions = SelectedOptions());
-  return NS_OK;
-}
-
-//NS_IMPL_INT_ATTR(HTMLSelectElement, SelectedIndex, selectedindex)
-
-NS_IMETHODIMP
-HTMLSelectElement::GetSelectedIndex(int32_t* aValue)
-{
-  *aValue = SelectedIndex();
-
-  return NS_OK;
-}
-
 nsresult
 HTMLSelectElement::SetSelectedIndexInternal(int32_t aIndex, bool aNotify)
 {
   int32_t oldSelectedIndex = mSelectedIndex;
   uint32_t mask = IS_SELECTED | CLEAR_ALL | SET_DISABLED;
   if (aNotify) {
     mask |= NOTIFY;
   }
@@ -803,22 +707,16 @@ HTMLSelectElement::SetSelectedIndexInter
   }
 
   SetSelectionChanged(true, aNotify);
 
   return rv;
 }
 
 NS_IMETHODIMP
-HTMLSelectElement::SetSelectedIndex(int32_t aIndex)
-{
-  return SetSelectedIndexInternal(aIndex, true);
-}
-
-NS_IMETHODIMP
 HTMLSelectElement::GetOptionIndex(nsIDOMHTMLOptionElement* aOption,
                                   int32_t aStartIndex, bool aForward,
                                   int32_t* aIndex)
 {
   nsCOMPtr<nsINode> option = do_QueryInterface(aOption);
   return mOptions->GetOptionIndex(option->AsElement(), aStartIndex, aForward, aIndex);
 }
 
@@ -1114,25 +1012,16 @@ HTMLSelectElement::IsOptionDisabled(HTML
         return true;
       }
     }
   }
 
   return false;
 }
 
-NS_IMETHODIMP
-HTMLSelectElement::GetValue(nsAString& aValue)
-{
-  DOMString value;
-  GetValue(value);
-  value.ToString(aValue);
-  return NS_OK;
-}
-
 void
 HTMLSelectElement::GetValue(DOMString& aValue)
 {
   int32_t selectedIndex = SelectedIndex();
   if (selectedIndex < 0) {
     return;
   }
 
@@ -1142,47 +1031,38 @@ HTMLSelectElement::GetValue(DOMString& a
   if (!option) {
     return;
   }
 
   DebugOnly<nsresult> rv = option->GetValue(aValue);
   MOZ_ASSERT(NS_SUCCEEDED(rv));
 }
 
-NS_IMETHODIMP
+void
 HTMLSelectElement::SetValue(const nsAString& aValue)
 {
   uint32_t length = Length();
 
   for (uint32_t i = 0; i < length; i++) {
     RefPtr<HTMLOptionElement> option = Item(i);
     if (!option) {
       continue;
     }
 
     nsAutoString optionVal;
     option->GetValue(optionVal);
     if (optionVal.Equals(aValue)) {
       SetSelectedIndexInternal(int32_t(i), true);
-      return NS_OK;
+      return;
     }
   }
   // No matching option was found.
   SetSelectedIndexInternal(-1, true);
-  return NS_OK;
 }
 
-
-NS_IMPL_BOOL_ATTR(HTMLSelectElement, Autofocus, autofocus)
-NS_IMPL_BOOL_ATTR(HTMLSelectElement, Disabled, disabled)
-NS_IMPL_BOOL_ATTR(HTMLSelectElement, Multiple, multiple)
-NS_IMPL_STRING_ATTR(HTMLSelectElement, Name, name)
-NS_IMPL_BOOL_ATTR(HTMLSelectElement, Required, required)
-NS_IMPL_UINT_ATTR(HTMLSelectElement, Size, size)
-
 int32_t
 HTMLSelectElement::TabIndexDefault()
 {
   return 0;
 }
 
 bool
 HTMLSelectElement::IsHTMLFocusable(bool aWithMouse,
@@ -1194,28 +1074,16 @@ HTMLSelectElement::IsHTMLFocusable(bool 
     return true;
   }
 
   *aIsFocusable = !IsDisabled();
 
   return false;
 }
 
-NS_IMETHODIMP
-HTMLSelectElement::Item(uint32_t aIndex, nsIDOMNode** aReturn)
-{
-  return mOptions->Item(aIndex, aReturn);
-}
-
-NS_IMETHODIMP
-HTMLSelectElement::NamedItem(const nsAString& aName, nsIDOMNode** aReturn)
-{
-  return mOptions->NamedItem(aName, aReturn);
-}
-
 bool
 HTMLSelectElement::CheckSelectSomething(bool aNotify)
 {
   if (mIsDoneAddingChildren) {
     if (mSelectedIndex < 0 && IsCombobox()) {
       return SelectSomething(aNotify);
     }
   }
@@ -1225,18 +1093,17 @@ HTMLSelectElement::CheckSelectSomething(
 bool
 HTMLSelectElement::SelectSomething(bool aNotify)
 {
   // If we're not done building the select, don't play with this yet.
   if (!mIsDoneAddingChildren) {
     return false;
   }
 
-  uint32_t count;
-  GetLength(&count);
+  uint32_t count = Length();
   for (uint32_t i = 0; i < count; i++) {
     bool disabled;
     nsresult rv = IsOptionDisabled(i, &disabled);
 
     if (NS_FAILED(rv) || !disabled) {
       rv = SetSelectedIndexInternal(i, aNotify);
       NS_ENSURE_SUCCESS(rv, false);
 
@@ -1581,17 +1448,18 @@ HTMLSelectElement::RestoreState(nsPresSt
     RestoreStateTo(state);
 
     // Don't flush, if the frame doesn't exist yet it doesn't care if
     // we're reset or not.
     DispatchContentReset();
   }
 
   if (aState->IsDisabledSet() && !aState->GetDisabled()) {
-    SetDisabled(false);
+    IgnoredErrorResult rv;
+    SetDisabled(false, rv);
   }
 
   return false;
 }
 
 void
 HTMLSelectElement::RestoreStateTo(SelectState* aNewSelected)
 {
--- a/dom/html/HTMLSelectElement.h
+++ b/dom/html/HTMLSelectElement.h
@@ -3,20 +3,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/. */
 #ifndef mozilla_dom_HTMLSelectElement_h
 #define mozilla_dom_HTMLSelectElement_h
 
 #include "mozilla/Attributes.h"
 #include "nsGenericHTMLElement.h"
-#include "nsIDOMHTMLSelectElement.h"
 #include "nsIConstraintValidation.h"
 
 #include "mozilla/dom/BindingDeclarations.h"
+#include "mozilla/dom/UnionTypes.h"
 #include "mozilla/dom/HTMLOptionsCollection.h"
 #include "mozilla/ErrorResult.h"
 #include "nsCheapSets.h"
 #include "nsCOMPtr.h"
 #include "nsError.h"
 #include "mozilla/dom/HTMLFormElement.h"
 #include "nsContentUtils.h"
 
@@ -115,17 +115,16 @@ private:
   nsMutationGuard            mGuard;
 };
 
 
 /**
  * Implementation of &lt;select&gt;
  */
 class HTMLSelectElement final : public nsGenericHTMLFormElementWithState,
-                                public nsIDOMHTMLSelectElement,
                                 public nsIConstraintValidation
 {
 public:
   /**
    *  IS_SELECTED   whether to set the option(s) to true or false
    *
    *  CLEAR_ALL     whether to clear all other options (for example, if you
    *                are normal-clicking on the current option)
@@ -159,19 +158,16 @@ public:
   virtual int32_t TabIndexDefault() override;
 
   // Element
   virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const override
   {
     return true;
   }
 
-  // nsIDOMHTMLSelectElement
-  NS_DECL_NSIDOMHTMLSELECTELEMENT
-
   // WebIdl HTMLSelectElement
   bool Autofocus() const
   {
     return GetBoolAttr(nsGkAtoms::autofocus);
   }
   void SetAutofocus(bool aVal, ErrorResult& aRv)
   {
     SetHTMLBoolAttr(nsGkAtoms::autofocus, aVal, aRv);
@@ -199,17 +195,21 @@ public:
   bool Multiple() const
   {
     return GetBoolAttr(nsGkAtoms::multiple);
   }
   void SetMultiple(bool aVal, ErrorResult& aRv)
   {
     SetHTMLBoolAttr(nsGkAtoms::multiple, aVal, aRv);
   }
-  // Uses XPCOM GetName.
+
+  void GetName(DOMString& aValue)
+  {
+    GetHTMLAttr(nsGkAtoms::name, aValue);
+  }
   void SetName(const nsAString& aName, ErrorResult& aRv)
   {
     SetHTMLAttr(nsGkAtoms::name, aName, aRv);
   }
   bool Required() const
   {
     return State().HasState(NS_EVENT_STATE_REQUIRED);
   }
@@ -221,17 +221,17 @@ public:
   {
     return GetUnsignedIntAttr(nsGkAtoms::size, 0);
   }
   void SetSize(uint32_t aSize, ErrorResult& aRv)
   {
     SetUnsignedIntAttr(nsGkAtoms::size, aSize, 0, aRv);
   }
 
-  // Uses XPCOM GetType.
+  void GetType(nsAString& aValue);
 
   HTMLOptionsCollection* Options() const
   {
     return mOptions;
   }
   uint32_t Length() const
   {
     return mOptions->Length();
@@ -247,17 +247,17 @@ public:
   }
   HTMLOptionElement* NamedItem(const nsAString& aName) const
   {
     return mOptions->GetNamedItem(aName);
   }
   void Add(const HTMLOptionElementOrHTMLOptGroupElement& aElement,
            const Nullable<HTMLElementOrLong>& aBefore,
            ErrorResult& aRv);
-  // Uses XPCOM Remove.
+  void Remove(int32_t aIndex);
   void IndexedSetter(uint32_t aIndex, HTMLOptionElement* aOption,
                      ErrorResult& aRv)
   {
     mOptions->IndexedSetter(aIndex, aOption, aRv);
   }
 
   static bool MatchSelectedOptions(Element* aElement, int32_t, nsAtom*,
                                    void*);
@@ -268,17 +268,17 @@ public:
   {
     return mSelectedIndex;
   }
   void SetSelectedIndex(int32_t aIdx, ErrorResult& aRv)
   {
     aRv = SetSelectedIndexInternal(aIdx, true);
   }
   void GetValue(DOMString& aValue);
-  // Uses XPCOM SetValue.
+  void SetValue(const nsAString& aValue);
 
   // Override SetCustomValidity so we update our state properly when it's called
   // via bindings.
   void SetCustomValidity(const nsAString& aError);
 
   using nsINode::Remove;
 
   // nsINode
--- a/dom/html/test/test_bug389797.html
+++ b/dom/html/test/test_bug389797.html
@@ -190,17 +190,17 @@ HTML_TAG("rb", "");
 HTML_TAG("rp", "");
 HTML_TAG("rt", "");
 HTML_TAG("rtc", "");
 HTML_TAG("ruby", "");
 HTML_TAG("s", "");
 HTML_TAG("samp", "");
 HTML_TAG("script", "Script", [ "nsIScriptLoaderObserver" ], []);
 HTML_TAG("section", "")
-HTML_TAG("select", "Select", ["nsIDOMHTMLSelectElement"]);
+HTML_TAG("select", "Select");
 HTML_TAG("small", "");
 HTML_TAG("span", "Span");
 HTML_TAG("strike", "");
 HTML_TAG("strong", "");
 HTML_TAG("style", "Style");
 HTML_TAG("sub", "");
 HTML_TAG("sup", "");
 HTML_TAG("table", "Table");
--- a/dom/interfaces/html/moz.build
+++ b/dom/interfaces/html/moz.build
@@ -12,19 +12,17 @@ XPIDL_SOURCES += [
     'nsIDOMHTMLCollection.idl',
     'nsIDOMHTMLDocument.idl',
     'nsIDOMHTMLElement.idl',
     'nsIDOMHTMLFormElement.idl',
     'nsIDOMHTMLHtmlElement.idl',
     'nsIDOMHTMLInputElement.idl',
     'nsIDOMHTMLMediaElement.idl',
     'nsIDOMHTMLOptionElement.idl',
-    'nsIDOMHTMLOptionsCollection.idl',
     'nsIDOMHTMLScriptElement.idl',
-    'nsIDOMHTMLSelectElement.idl',
     'nsIDOMMozBrowserFrame.idl',
     'nsIDOMTimeRanges.idl',
     'nsIDOMValidityState.idl',
     'nsIMozBrowserFrame.idl',
 ]
 
 XPIDL_MODULE = 'dom_html'
 
deleted file mode 100644
--- a/dom/interfaces/html/nsIDOMHTMLOptionsCollection.idl
+++ /dev/null
@@ -1,49 +0,0 @@
-/* -*- 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/. */
-
-#include "nsIDOMHTMLElement.idl"
-#include "nsIDOMHTMLCollection.idl"
-
-interface nsIDOMHTMLOptionElement;
-interface nsIDOMHTMLSelectElement;
-
-/**
- * The nsIDOMHTMLOptionsCollection interface is the interface to a
- * collection of [X]HTML option elements.
- *
- * This interface is trying to follow the DOM Level 2 HTML specification:
- * http://www.w3.org/TR/DOM-Level-2-HTML/
- *
- * with changes from the work-in-progress WHATWG HTML specification:
- * http://www.whatwg.org/specs/web-apps/current-work/
- */
-
-// Introduced in DOM Level 2:
-[uuid(4173cc53-30f6-4d12-a770-981ba53164e2)]
-interface nsIDOMHTMLOptionsCollection : nsISupports
-{
-           attribute unsigned long   length;
-                                        // raises(DOMException) on setting
-
-  // FIXME item should just be inherited from nsIDOMHTMLCollection
-  nsIDOMNode         item(in unsigned long index);
-
-  // FIXME namedItem (and getNamedItem) should return a NodeList if there are
-  //       multiple matching items
-  nsIDOMNode namedItem(in DOMString name);
-
-           attribute long             selectedIndex;
-
-  [noscript] readonly attribute nsIDOMHTMLSelectElement select;
-
-  // This add method implementation means the following
-  // since IDL doesn't support overloading.
-  //   void add(in nsIDOMHTMLOptionElement,
-  //            [optional] in nsIDOMHTMLOptionElement)
-  //   void add(in nsIDOMHTMLOptionElement, in long)
-  void                      add(in nsIDOMHTMLOptionElement option,
-                                [optional] in nsIVariant before);
-  void                      remove(in long index);
-};
deleted file mode 100644
--- a/dom/interfaces/html/nsIDOMHTMLSelectElement.idl
+++ /dev/null
@@ -1,52 +0,0 @@
-/* -*- 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/. */
-
-#include "nsIDOMHTMLElement.idl"
-#include "nsIDOMHTMLOptionsCollection.idl"
-
-/**
- * The nsIDOMHTMLSelectElement interface is the interface to a [X]HTML
- * select element.
- *
- * This interface is trying to follow the DOM Level 2 HTML specification:
- * http://www.w3.org/TR/DOM-Level-2-HTML/
- *
- * with changes from the work-in-progress WHATWG HTML specification:
- * http://www.whatwg.org/specs/web-apps/current-work/
- */
-
-interface nsIDOMValidityState;
-
-[uuid(d8914a2d-3556-4b66-911c-a84c4394e7fa)]
-interface nsIDOMHTMLSelectElement : nsISupports
-{
-           attribute boolean                     autofocus;
-           attribute boolean                     disabled;
-  readonly attribute nsIDOMHTMLFormElement       form;
-           attribute boolean                     multiple;
-           attribute DOMString                   name;
-           attribute unsigned long               size;
-
-  readonly attribute DOMString                   type;
-
-  readonly attribute nsIDOMHTMLOptionsCollection options;
-           attribute unsigned long               length;
-  nsIDOMNode                item(in unsigned long index);
-  nsIDOMNode                namedItem(in DOMString name);
-  // This add method implementation means the following
-  // since IDL doesn't support overfload.
-  //   void add(in nsIDOMHTMLElement, [optional] in nsIDOMHTMLElement)
-  //   void add(in nsIDOMHTMLElement, in long)
-  void                      add(in nsIDOMHTMLElement element, 
-                                [optional] in nsIVariant before)
-                                                     raises(DOMException);   
-  void                      remove(in long index);
-
-  readonly attribute nsIDOMHTMLCollection  selectedOptions;
-           attribute long                  selectedIndex;
-           attribute DOMString             value;
-
-  attribute boolean                      required;
-};
--- a/dom/webidl/HTMLOptionsCollection.webidl
+++ b/dom/webidl/HTMLOptionsCollection.webidl
@@ -6,19 +6,19 @@
  * The origin of this IDL file is
  * http://www.w3.org/TR/2012/WD-html5-20120329/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 interface HTMLOptionsCollection : HTMLCollection {
-  [CEReactions]
-           attribute unsigned long length;
+  [CEReactions, SetterThrows]
+  attribute unsigned long length;
   [CEReactions, Throws]
   setter void (unsigned long index, HTMLOptionElement? option);
   [CEReactions, Throws]
   void add((HTMLOptionElement or HTMLOptGroupElement) element, optional (HTMLElement or long)? before = null);
   [CEReactions, Throws]
   void remove(long index);
   [Throws]
-           attribute long selectedIndex;
+  attribute long selectedIndex;
 };
--- a/dom/webidl/HTMLSelectElement.webidl
+++ b/dom/webidl/HTMLSelectElement.webidl
@@ -5,53 +5,53 @@
  *
  * The origin of this IDL file is
  * http://www.whatwg.org/html/#the-select-element
  */
 
 [HTMLConstructor]
 interface HTMLSelectElement : HTMLElement {
   [CEReactions, SetterThrows, Pure]
-           attribute boolean autofocus;
+  attribute boolean autofocus;
   [CEReactions, Pref="dom.forms.autocomplete.formautofill", SetterThrows, Pure]
-           attribute DOMString autocomplete;
+  attribute DOMString autocomplete;
   [CEReactions, SetterThrows, Pure]
-           attribute boolean disabled;
+  attribute boolean disabled;
   [Pure]
   readonly attribute HTMLFormElement? form;
   [CEReactions, SetterThrows, Pure]
-           attribute boolean multiple;
+  attribute boolean multiple;
   [CEReactions, SetterThrows, Pure]
-           attribute DOMString name;
+  attribute DOMString name;
   [CEReactions, SetterThrows, Pure]
-           attribute boolean required;
+  attribute boolean required;
   [CEReactions, SetterThrows, Pure]
-           attribute unsigned long size;
+  attribute unsigned long size;
 
   [Pure]
   readonly attribute DOMString type;
 
   [Constant]
   readonly attribute HTMLOptionsCollection options;
   [CEReactions, SetterThrows, Pure]
-           attribute unsigned long length;
+  attribute unsigned long length;
   getter Element? item(unsigned long index);
   HTMLOptionElement? namedItem(DOMString name);
   [CEReactions, Throws]
   void add((HTMLOptionElement or HTMLOptGroupElement) element, optional (HTMLElement or long)? before = null);
   [CEReactions]
   void remove(long index);
   [CEReactions, Throws]
   setter void (unsigned long index, HTMLOptionElement? option);
 
   readonly attribute HTMLCollection selectedOptions;
   [SetterThrows, Pure]
-           attribute long selectedIndex;
+  attribute long selectedIndex;
   [Pure]
-           attribute DOMString value;
+  attribute DOMString value;
 
   readonly attribute boolean willValidate;
   readonly attribute ValidityState validity;
   [Throws]
   readonly attribute DOMString validationMessage;
   boolean checkValidity();
   boolean reportValidity();
   void setCustomValidity(DOMString error);
--- a/layout/forms/nsListControlFrame.cpp
+++ b/layout/forms/nsListControlFrame.cpp
@@ -5,17 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nscore.h"
 #include "nsCOMPtr.h"
 #include "nsUnicharUtils.h"
 #include "nsListControlFrame.h"
 #include "nsCheckboxRadioFrame.h" // for COMPARE macro
 #include "nsGkAtoms.h"
-#include "nsIDOMHTMLSelectElement.h"
 #include "nsIDOMHTMLOptionElement.h"
 #include "nsComboboxControlFrame.h"
 #include "nsIPresShell.h"
 #include "nsIDOMMouseEvent.h"
 #include "nsIXULRuntime.h"
 #include "nsFontMetrics.h"
 #include "nsIScrollableFrame.h"
 #include "nsCSSRendering.h"
@@ -1049,20 +1048,19 @@ nsListControlFrame::ResetList(bool aAllo
   }
 
   if (aAllowScrolling) {
     mPostChildrenLoadedReset = true;
 
     // Scroll to the selected index
     int32_t indexToSelect = kNothingSelected;
 
-    nsCOMPtr<nsIDOMHTMLSelectElement> selectElement(do_QueryInterface(mContent));
-    NS_ASSERTION(selectElement, "No select element!");
+    HTMLSelectElement* selectElement = HTMLSelectElement::FromContent(mContent);
     if (selectElement) {
-      selectElement->GetSelectedIndex(&indexToSelect);
+      indexToSelect = selectElement->SelectedIndex();
       AutoWeakFrame weakFrame(this);
       ScrollToIndex(indexToSelect);
       if (!weakFrame.IsAlive()) {
         return;
       }
     }
   }
 
--- a/security/manager/ssl/nsKeygenHandler.cpp
+++ b/security/manager/ssl/nsKeygenHandler.cpp
@@ -8,17 +8,17 @@
 
 #include "cryptohi.h"
 #include "keyhi.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/Base64.h"
 #include "mozilla/Casting.h"
 #include "nsDependentString.h"
 #include "nsIContent.h"
-#include "nsIDOMHTMLSelectElement.h"
+#include "nsIDOMHTMLElement.h"
 #include "nsIGenKeypairInfoDlg.h"
 #include "nsIServiceManager.h"
 #include "nsITokenDialogs.h"
 #include "nsKeygenHandlerContent.h"
 #include "nsKeygenThread.h"
 #include "nsNSSComponent.h" // for PIPNSS string bundle calls.
 #include "nsNSSHelper.h"
 #include "nsReadableUtils.h"
--- a/toolkit/modules/FormLikeFactory.jsm
+++ b/toolkit/modules/FormLikeFactory.jsm
@@ -58,17 +58,18 @@ let FormLikeFactory = {
    * Note that two FormLikes created from the same field won't return the same FormLike object.
    * Use the `rootElement` property on the FormLike as a key instead.
    *
    * @param {HTMLInputElement|HTMLSelectElement} aField - an <input> or <select> field in a document
    * @return {FormLike}
    * @throws Error if aField isn't a password or username field in a document
    */
   createFromField(aField) {
-    if ((!(aField instanceof Ci.nsIDOMHTMLInputElement) && !(aField instanceof Ci.nsIDOMHTMLSelectElement)) ||
+    if ((!(aField instanceof Ci.nsIDOMHTMLInputElement) &&
+         ChromeUtils.getClassName(aField) !== "HTMLSelectElement") ||
         !aField.ownerDocument) {
       throw new Error("createFromField requires a field in a document");
     }
 
     let rootElement = this.findRootForField(aField);
     if (rootElement instanceof Ci.nsIDOMHTMLFormElement) {
       return this.createFromForm(rootElement);
     }
--- a/xpcom/reflect/xptinfo/ShimInterfaceInfo.cpp
+++ b/xpcom/reflect/xptinfo/ShimInterfaceInfo.cpp
@@ -49,19 +49,17 @@
 #include "nsIDOMHTMLCollection.h"
 #include "nsIDOMHTMLDocument.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsIDOMHTMLFormElement.h"
 #include "nsIDOMHTMLHtmlElement.h"
 #include "nsIDOMHTMLInputElement.h"
 #include "nsIDOMHTMLMediaElement.h"
 #include "nsIDOMHTMLOptionElement.h"
-#include "nsIDOMHTMLOptionsCollection.h"
 #include "nsIDOMHTMLScriptElement.h"
-#include "nsIDOMHTMLSelectElement.h"
 #include "nsIDOMKeyEvent.h"
 #include "nsIDOMMediaList.h"
 #include "nsIDOMMouseEvent.h"
 #include "nsIDOMMouseScrollEvent.h"
 #include "nsIDOMMutationEvent.h"
 #include "nsIDOMMozNamedAttrMap.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMNodeIterator.h"
@@ -152,19 +150,17 @@
 #include "mozilla/dom/HTMLElementBinding.h"
 #include "mozilla/dom/HTMLFormElementBinding.h"
 #include "mozilla/dom/HTMLFrameSetElementBinding.h"
 #include "mozilla/dom/HTMLHtmlElementBinding.h"
 #include "mozilla/dom/HTMLInputElementBinding.h"
 #include "mozilla/dom/HTMLMediaElementBinding.h"
 #include "mozilla/dom/HTMLObjectElementBinding.h"
 #include "mozilla/dom/HTMLOptionElementBinding.h"
-#include "mozilla/dom/HTMLOptionsCollectionBinding.h"
 #include "mozilla/dom/HTMLScriptElementBinding.h"
-#include "mozilla/dom/HTMLSelectElementBinding.h"
 #include "mozilla/dom/KeyEventBinding.h"
 #include "mozilla/dom/ListBoxObjectBinding.h"
 #include "mozilla/dom/MediaListBinding.h"
 #include "mozilla/dom/MessageEventBinding.h"
 #include "mozilla/dom/MenuBoxObjectBinding.h"
 #include "mozilla/dom/MouseEventBinding.h"
 #include "mozilla/dom/MouseScrollEventBinding.h"
 #include "mozilla/dom/MutationEventBinding.h"
@@ -306,19 +302,17 @@ const ComponentsInterfaceShimEntry kComp
   DEFINE_SHIM(HTMLCollection),
   DEFINE_SHIM(HTMLDocument),
   DEFINE_SHIM(HTMLElement),
   DEFINE_SHIM(HTMLFormElement),
   DEFINE_SHIM(HTMLHtmlElement),
   DEFINE_SHIM(HTMLInputElement),
   DEFINE_SHIM(HTMLMediaElement),
   DEFINE_SHIM(HTMLOptionElement),
-  DEFINE_SHIM(HTMLOptionsCollection),
   DEFINE_SHIM(HTMLScriptElement),
-  DEFINE_SHIM(HTMLSelectElement),
   DEFINE_SHIM(KeyEvent),
   DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsIListBoxObject, ListBoxObject),
   DEFINE_SHIM(MediaList),
   DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsIMenuBoxObject, MenuBoxObject),
   DEFINE_SHIM(MouseEvent),
   DEFINE_SHIM(MouseScrollEvent),
   DEFINE_SHIM(MutationEvent),
   DEFINE_SHIM_WITH_CUSTOM_INTERFACE(nsIDOMMozNamedAttrMap, NamedNodeMap),