1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/dom/HTMLLegendElement.h"
8 #include "mozilla/dom/ElementBinding.h"
9 #include "mozilla/dom/HTMLLegendElementBinding.h"
10 #include "nsFocusManager.h"
13 NS_IMPL_NS_NEW_HTML_ELEMENT(Legend
)
15 namespace mozilla::dom
{
17 HTMLLegendElement::~HTMLLegendElement() = default;
19 NS_IMPL_ELEMENT_CLONE(HTMLLegendElement
)
21 nsIContent
* HTMLLegendElement::GetFieldSet() const {
22 nsIContent
* parent
= GetParent();
24 if (parent
&& parent
->IsHTMLElement(nsGkAtoms::fieldset
)) {
31 bool HTMLLegendElement::ParseAttribute(int32_t aNamespaceID
, nsAtom
* aAttribute
,
32 const nsAString
& aValue
,
33 nsIPrincipal
* aMaybeScriptedPrincipal
,
34 nsAttrValue
& aResult
) {
35 // this contains center, because IE4 does
36 static const nsAttrValue::EnumTable kAlignTable
[] = {
37 {"left", LegendAlignValue::Left
},
38 {"right", LegendAlignValue::Right
},
39 {"center", LegendAlignValue::Center
},
42 if (aAttribute
== nsGkAtoms::align
&& aNamespaceID
== kNameSpaceID_None
) {
43 return aResult
.ParseEnumValue(aValue
, kAlignTable
, false);
46 return nsGenericHTMLElement::ParseAttribute(aNamespaceID
, aAttribute
, aValue
,
47 aMaybeScriptedPrincipal
, aResult
);
50 nsChangeHint
HTMLLegendElement::GetAttributeChangeHint(const nsAtom
* aAttribute
,
51 int32_t aModType
) const {
53 nsGenericHTMLElement::GetAttributeChangeHint(aAttribute
, aModType
);
54 if (aAttribute
== nsGkAtoms::align
) {
55 retval
|= NS_STYLE_HINT_REFLOW
;
60 nsresult
HTMLLegendElement::BindToTree(BindContext
& aContext
,
62 return nsGenericHTMLElement::BindToTree(aContext
, aParent
);
65 void HTMLLegendElement::UnbindFromTree(UnbindContext
& aContext
) {
66 nsGenericHTMLElement::UnbindFromTree(aContext
);
69 void HTMLLegendElement::Focus(const FocusOptions
& aOptions
,
70 const CallerType aCallerType
,
71 ErrorResult
& aError
) {
72 nsIFrame
* frame
= GetPrimaryFrame();
77 if (frame
->IsFocusable()) {
78 nsGenericHTMLElement::Focus(aOptions
, aCallerType
, aError
);
82 // If the legend isn't focusable, focus whatever is focusable following
83 // the legend instead, bug 81481.
84 nsFocusManager
* fm
= nsFocusManager::GetFocusManager();
89 RefPtr
<Element
> result
;
90 aError
= fm
->MoveFocus(nullptr, this, nsIFocusManager::MOVEFOCUS_FORWARD
,
91 nsIFocusManager::FLAG_NOPARENTFRAME
|
92 nsFocusManager::ProgrammaticFocusFlags(aOptions
),
93 getter_AddRefs(result
));
96 Result
<bool, nsresult
> HTMLLegendElement::PerformAccesskey(
97 bool aKeyCausesActivation
, bool aIsTrustedEvent
) {
101 Focus(options
, CallerType::System
, rv
);
103 return Err(rv
.StealNSResult());
106 // XXXedgar, do we need to check whether the focus is really changed?
110 HTMLLegendElement::LegendAlignValue
HTMLLegendElement::LogicalAlign(
111 mozilla::WritingMode aCBWM
) const {
112 const nsAttrValue
* attr
= GetParsedAttr(nsGkAtoms::align
);
113 if (!attr
|| attr
->Type() != nsAttrValue::eEnum
) {
114 return LegendAlignValue::InlineStart
;
117 auto value
= static_cast<LegendAlignValue
>(attr
->GetEnumValue());
119 case LegendAlignValue::Left
:
120 return aCBWM
.IsBidiLTR() ? LegendAlignValue::InlineStart
121 : LegendAlignValue::InlineEnd
;
122 case LegendAlignValue::Right
:
123 return aCBWM
.IsBidiLTR() ? LegendAlignValue::InlineEnd
124 : LegendAlignValue::InlineStart
;
130 HTMLFormElement
* HTMLLegendElement::GetForm() const {
131 const auto* fieldsetControl
= nsIFormControl::FromNodeOrNull(GetFieldSet());
132 return fieldsetControl
? fieldsetControl
->GetForm() : nullptr;
135 JSObject
* HTMLLegendElement::WrapNode(JSContext
* aCx
,
136 JS::Handle
<JSObject
*> aGivenProto
) {
137 return HTMLLegendElement_Binding::Wrap(aCx
, this, aGivenProto
);
140 } // namespace mozilla::dom