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___
8 
9 #include "mozilla/Attributes.h"
10 #include "mozilla/EventForwards.h"
11 #include "nsMappedAttributeElement.h"
12 #include "nsIDOMHTMLElement.h"
13 #include "nsNameSpaceManager.h"  // for kNameSpaceID_None
14 #include "nsIFormControl.h"
15 #include "nsGkAtoms.h"
16 #include "nsContentCreatorFunctions.h"
17 #include "mozilla/ErrorResult.h"
18 #include "nsIDOMHTMLMenuElement.h"
19 #include "mozilla/dom/DOMRect.h"
20 #include "mozilla/dom/ValidityState.h"
21 #include "mozilla/dom/ElementInlines.h"
22 
23 class nsDOMTokenList;
24 class nsIDOMHTMLMenuElement;
25 class nsIEditor;
26 class nsIFormControlFrame;
27 class nsIFrame;
28 class nsILayoutHistoryState;
29 class nsIURI;
30 class nsPresState;
31 struct nsSize;
32 
33 namespace mozilla {
34 class EventChainPostVisitor;
35 class EventChainPreVisitor;
36 class EventChainVisitor;
37 class EventListenerManager;
38 class EventStates;
39 namespace dom {
40 class HTMLFormElement;
41 class HTMLMenuElement;
42 } // namespace dom
43 } // namespace mozilla
44 
45 typedef nsMappedAttributeElement nsGenericHTMLElementBase;
46 
47 /**
48  * A common superclass for HTML elements
49  */
50 class nsGenericHTMLElement : public nsGenericHTMLElementBase,
51                              public nsIDOMHTMLElement
52 {
53 public:
54   using Element::SetTabIndex;
55   using Element::Focus;
nsGenericHTMLElement(already_AddRefed<mozilla::dom::NodeInfo> & aNodeInfo)56   explicit nsGenericHTMLElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
57     : nsGenericHTMLElementBase(aNodeInfo)
58   {
59     NS_ASSERTION(mNodeInfo->NamespaceID() == kNameSpaceID_XHTML,
60                  "Unexpected namespace");
61     AddStatesSilently(NS_EVENT_STATE_LTR);
62     SetFlags(NODE_HAS_DIRECTION_LTR);
63   }
64 
65   NS_DECL_ISUPPORTS_INHERITED
66 
67   NS_IMPL_FROMCONTENT(nsGenericHTMLElement, kNameSpaceID_XHTML)
68 
69   // From Element
70   nsresult CopyInnerTo(mozilla::dom::Element* aDest);
71 
GetTitle(mozilla::dom::DOMString & aTitle)72   void GetTitle(mozilla::dom::DOMString& aTitle)
73   {
74     GetHTMLAttr(nsGkAtoms::title, aTitle);
75   }
SetTitle(const nsAString & aTitle)76   NS_IMETHOD SetTitle(const nsAString& aTitle) override
77   {
78     SetHTMLAttr(nsGkAtoms::title, aTitle);
79     return NS_OK;
80   }
GetLang(mozilla::dom::DOMString & aLang)81   void GetLang(mozilla::dom::DOMString& aLang)
82   {
83     GetHTMLAttr(nsGkAtoms::lang, aLang);
84   }
SetLang(const nsAString & aLang)85   NS_IMETHOD SetLang(const nsAString& aLang) override
86   {
87     SetHTMLAttr(nsGkAtoms::lang, aLang);
88     return NS_OK;
89   }
GetDir(mozilla::dom::DOMString & aDir)90   void GetDir(mozilla::dom::DOMString& aDir)
91   {
92     GetHTMLEnumAttr(nsGkAtoms::dir, aDir);
93   }
SetDir(const nsAString & aDir,mozilla::ErrorResult & aError)94   void SetDir(const nsAString& aDir, mozilla::ErrorResult& aError)
95   {
96     SetHTMLAttr(nsGkAtoms::dir, aDir, aError);
97   }
Hidden()98   bool Hidden() const
99   {
100     return GetBoolAttr(nsGkAtoms::hidden);
101   }
SetHidden(bool aHidden,mozilla::ErrorResult & aError)102   void SetHidden(bool aHidden, mozilla::ErrorResult& aError)
103   {
104     SetHTMLBoolAttr(nsGkAtoms::hidden, aHidden, aError);
105   }
106   virtual void Click();
GetAccessKey(nsString & aAccessKey)107   void GetAccessKey(nsString& aAccessKey)
108   {
109     GetHTMLAttr(nsGkAtoms::accesskey, aAccessKey);
110   }
SetAccessKey(const nsAString & aAccessKey,mozilla::ErrorResult & aError)111   void SetAccessKey(const nsAString& aAccessKey, mozilla::ErrorResult& aError)
112   {
113     SetHTMLAttr(nsGkAtoms::accesskey, aAccessKey, aError);
114   }
115   void GetAccessKeyLabel(nsString& aAccessKeyLabel);
Draggable()116   virtual bool Draggable() const
117   {
118     return AttrValueIs(kNameSpaceID_None, nsGkAtoms::draggable,
119                        nsGkAtoms::_true, eIgnoreCase);
120   }
SetDraggable(bool aDraggable,mozilla::ErrorResult & aError)121   void SetDraggable(bool aDraggable, mozilla::ErrorResult& aError)
122   {
123     SetHTMLAttr(nsGkAtoms::draggable,
124                 aDraggable ? NS_LITERAL_STRING("true")
125                            : NS_LITERAL_STRING("false"),
126                 aError);
127   }
GetContentEditable(nsString & aContentEditable)128   void GetContentEditable(nsString& aContentEditable)
129   {
130     ContentEditableTristate value = GetContentEditableValue();
131     if (value == eTrue) {
132       aContentEditable.AssignLiteral("true");
133     } else if (value == eFalse) {
134       aContentEditable.AssignLiteral("false");
135     } else {
136       aContentEditable.AssignLiteral("inherit");
137     }
138   }
SetContentEditable(const nsAString & aContentEditable,mozilla::ErrorResult & aError)139   void SetContentEditable(const nsAString& aContentEditable,
140                           mozilla::ErrorResult& aError)
141   {
142     if (aContentEditable.LowerCaseEqualsLiteral("inherit")) {
143       UnsetHTMLAttr(nsGkAtoms::contenteditable, aError);
144     } else if (aContentEditable.LowerCaseEqualsLiteral("true")) {
145       SetHTMLAttr(nsGkAtoms::contenteditable, NS_LITERAL_STRING("true"), aError);
146     } else if (aContentEditable.LowerCaseEqualsLiteral("false")) {
147       SetHTMLAttr(nsGkAtoms::contenteditable, NS_LITERAL_STRING("false"), aError);
148     } else {
149       aError.Throw(NS_ERROR_DOM_SYNTAX_ERR);
150     }
151   }
IsContentEditable()152   bool IsContentEditable()
153   {
154     for (nsIContent* node = this; node; node = node->GetParent()) {
155       nsGenericHTMLElement* element = FromContent(node);
156       if (element) {
157         ContentEditableTristate value = element->GetContentEditableValue();
158         if (value != eInherit) {
159           return value == eTrue;
160         }
161       }
162     }
163     return false;
164   }
165 
166   /**
167    * Returns the count of descendants (inclusive of this node) in
168    * the uncomposed document that are explicitly set as editable.
169    */
170   uint32_t EditableInclusiveDescendantCount();
171 
172   mozilla::dom::HTMLMenuElement* GetContextMenu() const;
173   bool Spellcheck();
SetSpellcheck(bool aSpellcheck,mozilla::ErrorResult & aError)174   void SetSpellcheck(bool aSpellcheck, mozilla::ErrorResult& aError)
175   {
176     SetHTMLAttr(nsGkAtoms::spellcheck,
177                 aSpellcheck ? NS_LITERAL_STRING("true")
178                             : NS_LITERAL_STRING("false"),
179                 aError);
180   }
Scrollgrab()181   bool Scrollgrab() const
182   {
183     return HasFlag(ELEMENT_HAS_SCROLLGRAB);
184   }
SetScrollgrab(bool aValue)185   void SetScrollgrab(bool aValue)
186   {
187     if (aValue) {
188       SetFlags(ELEMENT_HAS_SCROLLGRAB);
189     } else {
190       UnsetFlags(ELEMENT_HAS_SCROLLGRAB);
191     }
192   }
193 
194   void GetInnerText(mozilla::dom::DOMString& aValue, mozilla::ErrorResult& aError);
195   void SetInnerText(const nsAString& aValue);
196 
197   /**
198    * Determine whether an attribute is an event (onclick, etc.)
199    * @param aName the attribute
200    * @return whether the name is an event handler name
201    */
202   virtual bool IsEventAttributeName(nsIAtom* aName) override;
203 
204 #define EVENT(name_, id_, type_, struct_) /* nothing; handled by nsINode */
205 // The using nsINode::Get/SetOn* are to avoid warnings about shadowing the XPCOM
206 // getter and setter on nsINode.
207 #define FORWARDED_EVENT(name_, id_, type_, struct_)                           \
208   using nsINode::GetOn##name_;                                                \
209   using nsINode::SetOn##name_;                                                \
210   mozilla::dom::EventHandlerNonNull* GetOn##name_();                          \
211   void SetOn##name_(mozilla::dom::EventHandlerNonNull* handler);
212 #define ERROR_EVENT(name_, id_, type_, struct_)                               \
213   using nsINode::GetOn##name_;                                                \
214   using nsINode::SetOn##name_;                                                \
215   already_AddRefed<mozilla::dom::EventHandlerNonNull> GetOn##name_();         \
216   void SetOn##name_(mozilla::dom::EventHandlerNonNull* handler);
217 #include "mozilla/EventNameList.h" // IWYU pragma: keep
218 #undef ERROR_EVENT
219 #undef FORWARDED_EVENT
220 #undef EVENT
GetOffsetParent()221   mozilla::dom::Element* GetOffsetParent()
222   {
223     mozilla::CSSIntRect rcFrame;
224     return GetOffsetRect(rcFrame);
225   }
OffsetTop()226   int32_t OffsetTop()
227   {
228     mozilla::CSSIntRect rcFrame;
229     GetOffsetRect(rcFrame);
230 
231     return rcFrame.y;
232   }
OffsetLeft()233   int32_t OffsetLeft()
234   {
235     mozilla::CSSIntRect rcFrame;
236     GetOffsetRect(rcFrame);
237 
238     return rcFrame.x;
239   }
OffsetWidth()240   int32_t OffsetWidth()
241   {
242     mozilla::CSSIntRect rcFrame;
243     GetOffsetRect(rcFrame);
244 
245     return rcFrame.width;
246   }
OffsetHeight()247   int32_t OffsetHeight()
248   {
249     mozilla::CSSIntRect rcFrame;
250     GetOffsetRect(rcFrame);
251 
252     return rcFrame.height;
253   }
254 
255   // These methods are already implemented in nsIContent but we want something
256   // faster for HTMLElements ignoring the namespace checking.
257   // This is safe because we already know that we are in the HTML namespace.
IsHTMLElement()258   inline bool IsHTMLElement() const
259   {
260     return true;
261   }
262 
IsHTMLElement(nsIAtom * aTag)263   inline bool IsHTMLElement(nsIAtom* aTag) const
264   {
265     return mNodeInfo->Equals(aTag);
266   }
267 
268   template<typename First, typename... Args>
IsAnyOfHTMLElements(First aFirst,Args...aArgs)269   inline bool IsAnyOfHTMLElements(First aFirst, Args... aArgs) const
270   {
271     return IsNodeInternal(aFirst, aArgs...);
272   }
273 
274 protected:
~nsGenericHTMLElement()275   virtual ~nsGenericHTMLElement() {}
276 
277 public:
278   /**
279    * Get width and height, using given image request if attributes are unset.
280    * Pass a reference to the image request, since the method may change the
281    * value and we want to use the updated value.
282    */
283   nsSize GetWidthHeightForImage(RefPtr<imgRequestProxy>& aImageRequest);
284 
285   // XPIDL methods
286   NS_FORWARD_NSIDOMNODE_TO_NSINODE
287 
288   NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
289 
GetTitle(nsAString & aTitle)290   NS_IMETHOD GetTitle(nsAString& aTitle) final override {
291     mozilla::dom::DOMString title;
292     GetTitle(title);
293     title.ToString(aTitle);
294     return NS_OK;
295   }
GetLang(nsAString & aLang)296   NS_IMETHOD GetLang(nsAString& aLang) final override {
297     mozilla::dom::DOMString lang;
298     GetLang(lang);
299     lang.ToString(aLang);
300     return NS_OK;
301   }
GetDir(nsAString & aDir)302   NS_IMETHOD GetDir(nsAString& aDir) final override {
303     mozilla::dom::DOMString dir;
304     GetDir(dir);
305     dir.ToString(aDir);
306     return NS_OK;
307   }
SetDir(const nsAString & aDir)308   NS_IMETHOD SetDir(const nsAString& aDir) final override {
309     mozilla::ErrorResult rv;
310     SetDir(aDir, rv);
311     return rv.StealNSResult();
312   }
GetDOMClassName(nsAString & aClassName)313   NS_IMETHOD GetDOMClassName(nsAString& aClassName) final {
314     GetHTMLAttr(nsGkAtoms::_class, aClassName);
315     return NS_OK;
316   }
SetDOMClassName(const nsAString & aClassName)317   NS_IMETHOD SetDOMClassName(const nsAString& aClassName) final {
318     SetClassName(aClassName);
319     return NS_OK;
320   }
321   NS_IMETHOD GetDataset(nsISupports** aDataset) final override;
GetHidden(bool * aHidden)322   NS_IMETHOD GetHidden(bool* aHidden) final override {
323     *aHidden = Hidden();
324     return NS_OK;
325   }
SetHidden(bool aHidden)326   NS_IMETHOD SetHidden(bool aHidden) final override {
327     mozilla::ErrorResult rv;
328     SetHidden(aHidden, rv);
329     return rv.StealNSResult();
330   }
DOMBlur()331   NS_IMETHOD DOMBlur() final override {
332     mozilla::ErrorResult rv;
333     Blur(rv);
334     return rv.StealNSResult();
335   }
GetAccessKey(nsAString & aAccessKey)336   NS_IMETHOD GetAccessKey(nsAString& aAccessKey) final override {
337     nsString accessKey;
338     GetAccessKey(accessKey);
339     aAccessKey.Assign(accessKey);
340     return NS_OK;
341   }
SetAccessKey(const nsAString & aAccessKey)342   NS_IMETHOD SetAccessKey(const nsAString& aAccessKey) final override {
343     mozilla::ErrorResult rv;
344     SetAccessKey(aAccessKey, rv);
345     return rv.StealNSResult();
346   }
GetAccessKeyLabel(nsAString & aAccessKeyLabel)347   NS_IMETHOD GetAccessKeyLabel(nsAString& aAccessKeyLabel)
348     final override {
349     nsString accessKeyLabel;
350     GetAccessKeyLabel(accessKeyLabel);
351     aAccessKeyLabel.Assign(accessKeyLabel);
352     return NS_OK;
353   }
SetDraggable(bool aDraggable)354   NS_IMETHOD SetDraggable(bool aDraggable) final override {
355     mozilla::ErrorResult rv;
356     SetDraggable(aDraggable, rv);
357     return rv.StealNSResult();
358   }
GetContentEditable(nsAString & aContentEditable)359   NS_IMETHOD GetContentEditable(nsAString& aContentEditable)
360     final override {
361     nsString contentEditable;
362     GetContentEditable(contentEditable);
363     aContentEditable.Assign(contentEditable);
364     return NS_OK;
365   }
SetContentEditable(const nsAString & aContentEditable)366   NS_IMETHOD SetContentEditable(const nsAString& aContentEditable)
367     final override {
368     mozilla::ErrorResult rv;
369     SetContentEditable(aContentEditable, rv);
370     return rv.StealNSResult();
371   }
GetIsContentEditable(bool * aIsContentEditable)372   NS_IMETHOD GetIsContentEditable(bool* aIsContentEditable)
373     final override {
374     *aIsContentEditable = IsContentEditable();
375     return NS_OK;
376   }
377   NS_IMETHOD GetContextMenu(nsIDOMHTMLMenuElement** aContextMenu)
378     final override;
GetSpellcheck(bool * aSpellcheck)379   NS_IMETHOD GetSpellcheck(bool* aSpellcheck) final override {
380     *aSpellcheck = Spellcheck();
381     return NS_OK;
382   }
SetSpellcheck(bool aSpellcheck)383   NS_IMETHOD SetSpellcheck(bool aSpellcheck) final override {
384     mozilla::ErrorResult rv;
385     SetSpellcheck(aSpellcheck, rv);
386     return rv.StealNSResult();
387   }
GetOuterHTML(nsAString & aOuterHTML)388   NS_IMETHOD GetOuterHTML(nsAString& aOuterHTML) final override {
389     mozilla::dom::Element::GetOuterHTML(aOuterHTML);
390     return NS_OK;
391   }
SetOuterHTML(const nsAString & aOuterHTML)392   NS_IMETHOD SetOuterHTML(const nsAString& aOuterHTML) final override {
393     mozilla::ErrorResult rv;
394     mozilla::dom::Element::SetOuterHTML(aOuterHTML, rv);
395     return rv.StealNSResult();
396   }
397   NS_IMETHOD InsertAdjacentHTML(const nsAString& position,
398                                 const nsAString& text) final override;
ScrollIntoView(bool top,uint8_t _argc)399   NS_IMETHOD ScrollIntoView(bool top, uint8_t _argc) final override {
400     if (!_argc) {
401       top = true;
402     }
403     mozilla::dom::Element::ScrollIntoView(top);
404     return NS_OK;
405   }
GetOffsetParent(nsIDOMElement ** aOffsetParent)406   NS_IMETHOD GetOffsetParent(nsIDOMElement** aOffsetParent)
407     final override {
408     mozilla::dom::Element* offsetParent = GetOffsetParent();
409     if (!offsetParent) {
410       *aOffsetParent = nullptr;
411       return NS_OK;
412     }
413     return CallQueryInterface(offsetParent, aOffsetParent);
414   }
GetOffsetTop(int32_t * aOffsetTop)415   NS_IMETHOD GetOffsetTop(int32_t* aOffsetTop) final override {
416     *aOffsetTop = OffsetTop();
417     return NS_OK;
418   }
GetOffsetLeft(int32_t * aOffsetLeft)419   NS_IMETHOD GetOffsetLeft(int32_t* aOffsetLeft) final override {
420     *aOffsetLeft = OffsetLeft();
421     return NS_OK;
422   }
GetOffsetWidth(int32_t * aOffsetWidth)423   NS_IMETHOD GetOffsetWidth(int32_t* aOffsetWidth) final override {
424     *aOffsetWidth = OffsetWidth();
425     return NS_OK;
426   }
GetOffsetHeight(int32_t * aOffsetHeight)427   NS_IMETHOD GetOffsetHeight(int32_t* aOffsetHeight) final override {
428     *aOffsetHeight = OffsetHeight();
429     return NS_OK;
430   }
DOMClick()431   NS_IMETHOD DOMClick() final override {
432     Click();
433     return NS_OK;
434   }
GetTabIndex(int32_t * aTabIndex)435   NS_IMETHOD GetTabIndex(int32_t* aTabIndex) final override {
436     *aTabIndex = TabIndex();
437     return NS_OK;
438   }
SetTabIndex(int32_t aTabIndex)439   NS_IMETHOD SetTabIndex(int32_t aTabIndex) final override {
440     mozilla::ErrorResult rv;
441     SetTabIndex(aTabIndex, rv);
442     return rv.StealNSResult();
443   }
Focus()444   NS_IMETHOD Focus() final override {
445     mozilla::ErrorResult rv;
446     Focus(rv);
447     return rv.StealNSResult();
448   }
GetDraggable(bool * aDraggable)449   NS_IMETHOD GetDraggable(bool* aDraggable) final override {
450     *aDraggable = Draggable();
451     return NS_OK;
452   }
GetInnerHTML(nsAString & aInnerHTML)453   NS_IMETHOD GetInnerHTML(nsAString& aInnerHTML) override {
454     return mozilla::dom::Element::GetInnerHTML(aInnerHTML);
455   }
456   using mozilla::dom::Element::SetInnerHTML;
SetInnerHTML(const nsAString & aInnerHTML)457   NS_IMETHOD SetInnerHTML(const nsAString& aInnerHTML) final override {
458     mozilla::ErrorResult rv;
459     SetInnerHTML(aInnerHTML, rv);
460     return rv.StealNSResult();
461   }
462 
463   using nsGenericHTMLElementBase::GetOwnerDocument;
464 
AsDOMNode()465   virtual nsIDOMNode* AsDOMNode() override { return this; }
466 
467 public:
468   // Implementation for nsIContent
469   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
470                               nsIContent* aBindingParent,
471                               bool aCompileEventHandlers) override;
472   virtual void UnbindFromTree(bool aDeep = true,
473                               bool aNullParent = true) override;
474 
475   MOZ_ALWAYS_INLINE // Avoid a crashy hook from Avast 10 Beta
SetAttr(int32_t aNameSpaceID,nsIAtom * aName,const nsAString & aValue,bool aNotify)476   nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
477                    const nsAString& aValue, bool aNotify)
478   {
479     return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
480   }
481   virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
482                            nsIAtom* aPrefix, const nsAString& aValue,
483                            bool aNotify) override;
484   virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aName,
485                              bool aNotify) override;
IsFocusableInternal(int32_t * aTabIndex,bool aWithMouse)486   virtual bool IsFocusableInternal(int32_t *aTabIndex, bool aWithMouse) override
487   {
488     bool isFocusable = false;
489     IsHTMLFocusable(aWithMouse, &isFocusable, aTabIndex);
490     return isFocusable;
491   }
492   /**
493    * Returns true if a subclass is not allowed to override the value returned
494    * in aIsFocusable.
495    */
496   virtual bool IsHTMLFocusable(bool aWithMouse,
497                                bool *aIsFocusable,
498                                int32_t *aTabIndex);
499   virtual bool PerformAccesskey(bool aKeyCausesActivation,
500                                 bool aIsTrustedEvent) override;
501 
502   /**
503    * Check if an event for an anchor can be handled
504    * @return true if the event can be handled, false otherwise
505    */
506   bool CheckHandleEventForAnchorsPreconditions(
507          mozilla::EventChainVisitor& aVisitor);
508   nsresult PreHandleEventForAnchors(mozilla::EventChainPreVisitor& aVisitor);
509   nsresult PostHandleEventForAnchors(mozilla::EventChainPostVisitor& aVisitor);
510   bool IsHTMLLink(nsIURI** aURI) const;
511 
512   // HTML element methods
Compact()513   void Compact() { mAttrsAndChildren.Compact(); }
514 
515   virtual void UpdateEditableState(bool aNotify) override;
516 
517   virtual mozilla::EventStates IntrinsicState() const override;
518 
519   // Helper for setting our editable flag and notifying
DoSetEditableFlag(bool aEditable,bool aNotify)520   void DoSetEditableFlag(bool aEditable, bool aNotify) {
521     SetEditableFlag(aEditable);
522     UpdateState(aNotify);
523   }
524 
525   virtual bool ParseAttribute(int32_t aNamespaceID,
526                               nsIAtom* aAttribute,
527                               const nsAString& aValue,
528                               nsAttrValue& aResult) override;
529 
530   bool ParseBackgroundAttribute(int32_t aNamespaceID,
531                                 nsIAtom* aAttribute,
532                                 const nsAString& aValue,
533                                 nsAttrValue& aResult);
534 
535   NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const override;
536   virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const override;
537 
538   /**
539    * Get the base target for any links within this piece
540    * of content. Generally, this is the document's base target,
541    * but certain content carries a local base for backward
542    * compatibility.
543    *
544    * @param aBaseTarget the base target [OUT]
545    */
546   void GetBaseTarget(nsAString& aBaseTarget) const;
547 
548   /**
549    * Get the primary form control frame for this element.  Same as
550    * GetPrimaryFrame(), except it QI's to nsIFormControlFrame.
551    *
552    * @param aFlush whether to flush out frames so that they're up to date.
553    * @return the primary frame as nsIFormControlFrame
554    */
555   nsIFormControlFrame* GetFormControlFrame(bool aFlushFrames);
556 
557   //----------------------------------------
558 
559   /**
560    * Parse an alignment attribute (top/middle/bottom/baseline)
561    *
562    * @param aString the string to parse
563    * @param aResult the resulting HTMLValue
564    * @return whether the value was parsed
565    */
566   static bool ParseAlignValue(const nsAString& aString,
567                                 nsAttrValue& aResult);
568 
569   /**
570    * Parse a div align string to value (left/right/center/middle/justify)
571    *
572    * @param aString the string to parse
573    * @param aResult the resulting HTMLValue
574    * @return whether the value was parsed
575    */
576   static bool ParseDivAlignValue(const nsAString& aString,
577                                    nsAttrValue& aResult);
578 
579   /**
580    * Convert a table halign string to value (left/right/center/char/justify)
581    *
582    * @param aString the string to parse
583    * @param aResult the resulting HTMLValue
584    * @return whether the value was parsed
585    */
586   static bool ParseTableHAlignValue(const nsAString& aString,
587                                       nsAttrValue& aResult);
588 
589   /**
590    * Convert a table cell halign string to value
591    *
592    * @param aString the string to parse
593    * @param aResult the resulting HTMLValue
594    * @return whether the value was parsed
595    */
596   static bool ParseTableCellHAlignValue(const nsAString& aString,
597                                           nsAttrValue& aResult);
598 
599   /**
600    * Convert a table valign string to value (left/right/center/char/justify/
601    * abscenter/absmiddle/middle)
602    *
603    * @param aString the string to parse
604    * @param aResult the resulting HTMLValue
605    * @return whether the value was parsed
606    */
607   static bool ParseTableVAlignValue(const nsAString& aString,
608                                       nsAttrValue& aResult);
609 
610   /**
611    * Convert an image attribute to value (width, height, hspace, vspace, border)
612    *
613    * @param aAttribute the attribute to parse
614    * @param aString the string to parse
615    * @param aResult the resulting HTMLValue
616    * @return whether the value was parsed
617    */
618   static bool ParseImageAttribute(nsIAtom* aAttribute,
619                                     const nsAString& aString,
620                                     nsAttrValue& aResult);
621 
622   static bool ParseReferrerAttribute(const nsAString& aString,
623                                      nsAttrValue& aResult);
624 
625   /**
626    * Convert a frameborder string to value (yes/no/1/0)
627    *
628    * @param aString the string to parse
629    * @param aResult the resulting HTMLValue
630    * @return whether the value was parsed
631    */
632   static bool ParseFrameborderValue(const nsAString& aString,
633                                       nsAttrValue& aResult);
634 
635   /**
636    * Convert a scrolling string to value (yes/no/on/off/scroll/noscroll/auto)
637    *
638    * @param aString the string to parse
639    * @param aResult the resulting HTMLValue
640    * @return whether the value was parsed
641    */
642   static bool ParseScrollingValue(const nsAString& aString,
643                                     nsAttrValue& aResult);
644 
645   /*
646    * Attribute Mapping Helpers
647    */
648 
649   /**
650    * A style attribute mapping function for the most common attributes, to be
651    * called by subclasses' attribute mapping functions.  Currently handles
652    * dir, lang and hidden, could handle others.
653    *
654    * @param aAttributes the list of attributes to map
655    * @param aData the returned rule data [INOUT]
656    * @see GetAttributeMappingFunction
657    */
658   static void MapCommonAttributesInto(const nsMappedAttributes* aAttributes,
659                                       nsRuleData* aRuleData);
660   /**
661    * Same as MapCommonAttributesInto except that it does not handle hidden.
662    *
663    * @param aAttributes the list of attributes to map
664    * @param aData the returned rule data [INOUT]
665    * @see GetAttributeMappingFunction
666    */
667   static void MapCommonAttributesIntoExceptHidden(const nsMappedAttributes* aAttributes,
668                                                   nsRuleData* aRuleData);
669 
670   static const MappedAttributeEntry sCommonAttributeMap[];
671   static const MappedAttributeEntry sImageMarginSizeAttributeMap[];
672   static const MappedAttributeEntry sImageBorderAttributeMap[];
673   static const MappedAttributeEntry sImageAlignAttributeMap[];
674   static const MappedAttributeEntry sDivAlignAttributeMap[];
675   static const MappedAttributeEntry sBackgroundAttributeMap[];
676   static const MappedAttributeEntry sBackgroundColorAttributeMap[];
677 
678   /**
679    * Helper to map the align attribute into a style struct.
680    *
681    * @param aAttributes the list of attributes to map
682    * @param aData the returned rule data [INOUT]
683    * @see GetAttributeMappingFunction
684    */
685   static void MapImageAlignAttributeInto(const nsMappedAttributes* aAttributes,
686                                          nsRuleData* aData);
687 
688   /**
689    * Helper to map the align attribute into a style struct for things
690    * like <div>, <h1>, etc.
691    *
692    * @param aAttributes the list of attributes to map
693    * @param aData the returned rule data [INOUT]
694    * @see GetAttributeMappingFunction
695    */
696   static void MapDivAlignAttributeInto(const nsMappedAttributes* aAttributes,
697                                        nsRuleData* aData);
698 
699   /**
700    * Helper to map the image border attribute into a style struct.
701    *
702    * @param aAttributes the list of attributes to map
703    * @param aData the returned rule data [INOUT]
704    * @see GetAttributeMappingFunction
705    */
706   static void MapImageBorderAttributeInto(const nsMappedAttributes* aAttributes,
707                                           nsRuleData* aData);
708   /**
709    * Helper to map the image margin attribute into a style struct.
710    *
711    * @param aAttributes the list of attributes to map
712    * @param aData the returned rule data [INOUT]
713    * @see GetAttributeMappingFunction
714    */
715   static void MapImageMarginAttributeInto(const nsMappedAttributes* aAttributes,
716                                           nsRuleData* aData);
717   /**
718    * Helper to map the image position attribute into a style struct.
719    *
720    * @param aAttributes the list of attributes to map
721    * @param aData the returned rule data [INOUT]
722    * @see GetAttributeMappingFunction
723    */
724   static void MapImageSizeAttributesInto(const nsMappedAttributes* aAttributes,
725                                          nsRuleData* aData);
726   /**
727    * Helper to map the background attribute
728    * into a style struct.
729    *
730    * @param aAttributes the list of attributes to map
731    * @param aData the returned rule data [INOUT]
732    * @see GetAttributeMappingFunction
733    */
734   static void MapBackgroundInto(const nsMappedAttributes* aAttributes,
735                                 nsRuleData* aData);
736   /**
737    * Helper to map the bgcolor attribute
738    * into a style struct.
739    *
740    * @param aAttributes the list of attributes to map
741    * @param aData the returned rule data [INOUT]
742    * @see GetAttributeMappingFunction
743    */
744   static void MapBGColorInto(const nsMappedAttributes* aAttributes,
745                              nsRuleData* aData);
746   /**
747    * Helper to map the background attributes (currently background and bgcolor)
748    * into a style struct.
749    *
750    * @param aAttributes the list of attributes to map
751    * @param aData the returned rule data [INOUT]
752    * @see GetAttributeMappingFunction
753    */
754   static void MapBackgroundAttributesInto(const nsMappedAttributes* aAttributes,
755                                           nsRuleData* aData);
756   /**
757    * Helper to map the scrolling attribute on FRAME and IFRAME
758    * into a style struct.
759    *
760    * @param aAttributes the list of attributes to map
761    * @param aData the returned rule data [INOUT]
762    * @see GetAttributeMappingFunction
763    */
764   static void MapScrollingAttributeInto(const nsMappedAttributes* aAttributes,
765                                         nsRuleData* aData);
766   /**
767    * Get the presentation context for this content node.
768    * @return the presentation context
769    */
770   enum PresContextFor
771   {
772     eForComposedDoc,
773     eForUncomposedDoc
774   };
775   nsPresContext* GetPresContext(PresContextFor aFor);
776 
777   // Form Helper Routines
778   /**
779    * Find an ancestor of this content node which is a form (could be null)
780    * @param aCurrentForm the current form for this node.  If this is
781    *        non-null, and no ancestor form is found, and the current form is in
782    *        a connected subtree with the node, the current form will be
783    *        returned.  This is needed to handle cases when HTML elements have a
784    *        current form that they're not descendants of.
785    * @note This method should not be called if the element has a form attribute.
786    */
787   mozilla::dom::HTMLFormElement*
788   FindAncestorForm(mozilla::dom::HTMLFormElement* aCurrentForm = nullptr);
789 
790   virtual void RecompileScriptEventListeners() override;
791 
792   /**
793    * See if the document being tested has nav-quirks mode enabled.
794    * @param doc the document
795    */
796   static bool InNavQuirksMode(nsIDocument* aDoc);
797 
798   /**
799    * Locate an nsIEditor rooted at this content node, if there is one.
800    */
801   nsresult GetEditor(nsIEditor** aEditor);
802 
803   /**
804    * Helper method for NS_IMPL_URI_ATTR macro.
805    * Gets the absolute URI value of an attribute, by resolving any relative
806    * URIs in the attribute against the baseuri of the element. If the attribute
807    * isn't a relative URI the value of the attribute is returned as is. Only
808    * works for attributes in null namespace.
809    *
810    * @param aAttr      name of attribute.
811    * @param aBaseAttr  name of base attribute.
812    * @param aResult    result value [out]
813    */
814   void GetURIAttr(nsIAtom* aAttr, nsIAtom* aBaseAttr, nsAString& aResult) const;
815 
816   /**
817    * Gets the absolute URI values of an attribute, by resolving any relative
818    * URIs in the attribute against the baseuri of the element. If a substring
819    * isn't a relative URI, the substring is returned as is. Only works for
820    * attributes in null namespace.
821    */
822   bool GetURIAttr(nsIAtom* aAttr, nsIAtom* aBaseAttr, nsIURI** aURI) const;
823 
824   /**
825    * Returns the current disabled state of the element.
826    */
IsDisabled()827   virtual bool IsDisabled() const {
828     return false;
829   }
830 
IsHidden()831   bool IsHidden() const
832   {
833     return HasAttr(kNameSpaceID_None, nsGkAtoms::hidden);
834   }
835 
836   virtual bool IsLabelable() const override;
837   virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const override;
838 
839   static bool TouchEventsEnabled(JSContext* /* unused */, JSObject* /* unused */);
840 
841   static inline bool
CanHaveName(nsIAtom * aTag)842   CanHaveName(nsIAtom* aTag)
843   {
844     return aTag == nsGkAtoms::img ||
845            aTag == nsGkAtoms::form ||
846            aTag == nsGkAtoms::applet ||
847            aTag == nsGkAtoms::embed ||
848            aTag == nsGkAtoms::object;
849   }
850   static inline bool
ShouldExposeNameAsHTMLDocumentProperty(Element * aElement)851   ShouldExposeNameAsHTMLDocumentProperty(Element* aElement)
852   {
853     return aElement->IsHTMLElement() &&
854            CanHaveName(aElement->NodeInfo()->NameAtom());
855   }
856   static inline bool
ShouldExposeIdAsHTMLDocumentProperty(Element * aElement)857   ShouldExposeIdAsHTMLDocumentProperty(Element* aElement)
858   {
859     if (aElement->IsAnyOfHTMLElements(nsGkAtoms::applet,
860                                       nsGkAtoms::embed,
861                                       nsGkAtoms::object)) {
862       return true;
863     }
864 
865     // Per spec, <img> is exposed by id only if it also has a nonempty
866     // name (which doesn't have to match the id or anything).
867     // HasName() is true precisely when name is nonempty.
868     return aElement->IsHTMLElement(nsGkAtoms::img) && aElement->HasName();
869   }
870 
871   static bool
872   IsScrollGrabAllowed(JSContext*, JSObject*);
873 
874 protected:
875   /**
876    * Add/remove this element to the documents name cache
877    */
AddToNameTable(nsIAtom * aName)878   void AddToNameTable(nsIAtom* aName) {
879     NS_ASSERTION(HasName(), "Node doesn't have name?");
880     nsIDocument* doc = GetUncomposedDoc();
881     if (doc && !IsInAnonymousSubtree()) {
882       doc->AddToNameTable(this, aName);
883     }
884   }
RemoveFromNameTable()885   void RemoveFromNameTable() {
886     if (HasName()) {
887       nsIDocument* doc = GetUncomposedDoc();
888       if (doc) {
889         doc->RemoveFromNameTable(this, GetParsedAttr(nsGkAtoms::name)->
890                                          GetAtomValue());
891       }
892     }
893   }
894 
895   /**
896    * Register or unregister an access key to this element based on the
897    * accesskey attribute.
898    */
RegAccessKey()899   void RegAccessKey()
900   {
901     if (HasFlag(NODE_HAS_ACCESSKEY)) {
902       RegUnRegAccessKey(true);
903     }
904   }
905 
UnregAccessKey()906   void UnregAccessKey()
907   {
908     if (HasFlag(NODE_HAS_ACCESSKEY)) {
909       RegUnRegAccessKey(false);
910     }
911   }
912 
913 private:
914   void RegUnRegAccessKey(bool aDoReg);
915 
916 protected:
917   virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
918                                 const nsAttrValue* aValue, bool aNotify) override;
919 
920   virtual mozilla::EventListenerManager*
921     GetEventListenerManagerForAttr(nsIAtom* aAttrName,
922                                    bool* aDefer) override;
923 
924   /**
925    * Dispatch a simulated mouse click by keyboard to the given element.
926    */
927   nsresult DispatchSimulatedClick(nsGenericHTMLElement* aElement,
928                                   bool aIsTrusted,
929                                   nsPresContext* aPresContext);
930 
931   /**
932    * Create a URI for the given aURISpec string.
933    * Returns INVALID_STATE_ERR and nulls *aURI if aURISpec is empty
934    * and the document's URI matches the element's base URI.
935    */
936   nsresult NewURIFromString(const nsAString& aURISpec, nsIURI** aURI);
937 
GetHTMLAttr(nsIAtom * aName,nsAString & aResult)938   void GetHTMLAttr(nsIAtom* aName, nsAString& aResult) const
939   {
940     GetAttr(kNameSpaceID_None, aName, aResult);
941   }
GetHTMLAttr(nsIAtom * aName,mozilla::dom::DOMString & aResult)942   void GetHTMLAttr(nsIAtom* aName, mozilla::dom::DOMString& aResult) const
943   {
944     GetAttr(kNameSpaceID_None, aName, aResult);
945   }
GetHTMLEnumAttr(nsIAtom * aName,nsAString & aResult)946   void GetHTMLEnumAttr(nsIAtom* aName, nsAString& aResult) const
947   {
948     GetEnumAttr(aName, nullptr, aResult);
949   }
GetHTMLURIAttr(nsIAtom * aName,nsAString & aResult)950   void GetHTMLURIAttr(nsIAtom* aName, nsAString& aResult) const
951   {
952     GetURIAttr(aName, nullptr, aResult);
953   }
954 
SetHTMLAttr(nsIAtom * aName,const nsAString & aValue)955   void SetHTMLAttr(nsIAtom* aName, const nsAString& aValue)
956   {
957     SetAttr(kNameSpaceID_None, aName, aValue, true);
958   }
SetHTMLAttr(nsIAtom * aName,const nsAString & aValue,mozilla::ErrorResult & aError)959   void SetHTMLAttr(nsIAtom* aName, const nsAString& aValue, mozilla::ErrorResult& aError)
960   {
961     mozilla::dom::Element::SetAttr(aName, aValue, aError);
962   }
UnsetHTMLAttr(nsIAtom * aName,mozilla::ErrorResult & aError)963   void UnsetHTMLAttr(nsIAtom* aName, mozilla::ErrorResult& aError)
964   {
965     mozilla::dom::Element::UnsetAttr(aName, aError);
966   }
SetHTMLBoolAttr(nsIAtom * aName,bool aValue,mozilla::ErrorResult & aError)967   void SetHTMLBoolAttr(nsIAtom* aName, bool aValue, mozilla::ErrorResult& aError)
968   {
969     if (aValue) {
970       SetHTMLAttr(aName, EmptyString(), aError);
971     } else {
972       UnsetHTMLAttr(aName, aError);
973     }
974   }
975   template<typename T>
SetHTMLIntAttr(nsIAtom * aName,T aValue,mozilla::ErrorResult & aError)976   void SetHTMLIntAttr(nsIAtom* aName, T aValue, mozilla::ErrorResult& aError)
977   {
978     nsAutoString value;
979     value.AppendInt(aValue);
980 
981     SetHTMLAttr(aName, value, aError);
982   }
983 
984   /**
985    * Helper method for NS_IMPL_STRING_ATTR macro.
986    * Sets the value of an attribute, returns specified default value if the
987    * attribute isn't set. Only works for attributes in null namespace.
988    *
989    * @param aAttr    name of attribute.
990    * @param aDefault default-value to return if attribute isn't set.
991    * @param aResult  result value [out]
992    */
993   nsresult SetAttrHelper(nsIAtom* aAttr, const nsAString& aValue);
994 
995   /**
996    * Helper method for NS_IMPL_INT_ATTR macro.
997    * Gets the integer-value of an attribute, returns specified default value
998    * if the attribute isn't set or isn't set to an integer. Only works for
999    * attributes in null namespace.
1000    *
1001    * @param aAttr    name of attribute.
1002    * @param aDefault default-value to return if attribute isn't set.
1003    */
1004   int32_t GetIntAttr(nsIAtom* aAttr, int32_t aDefault) const;
1005 
1006   /**
1007    * Helper method for NS_IMPL_INT_ATTR macro.
1008    * Sets value of attribute to specified integer. Only works for attributes
1009    * in null namespace.
1010    *
1011    * @param aAttr    name of attribute.
1012    * @param aValue   Integer value of attribute.
1013    */
1014   nsresult SetIntAttr(nsIAtom* aAttr, int32_t aValue);
1015 
1016   /**
1017    * Helper method for NS_IMPL_UINT_ATTR macro.
1018    * Gets the unsigned integer-value of an attribute, returns specified default
1019    * value if the attribute isn't set or isn't set to an integer. Only works for
1020    * attributes in null namespace.
1021    *
1022    * @param aAttr    name of attribute.
1023    * @param aDefault default-value to return if attribute isn't set.
1024    */
1025   uint32_t GetUnsignedIntAttr(nsIAtom* aAttr, uint32_t aDefault) const;
1026 
1027   /**
1028    * Helper method for NS_IMPL_UINT_ATTR macro.
1029    * Sets value of attribute to specified unsigned integer. Only works for
1030    * attributes in null namespace.
1031    *
1032    * @param aAttr    name of attribute.
1033    * @param aValue   Integer value of attribute.
1034    * @param aDefault Default value (in case value is out of range).  If the spec
1035    *                 doesn't provide one, should be 1 if the value is limited to
1036    *                 nonzero values, and 0 otherwise.
1037    */
SetUnsignedIntAttr(nsIAtom * aName,uint32_t aValue,uint32_t aDefault,mozilla::ErrorResult & aError)1038   void SetUnsignedIntAttr(nsIAtom* aName, uint32_t aValue, uint32_t aDefault,
1039                           mozilla::ErrorResult& aError)
1040   {
1041     nsAutoString value;
1042     if (aValue > INT32_MAX) {
1043       value.AppendInt(aDefault);
1044     } else {
1045       value.AppendInt(aValue);
1046     }
1047 
1048     SetHTMLAttr(aName, value, aError);
1049   }
1050 
1051   /**
1052    * Sets value of attribute to specified double. Only works for attributes
1053    * in null namespace.
1054    *
1055    * @param aAttr    name of attribute.
1056    * @param aValue   Double value of attribute.
1057    */
SetDoubleAttr(nsIAtom * aAttr,double aValue,mozilla::ErrorResult & aRv)1058   void SetDoubleAttr(nsIAtom* aAttr, double aValue, mozilla::ErrorResult& aRv)
1059   {
1060     nsAutoString value;
1061     value.AppendFloat(aValue);
1062 
1063     SetHTMLAttr(aAttr, value, aRv);
1064   }
1065 
1066   /**
1067    * Locates the nsIEditor associated with this node.  In general this is
1068    * equivalent to GetEditorInternal(), but for designmode or contenteditable,
1069    * this may need to get an editor that's not actually on this element's
1070    * associated TextControlFrame.  This is used by the spellchecking routines
1071    * to get the editor affected by changing the spellcheck attribute on this
1072    * node.
1073    */
1074   virtual already_AddRefed<nsIEditor> GetAssociatedEditor();
1075 
1076   /**
1077    * Get the frame's offset information for offsetTop/Left/Width/Height.
1078    * Returns the parent the offset is relative to.
1079    * @note This method flushes pending notifications (Flush_Layout).
1080    * @param aRect the offset information [OUT]
1081    */
1082   mozilla::dom::Element* GetOffsetRect(mozilla::CSSIntRect& aRect);
1083 
1084   /**
1085    * Returns true if this is the current document's body element
1086    */
1087   bool IsCurrentBodyElement();
1088 
1089   /**
1090    * Ensures all editors associated with a subtree are synced, for purposes of
1091    * spellchecking.
1092    */
1093   static void SyncEditorsOnSubtree(nsIContent* content);
1094 
1095   enum ContentEditableTristate {
1096     eInherit = -1,
1097     eFalse = 0,
1098     eTrue = 1
1099   };
1100 
1101   /**
1102    * Returns eTrue if the element has a contentEditable attribute and its value
1103    * is "true" or an empty string. Returns eFalse if the element has a
1104    * contentEditable attribute and its value is "false". Otherwise returns
1105    * eInherit.
1106    */
GetContentEditableValue()1107   ContentEditableTristate GetContentEditableValue() const
1108   {
1109     static const nsIContent::AttrValuesArray values[] =
1110       { &nsGkAtoms::_false, &nsGkAtoms::_true, &nsGkAtoms::_empty, nullptr };
1111 
1112     if (!MayHaveContentEditableAttr())
1113       return eInherit;
1114 
1115     int32_t value = FindAttrValueIn(kNameSpaceID_None,
1116                                     nsGkAtoms::contenteditable, values,
1117                                     eIgnoreCase);
1118 
1119     return value > 0 ? eTrue : (value == 0 ? eFalse : eInherit);
1120   }
1121 
1122   // Used by A, AREA, LINK, and STYLE.
1123   already_AddRefed<nsIURI> GetHrefURIForAnchors() const;
1124 
1125   /**
1126    * Returns whether this element is an editable root. There are two types of
1127    * editable roots:
1128    *   1) the documentElement if the whole document is editable (for example for
1129    *      desginMode=on)
1130    *   2) an element that is marked editable with contentEditable=true and that
1131    *      doesn't have a parent or whose parent is not editable.
1132    * Note that this doesn't return input and textarea elements that haven't been
1133    * made editable through contentEditable or designMode.
1134    */
1135   bool IsEditableRoot() const;
1136 
1137 private:
1138   void ChangeEditableState(int32_t aChange);
1139 };
1140 
1141 namespace mozilla {
1142 namespace dom {
1143 class HTMLFieldSetElement;
1144 } // namespace dom
1145 } // namespace mozilla
1146 
1147 #define FORM_ELEMENT_FLAG_BIT(n_) NODE_FLAG_BIT(ELEMENT_TYPE_SPECIFIC_BITS_OFFSET + (n_))
1148 
1149 // Form element specific bits
1150 enum {
1151   // If this flag is set on an nsGenericHTMLFormElement or an HTMLImageElement,
1152   // that means that we have added ourselves to our mForm.  It's possible to
1153   // have a non-null mForm, but not have this flag set.  That happens when the
1154   // form is set via the content sink.
1155   ADDED_TO_FORM =                         FORM_ELEMENT_FLAG_BIT(0),
1156 
1157   // If this flag is set on an nsGenericHTMLFormElement or an HTMLImageElement,
1158   // that means that its form is in the process of being unbound from the tree,
1159   // and this form element hasn't re-found its form in
1160   // nsGenericHTMLFormElement::UnbindFromTree yet.
1161   MAYBE_ORPHAN_FORM_ELEMENT =             FORM_ELEMENT_FLAG_BIT(1)
1162 };
1163 
1164 // NOTE: I don't think it's possible to have the above two flags set at the
1165 // same time, so if it becomes an issue we can probably merge them into the
1166 // same bit.  --bz
1167 
1168 ASSERT_NODE_FLAGS_SPACE(ELEMENT_TYPE_SPECIFIC_BITS_OFFSET + 2);
1169 
1170 #undef FORM_ELEMENT_FLAG_BIT
1171 
1172 /**
1173  * A helper class for form elements that can contain children
1174  */
1175 class nsGenericHTMLFormElement : public nsGenericHTMLElement,
1176                                  public nsIFormControl
1177 {
1178 public:
1179   explicit nsGenericHTMLFormElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
1180 
1181   NS_DECL_ISUPPORTS_INHERITED
1182 
1183   nsINode* GetScopeChainParent() const override;
1184 
1185   virtual bool IsNodeOfType(uint32_t aFlags) const override;
1186   virtual void SaveSubtreeState() override;
1187 
1188   // nsIFormControl
1189   virtual mozilla::dom::HTMLFieldSetElement* GetFieldSet() override;
1190   virtual mozilla::dom::Element* GetFormElement() override;
GetForm()1191   mozilla::dom::HTMLFormElement* GetForm() const
1192   {
1193     return mForm;
1194   }
1195   virtual void SetForm(nsIDOMHTMLFormElement* aForm) override;
1196   virtual void ClearForm(bool aRemoveFromForm) override;
1197 
1198   nsresult GetForm(nsIDOMHTMLFormElement** aForm);
1199 
SaveState()1200   NS_IMETHOD SaveState() override
1201   {
1202     return NS_OK;
1203   }
1204 
RestoreState(nsPresState * aState)1205   virtual bool RestoreState(nsPresState* aState) override
1206   {
1207     return false;
1208   }
AllowDrop()1209   virtual bool AllowDrop() override
1210   {
1211     return true;
1212   }
1213 
1214   // nsIContent
1215   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
1216                               nsIContent* aBindingParent,
1217                               bool aCompileEventHandlers) override;
1218   virtual void UnbindFromTree(bool aDeep = true,
1219                               bool aNullParent = true) override;
1220   virtual IMEState GetDesiredIMEState() override;
1221   virtual mozilla::EventStates IntrinsicState() const override;
1222 
1223   virtual nsresult PreHandleEvent(
1224                      mozilla::EventChainPreVisitor& aVisitor) override;
1225 
1226   virtual bool IsDisabled() const override;
1227 
1228   /**
1229    * This callback is called by a fieldest on all its elements whenever its
1230    * disabled attribute is changed so the element knows its disabled state
1231    * might have changed.
1232    *
1233    * @note Classes redefining this method should not do any content
1234    * state updates themselves but should just make sure to call into
1235    * nsGenericHTMLFormElement::FieldSetDisabledChanged.
1236    */
1237   virtual void FieldSetDisabledChanged(bool aNotify);
1238 
FieldSetFirstLegendChanged(bool aNotify)1239   void FieldSetFirstLegendChanged(bool aNotify) {
1240     UpdateFieldSet(aNotify);
1241   }
1242 
1243   /**
1244    * This callback is called by a fieldset on all it's elements when it's being
1245    * destroyed. When called, the elements should check that aFieldset is there
1246    * first parent fieldset and null mFieldset in that case only.
1247    *
1248    * @param aFieldSet The fieldset being removed.
1249    */
1250   void ForgetFieldSet(nsIContent* aFieldset);
1251 
1252   /**
1253    * Returns if the control can be disabled.
1254    */
1255   bool CanBeDisabled() const;
1256 
1257   virtual bool IsHTMLFocusable(bool aWithMouse, bool* aIsFocusable,
1258                                  int32_t* aTabIndex) override;
1259 
1260   virtual bool IsLabelable() const override;
1261 
1262 protected:
1263   virtual ~nsGenericHTMLFormElement();
1264 
1265   virtual nsresult BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
1266                                  nsAttrValueOrString* aValue,
1267                                  bool aNotify) override;
1268 
1269   virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
1270                                 const nsAttrValue* aValue, bool aNotify) override;
1271 
1272   /**
1273    * This method will update the form owner, using @form or looking to a parent.
1274    *
1275    * @param aBindToTree Whether the element is being attached to the tree.
1276    * @param aFormIdElement The element associated with the id in @form. If
1277    * aBindToTree is false, aFormIdElement *must* contain the element associated
1278    * with the id in @form. Otherwise, it *must* be null.
1279    *
1280    * @note Callers of UpdateFormOwner have to be sure the element is in a
1281    * document (GetUncomposedDoc() != nullptr).
1282    */
1283   void UpdateFormOwner(bool aBindToTree, Element* aFormIdElement);
1284 
1285   /**
1286    * This method will update mFieldset and set it to the first fieldset parent.
1287    */
1288   void UpdateFieldSet(bool aNotify);
1289 
1290   /**
1291    * Add a form id observer which will observe when the element with the id in
1292    * @form will change.
1293    *
1294    * @return The element associated with the current id in @form (may be null).
1295    */
1296   Element* AddFormIdObserver();
1297 
1298   /**
1299    * Remove the form id observer.
1300    */
1301   void RemoveFormIdObserver();
1302 
1303   /**
1304    * This method is a a callback for IDTargetObserver (from nsIDocument).
1305    * It will be called each time the element associated with the id in @form
1306    * changes.
1307    */
1308   static bool FormIdUpdated(Element* aOldElement, Element* aNewElement,
1309                               void* aData);
1310 
1311   // Returns true if the event should not be handled from PreHandleEvent
1312   bool IsElementDisabledForEvents(mozilla::EventMessage aMessage,
1313                                   nsIFrame* aFrame);
1314 
1315   // The focusability state of this form control.  eUnfocusable means that it
1316   // shouldn't be focused at all, eInactiveWindow means it's in an inactive
1317   // window, eActiveWindow means it's in an active window.
1318   enum FocusTristate {
1319     eUnfocusable,
1320     eInactiveWindow,
1321     eActiveWindow
1322   };
1323 
1324   // Get our focus state.  If this returns eInactiveWindow, it will set this
1325   // element as the focused element for that window.
1326   FocusTristate FocusState();
1327 
1328   /** The form that contains this control */
1329   mozilla::dom::HTMLFormElement* mForm;
1330 
1331   /* This is a pointer to our closest fieldset parent if any */
1332   mozilla::dom::HTMLFieldSetElement* mFieldSet;
1333 };
1334 
1335 class nsGenericHTMLFormElementWithState : public nsGenericHTMLFormElement
1336 {
1337 public:
1338   explicit nsGenericHTMLFormElementWithState(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
1339 
1340   /**
1341    * Get the presentation state for a piece of content, or create it if it does
1342    * not exist.  Generally used by SaveState().
1343    */
1344   nsPresState* GetPrimaryPresState();
1345 
1346   /**
1347    * Get the layout history object for a particular piece of content.
1348    *
1349    * @param aRead if true, won't return a layout history state if the
1350    *              layout history state is empty.
1351    * @return the history state object
1352    */
1353   already_AddRefed<nsILayoutHistoryState>
1354     GetLayoutHistory(bool aRead);
1355 
1356   /**
1357    * Restore the state for a form control.  Ends up calling
1358    * nsIFormControl::RestoreState().
1359    *
1360    * @return false if RestoreState() was not called, the return
1361    *         value of RestoreState() otherwise.
1362    */
1363   bool RestoreFormControlState();
1364 
1365   /**
1366    * Called when we have been cloned and adopted, and the information of the
1367    * node has been changed.
1368    */
1369   virtual void NodeInfoChanged() override;
1370 
1371 protected:
1372   /* Generates the state key for saving the form state in the session if not
1373      computed already. The result is stored in mStateKey on success */
1374   nsresult GenerateStateKey();
1375 
1376   /* Used to store the key to that element in the session. Is void until
1377      GenerateStateKey has been used */
1378   nsCString mStateKey;
1379 };
1380 
1381 //----------------------------------------------------------------------
1382 
1383 /**
1384  * This macro is similar to NS_IMPL_STRING_ATTR except that the getter method
1385  * falls back to an alternative method if the content attribute isn't set.
1386  */
1387 #define NS_IMPL_STRING_ATTR_WITH_FALLBACK(_class, _method, _atom, _fallback) \
1388   NS_IMETHODIMP                                                              \
1389   _class::Get##_method(nsAString& aValue)                                    \
1390   {                                                                          \
1391     if (!GetAttr(kNameSpaceID_None, nsGkAtoms::_atom, aValue)) {             \
1392       _fallback(aValue);                                                     \
1393     }                                                                        \
1394     return NS_OK;                                                            \
1395   }                                                                          \
1396   NS_IMETHODIMP                                                              \
1397   _class::Set##_method(const nsAString& aValue)                              \
1398   {                                                                          \
1399     return SetAttrHelper(nsGkAtoms::_atom, aValue);                          \
1400   }
1401 
1402 /**
1403  * A macro to implement the getter and setter for a given integer
1404  * valued content property. The method uses the generic GetAttr and
1405  * SetAttr methods.
1406  */
1407 #define NS_IMPL_INT_ATTR(_class, _method, _atom)                    \
1408   NS_IMPL_INT_ATTR_DEFAULT_VALUE(_class, _method, _atom, 0)
1409 
1410 #define NS_IMPL_INT_ATTR_DEFAULT_VALUE(_class, _method, _atom, _default)  \
1411   NS_IMETHODIMP                                                           \
1412   _class::Get##_method(int32_t* aValue)                                   \
1413   {                                                                       \
1414     *aValue = GetIntAttr(nsGkAtoms::_atom, _default);                     \
1415     return NS_OK;                                                         \
1416   }                                                                       \
1417   NS_IMETHODIMP                                                           \
1418   _class::Set##_method(int32_t aValue)                                    \
1419   {                                                                       \
1420     return SetIntAttr(nsGkAtoms::_atom, aValue);                          \
1421   }
1422 
1423 /**
1424  * A macro to implement the getter and setter for a given unsigned integer
1425  * valued content property. The method uses GetUnsignedIntAttr and
1426  * SetUnsignedIntAttr methods.
1427  */
1428 #define NS_IMPL_UINT_ATTR(_class, _method, _atom)                         \
1429   NS_IMPL_UINT_ATTR_DEFAULT_VALUE(_class, _method, _atom, 0)
1430 
1431 #define NS_IMPL_UINT_ATTR_DEFAULT_VALUE(_class, _method, _atom, _default) \
1432   NS_IMETHODIMP                                                           \
1433   _class::Get##_method(uint32_t* aValue)                                  \
1434   {                                                                       \
1435     *aValue = GetUnsignedIntAttr(nsGkAtoms::_atom, _default);             \
1436     return NS_OK;                                                         \
1437   }                                                                       \
1438   NS_IMETHODIMP                                                           \
1439   _class::Set##_method(uint32_t aValue)                                   \
1440   {                                                                       \
1441     mozilla::ErrorResult rv;                                              \
1442     SetUnsignedIntAttr(nsGkAtoms::_atom, aValue, _default, rv);           \
1443     return rv.StealNSResult();                                            \
1444   }
1445 
1446 /**
1447  * A macro to implement the getter and setter for a given unsigned integer
1448  * valued content property. The method uses GetUnsignedIntAttr and
1449  * SetUnsignedIntAttr methods. This macro is similar to NS_IMPL_UINT_ATTR except
1450  * that it throws an exception if the set value is null.
1451  */
1452 #define NS_IMPL_UINT_ATTR_NON_ZERO(_class, _method, _atom)                \
1453   NS_IMPL_UINT_ATTR_NON_ZERO_DEFAULT_VALUE(_class, _method, _atom, 1)
1454 
1455 #define NS_IMPL_UINT_ATTR_NON_ZERO_DEFAULT_VALUE(_class, _method, _atom, _default) \
1456   NS_IMETHODIMP                                                           \
1457   _class::Get##_method(uint32_t* aValue)                                  \
1458   {                                                                       \
1459     *aValue = GetUnsignedIntAttr(nsGkAtoms::_atom, _default);             \
1460     return NS_OK;                                                         \
1461   }                                                                       \
1462   NS_IMETHODIMP                                                           \
1463   _class::Set##_method(uint32_t aValue)                                   \
1464   {                                                                       \
1465     if (aValue == 0) {                                                    \
1466       return NS_ERROR_DOM_INDEX_SIZE_ERR;                                 \
1467     }                                                                     \
1468     mozilla::ErrorResult rv;                                              \
1469     SetUnsignedIntAttr(nsGkAtoms::_atom, aValue, _default, rv);           \
1470     return rv.StealNSResult();                                            \
1471   }
1472 
1473 /**
1474  * A macro to implement the getter and setter for a given content
1475  * property that needs to return a URI in string form.  The method
1476  * uses the generic GetAttr and SetAttr methods.  This macro is much
1477  * like the NS_IMPL_STRING_ATTR macro, except we make sure the URI is
1478  * absolute.
1479  */
1480 #define NS_IMPL_URI_ATTR(_class, _method, _atom)                    \
1481   NS_IMETHODIMP                                                     \
1482   _class::Get##_method(nsAString& aValue)                           \
1483   {                                                                 \
1484     GetURIAttr(nsGkAtoms::_atom, nullptr, aValue);                  \
1485     return NS_OK;                                                   \
1486   }                                                                 \
1487   NS_IMETHODIMP                                                     \
1488   _class::Set##_method(const nsAString& aValue)                     \
1489   {                                                                 \
1490     return SetAttrHelper(nsGkAtoms::_atom, aValue);               \
1491   }
1492 
1493 #define NS_IMPL_URI_ATTR_WITH_BASE(_class, _method, _atom, _base_atom)       \
1494   NS_IMETHODIMP                                                              \
1495   _class::Get##_method(nsAString& aValue)                                    \
1496   {                                                                          \
1497     GetURIAttr(nsGkAtoms::_atom, nsGkAtoms::_base_atom, aValue);             \
1498     return NS_OK;                                                            \
1499   }                                                                          \
1500   NS_IMETHODIMP                                                              \
1501   _class::Set##_method(const nsAString& aValue)                              \
1502   {                                                                          \
1503     return SetAttrHelper(nsGkAtoms::_atom, aValue);                        \
1504   }
1505 
1506 /**
1507  * A macro to implement getter and setter for action and form action content
1508  * attributes. It's very similar to NS_IMPL_URI_ATTR excepted that if the
1509  * content attribute is the empty string, the empty string is returned.
1510  */
1511 #define NS_IMPL_ACTION_ATTR(_class, _method, _atom)                 \
1512   NS_IMETHODIMP                                                     \
1513   _class::Get##_method(nsAString& aValue)                           \
1514   {                                                                 \
1515     GetAttr(kNameSpaceID_None, nsGkAtoms::_atom, aValue);           \
1516     if (!aValue.IsEmpty()) {                                        \
1517       GetURIAttr(nsGkAtoms::_atom, nullptr, aValue);                 \
1518     }                                                               \
1519     return NS_OK;                                                   \
1520   }                                                                 \
1521   NS_IMETHODIMP                                                     \
1522   _class::Set##_method(const nsAString& aValue)                     \
1523   {                                                                 \
1524     return SetAttrHelper(nsGkAtoms::_atom, aValue);                 \
1525   }
1526 
1527 /**
1528  * A macro to implement the getter and setter for a given content
1529  * property that needs to set a non-negative integer. The method
1530  * uses the generic GetAttr and SetAttr methods. This macro is much
1531  * like the NS_IMPL_INT_ATTR macro except we throw an exception if
1532  * the set value is negative.
1533  */
1534 #define NS_IMPL_NON_NEGATIVE_INT_ATTR(_class, _method, _atom)             \
1535   NS_IMPL_NON_NEGATIVE_INT_ATTR_DEFAULT_VALUE(_class, _method, _atom, -1)
1536 
1537 #define NS_IMPL_NON_NEGATIVE_INT_ATTR_DEFAULT_VALUE(_class, _method, _atom, _default)  \
1538   NS_IMETHODIMP                                                           \
1539   _class::Get##_method(int32_t* aValue)                                   \
1540   {                                                                       \
1541     *aValue = GetIntAttr(nsGkAtoms::_atom, _default);                     \
1542     return NS_OK;                                                         \
1543   }                                                                       \
1544   NS_IMETHODIMP                                                           \
1545   _class::Set##_method(int32_t aValue)                                    \
1546   {                                                                       \
1547     if (aValue < 0) {                                                     \
1548       return NS_ERROR_DOM_INDEX_SIZE_ERR;                                 \
1549     }                                                                     \
1550     return SetIntAttr(nsGkAtoms::_atom, aValue);                          \
1551   }
1552 
1553 /**
1554  * A macro to implement the getter and setter for a given content
1555  * property that needs to set an enumerated string. The method
1556  * uses a specific GetEnumAttr and the generic SetAttrHelper methods.
1557  */
1558 #define NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(_class, _method, _atom, _default) \
1559   NS_IMETHODIMP                                                           \
1560   _class::Get##_method(nsAString& aValue)                                 \
1561   {                                                                       \
1562     GetEnumAttr(nsGkAtoms::_atom, _default, aValue);                      \
1563     return NS_OK;                                                         \
1564   }                                                                       \
1565   NS_IMETHODIMP                                                           \
1566   _class::Set##_method(const nsAString& aValue)                           \
1567   {                                                                       \
1568     return SetAttrHelper(nsGkAtoms::_atom, aValue);                       \
1569   }
1570 
1571 /**
1572  * A macro to implement the getter and setter for a given content
1573  * property that needs to set an enumerated string that has different
1574  * default values for missing and invalid values. The method uses a
1575  * specific GetEnumAttr and the generic SetAttrHelper methods.
1576  */
1577 #define NS_IMPL_ENUM_ATTR_DEFAULT_MISSING_INVALID_VALUES(_class, _method, _atom, _defaultMissing, _defaultInvalid) \
1578   NS_IMETHODIMP                                                                                   \
1579   _class::Get##_method(nsAString& aValue)                                                         \
1580   {                                                                                               \
1581     GetEnumAttr(nsGkAtoms::_atom, _defaultMissing, _defaultInvalid, aValue);                      \
1582     return NS_OK;                                                                                 \
1583   }                                                                                               \
1584   NS_IMETHODIMP                                                                                   \
1585   _class::Set##_method(const nsAString& aValue)                                                   \
1586   {                                                                                               \
1587     return SetAttrHelper(nsGkAtoms::_atom, aValue);                                               \
1588   }
1589 
1590 #define NS_INTERFACE_MAP_ENTRY_IF_TAG(_interface, _tag)                       \
1591   NS_INTERFACE_MAP_ENTRY_CONDITIONAL(_interface,                              \
1592                                      mNodeInfo->Equals(nsGkAtoms::_tag))
1593 
1594 
1595 /**
1596  * A macro to declare the NS_NewHTMLXXXElement() functions.
1597  */
1598 #define NS_DECLARE_NS_NEW_HTML_ELEMENT(_elementName)                       \
1599 namespace mozilla {                                                        \
1600 namespace dom {                                                            \
1601 class HTML##_elementName##Element;                                         \
1602 }                                                                          \
1603 }                                                                          \
1604 nsGenericHTMLElement*                                                      \
1605 NS_NewHTML##_elementName##Element(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo, \
1606                                   mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER);
1607 
1608 #define NS_DECLARE_NS_NEW_HTML_ELEMENT_AS_SHARED(_elementName)             \
1609 inline nsGenericHTMLElement*                                               \
1610 NS_NewHTML##_elementName##Element(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo, \
1611                                   mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER) \
1612 {                                                                          \
1613   return NS_NewHTMLSharedElement(mozilla::Move(aNodeInfo), aFromParser);   \
1614 }
1615 
1616 /**
1617  * A macro to implement the NS_NewHTMLXXXElement() functions.
1618  */
1619 #define NS_IMPL_NS_NEW_HTML_ELEMENT(_elementName)                            \
1620 nsGenericHTMLElement*                                                        \
1621 NS_NewHTML##_elementName##Element(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo, \
1622                                   mozilla::dom::FromParser aFromParser)      \
1623 {                                                                            \
1624   return new mozilla::dom::HTML##_elementName##Element(aNodeInfo);           \
1625 }
1626 
1627 #define NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(_elementName)               \
1628 nsGenericHTMLElement*                                                        \
1629 NS_NewHTML##_elementName##Element(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo, \
1630                                   mozilla::dom::FromParser aFromParser)      \
1631 {                                                                            \
1632   return new mozilla::dom::HTML##_elementName##Element(aNodeInfo,            \
1633                                                        aFromParser);         \
1634 }
1635 
1636 // Here, we expand 'NS_DECLARE_NS_NEW_HTML_ELEMENT()' by hand.
1637 // (Calling the macro directly (with no args) produces compiler warnings.)
1638 nsGenericHTMLElement*
1639 NS_NewHTMLElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
1640                   mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER);
1641 
1642 NS_DECLARE_NS_NEW_HTML_ELEMENT(Shared)
NS_DECLARE_NS_NEW_HTML_ELEMENT(SharedList)1643 NS_DECLARE_NS_NEW_HTML_ELEMENT(SharedList)
1644 NS_DECLARE_NS_NEW_HTML_ELEMENT(SharedObject)
1645 
1646 NS_DECLARE_NS_NEW_HTML_ELEMENT(Anchor)
1647 NS_DECLARE_NS_NEW_HTML_ELEMENT(Area)
1648 NS_DECLARE_NS_NEW_HTML_ELEMENT(Audio)
1649 NS_DECLARE_NS_NEW_HTML_ELEMENT(BR)
1650 NS_DECLARE_NS_NEW_HTML_ELEMENT(Body)
1651 NS_DECLARE_NS_NEW_HTML_ELEMENT(Button)
1652 NS_DECLARE_NS_NEW_HTML_ELEMENT(Canvas)
1653 NS_DECLARE_NS_NEW_HTML_ELEMENT(Content)
1654 NS_DECLARE_NS_NEW_HTML_ELEMENT(Mod)
1655 NS_DECLARE_NS_NEW_HTML_ELEMENT(Data)
1656 NS_DECLARE_NS_NEW_HTML_ELEMENT(DataList)
1657 NS_DECLARE_NS_NEW_HTML_ELEMENT(Details)
1658 NS_DECLARE_NS_NEW_HTML_ELEMENT(Div)
1659 NS_DECLARE_NS_NEW_HTML_ELEMENT(FieldSet)
1660 NS_DECLARE_NS_NEW_HTML_ELEMENT(Font)
1661 NS_DECLARE_NS_NEW_HTML_ELEMENT(Form)
1662 NS_DECLARE_NS_NEW_HTML_ELEMENT(Frame)
1663 NS_DECLARE_NS_NEW_HTML_ELEMENT(FrameSet)
1664 NS_DECLARE_NS_NEW_HTML_ELEMENT(HR)
1665 NS_DECLARE_NS_NEW_HTML_ELEMENT_AS_SHARED(Head)
1666 NS_DECLARE_NS_NEW_HTML_ELEMENT(Heading)
1667 NS_DECLARE_NS_NEW_HTML_ELEMENT_AS_SHARED(Html)
1668 NS_DECLARE_NS_NEW_HTML_ELEMENT(IFrame)
1669 NS_DECLARE_NS_NEW_HTML_ELEMENT(Image)
1670 NS_DECLARE_NS_NEW_HTML_ELEMENT(Input)
1671 NS_DECLARE_NS_NEW_HTML_ELEMENT(LI)
1672 NS_DECLARE_NS_NEW_HTML_ELEMENT(Label)
1673 NS_DECLARE_NS_NEW_HTML_ELEMENT(Legend)
1674 NS_DECLARE_NS_NEW_HTML_ELEMENT(Link)
1675 NS_DECLARE_NS_NEW_HTML_ELEMENT(Map)
1676 NS_DECLARE_NS_NEW_HTML_ELEMENT(Menu)
1677 NS_DECLARE_NS_NEW_HTML_ELEMENT(MenuItem)
1678 NS_DECLARE_NS_NEW_HTML_ELEMENT(Meta)
1679 NS_DECLARE_NS_NEW_HTML_ELEMENT(Meter)
1680 NS_DECLARE_NS_NEW_HTML_ELEMENT(Object)
1681 NS_DECLARE_NS_NEW_HTML_ELEMENT(OptGroup)
1682 NS_DECLARE_NS_NEW_HTML_ELEMENT(Option)
1683 NS_DECLARE_NS_NEW_HTML_ELEMENT(Output)
1684 NS_DECLARE_NS_NEW_HTML_ELEMENT(Paragraph)
1685 NS_DECLARE_NS_NEW_HTML_ELEMENT(Picture)
1686 NS_DECLARE_NS_NEW_HTML_ELEMENT(Pre)
1687 NS_DECLARE_NS_NEW_HTML_ELEMENT(Progress)
1688 NS_DECLARE_NS_NEW_HTML_ELEMENT(Script)
1689 NS_DECLARE_NS_NEW_HTML_ELEMENT(Select)
1690 NS_DECLARE_NS_NEW_HTML_ELEMENT(Shadow)
1691 NS_DECLARE_NS_NEW_HTML_ELEMENT(Source)
1692 NS_DECLARE_NS_NEW_HTML_ELEMENT(Span)
1693 NS_DECLARE_NS_NEW_HTML_ELEMENT(Style)
1694 NS_DECLARE_NS_NEW_HTML_ELEMENT(Summary)
1695 NS_DECLARE_NS_NEW_HTML_ELEMENT(TableCaption)
1696 NS_DECLARE_NS_NEW_HTML_ELEMENT(TableCell)
1697 NS_DECLARE_NS_NEW_HTML_ELEMENT(TableCol)
1698 NS_DECLARE_NS_NEW_HTML_ELEMENT(Table)
1699 NS_DECLARE_NS_NEW_HTML_ELEMENT(TableRow)
1700 NS_DECLARE_NS_NEW_HTML_ELEMENT(TableSection)
1701 NS_DECLARE_NS_NEW_HTML_ELEMENT(Tbody)
1702 NS_DECLARE_NS_NEW_HTML_ELEMENT(Template)
1703 NS_DECLARE_NS_NEW_HTML_ELEMENT(TextArea)
1704 NS_DECLARE_NS_NEW_HTML_ELEMENT(Tfoot)
1705 NS_DECLARE_NS_NEW_HTML_ELEMENT(Thead)
1706 NS_DECLARE_NS_NEW_HTML_ELEMENT(Time)
1707 NS_DECLARE_NS_NEW_HTML_ELEMENT(Title)
1708 NS_DECLARE_NS_NEW_HTML_ELEMENT(Track)
1709 NS_DECLARE_NS_NEW_HTML_ELEMENT(Unknown)
1710 NS_DECLARE_NS_NEW_HTML_ELEMENT(Video)
1711 
1712 inline nsISupports*
1713 ToSupports(nsGenericHTMLElement* aHTMLElement)
1714 {
1715   return static_cast<nsIContent*>(aHTMLElement);
1716 }
1717 
1718 inline nsISupports*
ToCanonicalSupports(nsGenericHTMLElement * aHTMLElement)1719 ToCanonicalSupports(nsGenericHTMLElement* aHTMLElement)
1720 {
1721   return static_cast<nsIContent*>(aHTMLElement);
1722 }
1723 
1724 #endif /* nsGenericHTMLElement_h___ */
1725