Bug 1408186 - Remove nsIDOMHTMLSelectElement and nsIDOMHTMLOptionsCollection; r=bz
authorKyle Machulis <kyle@nonpolynomial.com>
Thu, 12 Oct 2017 16:32:25 -0700
changeset 695376 68970144c5df771ce74c5bc3185bc6d32bc672fa
parent 695375 dfd49bfe648886bfbf0ae0deb1891a0dc8da0ded
child 695377 b12daff50304db61d4250754c58b7250778b141c
push id88406
push userbmo:mh+mozilla@glandium.org
push dateThu, 09 Nov 2017 05:17:33 +0000
reviewersbz
bugs1408186
milestone58.0a1
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),