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
7 #include "mozilla/dom/HTMLLegendElement.h"
8 #include "mozilla/dom/HTMLLegendElementBinding.h"
9 #include "nsFocusManager.h"
10 #include "nsIFrame.h"
11
12 NS_IMPL_NS_NEW_HTML_ELEMENT(Legend)
13
14 namespace mozilla {
15 namespace dom {
16
~HTMLLegendElement()17 HTMLLegendElement::~HTMLLegendElement() {}
18
NS_IMPL_ELEMENT_CLONE(HTMLLegendElement)19 NS_IMPL_ELEMENT_CLONE(HTMLLegendElement)
20
21 nsIContent* HTMLLegendElement::GetFieldSet() const {
22 nsIContent* parent = GetParent();
23
24 if (parent && parent->IsHTMLElement(nsGkAtoms::fieldset)) {
25 return parent;
26 }
27
28 return nullptr;
29 }
30
ParseAttribute(int32_t aNamespaceID,nsAtom * aAttribute,const nsAString & aValue,nsIPrincipal * aMaybeScriptedPrincipal,nsAttrValue & aResult)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", NS_STYLE_TEXT_ALIGN_LEFT},
38 {"right", NS_STYLE_TEXT_ALIGN_RIGHT},
39 {"center", NS_STYLE_TEXT_ALIGN_CENTER},
40 {"bottom", NS_STYLE_VERTICAL_ALIGN_BOTTOM},
41 {"top", NS_STYLE_VERTICAL_ALIGN_TOP},
42 {nullptr, 0}};
43
44 if (aAttribute == nsGkAtoms::align && aNamespaceID == kNameSpaceID_None) {
45 return aResult.ParseEnumValue(aValue, kAlignTable, false);
46 }
47
48 return nsGenericHTMLElement::ParseAttribute(aNamespaceID, aAttribute, aValue,
49 aMaybeScriptedPrincipal, aResult);
50 }
51
GetAttributeChangeHint(const nsAtom * aAttribute,int32_t aModType) const52 nsChangeHint HTMLLegendElement::GetAttributeChangeHint(const nsAtom* aAttribute,
53 int32_t aModType) const {
54 nsChangeHint retval =
55 nsGenericHTMLElement::GetAttributeChangeHint(aAttribute, aModType);
56 if (aAttribute == nsGkAtoms::align) {
57 retval |= NS_STYLE_HINT_REFLOW;
58 }
59 return retval;
60 }
61
BindToTree(nsIDocument * aDocument,nsIContent * aParent,nsIContent * aBindingParent,bool aCompileEventHandlers)62 nsresult HTMLLegendElement::BindToTree(nsIDocument* aDocument,
63 nsIContent* aParent,
64 nsIContent* aBindingParent,
65 bool aCompileEventHandlers) {
66 return nsGenericHTMLElement::BindToTree(aDocument, aParent, aBindingParent,
67 aCompileEventHandlers);
68 }
69
UnbindFromTree(bool aDeep,bool aNullParent)70 void HTMLLegendElement::UnbindFromTree(bool aDeep, bool aNullParent) {
71 nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
72 }
73
Focus(ErrorResult & aError)74 void HTMLLegendElement::Focus(ErrorResult& aError) {
75 nsIFrame* frame = GetPrimaryFrame();
76 if (!frame) {
77 return;
78 }
79
80 int32_t tabIndex;
81 if (frame->IsFocusable(&tabIndex, false)) {
82 nsGenericHTMLElement::Focus(aError);
83 return;
84 }
85
86 // If the legend isn't focusable, focus whatever is focusable following
87 // the legend instead, bug 81481.
88 nsIFocusManager* fm = nsFocusManager::GetFocusManager();
89 if (!fm) {
90 return;
91 }
92
93 nsCOMPtr<nsIDOMElement> result;
94 aError = fm->MoveFocus(nullptr, this, nsIFocusManager::MOVEFOCUS_FORWARD,
95 nsIFocusManager::FLAG_NOPARENTFRAME,
96 getter_AddRefs(result));
97 }
98
PerformAccesskey(bool aKeyCausesActivation,bool aIsTrustedEvent)99 bool HTMLLegendElement::PerformAccesskey(bool aKeyCausesActivation,
100 bool aIsTrustedEvent) {
101 // just use the same behaviour as the focus method
102 ErrorResult rv;
103 Focus(rv);
104 return NS_SUCCEEDED(rv.StealNSResult());
105 }
106
GetForm()107 already_AddRefed<HTMLFormElement> HTMLLegendElement::GetForm() {
108 Element* form = GetFormElement();
109 MOZ_ASSERT_IF(form, form->IsHTMLElement(nsGkAtoms::form));
110 RefPtr<HTMLFormElement> ret = static_cast<HTMLFormElement*>(form);
111 return ret.forget();
112 }
113
WrapNode(JSContext * aCx,JS::Handle<JSObject * > aGivenProto)114 JSObject* HTMLLegendElement::WrapNode(JSContext* aCx,
115 JS::Handle<JSObject*> aGivenProto) {
116 return HTMLLegendElementBinding::Wrap(aCx, this, aGivenProto);
117 }
118
119 } // namespace dom
120 } // namespace mozilla
121