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 7 #ifndef mozilla_dom_HTMLFormControlsCollection_h 8 #define mozilla_dom_HTMLFormControlsCollection_h 9 10 #include "nsIHTMLCollection.h" 11 #include "nsInterfaceHashtable.h" 12 #include "nsTArray.h" 13 #include "nsWrapperCache.h" 14 15 class nsGenericHTMLFormElement; 16 class nsIContent; 17 class nsIFormControl; 18 template <class T> 19 class RefPtr; 20 21 namespace mozilla::dom { 22 class Element; 23 class HTMLFormElement; 24 class HTMLImageElement; 25 class OwningRadioNodeListOrElement; 26 template <typename> 27 struct Nullable; 28 29 class HTMLFormControlsCollection final : public nsIHTMLCollection, 30 public nsWrapperCache { 31 public: 32 explicit HTMLFormControlsCollection(HTMLFormElement* aForm); 33 34 void DropFormReference(); 35 36 NS_DECL_CYCLE_COLLECTING_ISUPPORTS 37 38 virtual uint32_t Length() override; 39 virtual Element* GetElementAt(uint32_t index) override; 40 virtual nsINode* GetParentObject() override; 41 42 virtual Element* GetFirstNamedElement(const nsAString& aName, 43 bool& aFound) override; 44 45 void NamedGetter(const nsAString& aName, bool& aFound, 46 Nullable<OwningRadioNodeListOrElement>& aResult); NamedItem(const nsAString & aName,Nullable<OwningRadioNodeListOrElement> & aResult)47 void NamedItem(const nsAString& aName, 48 Nullable<OwningRadioNodeListOrElement>& aResult) { 49 bool dummy; 50 NamedGetter(aName, dummy, aResult); 51 } 52 virtual void GetSupportedNames(nsTArray<nsString>& aNames) override; 53 54 nsresult AddElementToTable(nsGenericHTMLFormElement* aChild, 55 const nsAString& aName); 56 nsresult AddImageElementToTable(HTMLImageElement* aChild, 57 const nsAString& aName); 58 nsresult RemoveElementFromTable(nsGenericHTMLFormElement* aChild, 59 const nsAString& aName); 60 nsresult IndexOfContent(nsIContent* aContent, int32_t* aIndex); 61 62 nsISupports* NamedItemInternal(const nsAString& aName); 63 64 /** 65 * Create a sorted list of form control elements. This list is sorted 66 * in document order and contains the controls in the mElements and 67 * mNotInElements list. This function does not add references to the 68 * elements. 69 * 70 * @param aControls The list of sorted controls[out]. 71 * @return NS_OK or NS_ERROR_OUT_OF_MEMORY. 72 */ 73 nsresult GetSortedControls( 74 nsTArray<RefPtr<nsGenericHTMLFormElement>>& aControls) const; 75 76 // nsWrapperCache 77 using nsWrapperCache::GetWrapperPreserveColor; 78 using nsWrapperCache::PreserveWrapper; 79 virtual JSObject* WrapObject(JSContext* aCx, 80 JS::Handle<JSObject*> aGivenProto) override; 81 82 protected: 83 virtual ~HTMLFormControlsCollection(); GetWrapperPreserveColorInternal()84 virtual JSObject* GetWrapperPreserveColorInternal() override { 85 return nsWrapperCache::GetWrapperPreserveColor(); 86 } PreserveWrapperInternal(nsISupports * aScriptObjectHolder)87 virtual void PreserveWrapperInternal( 88 nsISupports* aScriptObjectHolder) override { 89 nsWrapperCache::PreserveWrapper(aScriptObjectHolder); 90 } 91 92 public: 93 static bool ShouldBeInElements(nsIFormControl* aFormControl); 94 95 HTMLFormElement* mForm; // WEAK - the form owns me 96 97 nsTArray<nsGenericHTMLFormElement*> 98 mElements; // Holds WEAK references - bug 36639 99 100 // This array holds on to all form controls that are not contained 101 // in mElements (form.elements in JS, see ShouldBeInFormControl()). 102 // This is needed to properly clean up the bi-directional references 103 // (both weak and strong) between the form and its form controls. 104 105 nsTArray<nsGenericHTMLFormElement*> mNotInElements; // Holds WEAK references 106 107 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(HTMLFormControlsCollection) 108 109 protected: 110 // Drop all our references to the form elements 111 void Clear(); 112 113 // A map from an ID or NAME attribute to the form control(s), this 114 // hash holds strong references either to the named form control, or 115 // to a list of named form controls, in the case where this hash 116 // holds on to a list of named form controls the list has weak 117 // references to the form control. 118 119 nsInterfaceHashtable<nsStringHashKey, nsISupports> mNameLookupTable; 120 }; 121 122 } // namespace mozilla::dom 123 124 #endif // mozilla_dom_HTMLFormControlsCollection_h 125