Bug 1550519 - Show a translucent parent highlight when a subgrid is highlighted....
[gecko.git] / dom / base / Element.h
blobc87a0a54b0d05c0fcef0d2758230af7c2941711b
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; this provides an implementation
9 * of DOM Core's Element, implements nsIContent, provides
10 * utility methods for subclasses, and so forth.
13 #ifndef mozilla_dom_Element_h__
14 #define mozilla_dom_Element_h__
16 #include "AttrArray.h"
17 #include "DOMIntersectionObserver.h"
18 #include "nsAttrValue.h"
19 #include "nsAttrValueInlines.h"
20 #include "nsChangeHint.h"
21 #include "nsContentUtils.h"
22 #include "nsDOMAttributeMap.h"
23 #include "nsILinkHandler.h"
24 #include "nsINodeList.h"
25 #include "nsIScrollableFrame.h"
26 #include "nsNodeUtils.h"
27 #include "nsPresContext.h"
28 #include "Units.h"
29 #include "mozilla/Attributes.h"
30 #include "mozilla/CORSMode.h"
31 #include "mozilla/EventForwards.h"
32 #include "mozilla/EventStates.h"
33 #include "mozilla/FlushType.h"
34 #include "mozilla/PresShell.h"
35 #include "mozilla/PseudoStyleType.h"
36 #include "mozilla/RustCell.h"
37 #include "mozilla/SMILAttr.h"
38 #include "mozilla/UniquePtr.h"
39 #include "mozilla/dom/Attr.h"
40 #include "mozilla/dom/BindingDeclarations.h"
41 #include "mozilla/dom/DirectionalityUtils.h"
42 #include "mozilla/dom/FragmentOrElement.h"
43 #include "mozilla/dom/DOMRect.h"
44 #include "mozilla/dom/DOMTokenListSupportedTokens.h"
45 #include "mozilla/dom/ElementBinding.h"
46 #include "mozilla/dom/Nullable.h"
47 #include "mozilla/dom/PointerEventHandler.h"
48 #include "mozilla/dom/WindowBinding.h"
50 class mozAutoDocUpdate;
51 class nsIFrame;
52 class nsIMozBrowserFrame;
53 class nsIURI;
54 class nsIScrollableFrame;
55 class nsAttrValueOrString;
56 class nsContentList;
57 class nsDOMTokenList;
58 struct nsRect;
59 class nsFocusManager;
60 class nsGlobalWindowInner;
61 class nsGlobalWindowOuter;
62 class nsDOMCSSAttributeDeclaration;
63 class nsDOMStringMap;
64 struct ServoNodeData;
66 class nsIDOMXULButtonElement;
67 class nsIDOMXULContainerElement;
68 class nsIDOMXULContainerItemElement;
69 class nsIDOMXULControlElement;
70 class nsIDOMXULMenuListElement;
71 class nsIDOMXULMultiSelectControlElement;
72 class nsIDOMXULRadioGroupElement;
73 class nsIDOMXULRelatedElement;
74 class nsIDOMXULSelectControlElement;
75 class nsIDOMXULSelectControlItemElement;
76 class nsIBrowser;
77 class nsIAutoCompletePopup;
79 namespace mozilla {
80 class DeclarationBlock;
81 struct MutationClosureData;
82 class TextEditor;
83 namespace css {
84 struct URLValue;
85 } // namespace css
86 namespace dom {
87 struct GetAnimationsOptions;
88 struct ScrollIntoViewOptions;
89 struct ScrollToOptions;
90 class DOMIntersectionObserver;
91 class DOMMatrixReadOnly;
92 class Element;
93 class ElementOrCSSPseudoElement;
94 class UnrestrictedDoubleOrKeyframeAnimationOptions;
95 enum class CallerType : uint32_t;
96 typedef nsDataHashtable<nsRefPtrHashKey<DOMIntersectionObserver>, int32_t>
97 IntersectionObserverList;
98 } // namespace dom
99 } // namespace mozilla
101 // Declared here because of include hell.
102 extern "C" bool Servo_Element_IsDisplayContents(const mozilla::dom::Element*);
104 already_AddRefed<nsContentList> NS_GetContentList(nsINode* aRootNode,
105 int32_t aMatchNameSpaceId,
106 const nsAString& aTagname);
108 #define ELEMENT_FLAG_BIT(n_) \
109 NODE_FLAG_BIT(NODE_TYPE_SPECIFIC_BITS_OFFSET + (n_))
111 // Element-specific flags
112 enum {
113 // Whether this node has dirty descendants for Servo's style system.
114 ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO = ELEMENT_FLAG_BIT(0),
115 // Whether this node has dirty descendants for animation-only restyle for
116 // Servo's style system.
117 ELEMENT_HAS_ANIMATION_ONLY_DIRTY_DESCENDANTS_FOR_SERVO = ELEMENT_FLAG_BIT(1),
119 // Whether the element has been snapshotted due to attribute or state changes
120 // by the Servo restyle manager.
121 ELEMENT_HAS_SNAPSHOT = ELEMENT_FLAG_BIT(2),
123 // Whether the element has already handled its relevant snapshot.
125 // Used by the servo restyle process in order to accurately track whether the
126 // style of an element is up-to-date, even during the same restyle process.
127 ELEMENT_HANDLED_SNAPSHOT = ELEMENT_FLAG_BIT(3),
129 // Remaining bits are for subclasses
130 ELEMENT_TYPE_SPECIFIC_BITS_OFFSET = NODE_TYPE_SPECIFIC_BITS_OFFSET + 4
133 #undef ELEMENT_FLAG_BIT
135 // Make sure we have space for our bits
136 ASSERT_NODE_FLAGS_SPACE(ELEMENT_TYPE_SPECIFIC_BITS_OFFSET);
138 namespace mozilla {
139 enum class PseudoStyleType : uint8_t;
140 class EventChainPostVisitor;
141 class EventChainPreVisitor;
142 class EventChainVisitor;
143 class EventListenerManager;
144 class EventStateManager;
146 namespace dom {
148 struct CustomElementDefinition;
149 class Animation;
150 class CustomElementRegistry;
151 class Link;
152 class DOMRect;
153 class DOMRectList;
154 class Flex;
155 class Grid;
157 // IID for the dom::Element interface
158 #define NS_ELEMENT_IID \
160 0xc67ed254, 0xfd3b, 0x4b10, { \
161 0x96, 0xa2, 0xc5, 0x8b, 0x7b, 0x64, 0x97, 0xd1 \
165 class Element : public FragmentOrElement {
166 public:
167 #ifdef MOZILLA_INTERNAL_API
168 explicit Element(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
169 : FragmentOrElement(std::move(aNodeInfo)),
170 mState(NS_EVENT_STATE_MOZ_READONLY | NS_EVENT_STATE_DEFINED) {
171 MOZ_ASSERT(mNodeInfo->NodeType() == ELEMENT_NODE,
172 "Bad NodeType in aNodeInfo");
173 SetIsElement();
176 ~Element() {
177 NS_ASSERTION(!HasServoData(), "expected ServoData to be cleared earlier");
180 #endif // MOZILLA_INTERNAL_API
182 NS_DECLARE_STATIC_IID_ACCESSOR(NS_ELEMENT_IID)
184 NS_DECL_ADDSIZEOFEXCLUDINGTHIS
186 NS_IMPL_FROMNODE_HELPER(Element, IsElement())
188 NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override;
191 * Method to get the full state of this element. See mozilla/EventStates.h
192 * for the possible bits that could be set here.
194 EventStates State() const {
195 // mState is maintained by having whoever might have changed it
196 // call UpdateState() or one of the other mState mutators.
197 return mState;
201 * Ask this element to update its state. If aNotify is false, then
202 * state change notifications will not be dispatched; in that
203 * situation it is the caller's responsibility to dispatch them.
205 * In general, aNotify should only be false if we're guaranteed that
206 * the element can't have a frame no matter what its style is
207 * (e.g. if we're in the middle of adding it to the document or
208 * removing it from the document).
210 void UpdateState(bool aNotify);
213 * Method to update mState with link state information. This does not notify.
215 void UpdateLinkState(EventStates aState);
217 virtual int32_t TabIndexDefault() { return -1; }
220 * Get tabIndex of this element. If not found, return TabIndexDefault.
222 int32_t TabIndex();
225 * Set tabIndex value to this element.
227 void SetTabIndex(int32_t aTabIndex, mozilla::ErrorResult& aError);
230 * Sets or unsets an XBL binding for this element. Setting a
231 * binding on an element that already has a binding will remove the
232 * old binding.
234 * @param aBinding The binding to bind to this content. If nullptr is
235 * provided as the argument, then existing binding will be
236 * removed.
238 * @param aOldBindingManager The old binding manager that contains
239 * this content if this content was adopted
240 * to another document.
242 void SetXBLBinding(nsXBLBinding* aBinding,
243 nsBindingManager* aOldBindingManager = nullptr);
246 * Sets the ShadowRoot binding for this element. The contents of the
247 * binding is rendered in place of this node's children.
249 * @param aShadowRoot The ShadowRoot to be bound to this element.
251 void SetShadowRoot(ShadowRoot* aShadowRoot);
254 * Make focus on this element.
256 virtual void Focus(const FocusOptions& aOptions, ErrorResult& aError);
259 * Show blur and clear focus.
261 virtual void Blur(mozilla::ErrorResult& aError);
264 * The style state of this element. This is the real state of the element
265 * with any style locks applied for pseudo-class inspecting.
267 EventStates StyleState() const {
268 if (!HasLockedStyleStates()) {
269 return mState;
271 return StyleStateFromLocks();
275 * StyleStateLocks is used to specify which event states should be locked,
276 * and whether they should be locked to on or off.
278 struct StyleStateLocks {
279 // mLocks tracks which event states should be locked.
280 EventStates mLocks;
281 // mValues tracks if the locked state should be on or off.
282 EventStates mValues;
286 * The style state locks applied to this element.
288 StyleStateLocks LockedStyleStates() const;
291 * Add a style state lock on this element.
292 * aEnabled is the value to lock the given state bits to.
294 void LockStyleStates(EventStates aStates, bool aEnabled);
297 * Remove a style state lock on this element.
299 void UnlockStyleStates(EventStates aStates);
302 * Clear all style state locks on this element.
304 void ClearStyleStateLocks();
307 * Accessors for the state of our dir attribute.
309 bool HasDirAuto() const {
310 return State().HasState(NS_EVENT_STATE_DIR_ATTR_LIKE_AUTO);
314 * Elements with dir="rtl" or dir="ltr".
316 bool HasFixedDir() const {
317 return State().HasAtLeastOneOfStates(NS_EVENT_STATE_DIR_ATTR_LTR |
318 NS_EVENT_STATE_DIR_ATTR_RTL);
322 * Get the inline style declaration, if any, for this element.
324 DeclarationBlock* GetInlineStyleDeclaration() const;
327 * Get the mapped attributes, if any, for this element.
329 const nsMappedAttributes* GetMappedAttributes() const;
331 void ClearMappedServoStyle() { mAttrs.ClearMappedServoStyle(); }
334 * InlineStyleDeclarationWillChange is called before SetInlineStyleDeclaration
335 * so that the element implementation can access the old style attribute
336 * value.
338 virtual void InlineStyleDeclarationWillChange(MutationClosureData& aData);
341 * Set the inline style declaration for this element.
343 virtual nsresult SetInlineStyleDeclaration(DeclarationBlock& aDeclaration,
344 MutationClosureData& aData);
347 * Get the SMIL override style declaration for this element. If the
348 * rule hasn't been created, this method simply returns null.
350 DeclarationBlock* GetSMILOverrideStyleDeclaration();
353 * Set the SMIL override style declaration for this element. This method will
354 * notify the document's pres context, so that the style changes will be
355 * noticed.
357 nsresult SetSMILOverrideStyleDeclaration(DeclarationBlock* aDeclaration);
360 * Returns a new SMILAttr that allows the caller to animate the given
361 * attribute on this element.
363 virtual UniquePtr<SMILAttr> GetAnimatedAttr(int32_t aNamespaceID,
364 nsAtom* aName) {
365 return nullptr;
369 * Get the SMIL override style for this element. This is a style declaration
370 * that is applied *after* the inline style, and it can be used e.g. to store
371 * animated style values.
373 * Note: This method is analogous to the 'GetStyle' method in
374 * nsGenericHTMLElement and nsStyledElement.
376 nsDOMCSSAttributeDeclaration* SMILOverrideStyle();
379 * Returns if the element is labelable as per HTML specification.
381 virtual bool IsLabelable() const;
384 * Returns if the element is interactive content as per HTML specification.
386 virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const;
389 * Returns |this| as an nsIMozBrowserFrame* if the element is a frame or
390 * iframe element.
392 * We have this method, rather than using QI, so that we can use it during
393 * the servo traversal, where we can't QI DOM nodes because of non-thread-safe
394 * refcounts.
396 virtual nsIMozBrowserFrame* GetAsMozBrowserFrame() { return nullptr; }
399 * Is the attribute named stored in the mapped attributes?
401 * // XXXbz we use this method in HasAttributeDependentStyle, so svg
402 * returns true here even though it stores nothing in the mapped
403 * attributes.
405 NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const;
408 * Get a hint that tells the style system what to do when
409 * an attribute on this node changes, if something needs to happen
410 * in response to the change *other* than the result of what is
411 * mapped into style data via any type of style rule.
413 virtual nsChangeHint GetAttributeChangeHint(const nsAtom* aAttribute,
414 int32_t aModType) const;
416 inline Directionality GetDirectionality() const {
417 if (HasFlag(NODE_HAS_DIRECTION_RTL)) {
418 return eDir_RTL;
421 if (HasFlag(NODE_HAS_DIRECTION_LTR)) {
422 return eDir_LTR;
425 return eDir_NotSet;
428 inline void SetDirectionality(Directionality aDir, bool aNotify) {
429 UnsetFlags(NODE_ALL_DIRECTION_FLAGS);
430 if (!aNotify) {
431 RemoveStatesSilently(DIRECTION_STATES);
434 switch (aDir) {
435 case (eDir_RTL):
436 SetFlags(NODE_HAS_DIRECTION_RTL);
437 if (!aNotify) {
438 AddStatesSilently(NS_EVENT_STATE_RTL);
440 break;
442 case (eDir_LTR):
443 SetFlags(NODE_HAS_DIRECTION_LTR);
444 if (!aNotify) {
445 AddStatesSilently(NS_EVENT_STATE_LTR);
447 break;
449 default:
450 break;
454 * Only call UpdateState if we need to notify, because we call
455 * SetDirectionality for every element, and UpdateState is very very slow
456 * for some elements.
458 if (aNotify) {
459 UpdateState(true);
463 mozilla::StyleUrlOrNone GetBindingURL(Document* aDocument);
465 Directionality GetComputedDirectionality() const;
467 static const uint32_t kAllServoDescendantBits =
468 ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO |
469 ELEMENT_HAS_ANIMATION_ONLY_DIRTY_DESCENDANTS_FOR_SERVO |
470 NODE_DESCENDANTS_NEED_FRAMES;
473 * Notes that something in the given subtree of this element needs dirtying,
474 * and that all the relevant dirty bits have already been propagated up to the
475 * element.
477 * This is important because `NoteDirtyForServo` uses the dirty bits to reason
478 * about the shape of the tree, so we can't just call into there.
480 void NoteDirtySubtreeForServo();
482 void NoteDirtyForServo();
483 void NoteAnimationOnlyDirtyForServo();
484 void NoteDescendantsNeedFramesForServo();
486 bool HasDirtyDescendantsForServo() const {
487 return HasFlag(ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO);
490 void SetHasDirtyDescendantsForServo() {
491 SetFlags(ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO);
494 void UnsetHasDirtyDescendantsForServo() {
495 UnsetFlags(ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO);
498 bool HasAnimationOnlyDirtyDescendantsForServo() const {
499 return HasFlag(ELEMENT_HAS_ANIMATION_ONLY_DIRTY_DESCENDANTS_FOR_SERVO);
502 void SetHasAnimationOnlyDirtyDescendantsForServo() {
503 SetFlags(ELEMENT_HAS_ANIMATION_ONLY_DIRTY_DESCENDANTS_FOR_SERVO);
506 void UnsetHasAnimationOnlyDirtyDescendantsForServo() {
507 UnsetFlags(ELEMENT_HAS_ANIMATION_ONLY_DIRTY_DESCENDANTS_FOR_SERVO);
510 bool HasServoData() const { return !!mServoData.Get(); }
512 void ClearServoData() { ClearServoData(GetComposedDoc()); }
513 void ClearServoData(Document* aDocument);
516 * Gets the custom element data used by web components custom element.
517 * Custom element data is created at the first attempt to enqueue a callback.
519 * @return The custom element data or null if none.
521 inline CustomElementData* GetCustomElementData() const {
522 if (!HasCustomElementData()) {
523 return nullptr;
526 const nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
527 return slots ? slots->mCustomElementData.get() : nullptr;
531 * Sets the custom element data, ownership of the
532 * callback data is taken by this element.
534 * @param aData The custom element data.
536 void SetCustomElementData(CustomElementData* aData);
539 * Gets the custom element definition used by web components custom element.
541 * @return The custom element definition or null if element is not a custom
542 * element or custom element is not defined yet.
544 CustomElementDefinition* GetCustomElementDefinition() const;
547 * Sets the custom element definition, called when custom element is created
548 * or upgraded.
550 * @param aDefinition The custom element definition.
552 void SetCustomElementDefinition(CustomElementDefinition* aDefinition);
554 void SetDefined(bool aSet) {
555 if (aSet) {
556 AddStates(NS_EVENT_STATE_DEFINED);
557 } else {
558 RemoveStates(NS_EVENT_STATE_DEFINED);
562 protected:
564 * Method to get the _intrinsic_ content state of this element. This is the
565 * state that is independent of the element's presentation. To get the full
566 * content state, use State(). See mozilla/EventStates.h for
567 * the possible bits that could be set here.
569 virtual EventStates IntrinsicState() const;
572 * Method to add state bits. This should be called from subclass
573 * constructors to set up our event state correctly at construction
574 * time and other places where we don't want to notify a state
575 * change.
577 void AddStatesSilently(EventStates aStates) { mState |= aStates; }
580 * Method to remove state bits. This should be called from subclass
581 * constructors to set up our event state correctly at construction
582 * time and other places where we don't want to notify a state
583 * change.
585 void RemoveStatesSilently(EventStates aStates) { mState &= ~aStates; }
587 already_AddRefed<ShadowRoot> AttachShadowInternal(ShadowRootMode,
588 ErrorResult& aError);
590 MOZ_CAN_RUN_SCRIPT
591 nsIScrollableFrame* GetScrollFrame(nsIFrame** aStyledFrame = nullptr,
592 FlushType aFlushType = FlushType::Layout);
594 private:
595 // Need to allow the ESM, nsGlobalWindow, and the focus manager to
596 // set our state
597 friend class mozilla::EventStateManager;
598 friend class ::nsGlobalWindowInner;
599 friend class ::nsGlobalWindowOuter;
600 friend class ::nsFocusManager;
602 // Allow CusomtElementRegistry to call AddStates.
603 friend class CustomElementRegistry;
605 // Also need to allow Link to call UpdateLinkState.
606 friend class Link;
608 void NotifyStateChange(EventStates aStates);
610 void NotifyStyleStateChange(EventStates aStates);
612 // Style state computed from element's state and style locks.
613 EventStates StyleStateFromLocks() const;
615 protected:
616 // Methods for the ESM, nsGlobalWindow and focus manager to manage state bits.
617 // These will handle setting up script blockers when they notify, so no need
618 // to do it in the callers unless desired. States passed here must only be
619 // those in EXTERNALLY_MANAGED_STATES.
620 virtual void AddStates(EventStates aStates) {
621 MOZ_ASSERT(!aStates.HasAtLeastOneOfStates(INTRINSIC_STATES),
622 "Should only be adding externally-managed states here");
623 AddStatesSilently(aStates);
624 NotifyStateChange(aStates);
626 virtual void RemoveStates(EventStates aStates) {
627 MOZ_ASSERT(!aStates.HasAtLeastOneOfStates(INTRINSIC_STATES),
628 "Should only be removing externally-managed states here");
629 RemoveStatesSilently(aStates);
630 NotifyStateChange(aStates);
632 virtual void ToggleStates(EventStates aStates, bool aNotify) {
633 MOZ_ASSERT(!aStates.HasAtLeastOneOfStates(INTRINSIC_STATES),
634 "Should only be removing externally-managed states here");
635 mState ^= aStates;
636 if (aNotify) {
637 NotifyStateChange(aStates);
641 public:
642 // Public methods to manage state bits in MANUALLY_MANAGED_STATES.
643 void AddManuallyManagedStates(EventStates aStates) {
644 MOZ_ASSERT(MANUALLY_MANAGED_STATES.HasAllStates(aStates),
645 "Should only be adding manually-managed states here");
646 AddStates(aStates);
648 void RemoveManuallyManagedStates(EventStates aStates) {
649 MOZ_ASSERT(MANUALLY_MANAGED_STATES.HasAllStates(aStates),
650 "Should only be removing manually-managed states here");
651 RemoveStates(aStates);
654 void UpdateEditableState(bool aNotify) override;
656 nsresult BindToTree(BindContext&, nsINode& aParent) override;
658 void UnbindFromTree(bool aNullParent = true) override;
661 * Normalizes an attribute name and returns it as a nodeinfo if an attribute
662 * with that name exists. This method is intended for character case
663 * conversion if the content object is case insensitive (e.g. HTML). Returns
664 * the nodeinfo of the attribute with the specified name if one exists or
665 * null otherwise.
667 * @param aStr the unparsed attribute string
668 * @return the node info. May be nullptr.
670 already_AddRefed<mozilla::dom::NodeInfo> GetExistingAttrNameFromQName(
671 const nsAString& aStr) const;
674 * Helper for SetAttr/SetParsedAttr. This method will return true if aNotify
675 * is true or there are mutation listeners that must be triggered, the
676 * attribute is currently set, and the new value that is about to be set is
677 * different to the current value. As a perf optimization the new and old
678 * values will not actually be compared if we aren't notifying and we don't
679 * have mutation listeners (in which case it's cheap to just return false
680 * and let the caller go ahead and set the value).
681 * @param aOldValue [out] Set to the old value of the attribute, but only if
682 * there are event listeners. If set, the type of aOldValue will be either
683 * nsAttrValue::eString or nsAttrValue::eAtom.
684 * @param aModType [out] Set to MutationEvent_Binding::MODIFICATION or to
685 * MutationEvent_Binding::ADDITION, but only if this helper returns true
686 * @param aHasListeners [out] Set to true if there are mutation event
687 * listeners listening for NS_EVENT_BITS_MUTATION_ATTRMODIFIED
688 * @param aOldValueSet [out] Indicates whether an old attribute value has been
689 * stored in aOldValue. The bool will be set to true if a value was stored.
691 bool MaybeCheckSameAttrVal(int32_t aNamespaceID, const nsAtom* aName,
692 const nsAtom* aPrefix,
693 const nsAttrValueOrString& aValue, bool aNotify,
694 nsAttrValue& aOldValue, uint8_t* aModType,
695 bool* aHasListeners, bool* aOldValueSet);
698 * Notifies mutation listeners if aNotify is true, there are mutation
699 * listeners, and the attribute value is changing.
701 * @param aNamespaceID The namespace of the attribute
702 * @param aName The local name of the attribute
703 * @param aPrefix The prefix of the attribute
704 * @param aValue The value that the attribute is being changed to
705 * @param aNotify If true, mutation listeners will be notified if they exist
706 * and the attribute value is changing
707 * @param aOldValue [out] Set to the old value of the attribute, but only if
708 * there are event listeners. If set, the type of aOldValue will be either
709 * nsAttrValue::eString or nsAttrValue::eAtom.
710 * @param aModType [out] Set to MutationEvent_Binding::MODIFICATION or to
711 * MutationEvent_Binding::ADDITION, but only if this helper returns true
712 * @param aHasListeners [out] Set to true if there are mutation event
713 * listeners listening for NS_EVENT_BITS_MUTATION_ATTRMODIFIED
714 * @param aOldValueSet [out] Indicates whether an old attribute value has been
715 * stored in aOldValue. The bool will be set to true if a value was stored.
717 bool OnlyNotifySameValueSet(int32_t aNamespaceID, nsAtom* aName,
718 nsAtom* aPrefix,
719 const nsAttrValueOrString& aValue, bool aNotify,
720 nsAttrValue& aOldValue, uint8_t* aModType,
721 bool* aHasListeners, bool* aOldValueSet);
724 * Sets the class attribute to a value that contains no whitespace.
725 * Assumes that we are not notifying and that the attribute hasn't been
726 * set previously.
728 nsresult SetSingleClassFromParser(nsAtom* aSingleClassName);
730 // aParsedValue receives the old value of the attribute. That's useful if
731 // either the input or output value of aParsedValue is StoresOwnData.
732 nsresult SetParsedAttr(int32_t aNameSpaceID, nsAtom* aName, nsAtom* aPrefix,
733 nsAttrValue& aParsedValue, bool aNotify);
735 * Get the current value of the attribute. This returns a form that is
736 * suitable for passing back into SetAttr.
738 * @param aNameSpaceID the namespace of the attr (defaults to
739 kNameSpaceID_None in the overload that omits this arg)
740 * @param aName the name of the attr
741 * @param aResult the value (may legitimately be the empty string) [OUT]
742 * @returns true if the attribute was set (even when set to empty string)
743 * false when not set.
744 * GetAttr is not inlined on purpose, to keep down codesize from all the
745 * inlined nsAttrValue bits for C++ callers.
747 bool GetAttr(int32_t aNameSpaceID, const nsAtom* aName,
748 nsAString& aResult) const;
750 bool GetAttr(const nsAtom* aName, nsAString& aResult) const {
751 return GetAttr(kNameSpaceID_None, aName, aResult);
755 * Determine if an attribute has been set (empty string or otherwise).
757 * @param aNameSpaceId the namespace id of the attribute (defaults to
758 kNameSpaceID_None in the overload that omits this arg)
759 * @param aAttr the attribute name
760 * @return whether an attribute exists
762 inline bool HasAttr(int32_t aNameSpaceID, const nsAtom* aName) const;
764 bool HasAttr(const nsAtom* aAttr) const {
765 return HasAttr(kNameSpaceID_None, aAttr);
769 * Test whether this Element's given attribute has the given value. If the
770 * attribute is not set at all, this will return false.
772 * @param aNameSpaceID The namespace ID of the attribute. Must not
773 * be kNameSpaceID_Unknown.
774 * @param aName The name atom of the attribute. Must not be null.
775 * @param aValue The value to compare to.
776 * @param aCaseSensitive Whether to do a case-sensitive compare on the value.
778 inline bool AttrValueIs(int32_t aNameSpaceID, const nsAtom* aName,
779 const nsAString& aValue,
780 nsCaseTreatment aCaseSensitive) const;
783 * Test whether this Element's given attribute has the given value. If the
784 * attribute is not set at all, this will return false.
786 * @param aNameSpaceID The namespace ID of the attribute. Must not
787 * be kNameSpaceID_Unknown.
788 * @param aName The name atom of the attribute. Must not be null.
789 * @param aValue The value to compare to. Must not be null.
790 * @param aCaseSensitive Whether to do a case-sensitive compare on the value.
792 bool AttrValueIs(int32_t aNameSpaceID, const nsAtom* aName,
793 const nsAtom* aValue, nsCaseTreatment aCaseSensitive) const;
795 enum { ATTR_MISSING = -1, ATTR_VALUE_NO_MATCH = -2 };
797 * Check whether this Element's given attribute has one of a given list of
798 * values. If there is a match, we return the index in the list of the first
799 * matching value. If there was no attribute at all, then we return
800 * ATTR_MISSING. If there was an attribute but it didn't match, we return
801 * ATTR_VALUE_NO_MATCH. A non-negative result always indicates a match.
803 * @param aNameSpaceID The namespace ID of the attribute. Must not
804 * be kNameSpaceID_Unknown.
805 * @param aName The name atom of the attribute. Must not be null.
806 * @param aValues a nullptr-terminated array of pointers to atom values to
807 * test against.
808 * @param aCaseSensitive Whether to do a case-sensitive compare on the values.
809 * @return ATTR_MISSING, ATTR_VALUE_NO_MATCH or the non-negative index
810 * indicating the first value of aValues that matched
812 typedef nsStaticAtom* const AttrValuesArray;
813 int32_t FindAttrValueIn(int32_t aNameSpaceID, const nsAtom* aName,
814 AttrValuesArray* aValues,
815 nsCaseTreatment aCaseSensitive) const;
818 * Set attribute values. All attribute values are assumed to have a
819 * canonical string representation that can be used for these
820 * methods. The SetAttr method is assumed to perform a translation
821 * of the canonical form into the underlying content specific
822 * form.
824 * @param aNameSpaceID the namespace of the attribute
825 * @param aName the name of the attribute
826 * @param aValue the value to set
827 * @param aNotify specifies how whether or not the document should be
828 * notified of the attribute change.
830 nsresult SetAttr(int32_t aNameSpaceID, nsAtom* aName, const nsAString& aValue,
831 bool aNotify) {
832 return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
834 nsresult SetAttr(int32_t aNameSpaceID, nsAtom* aName, nsAtom* aPrefix,
835 const nsAString& aValue, bool aNotify) {
836 return SetAttr(aNameSpaceID, aName, aPrefix, aValue, nullptr, aNotify);
838 nsresult SetAttr(int32_t aNameSpaceID, nsAtom* aName, const nsAString& aValue,
839 nsIPrincipal* aTriggeringPrincipal, bool aNotify) {
840 return SetAttr(aNameSpaceID, aName, nullptr, aValue, aTriggeringPrincipal,
841 aNotify);
845 * Set attribute values. All attribute values are assumed to have a
846 * canonical String representation that can be used for these
847 * methods. The SetAttr method is assumed to perform a translation
848 * of the canonical form into the underlying content specific
849 * form.
851 * @param aNameSpaceID the namespace of the attribute
852 * @param aName the name of the attribute
853 * @param aPrefix the prefix of the attribute
854 * @param aValue the value to set
855 * @param aMaybeScriptedPrincipal the principal of the scripted caller
856 * responsible for setting the attribute, or null if no scripted caller can be
857 * determined. A null value here does not guarantee that there is no
858 * scripted caller, but a non-null value does guarantee that a scripted
859 * caller with the given principal is directly responsible for the
860 * attribute change.
861 * @param aNotify specifies how whether or not the document should be
862 * notified of the attribute change.
864 nsresult SetAttr(int32_t aNameSpaceID, nsAtom* aName, nsAtom* aPrefix,
865 const nsAString& aValue,
866 nsIPrincipal* aMaybeScriptedPrincipal, bool aNotify);
869 * Remove an attribute so that it is no longer explicitly specified.
871 * @param aNameSpaceID the namespace id of the attribute
872 * @param aAttr the name of the attribute to unset
873 * @param aNotify specifies whether or not the document should be
874 * notified of the attribute change
876 nsresult UnsetAttr(int32_t aNameSpaceID, nsAtom* aAttribute, bool aNotify);
879 * Get the namespace / name / prefix of a given attribute.
881 * @param aIndex the index of the attribute name
882 * @returns The name at the given index, or null if the index is
883 * out-of-bounds.
884 * @note The document returned by NodeInfo()->GetDocument() (if one is
885 * present) is *not* necessarily the owner document of the element.
886 * @note The pointer returned by this function is only valid until the
887 * next call of either GetAttrNameAt or SetAttr on the element.
889 const nsAttrName* GetAttrNameAt(uint32_t aIndex) const {
890 return mAttrs.GetSafeAttrNameAt(aIndex);
894 * Same as above, but does not do out-of-bounds checks!
896 const nsAttrName* GetUnsafeAttrNameAt(uint32_t aIndex) const {
897 return mAttrs.AttrNameAt(aIndex);
901 * Gets the attribute info (name and value) for this element at a given index.
903 BorrowedAttrInfo GetAttrInfoAt(uint32_t aIndex) const {
904 if (aIndex >= mAttrs.AttrCount()) {
905 return BorrowedAttrInfo(nullptr, nullptr);
908 return mAttrs.AttrInfoAt(aIndex);
912 * Get the number of all specified attributes.
914 * @return the number of attributes
916 uint32_t GetAttrCount() const { return mAttrs.AttrCount(); }
918 virtual bool IsNodeOfType(uint32_t aFlags) const override;
921 * Get the class list of this element (this corresponds to the value of the
922 * class attribute). This may be null if there are no classes, but that's not
923 * guaranteed (e.g. we could have class="").
925 const nsAttrValue* GetClasses() const {
926 if (!MayHaveClass()) {
927 return nullptr;
930 if (IsSVGElement()) {
931 if (const nsAttrValue* value = GetSVGAnimatedClass()) {
932 return value;
936 return GetParsedAttr(nsGkAtoms::_class);
939 #ifdef DEBUG
940 virtual void List(FILE* out = stdout, int32_t aIndent = 0) const override {
941 List(out, aIndent, EmptyCString());
943 virtual void DumpContent(FILE* out, int32_t aIndent,
944 bool aDumpAll) const override;
945 void List(FILE* out, int32_t aIndent, const nsCString& aPrefix) const;
946 void ListAttributes(FILE* out) const;
947 #endif
950 * Append to aOutDescription a short (preferably one line) string
951 * describing the element.
953 void Describe(nsAString& aOutDescription) const;
956 * Attribute Mapping Helpers
958 struct MappedAttributeEntry {
959 const nsStaticAtom* const attribute;
963 * A common method where you can just pass in a list of maps to check
964 * for attribute dependence. Most implementations of
965 * IsAttributeMapped should use this function as a default
966 * handler.
968 template <size_t N>
969 static bool FindAttributeDependence(
970 const nsAtom* aAttribute, const MappedAttributeEntry* const (&aMaps)[N]) {
971 return FindAttributeDependence(aAttribute, aMaps, N);
974 static nsStaticAtom* const* HTMLSVGPropertiesToTraverseAndUnlink();
976 private:
977 void DescribeAttribute(uint32_t index, nsAString& aOutDescription) const;
979 static bool FindAttributeDependence(const nsAtom* aAttribute,
980 const MappedAttributeEntry* const aMaps[],
981 uint32_t aMapCount);
983 protected:
984 inline bool GetAttr(int32_t aNameSpaceID, const nsAtom* aName,
985 DOMString& aResult) const {
986 NS_ASSERTION(nullptr != aName, "must have attribute name");
987 NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown,
988 "must have a real namespace ID!");
989 MOZ_ASSERT(aResult.IsEmpty(), "Should have empty string coming in");
990 const nsAttrValue* val = mAttrs.GetAttr(aName, aNameSpaceID);
991 if (val) {
992 val->ToString(aResult);
993 return true;
995 // else DOMString comes pre-emptied.
996 return false;
999 public:
1000 bool HasAttrs() const { return mAttrs.HasAttrs(); }
1002 inline bool GetAttr(const nsAString& aName, DOMString& aResult) const {
1003 MOZ_ASSERT(aResult.IsEmpty(), "Should have empty string coming in");
1004 const nsAttrValue* val = mAttrs.GetAttr(aName);
1005 if (val) {
1006 val->ToString(aResult);
1007 return true;
1009 // else DOMString comes pre-emptied.
1010 return false;
1013 void GetTagName(nsAString& aTagName) const { aTagName = NodeName(); }
1014 void GetId(nsAString& aId) const {
1015 GetAttr(kNameSpaceID_None, nsGkAtoms::id, aId);
1017 void GetId(DOMString& aId) const {
1018 GetAttr(kNameSpaceID_None, nsGkAtoms::id, aId);
1020 void SetId(const nsAString& aId) {
1021 SetAttr(kNameSpaceID_None, nsGkAtoms::id, aId, true);
1023 void GetClassName(nsAString& aClassName) {
1024 GetAttr(kNameSpaceID_None, nsGkAtoms::_class, aClassName);
1026 void GetClassName(DOMString& aClassName) {
1027 GetAttr(kNameSpaceID_None, nsGkAtoms::_class, aClassName);
1029 void SetClassName(const nsAString& aClassName) {
1030 SetAttr(kNameSpaceID_None, nsGkAtoms::_class, aClassName, true);
1033 nsDOMTokenList* ClassList();
1034 nsDOMAttributeMap* Attributes() {
1035 nsDOMSlots* slots = DOMSlots();
1036 if (!slots->mAttributeMap) {
1037 slots->mAttributeMap = new nsDOMAttributeMap(this);
1040 return slots->mAttributeMap;
1043 void GetAttributeNames(nsTArray<nsString>& aResult);
1045 void GetAttribute(const nsAString& aName, nsAString& aReturn) {
1046 DOMString str;
1047 GetAttribute(aName, str);
1048 str.ToString(aReturn);
1051 void GetAttribute(const nsAString& aName, DOMString& aReturn);
1052 void GetAttributeNS(const nsAString& aNamespaceURI,
1053 const nsAString& aLocalName, nsAString& aReturn);
1054 bool ToggleAttribute(const nsAString& aName, const Optional<bool>& aForce,
1055 nsIPrincipal* aTriggeringPrincipal, ErrorResult& aError);
1056 void SetAttribute(const nsAString& aName, const nsAString& aValue,
1057 nsIPrincipal* aTriggeringPrincipal, ErrorResult& aError);
1058 void SetAttributeNS(const nsAString& aNamespaceURI,
1059 const nsAString& aLocalName, const nsAString& aValue,
1060 nsIPrincipal* aTriggeringPrincipal, ErrorResult& aError);
1061 void SetAttribute(const nsAString& aName, const nsAString& aValue,
1062 ErrorResult& aError) {
1063 SetAttribute(aName, aValue, nullptr, aError);
1066 void RemoveAttribute(const nsAString& aName, ErrorResult& aError);
1067 void RemoveAttributeNS(const nsAString& aNamespaceURI,
1068 const nsAString& aLocalName, ErrorResult& aError);
1069 bool HasAttribute(const nsAString& aName) const {
1070 return InternalGetAttrNameFromQName(aName) != nullptr;
1072 bool HasAttributeNS(const nsAString& aNamespaceURI,
1073 const nsAString& aLocalName) const;
1074 bool HasAttributes() const { return HasAttrs(); }
1075 Element* Closest(const nsAString& aSelector, ErrorResult& aResult);
1076 bool Matches(const nsAString& aSelector, ErrorResult& aError);
1077 already_AddRefed<nsIHTMLCollection> GetElementsByTagName(
1078 const nsAString& aQualifiedName);
1079 already_AddRefed<nsIHTMLCollection> GetElementsByTagNameNS(
1080 const nsAString& aNamespaceURI, const nsAString& aLocalName,
1081 ErrorResult& aError);
1082 already_AddRefed<nsIHTMLCollection> GetElementsByClassName(
1083 const nsAString& aClassNames);
1085 PseudoStyleType GetPseudoElementType() const {
1086 nsresult rv = NS_OK;
1087 auto raw = GetProperty(nsGkAtoms::pseudoProperty, &rv);
1088 if (rv == NS_PROPTABLE_PROP_NOT_THERE) {
1089 return PseudoStyleType::NotPseudo;
1091 return PseudoStyleType(reinterpret_cast<uintptr_t>(raw));
1094 void SetPseudoElementType(PseudoStyleType aPseudo) {
1095 static_assert(sizeof(PseudoStyleType) <= sizeof(uintptr_t),
1096 "Need to be able to store this in a void*");
1097 MOZ_ASSERT(PseudoStyle::IsPseudoElement(aPseudo));
1098 SetProperty(nsGkAtoms::pseudoProperty, reinterpret_cast<void*>(aPseudo));
1102 * Return an array of all elements in the subtree rooted at this
1103 * element that have grid container frames. This does not include
1104 * pseudo-elements.
1106 void GetElementsWithGrid(nsTArray<RefPtr<Element>>& aElements);
1108 private:
1110 * Implement the algorithm specified at
1111 * https://dom.spec.whatwg.org/#insert-adjacent for both
1112 * |insertAdjacentElement()| and |insertAdjacentText()| APIs.
1114 nsINode* InsertAdjacent(const nsAString& aWhere, nsINode* aNode,
1115 ErrorResult& aError);
1117 public:
1118 Element* InsertAdjacentElement(const nsAString& aWhere, Element& aElement,
1119 ErrorResult& aError);
1121 void InsertAdjacentText(const nsAString& aWhere, const nsAString& aData,
1122 ErrorResult& aError);
1124 void SetPointerCapture(int32_t aPointerId, ErrorResult& aError) {
1125 bool activeState = false;
1126 if (nsContentUtils::ShouldResistFingerprinting(GetComposedDoc()) &&
1127 aPointerId != PointerEventHandler::GetSpoofedPointerIdForRFP()) {
1128 aError.Throw(NS_ERROR_DOM_INVALID_POINTER_ERR);
1129 return;
1131 if (!PointerEventHandler::GetPointerInfo(aPointerId, activeState)) {
1132 aError.Throw(NS_ERROR_DOM_INVALID_POINTER_ERR);
1133 return;
1135 if (!IsInComposedDoc()) {
1136 aError.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
1137 return;
1139 if (OwnerDoc()->GetPointerLockElement()) {
1140 // Throw an exception 'InvalidStateError' while the page has a locked
1141 // element.
1142 aError.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
1143 return;
1145 if (!activeState) {
1146 return;
1148 PointerEventHandler::SetPointerCaptureById(aPointerId, this);
1150 void ReleasePointerCapture(int32_t aPointerId, ErrorResult& aError) {
1151 bool activeState = false;
1152 if (nsContentUtils::ShouldResistFingerprinting(GetComposedDoc()) &&
1153 aPointerId != PointerEventHandler::GetSpoofedPointerIdForRFP()) {
1154 aError.Throw(NS_ERROR_DOM_INVALID_POINTER_ERR);
1155 return;
1157 if (!PointerEventHandler::GetPointerInfo(aPointerId, activeState)) {
1158 aError.Throw(NS_ERROR_DOM_INVALID_POINTER_ERR);
1159 return;
1161 if (HasPointerCapture(aPointerId)) {
1162 PointerEventHandler::ReleasePointerCaptureById(aPointerId);
1165 bool HasPointerCapture(long aPointerId) {
1166 PointerCaptureInfo* pointerCaptureInfo =
1167 PointerEventHandler::GetPointerCaptureInfo(aPointerId);
1168 if (pointerCaptureInfo && pointerCaptureInfo->mPendingContent == this) {
1169 return true;
1171 return false;
1173 void SetCapture(bool aRetargetToElement) {
1174 // If there is already an active capture, ignore this request. This would
1175 // occur if a splitter, frame resizer, etc had already captured and we don't
1176 // want to override those.
1177 if (!PresShell::GetCapturingContent()) {
1178 PresShell::SetCapturingContent(
1179 this, CaptureFlags::PreventDragStart |
1180 (aRetargetToElement ? CaptureFlags::RetargetToElement
1181 : CaptureFlags::None));
1185 void SetCaptureAlways(bool aRetargetToElement) {
1186 PresShell::SetCapturingContent(
1187 this, CaptureFlags::PreventDragStart |
1188 CaptureFlags::IgnoreAllowedState |
1189 (aRetargetToElement ? CaptureFlags::RetargetToElement
1190 : CaptureFlags::None));
1193 void ReleaseCapture() {
1194 if (PresShell::GetCapturingContent() == this) {
1195 PresShell::ReleaseCapturingContent();
1199 already_AddRefed<Promise> RequestFullscreen(CallerType, ErrorResult&);
1200 void RequestPointerLock(CallerType aCallerType);
1201 Attr* GetAttributeNode(const nsAString& aName);
1202 already_AddRefed<Attr> SetAttributeNode(Attr& aNewAttr, ErrorResult& aError);
1203 already_AddRefed<Attr> RemoveAttributeNode(Attr& aOldAttr,
1204 ErrorResult& aError);
1205 Attr* GetAttributeNodeNS(const nsAString& aNamespaceURI,
1206 const nsAString& aLocalName);
1207 already_AddRefed<Attr> SetAttributeNodeNS(Attr& aNewAttr,
1208 ErrorResult& aError);
1210 MOZ_CAN_RUN_SCRIPT already_AddRefed<DOMRectList> GetClientRects();
1211 MOZ_CAN_RUN_SCRIPT already_AddRefed<DOMRect> GetBoundingClientRect();
1213 // Shadow DOM v1
1214 already_AddRefed<ShadowRoot> AttachShadow(const ShadowRootInit& aInit,
1215 ErrorResult& aError);
1216 bool CanAttachShadowDOM() const;
1218 already_AddRefed<ShadowRoot> AttachShadowWithoutNameChecks(
1219 ShadowRootMode aMode);
1221 // Attach UA Shadow Root if it is not attached.
1222 void AttachAndSetUAShadowRoot();
1224 // Dispatch an event to UAWidgetsChild, triggering construction
1225 // or onchange callback on the existing widget.
1226 void NotifyUAWidgetSetupOrChange();
1228 enum class UnattachShadowRoot {
1230 Yes,
1233 // Dispatch an event to UAWidgetsChild, triggering UA Widget destruction.
1234 // and optionally remove the shadow root.
1235 void NotifyUAWidgetTeardown(UnattachShadowRoot = UnattachShadowRoot::Yes);
1237 void UnattachShadow();
1239 ShadowRoot* GetShadowRootByMode() const;
1240 void SetSlot(const nsAString& aName, ErrorResult& aError);
1241 void GetSlot(nsAString& aName);
1243 ShadowRoot* GetShadowRoot() const {
1244 const nsExtendedDOMSlots* slots = GetExistingExtendedDOMSlots();
1245 return slots ? slots->mShadowRoot.get() : nullptr;
1248 private:
1249 MOZ_CAN_RUN_SCRIPT void ScrollIntoView(const ScrollIntoViewOptions& aOptions);
1251 public:
1252 MOZ_CAN_RUN_SCRIPT
1253 void ScrollIntoView(const BooleanOrScrollIntoViewOptions& aObject);
1254 MOZ_CAN_RUN_SCRIPT void Scroll(double aXScroll, double aYScroll);
1255 MOZ_CAN_RUN_SCRIPT void Scroll(const ScrollToOptions& aOptions);
1256 MOZ_CAN_RUN_SCRIPT void ScrollTo(double aXScroll, double aYScroll);
1257 MOZ_CAN_RUN_SCRIPT void ScrollTo(const ScrollToOptions& aOptions);
1258 MOZ_CAN_RUN_SCRIPT void ScrollBy(double aXScrollDif, double aYScrollDif);
1259 MOZ_CAN_RUN_SCRIPT void ScrollBy(const ScrollToOptions& aOptions);
1260 MOZ_CAN_RUN_SCRIPT int32_t ScrollTop();
1261 MOZ_CAN_RUN_SCRIPT void SetScrollTop(int32_t aScrollTop);
1262 MOZ_CAN_RUN_SCRIPT int32_t ScrollLeft();
1263 MOZ_CAN_RUN_SCRIPT void SetScrollLeft(int32_t aScrollLeft);
1264 MOZ_CAN_RUN_SCRIPT int32_t ScrollWidth();
1265 MOZ_CAN_RUN_SCRIPT int32_t ScrollHeight();
1266 MOZ_CAN_RUN_SCRIPT void MozScrollSnap();
1267 MOZ_CAN_RUN_SCRIPT int32_t ClientTop() {
1268 return nsPresContext::AppUnitsToIntCSSPixels(GetClientAreaRect().y);
1270 MOZ_CAN_RUN_SCRIPT int32_t ClientLeft() {
1271 return nsPresContext::AppUnitsToIntCSSPixels(GetClientAreaRect().x);
1273 MOZ_CAN_RUN_SCRIPT int32_t ClientWidth() {
1274 return nsPresContext::AppUnitsToIntCSSPixels(GetClientAreaRect().Width());
1276 MOZ_CAN_RUN_SCRIPT int32_t ClientHeight() {
1277 return nsPresContext::AppUnitsToIntCSSPixels(GetClientAreaRect().Height());
1279 MOZ_CAN_RUN_SCRIPT int32_t ScrollTopMin() {
1280 nsIScrollableFrame* sf = GetScrollFrame();
1281 return sf ? nsPresContext::AppUnitsToIntCSSPixels(sf->GetScrollRange().y)
1282 : 0;
1284 MOZ_CAN_RUN_SCRIPT int32_t ScrollTopMax() {
1285 nsIScrollableFrame* sf = GetScrollFrame();
1286 return sf ? nsPresContext::AppUnitsToIntCSSPixels(
1287 sf->GetScrollRange().YMost())
1288 : 0;
1290 MOZ_CAN_RUN_SCRIPT int32_t ScrollLeftMin() {
1291 nsIScrollableFrame* sf = GetScrollFrame();
1292 return sf ? nsPresContext::AppUnitsToIntCSSPixels(sf->GetScrollRange().x)
1293 : 0;
1295 MOZ_CAN_RUN_SCRIPT int32_t ScrollLeftMax() {
1296 nsIScrollableFrame* sf = GetScrollFrame();
1297 return sf ? nsPresContext::AppUnitsToIntCSSPixels(
1298 sf->GetScrollRange().XMost())
1299 : 0;
1302 MOZ_CAN_RUN_SCRIPT double ClientHeightDouble() {
1303 return nsPresContext::AppUnitsToDoubleCSSPixels(
1304 GetClientAreaRect().Height());
1307 MOZ_CAN_RUN_SCRIPT double ClientWidthDouble() {
1308 return nsPresContext::AppUnitsToDoubleCSSPixels(
1309 GetClientAreaRect().Width());
1312 // This function will return the block size of first line box, no matter if
1313 // the box is 'block' or 'inline'. The return unit is pixel. If the element
1314 // can't get a primary frame, we will return be zero.
1315 double FirstLineBoxBSize() const;
1317 already_AddRefed<Flex> GetAsFlexContainer();
1318 void GetGridFragments(nsTArray<RefPtr<Grid>>& aResult);
1320 already_AddRefed<DOMMatrixReadOnly> GetTransformToAncestor(
1321 Element& aAncestor);
1322 already_AddRefed<DOMMatrixReadOnly> GetTransformToParent();
1323 already_AddRefed<DOMMatrixReadOnly> GetTransformToViewport();
1325 already_AddRefed<Animation> Animate(
1326 JSContext* aContext, JS::Handle<JSObject*> aKeyframes,
1327 const UnrestrictedDoubleOrKeyframeAnimationOptions& aOptions,
1328 ErrorResult& aError);
1330 // A helper method that factors out the common functionality needed by
1331 // Element::Animate and CSSPseudoElement::Animate
1332 static already_AddRefed<Animation> Animate(
1333 const Nullable<ElementOrCSSPseudoElement>& aTarget, JSContext* aContext,
1334 JS::Handle<JSObject*> aKeyframes,
1335 const UnrestrictedDoubleOrKeyframeAnimationOptions& aOptions,
1336 ErrorResult& aError);
1338 // Note: GetAnimations will flush style while GetAnimationsUnsorted won't.
1339 // Callers must keep this element alive because flushing style may destroy
1340 // this element.
1341 void GetAnimations(const GetAnimationsOptions& aOptions,
1342 nsTArray<RefPtr<Animation>>& aAnimations);
1343 static void GetAnimationsUnsorted(Element* aElement,
1344 PseudoStyleType aPseudoType,
1345 nsTArray<RefPtr<Animation>>& aAnimations);
1347 virtual void GetInnerHTML(nsAString& aInnerHTML, OOMReporter& aError);
1348 virtual void SetInnerHTML(const nsAString& aInnerHTML,
1349 nsIPrincipal* aSubjectPrincipal,
1350 ErrorResult& aError);
1351 void GetOuterHTML(nsAString& aOuterHTML);
1352 void SetOuterHTML(const nsAString& aOuterHTML, ErrorResult& aError);
1353 void InsertAdjacentHTML(const nsAString& aPosition, const nsAString& aText,
1354 ErrorResult& aError);
1356 //----------------------------------------
1359 * Add a script event listener with the given event handler name
1360 * (like onclick) and with the value as JS
1361 * @param aEventName the event listener name
1362 * @param aValue the JS to attach
1363 * @param aDefer indicates if deferred execution is allowed
1365 nsresult SetEventHandler(nsAtom* aEventName, const nsAString& aValue,
1366 bool aDefer = true);
1369 * Do whatever needs to be done when the mouse leaves a link
1371 nsresult LeaveLink(nsPresContext* aPresContext);
1373 static bool ShouldBlur(nsIContent* aContent);
1376 * Method to create and dispatch a left-click event loosely based on
1377 * aSourceEvent. If aFullDispatch is true, the event will be dispatched
1378 * through the full dispatching of the presshell of the aPresContext; if it's
1379 * false the event will be dispatched only as a DOM event.
1380 * If aPresContext is nullptr, this does nothing.
1382 * @param aFlags Extra flags for the dispatching event. The true flags
1383 * will be respected.
1385 MOZ_CAN_RUN_SCRIPT
1386 static nsresult DispatchClickEvent(nsPresContext* aPresContext,
1387 WidgetInputEvent* aSourceEvent,
1388 nsIContent* aTarget, bool aFullDispatch,
1389 const EventFlags* aFlags,
1390 nsEventStatus* aStatus);
1393 * Method to dispatch aEvent to aTarget. If aFullDispatch is true, the event
1394 * will be dispatched through the full dispatching of the presshell of the
1395 * aPresContext; if it's false the event will be dispatched only as a DOM
1396 * event.
1397 * If aPresContext is nullptr, this does nothing.
1399 using nsIContent::DispatchEvent;
1400 MOZ_CAN_RUN_SCRIPT
1401 static nsresult DispatchEvent(nsPresContext* aPresContext,
1402 WidgetEvent* aEvent, nsIContent* aTarget,
1403 bool aFullDispatch, nsEventStatus* aStatus);
1405 bool IsDisplayContents() const {
1406 return HasServoData() && Servo_Element_IsDisplayContents(this);
1410 * https://html.spec.whatwg.org/#being-rendered
1412 * With a gotcha for display contents:
1413 * https://github.com/whatwg/html/issues/1837
1415 bool IsRendered() const { return GetPrimaryFrame() || IsDisplayContents(); }
1417 const nsAttrValue* GetParsedAttr(const nsAtom* aAttr) const {
1418 return mAttrs.GetAttr(aAttr);
1421 const nsAttrValue* GetParsedAttr(const nsAtom* aAttr,
1422 int32_t aNameSpaceID) const {
1423 return mAttrs.GetAttr(aAttr, aNameSpaceID);
1427 * Returns the attribute map, if there is one.
1429 * @return existing attribute map or nullptr.
1431 nsDOMAttributeMap* GetAttributeMap() {
1432 nsDOMSlots* slots = GetExistingDOMSlots();
1434 return slots ? slots->mAttributeMap.get() : nullptr;
1437 virtual void RecompileScriptEventListeners() {}
1440 * Get the attr info for the given namespace ID and attribute name. The
1441 * namespace ID must not be kNameSpaceID_Unknown and the name must not be
1442 * null. Note that this can only return info on attributes that actually
1443 * live on this element (and is only virtual to handle XUL prototypes). That
1444 * is, this should only be called from methods that only care about attrs
1445 * that effectively live in mAttrs.
1447 BorrowedAttrInfo GetAttrInfo(int32_t aNamespaceID,
1448 const nsAtom* aName) const {
1449 NS_ASSERTION(aName, "must have attribute name");
1450 NS_ASSERTION(aNamespaceID != kNameSpaceID_Unknown,
1451 "must have a real namespace ID!");
1453 int32_t index = mAttrs.IndexOfAttr(aName, aNamespaceID);
1454 if (index < 0) {
1455 return BorrowedAttrInfo(nullptr, nullptr);
1458 return mAttrs.AttrInfoAt(index);
1462 * Called when we have been adopted, and the information of the
1463 * node has been changed.
1465 * The new document can be reached via OwnerDoc().
1467 * If you override this method,
1468 * please call up to the parent NodeInfoChanged.
1470 * If you change this, change also the similar method in Link.
1472 virtual void NodeInfoChanged(Document* aOldDoc) {}
1475 * Parse a string into an nsAttrValue for a CORS attribute. This
1476 * never fails. The resulting value is an enumerated value whose
1477 * GetEnumValue() returns one of the above constants.
1479 static void ParseCORSValue(const nsAString& aValue, nsAttrValue& aResult);
1482 * Return the CORS mode for a given string
1484 static CORSMode StringToCORSMode(const nsAString& aValue);
1487 * Return the CORS mode for a given nsAttrValue (which may be null,
1488 * but if not should have been parsed via ParseCORSValue).
1490 static CORSMode AttrValueToCORSMode(const nsAttrValue* aValue);
1492 JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) final;
1494 nsINode* GetScopeChainParent() const override;
1497 * Locate a TextEditor rooted at this content node, if there is one.
1499 mozilla::TextEditor* GetTextEditorInternal();
1502 * Gets value of boolean attribute. Only works for attributes in null
1503 * namespace.
1505 * @param aAttr name of attribute.
1506 * @param aValue Boolean value of attribute.
1508 bool GetBoolAttr(nsAtom* aAttr) const {
1509 return HasAttr(kNameSpaceID_None, aAttr);
1513 * Sets value of boolean attribute by removing attribute or setting it to
1514 * the empty string. Only works for attributes in null namespace.
1516 * @param aAttr name of attribute.
1517 * @param aValue Boolean value of attribute.
1519 nsresult SetBoolAttr(nsAtom* aAttr, bool aValue);
1522 * Gets the enum value string of an attribute and using a default value if
1523 * the attribute is missing or the string is an invalid enum value.
1525 * @param aType the name of the attribute.
1526 * @param aDefault the default value if the attribute is missing or invalid.
1527 * @param aResult string corresponding to the value [out].
1529 void GetEnumAttr(nsAtom* aAttr, const char* aDefault,
1530 nsAString& aResult) const;
1533 * Gets the enum value string of an attribute and using the default missing
1534 * value if the attribute is missing or the default invalid value if the
1535 * string is an invalid enum value.
1537 * @param aType the name of the attribute.
1538 * @param aDefaultMissing the default value if the attribute is missing. If
1539 null and the attribute is missing, aResult will be
1540 set to the null DOMString; this only matters for
1541 cases in which we're reflecting a nullable string.
1542 * @param aDefaultInvalid the default value if the attribute is invalid.
1543 * @param aResult string corresponding to the value [out].
1545 void GetEnumAttr(nsAtom* aAttr, const char* aDefaultMissing,
1546 const char* aDefaultInvalid, nsAString& aResult) const;
1549 * Unset an attribute.
1551 void UnsetAttr(nsAtom* aAttr, ErrorResult& aError) {
1552 aError = UnsetAttr(kNameSpaceID_None, aAttr, true);
1556 * Set an attribute in the simplest way possible.
1558 void SetAttr(nsAtom* aAttr, const nsAString& aValue, ErrorResult& aError) {
1559 aError = SetAttr(kNameSpaceID_None, aAttr, aValue, true);
1562 void SetAttr(nsAtom* aAttr, const nsAString& aValue,
1563 nsIPrincipal* aTriggeringPrincipal, ErrorResult& aError) {
1564 aError =
1565 SetAttr(kNameSpaceID_None, aAttr, aValue, aTriggeringPrincipal, true);
1569 * Set a content attribute via a reflecting nullable string IDL
1570 * attribute (e.g. a CORS attribute). If DOMStringIsNull(aValue),
1571 * this will actually remove the content attribute.
1573 void SetOrRemoveNullableStringAttr(nsAtom* aName, const nsAString& aValue,
1574 ErrorResult& aError);
1577 * Retrieve the ratio of font-size-inflated text font size to computed font
1578 * size for this element. This will query the element for its primary frame,
1579 * and then use this to get font size inflation information about the frame.
1581 * @returns The font size inflation ratio (inflated font size to uninflated
1582 * font size) for the primary frame of this element. Returns 1.0
1583 * by default if font size inflation is not enabled. Returns -1
1584 * if the element does not have a primary frame.
1586 * @note The font size inflation ratio that is returned is actually the
1587 * font size inflation data for the element's _primary frame_, not the
1588 * element itself, but for most purposes, this should be sufficient.
1590 float FontSizeInflation();
1592 net::ReferrerPolicy GetReferrerPolicyAsEnum();
1593 net::ReferrerPolicy ReferrerPolicyFromAttr(const nsAttrValue* aValue);
1596 * Helpers for .dataset. This is implemented on Element, though only some
1597 * sorts of elements expose it to JS as a .dataset property
1599 // Getter, to be called from bindings.
1600 already_AddRefed<nsDOMStringMap> Dataset();
1601 // Callback for destructor of dataset to ensure to null out our weak pointer
1602 // to it.
1603 void ClearDataset();
1605 void RegisterIntersectionObserver(DOMIntersectionObserver* aObserver);
1606 void UnregisterIntersectionObserver(DOMIntersectionObserver* aObserver);
1607 void UnlinkIntersectionObservers();
1608 bool UpdateIntersectionObservation(DOMIntersectionObserver* aObserver,
1609 int32_t threshold);
1611 // A number of methods to cast to various XUL interfaces. They return a
1612 // pointer only if the element implements that interface.
1613 already_AddRefed<nsIDOMXULButtonElement> AsXULButton();
1614 already_AddRefed<nsIDOMXULContainerElement> AsXULContainer();
1615 already_AddRefed<nsIDOMXULContainerItemElement> AsXULContainerItem();
1616 already_AddRefed<nsIDOMXULControlElement> AsXULControl();
1617 already_AddRefed<nsIDOMXULMenuListElement> AsXULMenuList();
1618 already_AddRefed<nsIDOMXULMultiSelectControlElement>
1619 AsXULMultiSelectControl();
1620 already_AddRefed<nsIDOMXULRadioGroupElement> AsXULRadioGroup();
1621 already_AddRefed<nsIDOMXULRelatedElement> AsXULRelated();
1622 already_AddRefed<nsIDOMXULSelectControlElement> AsXULSelectControl();
1623 already_AddRefed<nsIDOMXULSelectControlItemElement> AsXULSelectControlItem();
1624 already_AddRefed<nsIBrowser> AsBrowser();
1625 already_AddRefed<nsIAutoCompletePopup> AsAutoCompletePopup();
1627 protected:
1629 * Named-bools for use with SetAttrAndNotify to make call sites easier to
1630 * read.
1632 static const bool kFireMutationEvent = true;
1633 static const bool kDontFireMutationEvent = false;
1634 static const bool kNotifyDocumentObservers = true;
1635 static const bool kDontNotifyDocumentObservers = false;
1636 static const bool kCallAfterSetAttr = true;
1637 static const bool kDontCallAfterSetAttr = false;
1640 * Set attribute and (if needed) notify documentobservers and fire off
1641 * mutation events. This will send the AttributeChanged notification.
1642 * Callers of this method are responsible for calling AttributeWillChange,
1643 * since that needs to happen before the new attr value has been set, and
1644 * in particular before it has been parsed.
1646 * For the boolean parameters, consider using the named bools above to aid
1647 * code readability.
1649 * @param aNamespaceID namespace of attribute
1650 * @param aAttribute local-name of attribute
1651 * @param aPrefix aPrefix of attribute
1652 * @param aOldValue The old value of the attribute to use as a fallback
1653 * in the cases where the actual old value (i.e.
1654 * its current value) is !StoresOwnData() --- in which
1655 * case the current value is probably already useless.
1656 * If the current value is StoresOwnData() (or absent),
1657 * aOldValue will not be used. aOldValue will only be set
1658 * in certain circumstances (there are mutation
1659 * listeners, element is a custom element, attribute was
1660 * not previously unset). Otherwise it will be null.
1661 * @param aParsedValue parsed new value of attribute. Replaced by the
1662 * old value of the attribute. This old value is only
1663 * useful if either it or the new value is StoresOwnData.
1664 * @param aMaybeScriptedPrincipal
1665 * the principal of the scripted caller responsible for
1666 * setting the attribute, or null if no scripted caller
1667 * can be determined. A null value here does not
1668 * guarantee that there is no scripted caller, but a
1669 * non-null value does guarantee that a scripted caller
1670 * with the given principal is directly responsible for
1671 * the attribute change.
1672 * @param aModType MutationEvent_Binding::MODIFICATION or ADDITION. Only
1673 * needed if aFireMutation or aNotify is true.
1674 * @param aFireMutation should mutation-events be fired?
1675 * @param aNotify should we notify document-observers?
1676 * @param aCallAfterSetAttr should we call AfterSetAttr?
1677 * @param aComposedDocument The current composed document of the element.
1679 nsresult SetAttrAndNotify(int32_t aNamespaceID, nsAtom* aName,
1680 nsAtom* aPrefix, const nsAttrValue* aOldValue,
1681 nsAttrValue& aParsedValue,
1682 nsIPrincipal* aMaybeScriptedPrincipal,
1683 uint8_t aModType, bool aFireMutation, bool aNotify,
1684 bool aCallAfterSetAttr, Document* aComposedDocument,
1685 const mozAutoDocUpdate& aGuard);
1688 * Scroll to a new position using behavior evaluated from CSS and
1689 * a CSSOM-View DOM method ScrollOptions dictionary. The scrolling may
1690 * be performed asynchronously or synchronously depending on the resolved
1691 * scroll-behavior.
1693 * @param aScroll Destination of scroll, in CSS pixels
1694 * @param aOptions Dictionary of options to be evaluated
1696 MOZ_CAN_RUN_SCRIPT
1697 void Scroll(const CSSIntPoint& aScroll, const ScrollOptions& aOptions);
1700 * Convert an attribute string value to attribute type based on the type of
1701 * attribute. Called by SetAttr(). Note that at the moment we only do this
1702 * for attributes in the null namespace (kNameSpaceID_None).
1704 * @param aNamespaceID the namespace of the attribute to convert
1705 * @param aAttribute the attribute to convert
1706 * @param aValue the string value to convert
1707 * @param aMaybeScriptedPrincipal the principal of the script setting the
1708 * attribute, if one can be determined, or null otherwise. As in
1709 * AfterSetAttr, a null value does not guarantee that the attribute was
1710 * not set by a scripted caller, but a non-null value guarantees that
1711 * the attribute was set by a scripted caller with the given principal.
1712 * @param aResult the nsAttrValue [OUT]
1713 * @return true if the parsing was successful, false otherwise
1715 virtual bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
1716 const nsAString& aValue,
1717 nsIPrincipal* aMaybeScriptedPrincipal,
1718 nsAttrValue& aResult);
1721 * Try to set the attribute as a mapped attribute, if applicable. This will
1722 * only be called for attributes that are in the null namespace and only on
1723 * attributes that returned true when passed to IsAttributeMapped. The
1724 * caller will not try to set the attr in any other way if this method
1725 * returns true (the value of aRetval does not matter for that purpose).
1727 * @param aName the name of the attribute
1728 * @param aValue the nsAttrValue to set. Will be swapped with the existing
1729 * value of the attribute if the attribute already exists.
1730 * @param [out] aValueWasSet If the attribute was not set previously,
1731 * aValue will be swapped with an empty attribute
1732 * and aValueWasSet will be set to false. Otherwise,
1733 * aValueWasSet will be set to true and aValue will
1734 * contain the previous value set.
1735 * @param [out] aRetval the nsresult status of the operation, if any.
1736 * @return true if the setting was attempted, false otherwise.
1738 virtual bool SetAndSwapMappedAttribute(nsAtom* aName, nsAttrValue& aValue,
1739 bool* aValueWasSet, nsresult* aRetval);
1742 * Hook that is called by Element::SetAttr to allow subclasses to
1743 * deal with attribute sets. This will only be called after we verify that
1744 * we're actually doing an attr set and will be called before
1745 * AttributeWillChange and before ParseAttribute and hence before we've set
1746 * the new value.
1748 * @param aNamespaceID the namespace of the attr being set
1749 * @param aName the localname of the attribute being set
1750 * @param aValue the value it's being set to represented as either a string or
1751 * a parsed nsAttrValue. Alternatively, if the attr is being removed it
1752 * will be null.
1753 * @param aNotify Whether we plan to notify document observers.
1755 virtual nsresult BeforeSetAttr(int32_t aNamespaceID, nsAtom* aName,
1756 const nsAttrValueOrString* aValue,
1757 bool aNotify);
1760 * Hook that is called by Element::SetAttr to allow subclasses to
1761 * deal with attribute sets. This will only be called after we have called
1762 * SetAndSwapAttr (that is, after we have actually set the attr). It will
1763 * always be called under a scriptblocker.
1765 * @param aNamespaceID the namespace of the attr being set
1766 * @param aName the localname of the attribute being set
1767 * @param aValue the value it's being set to. If null, the attr is being
1768 * removed.
1769 * @param aOldValue the value that the attribute had previously. If null,
1770 * the attr was not previously set. This argument may not have the
1771 * correct value for SVG elements, or other cases in which the
1772 * attribute value doesn't store its own data
1773 * @param aMaybeScriptedPrincipal the principal of the scripted caller
1774 * responsible for setting the attribute, or null if no scripted caller
1775 * can be determined, or the attribute is being unset. A null value
1776 * here does not guarantee that there is no scripted caller, but a
1777 * non-null value does guarantee that a scripted caller with the given
1778 * principal is directly responsible for the attribute change.
1779 * @param aNotify Whether we plan to notify document observers.
1781 // Note that this is inlined so that when subclasses call it it gets
1782 // inlined. Those calls don't go through a vtable.
1783 virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsAtom* aName,
1784 const nsAttrValue* aValue,
1785 const nsAttrValue* aOldValue,
1786 nsIPrincipal* aMaybeScriptedPrincipal,
1787 bool aNotify) {
1788 return NS_OK;
1792 * This function shall be called just before the id attribute changes. It will
1793 * be called after BeforeSetAttr. If the attribute being changed is not the id
1794 * attribute, this function does nothing. Otherwise, it will remove the old id
1795 * from the document's id cache.
1797 * This must happen after BeforeSetAttr (rather than during) because the
1798 * the subclasses' calls to BeforeSetAttr may notify on state changes. If they
1799 * incorrectly determine whether the element had an id, the element may not be
1800 * restyled properly.
1802 * @param aNamespaceID the namespace of the attr being set
1803 * @param aName the localname of the attribute being set
1804 * @param aValue the new id value. Will be null if the id is being unset.
1806 void PreIdMaybeChange(int32_t aNamespaceID, nsAtom* aName,
1807 const nsAttrValueOrString* aValue);
1810 * This function shall be called just after the id attribute changes. It will
1811 * be called before AfterSetAttr. If the attribute being changed is not the id
1812 * attribute, this function does nothing. Otherwise, it will add the new id to
1813 * the document's id cache and properly set the ElementHasID flag.
1815 * This must happen before AfterSetAttr (rather than during) because the
1816 * the subclasses' calls to AfterSetAttr may notify on state changes. If they
1817 * incorrectly determine whether the element now has an id, the element may
1818 * not be restyled properly.
1820 * @param aNamespaceID the namespace of the attr being set
1821 * @param aName the localname of the attribute being set
1822 * @param aValue the new id value. Will be null if the id is being unset.
1824 void PostIdMaybeChange(int32_t aNamespaceID, nsAtom* aName,
1825 const nsAttrValue* aValue);
1828 * Usually, setting an attribute to the value that it already has results in
1829 * no action. However, in some cases, setting an attribute to its current
1830 * value should have the effect of, for example, forcing a reload of
1831 * network data. To address that, this function will be called in this
1832 * situation to allow the handling of such a case.
1834 * @param aNamespaceID the namespace of the attr being set
1835 * @param aName the localname of the attribute being set
1836 * @param aValue the value it's being set to represented as either a string or
1837 * a parsed nsAttrValue.
1838 * @param aNotify Whether we plan to notify document observers.
1840 // Note that this is inlined so that when subclasses call it it gets
1841 // inlined. Those calls don't go through a vtable.
1842 virtual nsresult OnAttrSetButNotChanged(int32_t aNamespaceID, nsAtom* aName,
1843 const nsAttrValueOrString& aValue,
1844 bool aNotify);
1847 * Hook to allow subclasses to produce a different EventListenerManager if
1848 * needed for attachment of attribute-defined handlers
1850 virtual EventListenerManager* GetEventListenerManagerForAttr(
1851 nsAtom* aAttrName, bool* aDefer);
1854 * Internal hook for converting an attribute name-string to nsAttrName in
1855 * case there is such existing attribute. aNameToUse can be passed to get
1856 * name which was used for looking for the attribute (lowercase in HTML).
1858 const nsAttrName* InternalGetAttrNameFromQName(
1859 const nsAString& aStr, nsAutoString* aNameToUse = nullptr) const;
1861 virtual Element* GetNameSpaceElement() override { return this; }
1863 Attr* GetAttributeNodeNSInternal(const nsAString& aNamespaceURI,
1864 const nsAString& aLocalName);
1866 inline void RegisterActivityObserver();
1867 inline void UnregisterActivityObserver();
1870 * Add/remove this element to the documents id cache
1872 void AddToIdTable(nsAtom* aId);
1873 void RemoveFromIdTable();
1876 * Functions to carry out event default actions for links of all types
1877 * (HTML links, XLinks, SVG "XLinks", etc.)
1881 * Check that we meet the conditions to handle a link event
1882 * and that we are actually on a link.
1884 * @param aVisitor event visitor
1885 * @param aURI the uri of the link, set only if the return value is true [OUT]
1886 * @return true if we can handle the link event, false otherwise
1888 bool CheckHandleEventForLinksPrecondition(EventChainVisitor& aVisitor,
1889 nsIURI** aURI) const;
1892 * Handle status bar updates before they can be cancelled.
1894 void GetEventTargetParentForLinks(EventChainPreVisitor& aVisitor);
1897 * Handle default actions for link event if the event isn't consumed yet.
1899 MOZ_CAN_RUN_SCRIPT
1900 nsresult PostHandleEventForLinks(EventChainPostVisitor& aVisitor);
1903 * Get the target of this link element. Consumers should established that
1904 * this element is a link (probably using IsLink) before calling this
1905 * function (or else why call it?)
1907 * Note: for HTML this gets the value of the 'target' attribute; for XLink
1908 * this gets the value of the xlink:_moz_target attribute, or failing that,
1909 * the value of xlink:show, converted to a suitably equivalent named target
1910 * (e.g. _blank).
1912 virtual void GetLinkTarget(nsAString& aTarget);
1914 nsDOMTokenList* GetTokenList(
1915 nsAtom* aAtom,
1916 const DOMTokenListSupportedTokenArray aSupportedTokens = nullptr);
1919 * Copy attributes and state to another element
1920 * @param aDest the object to copy to
1922 nsresult CopyInnerTo(Element* aDest);
1924 private:
1926 * Slow path for GetClasses, this should only be called for SVG elements.
1928 const nsAttrValue* GetSVGAnimatedClass() const;
1931 * Get this element's client area rect in app units.
1932 * @return the frame's client area
1934 MOZ_CAN_RUN_SCRIPT nsRect GetClientAreaRect();
1937 * GetCustomInterface is somewhat like a GetInterface, but it is expected
1938 * that the implementation is provided by a custom element or via the
1939 * the XBL implements keyword. To use this, create a public method that
1940 * wraps a call to GetCustomInterface.
1942 template <class T>
1943 void GetCustomInterface(nsGetterAddRefs<T> aResult);
1945 // Prevent people from doing pointless checks/casts on Element instances.
1946 void IsElement() = delete;
1947 void AsElement() = delete;
1949 // Data members
1950 EventStates mState;
1951 // Per-node data managed by Servo.
1953 // There should not be data on nodes that are not in the flattened tree, or
1954 // descendants of display: none elements.
1955 mozilla::RustCell<ServoNodeData*> mServoData;
1957 protected:
1958 // Array containing all attributes for this element
1959 AttrArray mAttrs;
1962 class RemoveFromBindingManagerRunnable : public mozilla::Runnable {
1963 public:
1964 RemoveFromBindingManagerRunnable(nsBindingManager* aManager,
1965 nsIContent* aContent, Document* aDoc);
1967 NS_IMETHOD Run() override;
1969 private:
1970 virtual ~RemoveFromBindingManagerRunnable();
1971 RefPtr<nsBindingManager> mManager;
1972 RefPtr<nsIContent> mContent;
1973 RefPtr<Document> mDoc;
1976 NS_DEFINE_STATIC_IID_ACCESSOR(Element, NS_ELEMENT_IID)
1978 inline bool Element::HasAttr(int32_t aNameSpaceID, const nsAtom* aName) const {
1979 NS_ASSERTION(nullptr != aName, "must have attribute name");
1980 NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown,
1981 "must have a real namespace ID!");
1983 return mAttrs.IndexOfAttr(aName, aNameSpaceID) >= 0;
1986 inline bool Element::AttrValueIs(int32_t aNameSpaceID, const nsAtom* aName,
1987 const nsAString& aValue,
1988 nsCaseTreatment aCaseSensitive) const {
1989 NS_ASSERTION(aName, "Must have attr name");
1990 NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown, "Must have namespace");
1992 const nsAttrValue* val = mAttrs.GetAttr(aName, aNameSpaceID);
1993 return val && val->Equals(aValue, aCaseSensitive);
1996 inline bool Element::AttrValueIs(int32_t aNameSpaceID, const nsAtom* aName,
1997 const nsAtom* aValue,
1998 nsCaseTreatment aCaseSensitive) const {
1999 NS_ASSERTION(aName, "Must have attr name");
2000 NS_ASSERTION(aNameSpaceID != kNameSpaceID_Unknown, "Must have namespace");
2001 NS_ASSERTION(aValue, "Null value atom");
2003 const nsAttrValue* val = mAttrs.GetAttr(aName, aNameSpaceID);
2004 return val && val->Equals(aValue, aCaseSensitive);
2007 } // namespace dom
2008 } // namespace mozilla
2010 inline mozilla::dom::Element* nsINode::AsElement() {
2011 MOZ_ASSERT(IsElement());
2012 return static_cast<mozilla::dom::Element*>(this);
2015 inline const mozilla::dom::Element* nsINode::AsElement() const {
2016 MOZ_ASSERT(IsElement());
2017 return static_cast<const mozilla::dom::Element*>(this);
2020 inline mozilla::dom::Element* nsINode::GetParentElement() const {
2021 return mozilla::dom::Element::FromNodeOrNull(mParent);
2024 inline mozilla::dom::Element* nsINode::GetPreviousElementSibling() const {
2025 nsIContent* previousSibling = GetPreviousSibling();
2026 while (previousSibling) {
2027 if (previousSibling->IsElement()) {
2028 return previousSibling->AsElement();
2030 previousSibling = previousSibling->GetPreviousSibling();
2033 return nullptr;
2036 inline mozilla::dom::Element* nsINode::GetNextElementSibling() const {
2037 nsIContent* nextSibling = GetNextSibling();
2038 while (nextSibling) {
2039 if (nextSibling->IsElement()) {
2040 return nextSibling->AsElement();
2042 nextSibling = nextSibling->GetNextSibling();
2045 return nullptr;
2049 * Macros to implement Clone(). _elementName is the class for which to implement
2050 * Clone.
2052 #define NS_IMPL_ELEMENT_CLONE(_elementName) \
2053 nsresult _elementName::Clone(mozilla::dom::NodeInfo* aNodeInfo, \
2054 nsINode** aResult) const { \
2055 *aResult = nullptr; \
2056 RefPtr<mozilla::dom::NodeInfo> ni(aNodeInfo); \
2057 RefPtr<_elementName> it = new _elementName(ni.forget()); \
2058 nsresult rv = const_cast<_elementName*>(this)->CopyInnerTo(it); \
2059 if (NS_SUCCEEDED(rv)) { \
2060 it.forget(aResult); \
2063 return rv; \
2066 #define EXPAND(...) __VA_ARGS__
2067 #define NS_IMPL_ELEMENT_CLONE_WITH_INIT_HELPER(_elementName, extra_args_) \
2068 nsresult _elementName::Clone(mozilla::dom::NodeInfo* aNodeInfo, \
2069 nsINode** aResult) const { \
2070 *aResult = nullptr; \
2071 RefPtr<mozilla::dom::NodeInfo> ni(aNodeInfo); \
2072 RefPtr<_elementName> it = \
2073 new _elementName(ni.forget() EXPAND extra_args_); \
2074 nsresult rv = it->Init(); \
2075 nsresult rv2 = const_cast<_elementName*>(this)->CopyInnerTo(it); \
2076 if (NS_FAILED(rv2)) { \
2077 rv = rv2; \
2079 if (NS_SUCCEEDED(rv)) { \
2080 it.forget(aResult); \
2083 return rv; \
2086 #define NS_IMPL_ELEMENT_CLONE_WITH_INIT(_elementName) \
2087 NS_IMPL_ELEMENT_CLONE_WITH_INIT_HELPER(_elementName, ())
2088 #define NS_IMPL_ELEMENT_CLONE_WITH_INIT_AND_PARSER(_elementName) \
2089 NS_IMPL_ELEMENT_CLONE_WITH_INIT_HELPER(_elementName, (, NOT_FROM_PARSER))
2091 #endif // mozilla_dom_Element_h__