Bug 1885602 - Part 5: Implement navigating to the SUMO help topic from the menu heade...
[gecko.git] / dom / html / nsGenericHTMLElement.h
blob86f87e8795a1864e92345be7520ac7f210cb54b7
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef nsGenericHTMLElement_h___
7 #define nsGenericHTMLElement_h___
9 #include "mozilla/Attributes.h"
10 #include "mozilla/EventForwards.h"
11 #include "nsNameSpaceManager.h" // for kNameSpaceID_None
12 #include "nsIFormControl.h"
13 #include "nsGkAtoms.h"
14 #include "nsContentCreatorFunctions.h"
15 #include "nsStyledElement.h"
16 #include "mozilla/dom/BindingDeclarations.h"
17 #include "mozilla/dom/Element.h"
18 #include "mozilla/dom/DOMRect.h"
19 #include "mozilla/dom/ValidityState.h"
20 #include "mozilla/dom/PopoverData.h"
21 #include "mozilla/dom/ToggleEvent.h"
23 #include <cstdint>
25 class nsDOMTokenList;
26 class nsIFormControlFrame;
27 class nsIFrame;
28 class nsILayoutHistoryState;
29 class nsIURI;
30 struct nsSize;
32 enum nsCSSPropertyID : int32_t;
34 namespace mozilla {
35 class EditorBase;
36 class ErrorResult;
37 class EventChainPostVisitor;
38 class EventChainPreVisitor;
39 class EventChainVisitor;
40 class EventListenerManager;
41 class PresState;
42 namespace dom {
43 class ElementInternals;
44 class HTMLFormElement;
45 enum class FetchPriority : uint8_t;
46 } // namespace dom
47 } // namespace mozilla
49 using nsGenericHTMLElementBase = nsStyledElement;
51 /**
52 * A common superclass for HTML elements
54 class nsGenericHTMLElement : public nsGenericHTMLElementBase {
55 public:
56 using Element::Focus;
57 using Element::SetTabIndex;
58 explicit nsGenericHTMLElement(
59 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
60 : nsGenericHTMLElementBase(std::move(aNodeInfo)) {
61 NS_ASSERTION(mNodeInfo->NamespaceID() == kNameSpaceID_XHTML,
62 "Unexpected namespace");
65 NS_INLINE_DECL_REFCOUNTING_INHERITED(nsGenericHTMLElement,
66 nsGenericHTMLElementBase)
68 NS_IMPL_FROMNODE(nsGenericHTMLElement, kNameSpaceID_XHTML)
70 // From Element
71 nsresult CopyInnerTo(mozilla::dom::Element* aDest);
73 void GetTitle(mozilla::dom::DOMString& aTitle) {
74 GetHTMLAttr(nsGkAtoms::title, aTitle);
76 void SetTitle(const nsAString& aTitle) {
77 SetHTMLAttr(nsGkAtoms::title, aTitle);
79 void GetLang(mozilla::dom::DOMString& aLang) {
80 GetHTMLAttr(nsGkAtoms::lang, aLang);
82 void SetLang(const nsAString& aLang) { SetHTMLAttr(nsGkAtoms::lang, aLang); }
83 bool Translate() const override;
84 void SetTranslate(bool aTranslate, mozilla::ErrorResult& aError) {
85 SetHTMLAttr(nsGkAtoms::translate, aTranslate ? u"yes"_ns : u"no"_ns,
86 aError);
88 void GetDir(nsAString& aDir) { GetHTMLEnumAttr(nsGkAtoms::dir, aDir); }
89 void SetDir(const nsAString& aDir, mozilla::ErrorResult& aError) {
90 SetHTMLAttr(nsGkAtoms::dir, aDir, aError);
92 void GetPopover(nsString& aPopover) const;
93 void SetPopover(const nsAString& aPopover, mozilla::ErrorResult& aError) {
94 SetOrRemoveNullableStringAttr(nsGkAtoms::popover, aPopover, aError);
96 bool Hidden() const { return GetBoolAttr(nsGkAtoms::hidden); }
97 void SetHidden(bool aHidden, mozilla::ErrorResult& aError) {
98 SetHTMLBoolAttr(nsGkAtoms::hidden, aHidden, aError);
100 bool Inert() const { return GetBoolAttr(nsGkAtoms::inert); }
101 void SetInert(bool aInert, mozilla::ErrorResult& aError) {
102 SetHTMLBoolAttr(nsGkAtoms::inert, aInert, aError);
104 MOZ_CAN_RUN_SCRIPT void Click(mozilla::dom::CallerType aCallerType);
105 void GetAccessKey(nsString& aAccessKey) {
106 GetHTMLAttr(nsGkAtoms::accesskey, aAccessKey);
108 void SetAccessKey(const nsAString& aAccessKey, mozilla::ErrorResult& aError) {
109 SetHTMLAttr(nsGkAtoms::accesskey, aAccessKey, aError);
111 void GetAccessKeyLabel(nsString& aAccessKeyLabel);
112 virtual bool Draggable() const {
113 return AttrValueIs(kNameSpaceID_None, nsGkAtoms::draggable,
114 nsGkAtoms::_true, eIgnoreCase);
116 void SetDraggable(bool aDraggable, mozilla::ErrorResult& aError) {
117 SetHTMLAttr(nsGkAtoms::draggable, aDraggable ? u"true"_ns : u"false"_ns,
118 aError);
120 void GetContentEditable(nsString& aContentEditable) {
121 ContentEditableTristate value = GetContentEditableValue();
122 if (value == eTrue) {
123 aContentEditable.AssignLiteral("true");
124 } else if (value == eFalse) {
125 aContentEditable.AssignLiteral("false");
126 } else {
127 aContentEditable.AssignLiteral("inherit");
130 void SetContentEditable(const nsAString& aContentEditable,
131 mozilla::ErrorResult& aError) {
132 if (aContentEditable.LowerCaseEqualsLiteral("inherit")) {
133 UnsetHTMLAttr(nsGkAtoms::contenteditable, aError);
134 } else if (aContentEditable.LowerCaseEqualsLiteral("true")) {
135 SetHTMLAttr(nsGkAtoms::contenteditable, u"true"_ns, aError);
136 } else if (aContentEditable.LowerCaseEqualsLiteral("false")) {
137 SetHTMLAttr(nsGkAtoms::contenteditable, u"false"_ns, aError);
138 } else {
139 aError.Throw(NS_ERROR_DOM_SYNTAX_ERR);
142 bool IsContentEditable() {
143 for (nsIContent* node = this; node; node = node->GetParent()) {
144 nsGenericHTMLElement* element = FromNode(node);
145 if (element) {
146 ContentEditableTristate value = element->GetContentEditableValue();
147 if (value != eInherit) {
148 return value == eTrue;
152 return false;
155 mozilla::dom::PopoverAttributeState GetPopoverAttributeState() const;
156 void PopoverPseudoStateUpdate(bool aOpen, bool aNotify);
157 bool PopoverOpen() const;
158 bool CheckPopoverValidity(mozilla::dom::PopoverVisibilityState aExpectedState,
159 Document* aExpectedDocument, ErrorResult& aRv);
160 already_AddRefed<mozilla::dom::ToggleEvent> CreateToggleEvent(
161 const nsAString& aEventType, const nsAString& aOldState,
162 const nsAString& aNewState, mozilla::Cancelable);
163 /** Returns true if the event has been cancelled. */
164 MOZ_CAN_RUN_SCRIPT bool FireToggleEvent(
165 mozilla::dom::PopoverVisibilityState aOldState,
166 mozilla::dom::PopoverVisibilityState aNewState, const nsAString& aType);
167 MOZ_CAN_RUN_SCRIPT void QueuePopoverEventTask(
168 mozilla::dom::PopoverVisibilityState aOldState);
169 MOZ_CAN_RUN_SCRIPT void RunPopoverToggleEventTask(
170 mozilla::dom::PopoverToggleEventTask* aTask,
171 mozilla::dom::PopoverVisibilityState aOldState);
172 MOZ_CAN_RUN_SCRIPT void ShowPopover(ErrorResult& aRv);
173 MOZ_CAN_RUN_SCRIPT void ShowPopoverInternal(Element* aInvoker,
174 ErrorResult& aRv);
175 MOZ_CAN_RUN_SCRIPT_BOUNDARY void HidePopoverWithoutRunningScript();
176 MOZ_CAN_RUN_SCRIPT void HidePopoverInternal(bool aFocusPreviousElement,
177 bool aFireEvents,
178 ErrorResult& aRv);
179 MOZ_CAN_RUN_SCRIPT void HidePopover(ErrorResult& aRv);
180 MOZ_CAN_RUN_SCRIPT bool TogglePopover(
181 const mozilla::dom::Optional<bool>& aForce, ErrorResult& aRv);
182 MOZ_CAN_RUN_SCRIPT void FocusPopover();
183 void ForgetPreviouslyFocusedElementAfterHidingPopover();
184 MOZ_CAN_RUN_SCRIPT void FocusPreviousElementAfterHidingPopover();
186 MOZ_CAN_RUN_SCRIPT void FocusCandidate(Element*, bool aClearUpFocus);
188 void SetNonce(const nsAString& aNonce) {
189 SetProperty(nsGkAtoms::nonce, new nsString(aNonce),
190 nsINode::DeleteProperty<nsString>, /* aTransfer = */ true);
192 void RemoveNonce() { RemoveProperty(nsGkAtoms::nonce); }
193 void GetNonce(nsAString& aNonce) const {
194 nsString* cspNonce = static_cast<nsString*>(GetProperty(nsGkAtoms::nonce));
195 if (cspNonce) {
196 aNonce = *cspNonce;
200 /** Returns whether a form control should be default-focusable. */
201 bool IsFormControlDefaultFocusable(bool aWithMouse) const;
204 * Returns the count of descendants (inclusive of this node) in
205 * the uncomposed document that are explicitly set as editable.
207 uint32_t EditableInclusiveDescendantCount();
209 bool Spellcheck();
210 void SetSpellcheck(bool aSpellcheck, mozilla::ErrorResult& aError) {
211 SetHTMLAttr(nsGkAtoms::spellcheck, aSpellcheck ? u"true"_ns : u"false"_ns,
212 aError);
215 MOZ_CAN_RUN_SCRIPT
216 void GetInnerText(mozilla::dom::DOMString& aValue, ErrorResult& aError);
217 MOZ_CAN_RUN_SCRIPT
218 void GetOuterText(mozilla::dom::DOMString& aValue, ErrorResult& aError) {
219 return GetInnerText(aValue, aError);
221 MOZ_CAN_RUN_SCRIPT void SetInnerText(const nsAString& aValue);
222 MOZ_CAN_RUN_SCRIPT void SetOuterText(const nsAString& aValue,
223 ErrorResult& aRv);
225 void GetInputMode(nsAString& aValue) {
226 GetEnumAttr(nsGkAtoms::inputmode, nullptr, aValue);
228 void SetInputMode(const nsAString& aValue, ErrorResult& aRv) {
229 SetHTMLAttr(nsGkAtoms::inputmode, aValue, aRv);
231 virtual void GetAutocapitalize(nsAString& aValue) const;
232 void SetAutocapitalize(const nsAString& aValue, ErrorResult& aRv) {
233 SetHTMLAttr(nsGkAtoms::autocapitalize, aValue, aRv);
236 void GetEnterKeyHint(nsAString& aValue) const {
237 GetEnumAttr(nsGkAtoms::enterkeyhint, nullptr, aValue);
239 void SetEnterKeyHint(const nsAString& aValue, ErrorResult& aRv) {
240 SetHTMLAttr(nsGkAtoms::enterkeyhint, aValue, aRv);
244 * Determine whether an attribute is an event (onclick, etc.)
245 * @param aName the attribute
246 * @return whether the name is an event handler name
248 bool IsEventAttributeNameInternal(nsAtom* aName) override;
250 #define EVENT(name_, id_, type_, struct_) /* nothing; handled by nsINode */
251 // The using nsINode::Get/SetOn* are to avoid warnings about shadowing the XPCOM
252 // getter and setter on nsINode.
253 #define FORWARDED_EVENT(name_, id_, type_, struct_) \
254 using nsINode::GetOn##name_; \
255 using nsINode::SetOn##name_; \
256 mozilla::dom::EventHandlerNonNull* GetOn##name_(); \
257 void SetOn##name_(mozilla::dom::EventHandlerNonNull* handler);
258 #define ERROR_EVENT(name_, id_, type_, struct_) \
259 using nsINode::GetOn##name_; \
260 using nsINode::SetOn##name_; \
261 already_AddRefed<mozilla::dom::EventHandlerNonNull> GetOn##name_(); \
262 void SetOn##name_(mozilla::dom::EventHandlerNonNull* handler);
263 #include "mozilla/EventNameList.h" // IWYU pragma: keep
264 #undef ERROR_EVENT
265 #undef FORWARDED_EVENT
266 #undef EVENT
267 mozilla::dom::Element* GetOffsetParent() {
268 mozilla::CSSIntRect rcFrame;
269 return GetOffsetRect(rcFrame);
271 int32_t OffsetTop() {
272 mozilla::CSSIntRect rcFrame;
273 GetOffsetRect(rcFrame);
275 return rcFrame.y;
277 int32_t OffsetLeft() {
278 mozilla::CSSIntRect rcFrame;
279 GetOffsetRect(rcFrame);
281 return rcFrame.x;
283 int32_t OffsetWidth() {
284 mozilla::CSSIntRect rcFrame;
285 GetOffsetRect(rcFrame);
287 return rcFrame.Width();
289 int32_t OffsetHeight() {
290 mozilla::CSSIntRect rcFrame;
291 GetOffsetRect(rcFrame);
293 return rcFrame.Height();
296 // These methods are already implemented in nsIContent but we want something
297 // faster for HTMLElements ignoring the namespace checking.
298 // This is safe because we already know that we are in the HTML namespace.
299 inline bool IsHTMLElement() const { return true; }
301 inline bool IsHTMLElement(nsAtom* aTag) const {
302 return mNodeInfo->Equals(aTag);
305 template <typename First, typename... Args>
306 inline bool IsAnyOfHTMLElements(First aFirst, Args... aArgs) const {
307 return IsNodeInternal(aFirst, aArgs...);
310 // https://html.spec.whatwg.org/multipage/custom-elements.html#dom-attachinternals
311 virtual already_AddRefed<mozilla::dom::ElementInternals> AttachInternals(
312 ErrorResult& aRv);
314 mozilla::dom::ElementInternals* GetInternals() const;
316 bool IsFormAssociatedCustomElements() const;
318 // Returns true if the event should not be handled from GetEventTargetParent.
319 virtual bool IsDisabledForEvents(mozilla::WidgetEvent* aEvent) {
320 return false;
323 bool Autofocus() const { return GetBoolAttr(nsGkAtoms::autofocus); }
324 void SetAutofocus(bool aVal, ErrorResult& aRv) {
325 SetHTMLBoolAttr(nsGkAtoms::autofocus, aVal, aRv);
328 protected:
329 virtual ~nsGenericHTMLElement() = default;
331 public:
332 // Implementation for nsIContent
333 nsresult BindToTree(BindContext&, nsINode& aParent) override;
334 void UnbindFromTree(UnbindContext&) override;
336 Focusable IsFocusableWithoutStyle(bool aWithMouse) override {
337 Focusable result;
338 IsHTMLFocusable(aWithMouse, &result.mFocusable, &result.mTabIndex);
339 return result;
342 * Returns true if a subclass is not allowed to override the value returned
343 * in aIsFocusable.
345 virtual bool IsHTMLFocusable(bool aWithMouse, bool* aIsFocusable,
346 int32_t* aTabIndex);
347 MOZ_CAN_RUN_SCRIPT
348 mozilla::Result<bool, nsresult> PerformAccesskey(
349 bool aKeyCausesActivation, bool aIsTrustedEvent) override;
352 * Check if an event for an anchor can be handled
353 * @return true if the event can be handled, false otherwise
355 bool CheckHandleEventForAnchorsPreconditions(
356 mozilla::EventChainVisitor& aVisitor);
357 void GetEventTargetParentForAnchors(mozilla::EventChainPreVisitor& aVisitor);
358 MOZ_CAN_RUN_SCRIPT
359 nsresult PostHandleEventForAnchors(mozilla::EventChainPostVisitor& aVisitor);
360 bool IsHTMLLink(nsIURI** aURI) const;
362 // HTML element methods
363 void Compact() { mAttrs.Compact(); }
365 void UpdateEditableState(bool aNotify) override;
367 bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
368 const nsAString& aValue,
369 nsIPrincipal* aMaybeScriptedPrincipal,
370 nsAttrValue& aResult) override;
372 bool ParseBackgroundAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
373 const nsAString& aValue, nsAttrValue& aResult);
375 NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
376 nsMapRuleToAttributesFunc GetAttributeMappingFunction() const override;
379 * Get the base target for any links within this piece
380 * of content. Generally, this is the document's base target,
381 * but certain content carries a local base for backward
382 * compatibility.
384 * @param aBaseTarget the base target [OUT]
386 void GetBaseTarget(nsAString& aBaseTarget) const;
389 * Get the primary form control frame for this element. Same as
390 * GetPrimaryFrame(), except it QI's to nsIFormControlFrame.
392 * @param aFlush whether to flush out frames so that they're up to date.
393 * @return the primary frame as nsIFormControlFrame
395 nsIFormControlFrame* GetFormControlFrame(bool aFlushFrames);
397 //----------------------------------------
400 * Parse an alignment attribute (top/middle/bottom/baseline)
402 * @param aString the string to parse
403 * @param aResult the resulting HTMLValue
404 * @return whether the value was parsed
406 static bool ParseAlignValue(const nsAString& aString, nsAttrValue& aResult);
409 * Parse a div align string to value (left/right/center/middle/justify)
411 * @param aString the string to parse
412 * @param aResult the resulting HTMLValue
413 * @return whether the value was parsed
415 static bool ParseDivAlignValue(const nsAString& aString,
416 nsAttrValue& aResult);
419 * Convert a table halign string to value (left/right/center/char/justify)
421 * @param aString the string to parse
422 * @param aResult the resulting HTMLValue
423 * @return whether the value was parsed
425 static bool ParseTableHAlignValue(const nsAString& aString,
426 nsAttrValue& aResult);
429 * Convert a table cell halign string to value
431 * @param aString the string to parse
432 * @param aResult the resulting HTMLValue
433 * @return whether the value was parsed
435 static bool ParseTableCellHAlignValue(const nsAString& aString,
436 nsAttrValue& aResult);
439 * Convert a table valign string to value (left/right/center/char/justify/
440 * abscenter/absmiddle/middle)
442 * @param aString the string to parse
443 * @param aResult the resulting HTMLValue
444 * @return whether the value was parsed
446 static bool ParseTableVAlignValue(const nsAString& aString,
447 nsAttrValue& aResult);
450 * Convert an image attribute to value (width, height, hspace, vspace, border)
452 * @param aAttribute the attribute to parse
453 * @param aString the string to parse
454 * @param aResult the resulting HTMLValue
455 * @return whether the value was parsed
457 static bool ParseImageAttribute(nsAtom* aAttribute, const nsAString& aString,
458 nsAttrValue& aResult);
460 static bool ParseReferrerAttribute(const nsAString& aString,
461 nsAttrValue& aResult);
464 * Convert a frameborder string to value (yes/no/1/0)
466 * @param aString the string to parse
467 * @param aResult the resulting HTMLValue
468 * @return whether the value was parsed
470 static bool ParseFrameborderValue(const nsAString& aString,
471 nsAttrValue& aResult);
474 * Convert a scrolling string to value (yes/no/on/off/scroll/noscroll/auto)
476 * @param aString the string to parse
477 * @param aResult the resulting HTMLValue
478 * @return whether the value was parsed
480 static bool ParseScrollingValue(const nsAString& aString,
481 nsAttrValue& aResult);
484 * Attribute Mapping Helpers
488 * A style attribute mapping function for the most common attributes, to be
489 * called by subclasses' attribute mapping functions. Currently handles
490 * dir, lang and hidden, could handle others.
492 * @param aAttributes the list of attributes to map
493 * @param aData the returned rule data [INOUT]
494 * @see GetAttributeMappingFunction
496 static void MapCommonAttributesInto(mozilla::MappedDeclarationsBuilder&);
498 * Same as MapCommonAttributesInto except that it does not handle hidden.
499 * @see GetAttributeMappingFunction
501 static void MapCommonAttributesIntoExceptHidden(
502 mozilla::MappedDeclarationsBuilder&);
504 static const MappedAttributeEntry sCommonAttributeMap[];
505 static const MappedAttributeEntry sImageMarginSizeAttributeMap[];
506 static const MappedAttributeEntry sImageBorderAttributeMap[];
507 static const MappedAttributeEntry sImageAlignAttributeMap[];
508 static const MappedAttributeEntry sDivAlignAttributeMap[];
509 static const MappedAttributeEntry sBackgroundAttributeMap[];
510 static const MappedAttributeEntry sBackgroundColorAttributeMap[];
513 * Helper to map the align attribute.
514 * @see GetAttributeMappingFunction
516 static void MapImageAlignAttributeInto(mozilla::MappedDeclarationsBuilder&);
519 * Helper to map the align attribute for things like <div>, <h1>, etc.
520 * @see GetAttributeMappingFunction
522 static void MapDivAlignAttributeInto(mozilla::MappedDeclarationsBuilder&);
525 * Helper to map the valign attribute for things like <col>, <tr>, <section>.
526 * @see GetAttributeMappingFunction
528 static void MapVAlignAttributeInto(mozilla::MappedDeclarationsBuilder&);
531 * Helper to map the image border attribute.
532 * @see GetAttributeMappingFunction
534 static void MapImageBorderAttributeInto(mozilla::MappedDeclarationsBuilder&);
536 * Helper to map the image margin attribute into a style struct.
538 * @param aAttributes the list of attributes to map
539 * @param aData the returned rule data [INOUT]
540 * @see GetAttributeMappingFunction
542 static void MapImageMarginAttributeInto(mozilla::MappedDeclarationsBuilder&);
545 * Helper to map a given dimension (width/height) into the declaration
546 * block, handling percentages and numbers.
548 static void MapDimensionAttributeInto(mozilla::MappedDeclarationsBuilder&,
549 nsCSSPropertyID, const nsAttrValue&);
552 * Maps the aspect ratio given width and height attributes.
554 static void DoMapAspectRatio(const nsAttrValue& aWidth,
555 const nsAttrValue& aHeight,
556 mozilla::MappedDeclarationsBuilder&);
558 // Whether to map the width and height attributes to aspect-ratio.
559 enum class MapAspectRatio { No, Yes };
562 * Helper to map the image position attribute into a style struct.
564 static void MapImageSizeAttributesInto(mozilla::MappedDeclarationsBuilder&,
565 MapAspectRatio = MapAspectRatio::No);
568 * Helper to map the width and height attributes into the aspect-ratio
569 * property.
571 * If you also map the width/height attributes to width/height (as you should
572 * for any HTML element that isn't <canvas>) then you should use
573 * MapImageSizeAttributesInto instead, passing MapAspectRatio::Yes instead, as
574 * that'd be faster.
576 static void MapAspectRatioInto(mozilla::MappedDeclarationsBuilder&);
579 * Helper to map `width` attribute into a style struct.
581 * @param aAttributes the list of attributes to map
582 * @param aData the returned rule data [INOUT]
583 * @see GetAttributeMappingFunction
585 static void MapWidthAttributeInto(mozilla::MappedDeclarationsBuilder&);
588 * Helper to map `height` attribute.
589 * @see GetAttributeMappingFunction
591 static void MapHeightAttributeInto(mozilla::MappedDeclarationsBuilder&);
593 * Helper to map the background attribute
594 * @see GetAttributeMappingFunction
596 static void MapBackgroundInto(mozilla::MappedDeclarationsBuilder&);
598 * Helper to map the bgcolor attribute
599 * @see GetAttributeMappingFunction
601 static void MapBGColorInto(mozilla::MappedDeclarationsBuilder&);
603 * Helper to map the background attributes (currently background and bgcolor)
604 * @see GetAttributeMappingFunction
606 static void MapBackgroundAttributesInto(mozilla::MappedDeclarationsBuilder&);
608 * Helper to map the scrolling attribute on FRAME and IFRAME.
609 * @see GetAttributeMappingFunction
611 static void MapScrollingAttributeInto(mozilla::MappedDeclarationsBuilder&);
613 // Form Helper Routines
615 * Find an ancestor of this content node which is a form (could be null)
616 * @param aCurrentForm the current form for this node. If this is
617 * non-null, and no ancestor form is found, and the current form is in
618 * a connected subtree with the node, the current form will be
619 * returned. This is needed to handle cases when HTML elements have a
620 * current form that they're not descendants of.
621 * @note This method should not be called if the element has a form attribute.
623 mozilla::dom::HTMLFormElement* FindAncestorForm(
624 mozilla::dom::HTMLFormElement* aCurrentForm = nullptr);
627 * See if the document being tested has nav-quirks mode enabled.
628 * @param doc the document
630 static bool InNavQuirksMode(Document*);
633 * Gets the absolute URI value of an attribute, by resolving any relative
634 * URIs in the attribute against the baseuri of the element. If the attribute
635 * isn't a relative URI the value of the attribute is returned as is. Only
636 * works for attributes in null namespace.
638 * @param aAttr name of attribute.
639 * @param aBaseAttr name of base attribute.
640 * @param aResult result value [out]
642 void GetURIAttr(nsAtom* aAttr, nsAtom* aBaseAttr, nsAString& aResult) const;
643 void GetURIAttr(nsAtom* aAttr, nsAtom* aBaseAttr, nsACString& aResult) const;
646 * Gets the absolute URI values of an attribute, by resolving any relative
647 * URIs in the attribute against the baseuri of the element. If a substring
648 * isn't a relative URI, the substring is returned as is. Only works for
649 * attributes in null namespace.
651 const nsAttrValue* GetURIAttr(nsAtom* aAttr, nsAtom* aBaseAttr,
652 nsIURI** aURI) const;
654 bool IsHidden() const { return HasAttr(nsGkAtoms::hidden); }
656 bool IsLabelable() const override;
658 static bool MatchLabelsElement(Element* aElement, int32_t aNamespaceID,
659 nsAtom* aAtom, void* aData);
661 already_AddRefed<nsINodeList> Labels();
663 static bool LegacyTouchAPIEnabled(JSContext* aCx, JSObject* aObj);
665 static inline bool CanHaveName(nsAtom* aTag) {
666 return aTag == nsGkAtoms::img || aTag == nsGkAtoms::form ||
667 aTag == nsGkAtoms::embed || aTag == nsGkAtoms::object;
669 static inline bool ShouldExposeNameAsHTMLDocumentProperty(Element* aElement) {
670 return aElement->IsHTMLElement() &&
671 CanHaveName(aElement->NodeInfo()->NameAtom());
673 static inline bool ShouldExposeIdAsHTMLDocumentProperty(Element* aElement) {
674 if (aElement->IsHTMLElement(nsGkAtoms::object)) {
675 return true;
678 // Per spec, <img> is exposed by id only if it also has a nonempty
679 // name (which doesn't have to match the id or anything).
680 // HasName() is true precisely when name is nonempty.
681 return aElement->IsHTMLElement(nsGkAtoms::img) && aElement->HasName();
684 virtual inline void ResultForDialogSubmit(nsAString& aResult) {
685 GetAttr(nsGkAtoms::value, aResult);
688 // <https://html.spec.whatwg.org/#fetch-priority-attribute>.
689 static mozilla::dom::FetchPriority ToFetchPriority(const nsAString& aValue);
691 void GetFetchPriority(nsAString& aFetchPriority) const;
693 void SetFetchPriority(const nsAString& aFetchPriority) {
694 SetHTMLAttr(nsGkAtoms::fetchpriority, aFetchPriority);
697 protected:
698 mozilla::dom::FetchPriority GetFetchPriority() const;
700 static void ParseFetchPriority(const nsAString& aValue, nsAttrValue& aResult);
702 private:
704 * Add/remove this element to the documents name cache
706 void AddToNameTable(nsAtom* aName);
707 void RemoveFromNameTable();
710 * Register or unregister an access key to this element based on the
711 * accesskey attribute.
713 void RegUnRegAccessKey(bool aDoReg) override {
714 if (!HasFlag(NODE_HAS_ACCESSKEY)) {
715 return;
718 nsStyledElement::RegUnRegAccessKey(aDoReg);
721 protected:
722 void BeforeSetAttr(int32_t aNamespaceID, nsAtom* aName,
723 const nsAttrValue* aValue, bool aNotify) override;
724 // TODO: Convert AfterSetAttr to MOZ_CAN_RUN_SCRIPT and get rid of
725 // kungFuDeathGrip in it.
726 MOZ_CAN_RUN_SCRIPT_BOUNDARY void AfterSetAttr(
727 int32_t aNamespaceID, nsAtom* aName, const nsAttrValue* aValue,
728 const nsAttrValue* aOldValue, nsIPrincipal* aMaybeScriptedPrincipal,
729 bool aNotify) override;
731 void OnAttrSetButNotChanged(int32_t aNamespaceID, nsAtom* aName,
732 const nsAttrValueOrString& aValue,
733 bool aNotify) override;
735 MOZ_CAN_RUN_SCRIPT void AfterSetPopoverAttr();
737 mozilla::EventListenerManager* GetEventListenerManagerForAttr(
738 nsAtom* aAttrName, bool* aDefer) override;
741 * Handles dispatching a simulated click on `this` on space or enter.
742 * TODO: Convert this to MOZ_CAN_RUN_SCRIPT (bug 1415230)
744 MOZ_CAN_RUN_SCRIPT_BOUNDARY void HandleKeyboardActivation(
745 mozilla::EventChainPostVisitor&);
747 /** Dispatch a simulated mouse click by keyboard to the given element. */
748 MOZ_CAN_RUN_SCRIPT static nsresult DispatchSimulatedClick(
749 nsGenericHTMLElement* aElement, bool aIsTrusted,
750 nsPresContext* aPresContext);
753 * Create a URI for the given aURISpec string.
754 * Returns INVALID_STATE_ERR and nulls *aURI if aURISpec is empty
755 * and the document's URI matches the element's base URI.
757 nsresult NewURIFromString(const nsAString& aURISpec, nsIURI** aURI);
759 void GetHTMLAttr(nsAtom* aName, nsAString& aResult) const {
760 GetAttr(aName, aResult);
762 void GetHTMLAttr(nsAtom* aName, mozilla::dom::DOMString& aResult) const {
763 GetAttr(aName, aResult);
765 void GetHTMLEnumAttr(nsAtom* aName, nsAString& aResult) const {
766 GetEnumAttr(aName, nullptr, aResult);
768 void GetHTMLURIAttr(nsAtom* aName, nsAString& aResult) const {
769 GetURIAttr(aName, nullptr, aResult);
771 void GetHTMLURIAttr(nsAtom* aName, nsACString& aResult) const {
772 GetURIAttr(aName, nullptr, aResult);
775 void SetHTMLAttr(nsAtom* aName, const nsAString& aValue) {
776 SetAttr(kNameSpaceID_None, aName, aValue, true);
778 void SetHTMLAttr(nsAtom* aName, const nsAString& aValue,
779 mozilla::ErrorResult& aError) {
780 SetAttr(aName, aValue, aError);
782 void SetHTMLAttr(nsAtom* aName, const nsAString& aValue,
783 nsIPrincipal* aTriggeringPrincipal,
784 mozilla::ErrorResult& aError) {
785 SetAttr(aName, aValue, aTriggeringPrincipal, aError);
787 void UnsetHTMLAttr(nsAtom* aName, mozilla::ErrorResult& aError) {
788 UnsetAttr(aName, aError);
790 void SetHTMLBoolAttr(nsAtom* aName, bool aValue,
791 mozilla::ErrorResult& aError) {
792 if (aValue) {
793 SetHTMLAttr(aName, u""_ns, aError);
794 } else {
795 UnsetHTMLAttr(aName, aError);
798 template <typename T>
799 void SetHTMLIntAttr(nsAtom* aName, T aValue, mozilla::ErrorResult& aError) {
800 nsAutoString value;
801 value.AppendInt(aValue);
803 SetHTMLAttr(aName, value, aError);
807 * Gets the integer-value of an attribute, returns specified default value
808 * if the attribute isn't set or isn't set to an integer. Only works for
809 * attributes in null namespace.
811 * @param aAttr name of attribute.
812 * @param aDefault default-value to return if attribute isn't set.
814 int32_t GetIntAttr(nsAtom* aAttr, int32_t aDefault) const;
817 * Sets value of attribute to specified integer. Only works for attributes
818 * in null namespace.
820 * @param aAttr name of attribute.
821 * @param aValue Integer value of attribute.
823 nsresult SetIntAttr(nsAtom* aAttr, int32_t aValue);
826 * Gets the unsigned integer-value of an attribute, returns specified default
827 * value if the attribute isn't set or isn't set to an integer. Only works for
828 * attributes in null namespace.
830 * @param aAttr name of attribute.
831 * @param aDefault default-value to return if attribute isn't set.
833 uint32_t GetUnsignedIntAttr(nsAtom* aAttr, uint32_t aDefault) const;
836 * Sets value of attribute to specified unsigned integer. Only works for
837 * attributes in null namespace.
839 * @param aAttr name of attribute.
840 * @param aValue Integer value of attribute.
841 * @param aDefault Default value (in case value is out of range). If the spec
842 * doesn't provide one, should be 1 if the value is limited to
843 * nonzero values, and 0 otherwise.
845 void SetUnsignedIntAttr(nsAtom* aName, uint32_t aValue, uint32_t aDefault,
846 mozilla::ErrorResult& aError) {
847 nsAutoString value;
848 if (aValue > INT32_MAX) {
849 value.AppendInt(aDefault);
850 } else {
851 value.AppendInt(aValue);
854 SetHTMLAttr(aName, value, aError);
858 * Gets the unsigned integer-value of an attribute that is stored as a
859 * dimension (i.e. could be an integer or a percentage), returns specified
860 * default value if the attribute isn't set or isn't set to a dimension. Only
861 * works for attributes in null namespace.
863 * @param aAttr name of attribute.
864 * @param aDefault default-value to return if attribute isn't set.
866 uint32_t GetDimensionAttrAsUnsignedInt(nsAtom* aAttr,
867 uint32_t aDefault) const;
869 enum class Reflection {
870 Unlimited,
871 OnlyPositive,
875 * Sets value of attribute to specified double. Only works for attributes
876 * in null namespace.
878 * Implements
879 * https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#reflecting-content-attributes-in-idl-attributes:idl-double
881 * @param aAttr name of attribute.
882 * @param aValue Double value of attribute.
884 template <Reflection Limited = Reflection::Unlimited>
885 void SetDoubleAttr(nsAtom* aAttr, double aValue, mozilla::ErrorResult& aRv) {
886 // 1. If the reflected IDL attribute is limited to only positive numbers and
887 // the given value is not greater than 0, then return.
888 if (Limited == Reflection::OnlyPositive && aValue <= 0) {
889 return;
892 // 2. Run this's set the content attribute with the given value, converted
893 // to the best representation of the number as a floating-point number.
894 nsAutoString value;
895 value.AppendFloat(aValue);
897 SetHTMLAttr(aAttr, value, aRv);
901 * Locates the EditorBase associated with this node. In general this is
902 * equivalent to GetEditorInternal(), but for designmode or contenteditable,
903 * this may need to get an editor that's not actually on this element's
904 * associated TextControlFrame. This is used by the spellchecking routines
905 * to get the editor affected by changing the spellcheck attribute on this
906 * node.
908 virtual already_AddRefed<mozilla::EditorBase> GetAssociatedEditor();
911 * Get the frame's offset information for offsetTop/Left/Width/Height.
912 * Returns the parent the offset is relative to.
913 * @note This method flushes pending notifications (FlushType::Layout).
914 * @param aRect the offset information [OUT]
916 mozilla::dom::Element* GetOffsetRect(mozilla::CSSIntRect& aRect);
919 * Ensures all editors associated with a subtree are synced, for purposes of
920 * spellchecking.
922 static void SyncEditorsOnSubtree(nsIContent* content);
924 enum ContentEditableTristate { eInherit = -1, eFalse = 0, eTrue = 1 };
927 * Returns eTrue if the element has a contentEditable attribute and its value
928 * is "true" or an empty string. Returns eFalse if the element has a
929 * contentEditable attribute and its value is "false". Otherwise returns
930 * eInherit.
932 ContentEditableTristate GetContentEditableValue() const {
933 static const Element::AttrValuesArray values[] = {
934 nsGkAtoms::_false, nsGkAtoms::_true, nsGkAtoms::_empty, nullptr};
936 if (!MayHaveContentEditableAttr()) return eInherit;
938 int32_t value = FindAttrValueIn(
939 kNameSpaceID_None, nsGkAtoms::contenteditable, values, eIgnoreCase);
941 return value > 0 ? eTrue : (value == 0 ? eFalse : eInherit);
944 // Used by A, AREA, LINK, and STYLE.
945 already_AddRefed<nsIURI> GetHrefURIForAnchors() const;
947 private:
948 void ChangeEditableState(int32_t aChange);
951 namespace mozilla::dom {
952 class HTMLFieldSetElement;
953 } // namespace mozilla::dom
955 #define HTML_ELEMENT_FLAG_BIT(n_) \
956 NODE_FLAG_BIT(ELEMENT_TYPE_SPECIFIC_BITS_OFFSET + (n_))
958 // HTMLElement specific bits
959 enum {
960 // Used to handle keyboard activation.
961 HTML_ELEMENT_ACTIVE_FOR_KEYBOARD = HTML_ELEMENT_FLAG_BIT(0),
962 // Similar to HTMLInputElement's mInhibitRestoration, used to prevent
963 // form-associated custom elements not created by a network parser from
964 // being restored.
965 HTML_ELEMENT_INHIBIT_RESTORATION = HTML_ELEMENT_FLAG_BIT(1),
967 // Remaining bits are type specific.
968 HTML_ELEMENT_TYPE_SPECIFIC_BITS_OFFSET =
969 ELEMENT_TYPE_SPECIFIC_BITS_OFFSET + 2,
972 ASSERT_NODE_FLAGS_SPACE(HTML_ELEMENT_TYPE_SPECIFIC_BITS_OFFSET);
974 #define FORM_ELEMENT_FLAG_BIT(n_) \
975 NODE_FLAG_BIT(HTML_ELEMENT_TYPE_SPECIFIC_BITS_OFFSET + (n_))
977 // Form element specific bits
978 enum {
979 // If this flag is set on an nsGenericHTMLFormElement or an HTMLImageElement,
980 // that means that we have added ourselves to our mForm. It's possible to
981 // have a non-null mForm, but not have this flag set. That happens when the
982 // form is set via the content sink.
983 ADDED_TO_FORM = FORM_ELEMENT_FLAG_BIT(0),
985 // If this flag is set on an nsGenericHTMLFormElement or an HTMLImageElement,
986 // that means that its form is in the process of being unbound from the tree,
987 // and this form element hasn't re-found its form in
988 // nsGenericHTMLFormElement::UnbindFromTree yet.
989 MAYBE_ORPHAN_FORM_ELEMENT = FORM_ELEMENT_FLAG_BIT(1),
991 // If this flag is set on an nsGenericHTMLElement or an HTMLImageElement, then
992 // the element might be in the past names map of its form.
993 MAY_BE_IN_PAST_NAMES_MAP = FORM_ELEMENT_FLAG_BIT(2)
996 // NOTE: I don't think it's possible to have both ADDED_TO_FORM and
997 // MAYBE_ORPHAN_FORM_ELEMENT set at the same time, so if it becomes an issue we
998 // can probably merge them into the same bit. --bz
1000 ASSERT_NODE_FLAGS_SPACE(HTML_ELEMENT_TYPE_SPECIFIC_BITS_OFFSET + 3);
1002 #undef FORM_ELEMENT_FLAG_BIT
1005 * A helper class for form elements that can contain children
1007 class nsGenericHTMLFormElement : public nsGenericHTMLElement {
1008 public:
1009 nsGenericHTMLFormElement(
1010 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
1012 // nsIContent
1013 void SaveSubtreeState() override;
1014 nsresult BindToTree(BindContext&, nsINode& aParent) override;
1015 void UnbindFromTree(UnbindContext&) override;
1018 * This callback is called by a fieldest on all its elements whenever its
1019 * disabled attribute is changed so the element knows its disabled state
1020 * might have changed.
1022 * @note Classes redefining this method should not do any content
1023 * state updates themselves but should just make sure to call into
1024 * nsGenericHTMLFormElement::FieldSetDisabledChanged.
1026 virtual void FieldSetDisabledChanged(bool aNotify);
1028 void FieldSetFirstLegendChanged(bool aNotify) { UpdateFieldSet(aNotify); }
1031 * This callback is called by a fieldset on all it's elements when it's being
1032 * destroyed. When called, the elements should check that aFieldset is there
1033 * first parent fieldset and null mFieldset in that case only.
1035 * @param aFieldSet The fieldset being removed.
1037 void ForgetFieldSet(nsIContent* aFieldset);
1039 void ClearForm(bool aRemoveFromForm, bool aUnbindOrDelete);
1042 * Get the layout history object for a particular piece of content.
1044 * @param aRead if true, won't return a layout history state if the
1045 * layout history state is empty.
1046 * @return the history state object
1048 already_AddRefed<nsILayoutHistoryState> GetLayoutHistory(bool aRead);
1050 // Sets the user-interacted flag in
1051 // https://html.spec.whatwg.org/#user-interacted, if it applies.
1052 virtual void SetUserInteracted(bool aNotify) {}
1054 protected:
1055 virtual ~nsGenericHTMLFormElement() = default;
1057 void BeforeSetAttr(int32_t aNamespaceID, nsAtom* aName,
1058 const nsAttrValue* aValue, bool aNotify) override;
1060 void AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
1061 const nsAttrValue* aValue, const nsAttrValue* aOldValue,
1062 nsIPrincipal* aMaybeScriptedPrincipal,
1063 bool aNotify) override;
1065 virtual void BeforeSetForm(mozilla::dom::HTMLFormElement* aForm,
1066 bool aBindToTree) {}
1068 virtual void AfterClearForm(bool aUnbindOrDelete) {}
1071 * Check our disabled content attribute and fieldset's (if it exists) disabled
1072 * state to decide whether our disabled flag should be toggled.
1074 virtual void UpdateDisabledState(bool aNotify);
1075 bool IsReadOnlyInternal() const final;
1077 virtual void SetFormInternal(mozilla::dom::HTMLFormElement* aForm,
1078 bool aBindToTree) {}
1080 virtual mozilla::dom::HTMLFormElement* GetFormInternal() const {
1081 return nullptr;
1084 virtual mozilla::dom::HTMLFieldSetElement* GetFieldSetInternal() const {
1085 return nullptr;
1088 virtual void SetFieldSetInternal(
1089 mozilla::dom::HTMLFieldSetElement* aFieldset) {}
1092 * This method will update the form owner, using @form or looking to a parent.
1094 * @param aBindToTree Whether the element is being attached to the tree.
1095 * @param aFormIdElement The element associated with the id in @form. If
1096 * aBindToTree is false, aFormIdElement *must* contain the element associated
1097 * with the id in @form. Otherwise, it *must* be null.
1099 * @note Callers of UpdateFormOwner have to be sure the element is in a
1100 * document (GetUncomposedDoc() != nullptr).
1102 virtual void UpdateFormOwner(bool aBindToTree, Element* aFormIdElement);
1105 * This method will update mFieldset and set it to the first fieldset parent.
1107 void UpdateFieldSet(bool aNotify);
1110 * Add a form id observer which will observe when the element with the id in
1111 * @form will change.
1113 * @return The element associated with the current id in @form (may be null).
1115 Element* AddFormIdObserver();
1118 * Remove the form id observer.
1120 void RemoveFormIdObserver();
1123 * This method is a a callback for IDTargetObserver (from Document).
1124 * It will be called each time the element associated with the id in @form
1125 * changes.
1127 static bool FormIdUpdated(Element* aOldElement, Element* aNewElement,
1128 void* aData);
1130 // Returns true if the event should not be handled from GetEventTargetParent
1131 bool IsElementDisabledForEvents(mozilla::WidgetEvent* aEvent,
1132 nsIFrame* aFrame);
1135 * Returns if the control can be disabled.
1137 virtual bool CanBeDisabled() const { return false; }
1140 * Returns if the readonly attribute applies.
1142 virtual bool DoesReadOnlyApply() const { return false; }
1145 * Returns true if the element is a form associated element.
1146 * See https://html.spec.whatwg.org/#form-associated-element.
1148 virtual bool IsFormAssociatedElement() const { return false; }
1151 * Save to presentation state. The form element will determine whether it
1152 * has anything to save and if so, create an entry in the layout history for
1153 * its pres context.
1155 virtual void SaveState() {}
1158 class nsGenericHTMLFormControlElement : public nsGenericHTMLFormElement,
1159 public nsIFormControl {
1160 public:
1161 nsGenericHTMLFormControlElement(
1162 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo, FormControlType);
1164 NS_DECL_ISUPPORTS_INHERITED
1166 NS_IMPL_FROMNODE_HELPER(nsGenericHTMLFormControlElement,
1167 IsHTMLFormControlElement())
1169 // nsINode
1170 nsINode* GetScopeChainParent() const override;
1171 bool IsHTMLFormControlElement() const final { return true; }
1173 // nsIContent
1174 IMEState GetDesiredIMEState() override;
1176 // nsGenericHTMLElement
1177 // autocapitalize attribute support
1178 void GetAutocapitalize(nsAString& aValue) const override;
1179 bool IsHTMLFocusable(bool aWithMouse, bool* aIsFocusable,
1180 int32_t* aTabIndex) override;
1182 // EventTarget
1183 void GetEventTargetParent(mozilla::EventChainPreVisitor& aVisitor) override;
1184 nsresult PreHandleEvent(mozilla::EventChainVisitor& aVisitor) override;
1186 // nsIFormControl
1187 mozilla::dom::HTMLFieldSetElement* GetFieldSet() override;
1188 mozilla::dom::HTMLFormElement* GetForm() const override { return mForm; }
1189 void SetForm(mozilla::dom::HTMLFormElement* aForm) override;
1190 void ClearForm(bool aRemoveFromForm, bool aUnbindOrDelete) override;
1192 protected:
1193 virtual ~nsGenericHTMLFormControlElement();
1195 // Element
1196 bool IsLabelable() const override;
1198 // nsGenericHTMLFormElement
1199 bool CanBeDisabled() const override;
1200 bool DoesReadOnlyApply() const override;
1201 void SetFormInternal(mozilla::dom::HTMLFormElement* aForm,
1202 bool aBindToTree) override;
1203 mozilla::dom::HTMLFormElement* GetFormInternal() const override;
1204 mozilla::dom::HTMLFieldSetElement* GetFieldSetInternal() const override;
1205 void SetFieldSetInternal(
1206 mozilla::dom::HTMLFieldSetElement* aFieldset) override;
1207 bool IsFormAssociatedElement() const override { return true; }
1210 * Update our required/optional flags to match the given aIsRequired boolean.
1212 void UpdateRequiredState(bool aIsRequired, bool aNotify);
1214 bool IsAutocapitalizeInheriting() const;
1216 nsresult SubmitDirnameDir(mozilla::dom::FormData* aFormData);
1218 /** The form that contains this control */
1219 mozilla::dom::HTMLFormElement* mForm;
1221 /* This is a pointer to our closest fieldset parent if any */
1222 mozilla::dom::HTMLFieldSetElement* mFieldSet;
1225 enum class PopoverTargetAction : uint8_t {
1226 Toggle,
1227 Show,
1228 Hide,
1231 class nsGenericHTMLFormControlElementWithState
1232 : public nsGenericHTMLFormControlElement {
1233 public:
1234 nsGenericHTMLFormControlElementWithState(
1235 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
1236 mozilla::dom::FromParser aFromParser, FormControlType);
1238 bool IsGenericHTMLFormControlElementWithState() const final { return true; }
1239 NS_IMPL_FROMNODE_HELPER(nsGenericHTMLFormControlElementWithState,
1240 IsGenericHTMLFormControlElementWithState())
1242 // Element
1243 bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
1244 const nsAString& aValue,
1245 nsIPrincipal* aMaybeScriptedPrincipal,
1246 nsAttrValue& aResult) override;
1248 // PopoverInvokerElement
1249 mozilla::dom::Element* GetPopoverTargetElement() const;
1250 void SetPopoverTargetElement(mozilla::dom::Element*);
1251 void GetPopoverTargetAction(nsAString& aValue) const {
1252 GetHTMLEnumAttr(nsGkAtoms::popovertargetaction, aValue);
1254 void SetPopoverTargetAction(const nsAString& aValue) {
1255 SetHTMLAttr(nsGkAtoms::popovertargetaction, aValue);
1258 // InvokerElement
1259 mozilla::dom::Element* GetInvokeTargetElement() const;
1260 void SetInvokeTargetElement(mozilla::dom::Element*);
1261 void GetInvokeAction(nsAString& aValue) const;
1262 nsAtom* GetInvokeAction() const;
1263 void SetInvokeAction(const nsAString& aValue) {
1264 SetHTMLAttr(nsGkAtoms::invokeaction, aValue);
1268 * https://html.spec.whatwg.org/#popover-target-attribute-activation-behavior
1270 MOZ_CAN_RUN_SCRIPT void HandlePopoverTargetAction();
1272 MOZ_CAN_RUN_SCRIPT void HandleInvokeTargetAction();
1275 * Get the presentation state for a piece of content, or create it if it does
1276 * not exist. Generally used by SaveState().
1278 mozilla::PresState* GetPrimaryPresState();
1281 * Called when we have been cloned and adopted, and the information of the
1282 * node has been changed.
1284 void NodeInfoChanged(Document* aOldDoc) override;
1286 void GetFormAction(nsString& aValue);
1288 protected:
1290 * Restore from presentation state. You pass in the presentation state for
1291 * this form control (generated with GenerateStateKey() + "-C") and the form
1292 * control will grab its state from there.
1294 * @param aState the pres state to use to restore the control
1295 * @return true if the form control was a checkbox and its
1296 * checked state was restored, false otherwise.
1298 virtual bool RestoreState(mozilla::PresState* aState) { return false; }
1301 * Restore the state for a form control in response to the element being
1302 * inserted into the document by the parser. Ends up calling RestoreState().
1304 * GenerateStateKey() must already have been called.
1306 * @return false if RestoreState() was not called, the return
1307 * value of RestoreState() otherwise.
1309 bool RestoreFormControlState();
1311 /* Generates the state key for saving the form state in the session if not
1312 computed already. The result is stored in mStateKey. */
1313 void GenerateStateKey();
1315 int32_t GetParserInsertedControlNumberForStateKey() const override {
1316 return mControlNumber;
1319 /* Used to store the key to that element in the session. Is void until
1320 GenerateStateKey has been used */
1321 nsCString mStateKey;
1323 // A number for this form control that is unique within its owner document.
1324 // This is only set to a number for elements inserted into the document by
1325 // the parser from the network. Otherwise, it is -1.
1326 int32_t mControlNumber;
1329 #define NS_INTERFACE_MAP_ENTRY_IF_TAG(_interface, _tag) \
1330 NS_INTERFACE_MAP_ENTRY_CONDITIONAL(_interface, \
1331 mNodeInfo->Equals(nsGkAtoms::_tag))
1333 namespace mozilla::dom {
1335 using HTMLContentCreatorFunction =
1336 nsGenericHTMLElement* (*)(already_AddRefed<mozilla::dom::NodeInfo>&&,
1337 mozilla::dom::FromParser);
1339 } // namespace mozilla::dom
1342 * A macro to declare the NS_NewHTMLXXXElement() functions.
1344 #define NS_DECLARE_NS_NEW_HTML_ELEMENT(_elementName) \
1345 namespace mozilla { \
1346 namespace dom { \
1347 class HTML##_elementName##Element; \
1350 nsGenericHTMLElement* NS_NewHTML##_elementName##Element( \
1351 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo, \
1352 mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER);
1354 #define NS_DECLARE_NS_NEW_HTML_ELEMENT_AS_SHARED(_elementName) \
1355 inline nsGenericHTMLElement* NS_NewHTML##_elementName##Element( \
1356 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo, \
1357 mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER) { \
1358 return NS_NewHTMLSharedElement(std::move(aNodeInfo), aFromParser); \
1362 * A macro to implement the NS_NewHTMLXXXElement() functions.
1364 #define NS_IMPL_NS_NEW_HTML_ELEMENT(_elementName) \
1365 nsGenericHTMLElement* NS_NewHTML##_elementName##Element( \
1366 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo, \
1367 mozilla::dom::FromParser aFromParser) { \
1368 RefPtr<mozilla::dom::NodeInfo> nodeInfo(aNodeInfo); \
1369 auto* nim = nodeInfo->NodeInfoManager(); \
1370 MOZ_ASSERT(nim); \
1371 return new (nim) \
1372 mozilla::dom::HTML##_elementName##Element(nodeInfo.forget()); \
1375 #define NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(_elementName) \
1376 nsGenericHTMLElement* NS_NewHTML##_elementName##Element( \
1377 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo, \
1378 mozilla::dom::FromParser aFromParser) { \
1379 RefPtr<mozilla::dom::NodeInfo> nodeInfo(aNodeInfo); \
1380 auto* nim = nodeInfo->NodeInfoManager(); \
1381 MOZ_ASSERT(nim); \
1382 return new (nim) mozilla::dom::HTML##_elementName##Element( \
1383 nodeInfo.forget(), aFromParser); \
1386 // Here, we expand 'NS_DECLARE_NS_NEW_HTML_ELEMENT()' by hand.
1387 // (Calling the macro directly (with no args) produces compiler warnings.)
1388 nsGenericHTMLElement* NS_NewHTMLElement(
1389 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
1390 mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER);
1392 // Distinct from the above in order to have function pointer that compared
1393 // unequal to a function pointer to the above.
1394 nsGenericHTMLElement* NS_NewCustomElement(
1395 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
1396 mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER);
1398 NS_DECLARE_NS_NEW_HTML_ELEMENT(Shared)
1399 NS_DECLARE_NS_NEW_HTML_ELEMENT(SharedList)
1401 NS_DECLARE_NS_NEW_HTML_ELEMENT(Anchor)
1402 NS_DECLARE_NS_NEW_HTML_ELEMENT(Area)
1403 NS_DECLARE_NS_NEW_HTML_ELEMENT(Audio)
1404 NS_DECLARE_NS_NEW_HTML_ELEMENT(BR)
1405 NS_DECLARE_NS_NEW_HTML_ELEMENT(Body)
1406 NS_DECLARE_NS_NEW_HTML_ELEMENT(Button)
1407 NS_DECLARE_NS_NEW_HTML_ELEMENT(Canvas)
1408 NS_DECLARE_NS_NEW_HTML_ELEMENT(Content)
1409 NS_DECLARE_NS_NEW_HTML_ELEMENT(Mod)
1410 NS_DECLARE_NS_NEW_HTML_ELEMENT(Data)
1411 NS_DECLARE_NS_NEW_HTML_ELEMENT(DataList)
1412 NS_DECLARE_NS_NEW_HTML_ELEMENT(Details)
1413 NS_DECLARE_NS_NEW_HTML_ELEMENT(Dialog)
1414 NS_DECLARE_NS_NEW_HTML_ELEMENT(Div)
1415 NS_DECLARE_NS_NEW_HTML_ELEMENT(Embed)
1416 NS_DECLARE_NS_NEW_HTML_ELEMENT(FieldSet)
1417 NS_DECLARE_NS_NEW_HTML_ELEMENT(Font)
1418 NS_DECLARE_NS_NEW_HTML_ELEMENT(Form)
1419 NS_DECLARE_NS_NEW_HTML_ELEMENT(Frame)
1420 NS_DECLARE_NS_NEW_HTML_ELEMENT(FrameSet)
1421 NS_DECLARE_NS_NEW_HTML_ELEMENT(HR)
1422 NS_DECLARE_NS_NEW_HTML_ELEMENT_AS_SHARED(Head)
1423 NS_DECLARE_NS_NEW_HTML_ELEMENT(Heading)
1424 NS_DECLARE_NS_NEW_HTML_ELEMENT_AS_SHARED(Html)
1425 NS_DECLARE_NS_NEW_HTML_ELEMENT(IFrame)
1426 NS_DECLARE_NS_NEW_HTML_ELEMENT(Image)
1427 NS_DECLARE_NS_NEW_HTML_ELEMENT(Input)
1428 NS_DECLARE_NS_NEW_HTML_ELEMENT(LI)
1429 NS_DECLARE_NS_NEW_HTML_ELEMENT(Label)
1430 NS_DECLARE_NS_NEW_HTML_ELEMENT(Legend)
1431 NS_DECLARE_NS_NEW_HTML_ELEMENT(Link)
1432 NS_DECLARE_NS_NEW_HTML_ELEMENT(Marquee)
1433 NS_DECLARE_NS_NEW_HTML_ELEMENT(Map)
1434 NS_DECLARE_NS_NEW_HTML_ELEMENT(Menu)
1435 NS_DECLARE_NS_NEW_HTML_ELEMENT(Meta)
1436 NS_DECLARE_NS_NEW_HTML_ELEMENT(Meter)
1437 NS_DECLARE_NS_NEW_HTML_ELEMENT(Object)
1438 NS_DECLARE_NS_NEW_HTML_ELEMENT(OptGroup)
1439 NS_DECLARE_NS_NEW_HTML_ELEMENT(Option)
1440 NS_DECLARE_NS_NEW_HTML_ELEMENT(Output)
1441 NS_DECLARE_NS_NEW_HTML_ELEMENT(Paragraph)
1442 NS_DECLARE_NS_NEW_HTML_ELEMENT(Picture)
1443 NS_DECLARE_NS_NEW_HTML_ELEMENT(Pre)
1444 NS_DECLARE_NS_NEW_HTML_ELEMENT(Progress)
1445 NS_DECLARE_NS_NEW_HTML_ELEMENT(Script)
1446 NS_DECLARE_NS_NEW_HTML_ELEMENT(Select)
1447 NS_DECLARE_NS_NEW_HTML_ELEMENT(Slot)
1448 NS_DECLARE_NS_NEW_HTML_ELEMENT(Source)
1449 NS_DECLARE_NS_NEW_HTML_ELEMENT(Span)
1450 NS_DECLARE_NS_NEW_HTML_ELEMENT(Style)
1451 NS_DECLARE_NS_NEW_HTML_ELEMENT(Summary)
1452 NS_DECLARE_NS_NEW_HTML_ELEMENT(TableCaption)
1453 NS_DECLARE_NS_NEW_HTML_ELEMENT(TableCell)
1454 NS_DECLARE_NS_NEW_HTML_ELEMENT(TableCol)
1455 NS_DECLARE_NS_NEW_HTML_ELEMENT(Table)
1456 NS_DECLARE_NS_NEW_HTML_ELEMENT(TableRow)
1457 NS_DECLARE_NS_NEW_HTML_ELEMENT(TableSection)
1458 NS_DECLARE_NS_NEW_HTML_ELEMENT(Tbody)
1459 NS_DECLARE_NS_NEW_HTML_ELEMENT(Template)
1460 NS_DECLARE_NS_NEW_HTML_ELEMENT(TextArea)
1461 NS_DECLARE_NS_NEW_HTML_ELEMENT(Tfoot)
1462 NS_DECLARE_NS_NEW_HTML_ELEMENT(Thead)
1463 NS_DECLARE_NS_NEW_HTML_ELEMENT(Time)
1464 NS_DECLARE_NS_NEW_HTML_ELEMENT(Title)
1465 NS_DECLARE_NS_NEW_HTML_ELEMENT(Track)
1466 NS_DECLARE_NS_NEW_HTML_ELEMENT(Unknown)
1467 NS_DECLARE_NS_NEW_HTML_ELEMENT(Video)
1469 #endif /* nsGenericHTMLElement_h___ */