Backed out changeset 9d8b4c0b99ed (bug 1945683) for causing btime failures. CLOSED...
[gecko.git] / dom / base / FragmentOrElement.h
blobafa155d3a96d6fc2edbe8db7539bca8eff6476fc
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 DOMIntersectionObserver;
78 class ShadowRoot;
80 class FragmentOrElement : public nsIContent {
81 public:
82 explicit FragmentOrElement(
83 already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
84 explicit FragmentOrElement(
85 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
87 // We want to avoid the overhead of extra function calls for
88 // refcounting when we're not doing refcount logging, so we can't
89 // NS_DECL_ISUPPORTS_INHERITED.
90 NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override;
91 NS_INLINE_DECL_REFCOUNTING_INHERITED(FragmentOrElement, nsIContent);
93 NS_DECL_ADDSIZEOFEXCLUDINGTHIS
95 // nsINode interface methods
96 virtual void GetTextContentInternal(nsAString& aTextContent,
97 mozilla::OOMReporter& aError) override;
98 virtual void SetTextContentInternal(const nsAString& aTextContent,
99 nsIPrincipal* aSubjectPrincipal,
100 mozilla::ErrorResult& aError) override;
102 // nsIContent interface methods
103 const nsTextFragment* GetText() override;
104 uint32_t TextLength() const override;
105 bool TextIsOnlyWhitespace() override;
106 bool ThreadSafeTextIsOnlyWhitespace() const override;
108 void DestroyContent() override;
109 void SaveSubtreeState() override;
111 nsIHTMLCollection* Children();
112 uint32_t ChildElementCount() {
113 if (!HasChildren()) {
114 return 0;
116 return Children()->Length();
119 RadioGroupContainer& OwnedRadioGroupContainer() {
120 auto* slots = ExtendedDOMSlots();
121 if (!slots->mRadioGroupContainer) {
122 slots->mRadioGroupContainer = MakeUnique<RadioGroupContainer>();
124 return *slots->mRadioGroupContainer;
127 public:
129 * If there are listeners for DOMNodeInserted event, fires the event on all
130 * aNodes
132 static void FireNodeInserted(Document* aDoc, nsINode* aParent,
133 const nsTArray<nsCOMPtr<nsIContent>>& aNodes);
135 NS_DECL_CYCLE_COLLECTION_SKIPPABLE_WRAPPERCACHE_CLASS_INHERITED(
136 FragmentOrElement, nsIContent)
138 static void ClearContentUnbinder();
139 static bool CanSkip(nsINode* aNode, bool aRemovingAllowed);
140 static bool CanSkipInCC(nsINode* aNode);
141 static bool CanSkipThis(nsINode* aNode);
142 static void RemoveBlackMarkedNode(nsINode* aNode);
143 static void MarkNodeChildren(nsINode* aNode);
144 static void InitCCCallbacks();
147 * Is the HTML local name a void element?
149 static bool IsHTMLVoid(nsAtom* aLocalName);
151 protected:
152 virtual ~FragmentOrElement();
155 * Dummy CopyInnerTo so that we can use the same macros for
156 * Elements and DocumentFragments.
158 nsresult CopyInnerTo(FragmentOrElement* aDest) { return NS_OK; }
160 public:
162 * There are a set of DOM- and scripting-specific instance variables
163 * that may only be instantiated when a content object is accessed
164 * through the DOM. Rather than burn actual slots in the content
165 * objects for each of these instance variables, we put them off
166 * in a side structure that's only allocated when the content is
167 * accessed through the DOM.
170 class nsExtendedDOMSlots : public nsIContent::nsExtendedContentSlots {
171 public:
172 nsExtendedDOMSlots();
173 ~nsExtendedDOMSlots();
175 void TraverseExtendedSlots(nsCycleCollectionTraversalCallback&) final;
176 void UnlinkExtendedSlots(nsIContent&) final;
178 size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const final;
181 * SMIL Overridde style rules (for SMIL animation of CSS properties)
182 * @see Element::GetSMILOverrideStyle
184 RefPtr<nsDOMCSSAttributeDeclaration> mSMILOverrideStyle;
187 * Holds any SMIL override style declaration for this element.
189 RefPtr<DeclarationBlock> mSMILOverrideStyleDeclaration;
192 * The controllers of the XUL Element.
194 nsCOMPtr<nsIControllers> mControllers;
197 * An object implementing the .labels property for this element.
199 RefPtr<nsLabelsNodeList> mLabelsList;
202 * ShadowRoot bound to the element.
204 RefPtr<ShadowRoot> mShadowRoot;
207 * Web components custom element data.
209 UniquePtr<CustomElementData> mCustomElementData;
212 * Web animations data.
214 UniquePtr<ElementAnimationData> mAnimations;
217 * PopoverData for the element.
219 UniquePtr<PopoverData> mPopoverData;
222 * CustomStates for the element.
224 nsTArray<RefPtr<nsAtom>> mCustomStates;
227 * RadioGroupContainer for radio buttons grouped under this disconnected
228 * element.
230 UniquePtr<RadioGroupContainer> mRadioGroupContainer;
233 * Last remembered size (in CSS pixels) for the element.
234 * @see {@link https://drafts.csswg.org/css-sizing-4/#last-remembered}
236 Maybe<float> mLastRememberedBSize;
237 Maybe<float> mLastRememberedISize;
240 * Whether the content of this element is relevant for the purposes
241 * of `content-visibility: auto.
242 * Reflects 'relevant to the user' concept, see
243 * https://drafts.csswg.org/css-contain/#relevant-to-the-user.
245 Maybe<ContentRelevancy> mContentRelevancy;
248 * Whether the content of this element is considered visible for
249 * the purposes of `content-visibility: auto.
250 * Reflects 'proximity to the viewport' concept, see
251 * https://drafts.csswg.org/css-contain/#proximity-to-the-viewport.
253 Maybe<bool> mVisibleForContentVisibility;
256 * Whether content-visibility: auto is temporarily visible for
257 * the purposes of the descendant of scrollIntoView.
259 bool mTemporarilyVisibleForScrolledIntoViewDescendant = false;
262 * The .dataset attribute.
263 * @see nsGenericHTMLElement::GetDataset
265 nsDOMStringMap* MOZ_UNSAFE_REF("ClearDataSet clears it") mDataset = nullptr;
267 /** An object implementing the .part property for this element. */
268 RefPtr<nsDOMTokenList> mPart;
271 * Explicitly set attr-element, see
272 * https://html.spec.whatwg.org/#explicitly-set-attr-element
274 nsTHashMap<RefPtr<nsAtom>, nsWeakPtr> mExplicitlySetAttrElementMap;
276 * Explicitly set attr-elements, see
277 * https://html.spec.whatwg.org/#explicitly-set-attr-elements
279 * The first member of the pair are the explicitly set attr-elements. The
280 * second member is the cached attr-associated elements.
283 nsTHashMap<RefPtr<nsAtom>, std::pair<Maybe<nsTArray<nsWeakPtr>>,
284 Maybe<nsTArray<RefPtr<Element>>>>>
285 mAttrElementsMap;
288 class nsDOMSlots : public nsIContent::nsContentSlots {
289 public:
290 nsDOMSlots();
291 ~nsDOMSlots();
293 void Traverse(nsCycleCollectionTraversalCallback&) final;
294 void Unlink(nsINode&) final;
296 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
299 * The .style attribute (an interface that forwards to the actual
300 * style rules)
301 * @see nsGenericHTMLElement::GetStyle
303 nsCOMPtr<nsICSSDeclaration> mStyle;
306 * @see Element::Attributes
308 RefPtr<nsDOMAttributeMap> mAttributeMap;
311 * An object implementing the .children property for this element.
313 RefPtr<nsContentList> mChildrenList;
316 * An object implementing the .classList property for this element.
318 RefPtr<nsDOMTokenList> mClassList;
322 * In case ExtendedDOMSlots is needed before normal DOMSlots, an instance of
323 * FatSlots class, which combines those two slot types, is created.
324 * This way we can avoid extra allocation for ExtendedDOMSlots.
325 * FatSlots is useful for example when creating Custom Elements.
327 class FatSlots final : public nsDOMSlots, public nsExtendedDOMSlots {
328 public:
329 FatSlots() : nsDOMSlots(), nsExtendedDOMSlots() {
330 MOZ_COUNT_CTOR(FatSlots);
331 SetExtendedContentSlots(this, false);
334 ~FatSlots() final { MOZ_COUNT_DTOR(FatSlots); }
337 protected:
338 void GetMarkup(bool aIncludeSelf, nsAString& aMarkup);
339 void SetInnerHTMLInternal(const nsAString& aInnerHTML, ErrorResult& aError);
341 // Override from nsINode
342 nsIContent::nsContentSlots* CreateSlots() override {
343 return new nsDOMSlots();
346 nsIContent::nsExtendedContentSlots* CreateExtendedSlots() final {
347 return new nsExtendedDOMSlots();
350 nsDOMSlots* DOMSlots() { return static_cast<nsDOMSlots*>(Slots()); }
352 nsDOMSlots* GetExistingDOMSlots() const {
353 return static_cast<nsDOMSlots*>(GetExistingSlots());
356 nsExtendedDOMSlots* ExtendedDOMSlots() {
357 nsContentSlots* slots = GetExistingContentSlots();
358 if (!slots) {
359 FatSlots* fatSlots = new FatSlots();
360 mSlots = fatSlots;
361 return fatSlots;
364 if (!slots->GetExtendedContentSlots()) {
365 slots->SetExtendedContentSlots(CreateExtendedSlots(), true);
368 return static_cast<nsExtendedDOMSlots*>(slots->GetExtendedContentSlots());
371 const nsExtendedDOMSlots* GetExistingExtendedDOMSlots() const {
372 return static_cast<const nsExtendedDOMSlots*>(
373 GetExistingExtendedContentSlots());
376 nsExtendedDOMSlots* GetExistingExtendedDOMSlots() {
377 return static_cast<nsExtendedDOMSlots*>(GetExistingExtendedContentSlots());
380 friend class ::ContentUnbinder;
383 } // namespace mozilla::dom
385 #define NS_ELEMENT_INTERFACE_TABLE_TO_MAP_SEGUE \
386 if (NS_SUCCEEDED(rv)) return rv; \
388 rv = FragmentOrElement::QueryInterface(aIID, aInstancePtr); \
389 NS_INTERFACE_TABLE_TO_MAP_SEGUE
391 #endif /* FragmentOrElement_h___ */