Bug 1842773 - Part 5: Add ArrayBuffer.prototype.{maxByteLength,resizable} getters...
[gecko.git] / dom / base / FragmentOrElement.h
blob81b2acf099e52514886a76d7cc502355772e63a0
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/. */
7 /*
8 * Base class for all element classes as well as nsDocumentFragment. This
9 * provides an implementation of nsINode, implements nsIContent, provides
10 * utility methods for subclasses, and so forth.
13 #ifndef FragmentOrElement_h___
14 #define FragmentOrElement_h___
16 #include "mozilla/Attributes.h"
17 #include "mozilla/EnumSet.h"
18 #include "mozilla/MemoryReporting.h"
19 #include "mozilla/UniquePtr.h"
20 #include "mozilla/dom/RadioGroupContainer.h"
21 #include "nsCycleCollectionParticipant.h" // NS_DECL_CYCLE_*
22 #include "nsIContent.h" // base class
23 #include "nsAtomHashKeys.h"
24 #include "nsIHTMLCollection.h"
25 #include "nsIWeakReferenceUtils.h"
27 class ContentUnbinder;
28 class nsContentList;
29 class nsLabelsNodeList;
30 class nsDOMAttributeMap;
31 class nsDOMTokenList;
32 class nsIControllers;
33 class nsICSSDeclaration;
34 class nsDOMCSSAttributeDeclaration;
35 class nsDOMStringMap;
36 class nsIURI;
38 namespace mozilla {
39 class DeclarationBlock;
40 enum class ContentRelevancyReason;
41 using ContentRelevancy = EnumSet<ContentRelevancyReason, uint8_t>;
42 class ElementAnimationData;
43 namespace dom {
44 struct CustomElementData;
45 class Element;
46 class PopoverData;
47 } // namespace dom
48 } // namespace mozilla
50 /**
51 * Tearoff to use for nodes to implement nsISupportsWeakReference
53 class nsNodeSupportsWeakRefTearoff final : public nsISupportsWeakReference {
54 public:
55 explicit nsNodeSupportsWeakRefTearoff(nsINode* aNode) : mNode(aNode) {}
57 // nsISupports
58 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
60 // nsISupportsWeakReference
61 NS_DECL_NSISUPPORTSWEAKREFERENCE
63 NS_DECL_CYCLE_COLLECTION_CLASS(nsNodeSupportsWeakRefTearoff)
65 private:
66 ~nsNodeSupportsWeakRefTearoff() = default;
68 nsCOMPtr<nsINode> mNode;
71 /**
72 * A generic base class for DOM elements and document fragments,
73 * implementing many nsIContent, nsINode and Element methods.
75 namespace mozilla::dom {
77 class ShadowRoot;
79 class FragmentOrElement : public nsIContent {
80 public:
81 explicit FragmentOrElement(
82 already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
83 explicit FragmentOrElement(
84 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
86 // We want to avoid the overhead of extra function calls for
87 // refcounting when we're not doing refcount logging, so we can't
88 // NS_DECL_ISUPPORTS_INHERITED.
89 NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override;
90 NS_INLINE_DECL_REFCOUNTING_INHERITED(FragmentOrElement, nsIContent);
92 NS_DECL_ADDSIZEOFEXCLUDINGTHIS
94 // nsINode interface methods
95 virtual void GetTextContentInternal(nsAString& aTextContent,
96 mozilla::OOMReporter& aError) override;
97 virtual void SetTextContentInternal(const nsAString& aTextContent,
98 nsIPrincipal* aSubjectPrincipal,
99 mozilla::ErrorResult& aError) override;
101 // nsIContent interface methods
102 const nsTextFragment* GetText() override;
103 uint32_t TextLength() const override;
104 bool TextIsOnlyWhitespace() override;
105 bool ThreadSafeTextIsOnlyWhitespace() const override;
107 void DestroyContent() override;
108 void SaveSubtreeState() override;
110 nsIHTMLCollection* Children();
111 uint32_t ChildElementCount() {
112 if (!HasChildren()) {
113 return 0;
115 return Children()->Length();
118 RadioGroupContainer& OwnedRadioGroupContainer() {
119 auto* slots = ExtendedDOMSlots();
120 if (!slots->mRadioGroupContainer) {
121 slots->mRadioGroupContainer = MakeUnique<RadioGroupContainer>();
123 return *slots->mRadioGroupContainer;
126 public:
128 * If there are listeners for DOMNodeInserted event, fires the event on all
129 * aNodes
131 static void FireNodeInserted(Document* aDoc, nsINode* aParent,
132 const nsTArray<nsCOMPtr<nsIContent>>& aNodes);
134 NS_DECL_CYCLE_COLLECTION_SKIPPABLE_WRAPPERCACHE_CLASS_INHERITED(
135 FragmentOrElement, nsIContent)
137 static void ClearContentUnbinder();
138 static bool CanSkip(nsINode* aNode, bool aRemovingAllowed);
139 static bool CanSkipInCC(nsINode* aNode);
140 static bool CanSkipThis(nsINode* aNode);
141 static void RemoveBlackMarkedNode(nsINode* aNode);
142 static void MarkNodeChildren(nsINode* aNode);
143 static void InitCCCallbacks();
146 * Is the HTML local name a void element?
148 static bool IsHTMLVoid(nsAtom* aLocalName);
150 protected:
151 virtual ~FragmentOrElement();
154 * Dummy CopyInnerTo so that we can use the same macros for
155 * Elements and DocumentFragments.
157 nsresult CopyInnerTo(FragmentOrElement* aDest) { return NS_OK; }
159 public:
161 * There are a set of DOM- and scripting-specific instance variables
162 * that may only be instantiated when a content object is accessed
163 * through the DOM. Rather than burn actual slots in the content
164 * objects for each of these instance variables, we put them off
165 * in a side structure that's only allocated when the content is
166 * accessed through the DOM.
169 class nsExtendedDOMSlots : public nsIContent::nsExtendedContentSlots {
170 public:
171 nsExtendedDOMSlots();
172 ~nsExtendedDOMSlots();
174 void TraverseExtendedSlots(nsCycleCollectionTraversalCallback&) final;
175 void UnlinkExtendedSlots(nsIContent&) final;
177 size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const final;
180 * SMIL Overridde style rules (for SMIL animation of CSS properties)
181 * @see Element::GetSMILOverrideStyle
183 RefPtr<nsDOMCSSAttributeDeclaration> mSMILOverrideStyle;
186 * Holds any SMIL override style declaration for this element.
188 RefPtr<DeclarationBlock> mSMILOverrideStyleDeclaration;
191 * The controllers of the XUL Element.
193 nsCOMPtr<nsIControllers> mControllers;
196 * An object implementing the .labels property for this element.
198 RefPtr<nsLabelsNodeList> mLabelsList;
201 * ShadowRoot bound to the element.
203 RefPtr<ShadowRoot> mShadowRoot;
206 * Web components custom element data.
208 UniquePtr<CustomElementData> mCustomElementData;
211 * Web animations data.
213 UniquePtr<ElementAnimationData> mAnimations;
216 * PopoverData for the element.
218 UniquePtr<PopoverData> mPopoverData;
221 * CustomStates for the element.
223 nsTArray<RefPtr<nsAtom>> mCustomStates;
226 * RadioGroupContainer for radio buttons grouped under this disconnected
227 * element.
229 UniquePtr<RadioGroupContainer> mRadioGroupContainer;
232 * Last remembered size (in CSS pixels) for the element.
233 * @see {@link https://drafts.csswg.org/css-sizing-4/#last-remembered}
235 Maybe<float> mLastRememberedBSize;
236 Maybe<float> mLastRememberedISize;
239 * Whether the content of this element is relevant for the purposes
240 * of `content-visibility: auto.
241 * Reflects 'relevant to the user' concept, see
242 * https://drafts.csswg.org/css-contain/#relevant-to-the-user.
244 Maybe<ContentRelevancy> mContentRelevancy;
247 * Whether the content of this element is considered visible for
248 * the purposes of `content-visibility: auto.
249 * Reflects 'proximity to the viewport' concept, see
250 * https://drafts.csswg.org/css-contain/#proximity-to-the-viewport.
252 Maybe<bool> mVisibleForContentVisibility;
255 * Whether content-visibility: auto is temporarily visible for
256 * the purposes of the descendant of scrollIntoView.
258 bool mTemporarilyVisibleForScrolledIntoViewDescendant = false;
261 * Explicitly set attr-elements, see
262 * https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#explicitly-set-attr-element
264 nsTHashMap<RefPtr<nsAtom>, nsWeakPtr> mExplicitlySetAttrElements;
267 class nsDOMSlots : public nsIContent::nsContentSlots {
268 public:
269 nsDOMSlots();
270 ~nsDOMSlots();
272 void Traverse(nsCycleCollectionTraversalCallback&) final;
273 void Unlink(nsINode&) final;
275 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
278 * The .style attribute (an interface that forwards to the actual
279 * style rules)
280 * @see nsGenericHTMLElement::GetStyle
282 nsCOMPtr<nsICSSDeclaration> mStyle;
285 * The .dataset attribute.
286 * @see nsGenericHTMLElement::GetDataset
288 nsDOMStringMap* mDataset; // [Weak]
291 * @see Element::Attributes
293 RefPtr<nsDOMAttributeMap> mAttributeMap;
296 * An object implementing the .children property for this element.
298 RefPtr<nsContentList> mChildrenList;
301 * An object implementing the .classList property for this element.
303 RefPtr<nsDOMTokenList> mClassList;
306 * An object implementing the .part property for this element.
308 RefPtr<nsDOMTokenList> mPart;
312 * In case ExtendedDOMSlots is needed before normal DOMSlots, an instance of
313 * FatSlots class, which combines those two slot types, is created.
314 * This way we can avoid extra allocation for ExtendedDOMSlots.
315 * FatSlots is useful for example when creating Custom Elements.
317 class FatSlots final : public nsDOMSlots, public nsExtendedDOMSlots {
318 public:
319 FatSlots() : nsDOMSlots(), nsExtendedDOMSlots() {
320 MOZ_COUNT_CTOR(FatSlots);
321 SetExtendedContentSlots(this, false);
324 ~FatSlots() final { MOZ_COUNT_DTOR(FatSlots); }
327 protected:
328 void GetMarkup(bool aIncludeSelf, nsAString& aMarkup);
329 void SetInnerHTMLInternal(const nsAString& aInnerHTML, ErrorResult& aError);
331 // Override from nsINode
332 nsIContent::nsContentSlots* CreateSlots() override {
333 return new nsDOMSlots();
336 nsIContent::nsExtendedContentSlots* CreateExtendedSlots() final {
337 return new nsExtendedDOMSlots();
340 nsDOMSlots* DOMSlots() { return static_cast<nsDOMSlots*>(Slots()); }
342 nsDOMSlots* GetExistingDOMSlots() const {
343 return static_cast<nsDOMSlots*>(GetExistingSlots());
346 nsExtendedDOMSlots* ExtendedDOMSlots() {
347 nsContentSlots* slots = GetExistingContentSlots();
348 if (!slots) {
349 FatSlots* fatSlots = new FatSlots();
350 mSlots = fatSlots;
351 return fatSlots;
354 if (!slots->GetExtendedContentSlots()) {
355 slots->SetExtendedContentSlots(CreateExtendedSlots(), true);
358 return static_cast<nsExtendedDOMSlots*>(slots->GetExtendedContentSlots());
361 const nsExtendedDOMSlots* GetExistingExtendedDOMSlots() const {
362 return static_cast<const nsExtendedDOMSlots*>(
363 GetExistingExtendedContentSlots());
366 nsExtendedDOMSlots* GetExistingExtendedDOMSlots() {
367 return static_cast<nsExtendedDOMSlots*>(GetExistingExtendedContentSlots());
370 friend class ::ContentUnbinder;
373 } // namespace mozilla::dom
375 #define NS_ELEMENT_INTERFACE_TABLE_TO_MAP_SEGUE \
376 if (NS_SUCCEEDED(rv)) return rv; \
378 rv = FragmentOrElement::QueryInterface(aIID, aInstancePtr); \
379 NS_INTERFACE_TABLE_TO_MAP_SEGUE
381 #endif /* FragmentOrElement_h___ */