Unreviewed, rolling out r106909.
[WebKit-https.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 "ProgressShadowElement.h"
34 #include "RenderProgress.h"
35 #include "ShadowRoot.h"
36 #include <wtf/StdLibExtras.h>
37
38 namespace WebCore {
39
40 using namespace HTMLNames;
41
42 const double HTMLProgressElement::IndeterminatePosition = -1;
43 const double HTMLProgressElement::InvalidPosition = -2;
44
45 HTMLProgressElement::HTMLProgressElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
46     : HTMLFormControlElement(tagName, document, form)
47 {
48     ASSERT(hasTagName(progressTag));
49 }
50
51 HTMLProgressElement::~HTMLProgressElement()
52 {
53 }
54
55 PassRefPtr<HTMLProgressElement> HTMLProgressElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
56 {
57     RefPtr<HTMLProgressElement> progress = adoptRef(new HTMLProgressElement(tagName, document, form));
58     progress->createShadowSubtree();
59     return progress;
60 }
61
62 RenderObject* HTMLProgressElement::createRenderer(RenderArena* arena, RenderStyle*)
63 {
64     return new (arena) RenderProgress(this);
65 }
66
67 bool HTMLProgressElement::supportsFocus() const
68 {
69     return Node::supportsFocus() && !disabled();
70 }
71
72 const AtomicString& HTMLProgressElement::formControlType() const
73 {
74     DEFINE_STATIC_LOCAL(const AtomicString, progress, ("progress"));
75     return progress;
76 }
77
78 void HTMLProgressElement::parseAttribute(Attribute* attribute)
79 {
80     if (attribute->name() == valueAttr)
81         didElementStateChange();
82     else if (attribute->name() == maxAttr)
83         didElementStateChange();
84     else
85         HTMLFormControlElement::parseAttribute(attribute);
86 }
87
88 void HTMLProgressElement::attach()
89 {
90     HTMLFormControlElement::attach();
91     didElementStateChange();
92 }
93
94 double HTMLProgressElement::value() const
95 {
96     double value;
97     bool ok = parseToDoubleForNumberType(fastGetAttribute(valueAttr), &value);
98     if (!ok || value < 0)
99         return 0;
100     return (value > max()) ? max() : value;
101 }
102
103 void HTMLProgressElement::setValue(double value, ExceptionCode& ec)
104 {
105     if (!isfinite(value)) {
106         ec = NOT_SUPPORTED_ERR;
107         return;
108     }
109     setAttribute(valueAttr, String::number(value >= 0 ? value : 0));
110 }
111
112 double HTMLProgressElement::max() const
113 {
114     double max;
115     bool ok = parseToDoubleForNumberType(getAttribute(maxAttr), &max);
116     if (!ok || max <= 0)
117         return 1;
118     return max;
119 }
120
121 void HTMLProgressElement::setMax(double max, ExceptionCode& ec)
122 {
123     if (!isfinite(max)) {
124         ec = NOT_SUPPORTED_ERR;
125         return;
126     }
127     setAttribute(maxAttr, String::number(max > 0 ? max : 1));
128 }
129
130 double HTMLProgressElement::position() const
131 {
132     if (!isDeterminate())
133         return HTMLProgressElement::IndeterminatePosition;
134     return value() / max();
135 }
136
137 bool HTMLProgressElement::isDeterminate() const
138 {
139     return fastHasAttribute(valueAttr);
140 }
141     
142 void HTMLProgressElement::didElementStateChange()
143 {
144     m_value->setWidthPercentage(position() * 100);
145     if (renderer()) {
146         RenderProgress* render = toRenderProgress(renderer());
147         bool wasDeterminate = render->isDeterminate();
148         renderer()->updateFromElement();
149         if (wasDeterminate != isDeterminate())
150             setNeedsStyleRecalc();
151     }
152 }
153
154 void HTMLProgressElement::createShadowSubtree()
155 {
156     RefPtr<ProgressBarElement> bar = ProgressBarElement::create(document());
157     m_value = ProgressValueElement::create(document());
158     ExceptionCode ec = 0;
159     bar->appendChild(m_value, ec);
160     ensureShadowRoot()->appendChild(bar, ec);
161 }
162
163 } // namespace
164 #endif