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