1 /**
2 * Copyright (C) 2008, 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 "WMLDoElement.h"
25
26 #include "Event.h"
27 #include "EventNames.h"
28 #include "HTMLNames.h"
29 #include "KeyboardEvent.h"
30 #include "MappedAttribute.h"
31 #include "Page.h"
32 #include "RenderButton.h"
33 #include "WMLCardElement.h"
34 #include "WMLDocument.h"
35 #include "WMLTaskElement.h"
36 #include "WMLTimerElement.h"
37 #include "WMLNames.h"
38 #include "WMLPageState.h"
39 #include "WMLVariables.h"
40
41 namespace WebCore {
42
43 using namespace WMLNames;
44
WMLDoElement(const QualifiedName & tagName,Document * doc)45 WMLDoElement::WMLDoElement(const QualifiedName& tagName, Document* doc)
46 : WMLElement(tagName, doc)
47 , m_task(0)
48 , m_isActive(false)
49 , m_isNoop(false)
50 , m_isOptional(false)
51 {
52 }
53
defaultEventHandler(Event * event)54 void WMLDoElement::defaultEventHandler(Event* event)
55 {
56 if (m_isOptional)
57 return;
58
59 if (event->type() == eventNames().keypressEvent) {
60 WMLElement::defaultEventHandler(event);
61 return;
62 }
63
64 if (event->type() != eventNames().clickEvent && event->type() != eventNames().keydownEvent)
65 return;
66
67 if (event->isKeyboardEvent()
68 && static_cast<KeyboardEvent*>(event)->keyIdentifier() != "Enter")
69 return;
70
71 if (m_type == "accept" || m_type == "options") {
72 if (m_task)
73 m_task->executeTask(event);
74 } else if (m_type == "prev") {
75 WMLPageState* pageState = wmlPageStateForDocument(document());
76 if (!pageState)
77 return;
78
79 // Stop the timer of the current card if it is active
80 if (WMLCardElement* card = pageState->activeCard()) {
81 if (WMLTimerElement* eventTimer = card->eventTimer())
82 eventTimer->stop();
83 }
84
85 pageState->page()->goBack();
86 } else if (m_type == "reset") {
87 WMLPageState* pageState = wmlPageStateForDocument(document());
88 if (!pageState)
89 return;
90
91 pageState->reset();
92 }
93 }
94
parseMappedAttribute(MappedAttribute * attr)95 void WMLDoElement::parseMappedAttribute(MappedAttribute* attr)
96 {
97 if (attr->name() == HTMLNames::typeAttr)
98 m_type = parseValueForbiddingVariableReferences(attr->value());
99 else if (attr->name() == HTMLNames::nameAttr)
100 m_name = parseValueForbiddingVariableReferences(attr->value());
101 else if (attr->name() == optionalAttr)
102 m_isOptional = (attr->value() == "true");
103 else
104 WMLElement::parseMappedAttribute(attr);
105 }
106
insertedIntoDocument()107 void WMLDoElement::insertedIntoDocument()
108 {
109 WMLElement::insertedIntoDocument();
110
111 // Spec: An unspecified 'name' defaults to the value of the 'type' attribute.
112 if (!hasAttribute(HTMLNames::nameAttr))
113 m_name = m_type;
114
115 Node* parent = parentNode();
116 if (!parent || !parent->isWMLElement())
117 return;
118
119 if (WMLEventHandlingElement* eventHandlingElement = toWMLEventHandlingElement(static_cast<WMLElement*>(parent)))
120 eventHandlingElement->registerDoElement(this, document());
121 }
122
removedFromDocument()123 void WMLDoElement::removedFromDocument()
124 {
125 Node* parent = parentNode();
126
127 if (parent && parent->isWMLElement()) {
128 if (WMLEventHandlingElement* eventHandlingElement = toWMLEventHandlingElement(static_cast<WMLElement*>(parent)))
129 eventHandlingElement->deregisterDoElement(this);
130 }
131
132 WMLElement::removedFromDocument();
133 }
134
attach()135 void WMLDoElement::attach()
136 {
137 WMLElement::attach();
138
139 // The call to updateFromElement() needs to go after the call through
140 // to the base class's attach() because that can sometimes do a close
141 // on the renderer.
142 if (renderer())
143 renderer()->updateFromElement();
144 }
145
createRenderer(RenderArena * arena,RenderStyle * style)146 RenderObject* WMLDoElement::createRenderer(RenderArena* arena, RenderStyle* style)
147 {
148 if (!m_isActive || m_isOptional || m_isNoop)
149 return 0;
150
151 if (style) {
152 style->setUnique();
153 style->setBackgroundColor(Color::lightGray);
154 }
155
156 return new (arena) RenderButton(this);
157 }
158
recalcStyle(StyleChange change)159 void WMLDoElement::recalcStyle(StyleChange change)
160 {
161 WMLElement::recalcStyle(change);
162
163 if (renderer())
164 renderer()->updateFromElement();
165 }
166
registerTask(WMLTaskElement * task)167 void WMLDoElement::registerTask(WMLTaskElement* task)
168 {
169 ASSERT(!m_task);
170 m_task = task;
171 }
172
deregisterTask(WMLTaskElement * task)173 void WMLDoElement::deregisterTask(WMLTaskElement* task)
174 {
175 ASSERT(m_task == task);
176 m_task = 0;
177 }
178
label() const179 String WMLDoElement::label() const
180 {
181 return parseValueSubstitutingVariableReferences(getAttribute(HTMLNames::labelAttr));
182 }
183
184 }
185
186 #endif
187