1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 #ifndef mozilla_dom_HTMLOptionsCollection_h 7 #define mozilla_dom_HTMLOptionsCollection_h 8 9 #include "mozilla/Attributes.h" 10 #include "nsIHTMLCollection.h" 11 #include "nsWrapperCache.h" 12 13 #include "mozilla/dom/HTMLOptionElement.h" 14 #include "mozilla/ErrorResult.h" 15 #include "nsCOMPtr.h" 16 #include "nsError.h" 17 #include "nsGenericHTMLElement.h" 18 #include "nsTArray.h" 19 20 namespace mozilla { 21 namespace dom { 22 23 class DocGroup; 24 class HTMLElementOrLong; 25 class HTMLOptionElementOrHTMLOptGroupElement; 26 class HTMLSelectElement; 27 28 /** 29 * The collection of options in the select (what you get back when you do 30 * select.options in DOM) 31 */ 32 class HTMLOptionsCollection final : public nsIHTMLCollection, 33 public nsWrapperCache { 34 typedef HTMLOptionElementOrHTMLOptGroupElement HTMLOptionOrOptGroupElement; 35 36 public: 37 explicit HTMLOptionsCollection(HTMLSelectElement* aSelect); 38 39 NS_DECL_CYCLE_COLLECTING_ISUPPORTS 40 41 // nsWrapperCache 42 using nsWrapperCache::GetWrapper; 43 using nsWrapperCache::GetWrapperPreserveColor; 44 using nsWrapperCache::PreserveWrapper; 45 virtual JSObject* WrapObject(JSContext* aCx, 46 JS::Handle<JSObject*> aGivenProto) override; 47 48 protected: 49 virtual ~HTMLOptionsCollection() = default; 50 GetWrapperPreserveColorInternal()51 virtual JSObject* GetWrapperPreserveColorInternal() override { 52 return nsWrapperCache::GetWrapperPreserveColor(); 53 } PreserveWrapperInternal(nsISupports * aScriptObjectHolder)54 virtual void PreserveWrapperInternal( 55 nsISupports* aScriptObjectHolder) override { 56 nsWrapperCache::PreserveWrapper(aScriptObjectHolder); 57 } 58 59 public: 60 virtual uint32_t Length() override; 61 virtual Element* GetElementAt(uint32_t aIndex) override; 62 virtual nsINode* GetParentObject() override; 63 DocGroup* GetDocGroup() const; 64 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(HTMLOptionsCollection,nsIHTMLCollection)65 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(HTMLOptionsCollection, 66 nsIHTMLCollection) 67 68 // Helpers for HTMLSelectElement 69 /** 70 * Insert an option 71 * @param aOption the option to insert 72 * @param aIndex the index to insert at 73 */ 74 void InsertOptionAt(mozilla::dom::HTMLOptionElement* aOption, 75 uint32_t aIndex) { 76 mElements.InsertElementAt(aIndex, aOption); 77 } 78 79 /** 80 * Remove an option 81 * @param aIndex the index of the option to remove 82 */ RemoveOptionAt(uint32_t aIndex)83 void RemoveOptionAt(uint32_t aIndex) { mElements.RemoveElementAt(aIndex); } 84 85 /** 86 * Get the option at the index 87 * @param aIndex the index 88 * @param aReturn the option returned [OUT] 89 */ ItemAsOption(uint32_t aIndex)90 mozilla::dom::HTMLOptionElement* ItemAsOption(uint32_t aIndex) { 91 return mElements.SafeElementAt(aIndex, nullptr); 92 } 93 94 /** 95 * Clears out all options 96 */ Clear()97 void Clear() { mElements.Clear(); } 98 99 /** 100 * Append an option to end of array 101 */ AppendOption(mozilla::dom::HTMLOptionElement * aOption)102 void AppendOption(mozilla::dom::HTMLOptionElement* aOption) { 103 mElements.AppendElement(aOption); 104 } 105 106 /** 107 * Finds the index of a given option element. 108 * If the option isn't part of the collection, return NS_ERROR_FAILURE 109 * without setting aIndex. 110 * 111 * @param aOption the option to get the index of 112 * @param aStartIndex the index to start looking at 113 * @param aForward TRUE to look forward, FALSE to look backward 114 * @return the option index 115 */ 116 nsresult GetOptionIndex(Element* aOption, int32_t aStartIndex, bool aForward, 117 int32_t* aIndex); 118 GetNamedItem(const nsAString & aName)119 HTMLOptionElement* GetNamedItem(const nsAString& aName) { 120 bool dummy; 121 return NamedGetter(aName, dummy); 122 } 123 HTMLOptionElement* NamedGetter(const nsAString& aName, bool& aFound); GetFirstNamedElement(const nsAString & aName,bool & aFound)124 virtual Element* GetFirstNamedElement(const nsAString& aName, 125 bool& aFound) override { 126 return NamedGetter(aName, aFound); 127 } 128 void Add(const HTMLOptionOrOptGroupElement& aElement, 129 const Nullable<HTMLElementOrLong>& aBefore, ErrorResult& aError); 130 void Remove(int32_t aIndex, ErrorResult& aError); 131 int32_t GetSelectedIndex(ErrorResult& aError); 132 void SetSelectedIndex(int32_t aSelectedIndex, ErrorResult& aError); 133 void IndexedSetter(uint32_t aIndex, HTMLOptionElement* aOption, 134 ErrorResult& aError); 135 virtual void GetSupportedNames(nsTArray<nsString>& aNames) override; 136 void SetLength(uint32_t aLength, ErrorResult& aError); 137 138 private: 139 /** The list of options (holds strong references). This is infallible, so 140 * various members such as InsertOptionAt are also infallible. */ 141 nsTArray<RefPtr<mozilla::dom::HTMLOptionElement> > mElements; 142 /** The select element that contains this array */ 143 RefPtr<HTMLSelectElement> mSelect; 144 }; 145 146 } // namespace dom 147 } // namespace mozilla 148 149 #endif // mozilla_dom_HTMLOptionsCollection_h 150