2011-02-02 MORITA Hajime <morrita@google.com>
[WebKit.git] / Source / WebCore / html / HTMLProgressElement.cpp
1 /*
2  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
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 #if ENABLE(PROGRESS_TAG)
23 #include "HTMLProgressElement.h"
24
25 #include "Attribute.h"
26 #include "EventNames.h"
27 #include "ExceptionCode.h"
28 #include "FormDataList.h"
29 #include "HTMLDivElement.h"
30 #include "HTMLFormElement.h"
31 #include "HTMLNames.h"
32 #include "HTMLParserIdioms.h"
33 #include "ProgressBarValueElement.h"
34 #include "RenderProgress.h"
35 #include <wtf/StdLibExtras.h>
36
37 namespace WebCore {
38
39 using namespace HTMLNames;
40
41 HTMLProgressElement::HTMLProgressElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
42     : HTMLFormControlElement(tagName, document, form)
43 {
44     ASSERT(hasTagName(progressTag));
45 }
46
47 PassRefPtr<HTMLProgressElement> HTMLProgressElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
48 {
49     return adoptRef(new HTMLProgressElement(tagName, document, form));
50 }
51
52 RenderObject* HTMLProgressElement::createRenderer(RenderArena* arena, RenderStyle*)
53 {
54     return new (arena) RenderProgress(this);
55 }
56
57 const AtomicString& HTMLProgressElement::formControlType() const
58 {
59     DEFINE_STATIC_LOCAL(const AtomicString, progress, ("progress"));
60     return progress;
61 }
62
63 void HTMLProgressElement::parseMappedAttribute(Attribute* attribute)
64 {
65     if (attribute->name() == valueAttr)
66         didElementStateChange();
67     else if (attribute->name() == maxAttr)
68         didElementStateChange();
69     else
70         HTMLFormControlElement::parseMappedAttribute(attribute);
71 }
72
73 void HTMLProgressElement::attach()
74 {
75     createShadowSubtreeIfNeeded();
76     HTMLFormControlElement::attach();
77     didElementStateChange();
78 }
79
80 double HTMLProgressElement::value() const
81 {
82     const AtomicString& valueString = getAttribute(valueAttr);
83     double value;
84     bool ok = parseToDoubleForNumberType(valueString, &value);
85     if (!ok || value < 0)
86         return valueString.isNull() ? 1 : 0;
87     return (value > max()) ? max() : value;
88 }
89
90 void HTMLProgressElement::setValue(double value, ExceptionCode& ec)
91 {
92     if (!isfinite(value)) {
93         ec = NOT_SUPPORTED_ERR;
94         return;
95     }
96     setAttribute(valueAttr, String::number(value >= 0 ? value : 0));
97 }
98
99 double HTMLProgressElement::max() const
100 {
101     double max;
102     bool ok = parseToDoubleForNumberType(getAttribute(maxAttr), &max);
103     if (!ok || max <= 0)
104         return 1;
105     return max;
106 }
107
108 void HTMLProgressElement::setMax(double max, ExceptionCode& ec)
109 {
110     if (!isfinite(max)) {
111         ec = NOT_SUPPORTED_ERR;
112         return;
113     }
114     setAttribute(maxAttr, String::number(max > 0 ? max : 1));
115 }
116
117 double HTMLProgressElement::position() const
118 {
119     if (!hasAttribute(valueAttr))
120         return -1;
121     return value() / max();
122 }
123
124 void HTMLProgressElement::didElementStateChange()
125 {
126     if (renderer())
127         renderer()->updateFromElement();
128 }
129
130 void HTMLProgressElement::createShadowSubtreeIfNeeded()
131 {
132     if (shadowRoot())
133         return;
134     setShadowRoot(ProgressBarValueElement::create(document()).get());
135 }
136
137 } // namespace
138 #endif