1/**
2 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB.  If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 *
19 */
20
21#include "config.h"
22
23#if ENABLE(WML)
24#include "WMLOptionElement.h"
25
26#include "HTMLNames.h"
27#include "MappedAttribute.h"
28#include "NodeRenderStyle.h"
29#include "RenderStyle.h"
30#include "WMLNames.h"
31#include "WMLSelectElement.h"
32
33namespace WebCore {
34
35using namespace WMLNames;
36
37WMLOptionElement::WMLOptionElement(const QualifiedName& tagName, Document* doc)
38    : WMLFormControlElement(tagName, doc)
39{
40}
41
42WMLOptionElement::~WMLOptionElement()
43{
44}
45
46const AtomicString& WMLOptionElement::formControlType() const
47{
48    DEFINE_STATIC_LOCAL(const AtomicString, option, ("option"));
49    return option;
50}
51
52static inline WMLSelectElement* ownerSelectElement(Element* element)
53{
54    Node* select = element->parentNode();
55    while (select && !select->hasTagName(selectTag))
56        select = select->parentNode();
57
58    if (!select)
59        return 0;
60
61    return static_cast<WMLSelectElement*>(select);
62}
63
64void WMLOptionElement::accessKeyAction(bool)
65{
66    if (WMLSelectElement* select = ownerSelectElement(this))
67        select->accessKeySetSelectedIndex(OptionElement::optionIndex(select, this));
68}
69
70void WMLOptionElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
71{
72    if (WMLSelectElement* select = ownerSelectElement(this))
73        select->childrenChanged(changedByParser);
74
75    WMLFormControlElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
76}
77
78void WMLOptionElement::parseMappedAttribute(MappedAttribute* attr)
79{
80    if (attr->name() == HTMLNames::valueAttr)
81        m_data.setValue(parseValueSubstitutingVariableReferences(attr->value()));
82    else if (attr->name() == HTMLNames::titleAttr)
83        m_data.setLabel(parseValueSubstitutingVariableReferences(attr->value()));
84    else if (attr->name() == onpickAttr) {
85        // Register intrinsic event in card
86        RefPtr<WMLIntrinsicEvent> event = WMLIntrinsicEvent::create(document(), attr->value());
87
88        createEventHandlerIfNeeded();
89        eventHandler()->registerIntrinsicEvent(WMLIntrinsicEventOnPick, event);
90    } else
91        WMLFormControlElement::parseMappedAttribute(attr);
92}
93
94void WMLOptionElement::attach()
95{
96    if (parentNode()->renderStyle())
97        setRenderStyle(styleForRenderer());
98    WMLFormControlElement::attach();
99}
100
101void WMLOptionElement::detach()
102{
103    m_style.clear();
104    WMLFormControlElement::detach();
105}
106
107void WMLOptionElement::setRenderStyle(PassRefPtr<RenderStyle> style)
108{
109    m_style = style;
110}
111
112void WMLOptionElement::insertedIntoDocument()
113{
114    WMLSelectElement* select;
115    if (selected() && (select = ownerSelectElement(this)))
116        select->scrollToSelection();
117
118    WMLFormControlElement::insertedIntoDocument();
119}
120
121bool WMLOptionElement::selected() const
122{
123    return m_data.selected();
124}
125
126void WMLOptionElement::setSelectedState(bool selected)
127{
128    if (this->selected() == selected)
129        return;
130
131    OptionElement::setSelectedState(m_data, this, selected);
132
133    if (WMLSelectElement* select = ownerSelectElement(this)) {
134        if (select->multiple() || selected)
135            handleIntrinsicEventIfNeeded();
136    }
137}
138
139String WMLOptionElement::value() const
140{
141    return OptionElement::collectOptionValue(m_data, this);
142}
143
144String WMLOptionElement::text() const
145{
146    return OptionElement::collectOptionLabelOrText(m_data, this);
147}
148
149String WMLOptionElement::textIndentedToRespectGroupLabel() const
150{
151    return OptionElement::collectOptionTextRespectingGroupLabel(m_data, this);
152}
153
154RenderStyle* WMLOptionElement::nonRendererRenderStyle() const
155{
156    return m_style.get();
157}
158
159void WMLOptionElement::handleIntrinsicEventIfNeeded()
160{
161    WMLSelectElement* select = ownerSelectElement(this);
162    if (!select || !select->initialized())
163        return;
164
165    WMLIntrinsicEventHandler* eventHandler = this->eventHandler();
166    if (!eventHandler)
167        return;
168
169    if (eventHandler->hasIntrinsicEvent(WMLIntrinsicEventOnPick))
170        eventHandler->triggerIntrinsicEvent(WMLIntrinsicEventOnPick);
171}
172
173}
174
175#endif
176