1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2001 Dirk Mueller (mueller@kde.org)
5 * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. ALl rights reserved.
6 * (C) 2006 Alexey Proskuryakov (ap@nypop.com)
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public License
19 * along with this library; see the file COPYING.LIB. If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 *
23 */
24
25 #include "config.h"
26 #include "HTMLLabelElement.h"
27
28 #include "Document.h"
29 #include "Event.h"
30 #include "EventNames.h"
31 #include "HTMLFormElement.h"
32 #include "HTMLNames.h"
33
34 namespace WebCore {
35
36 using namespace HTMLNames;
37
HTMLLabelElement(const QualifiedName & tagName,Document * doc)38 HTMLLabelElement::HTMLLabelElement(const QualifiedName& tagName, Document *doc)
39 : HTMLElement(tagName, doc)
40 {
41 ASSERT(hasTagName(labelTag));
42 }
43
~HTMLLabelElement()44 HTMLLabelElement::~HTMLLabelElement()
45 {
46 }
47
isFocusable() const48 bool HTMLLabelElement::isFocusable() const
49 {
50 return false;
51 }
52
correspondingControl()53 HTMLElement* HTMLLabelElement::correspondingControl()
54 {
55 const AtomicString& controlId = getAttribute(forAttr);
56 if (controlId.isNull()) {
57 // Search children of the label element for a form element.
58 Node* node = this;
59 while ((node = node->traverseNextNode(this))) {
60 if (node->isHTMLElement()) {
61 HTMLElement* element = static_cast<HTMLElement*>(node);
62 if (element->isFormControlElement())
63 return element;
64 }
65 }
66 return 0;
67 }
68
69 // Only return HTML elements.
70 Element* elt = document()->getElementById(controlId);
71 if (elt && elt->isHTMLElement())
72 return static_cast<HTMLElement*>(elt);
73 return 0;
74 }
75
setActive(bool down,bool pause)76 void HTMLLabelElement::setActive(bool down, bool pause)
77 {
78 if (down == active())
79 return;
80
81 // Update our status first.
82 HTMLElement::setActive(down, pause);
83
84 // Also update our corresponding control.
85 if (HTMLElement* element = correspondingControl())
86 element->setActive(down, pause);
87 }
88
setHovered(bool over)89 void HTMLLabelElement::setHovered(bool over)
90 {
91 if (over == hovered())
92 return;
93
94 // Update our status first.
95 HTMLElement::setHovered(over);
96
97 // Also update our corresponding control.
98 if (HTMLElement* element = correspondingControl())
99 element->setHovered(over);
100 }
101
defaultEventHandler(Event * evt)102 void HTMLLabelElement::defaultEventHandler(Event* evt)
103 {
104 static bool processingClick = false;
105
106 if (evt->type() == eventNames().clickEvent && !processingClick) {
107 RefPtr<HTMLElement> control = correspondingControl();
108
109 // If we can't find a control or if the control received the click
110 // event, then there's no need for us to do anything.
111 if (!control || (evt->target() && control->contains(evt->target()->toNode())))
112 return;
113
114 processingClick = true;
115
116 // Click the corresponding control.
117 control->dispatchSimulatedClick(evt);
118
119 // If the control can be focused via the mouse, then do that too.
120 if (control->isMouseFocusable())
121 control->focus();
122
123 processingClick = false;
124
125 evt->setDefaultHandled();
126 }
127
128 HTMLElement::defaultEventHandler(evt);
129 }
130
focus(bool)131 void HTMLLabelElement::focus(bool)
132 {
133 // to match other browsers, always restore previous selection
134 if (HTMLElement* element = correspondingControl())
135 element->focus();
136 }
137
accessKeyAction(bool sendToAnyElement)138 void HTMLLabelElement::accessKeyAction(bool sendToAnyElement)
139 {
140 if (HTMLElement* element = correspondingControl())
141 element->accessKeyAction(sendToAnyElement);
142 }
143
accessKey() const144 String HTMLLabelElement::accessKey() const
145 {
146 return getAttribute(accesskeyAttr);
147 }
148
setAccessKey(const String & value)149 void HTMLLabelElement::setAccessKey(const String &value)
150 {
151 setAttribute(accesskeyAttr, value);
152 }
153
htmlFor() const154 String HTMLLabelElement::htmlFor() const
155 {
156 return getAttribute(forAttr);
157 }
158
setHtmlFor(const String & value)159 void HTMLLabelElement::setHtmlFor(const String &value)
160 {
161 setAttribute(forAttr, value);
162 }
163
164 } // namespace
165