2
* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
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.
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.
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.
22
#include "HTMLProgressElement.h"
24
#if ENABLE(PROGRESS_ELEMENT)
25
#include "Attribute.h"
26
#include "EventNames.h"
27
#include "ExceptionCode.h"
28
#include "NodeRenderingContext.h"
29
#include "HTMLDivElement.h"
30
#include "HTMLNames.h"
31
#include "HTMLParserIdioms.h"
32
#include "ProgressShadowElement.h"
33
#include "RenderProgress.h"
34
#include "SelectRuleFeatureSet.h"
35
#include "ShadowRoot.h"
36
#include <wtf/StdLibExtras.h>
40
using namespace HTMLNames;
42
const double HTMLProgressElement::IndeterminatePosition = -1;
43
const double HTMLProgressElement::InvalidPosition = -2;
45
HTMLProgressElement::HTMLProgressElement(const QualifiedName& tagName, Document* document)
46
: LabelableElement(tagName, document)
48
, m_hasAuthorShadowRoot(false)
50
ASSERT(hasTagName(progressTag));
53
HTMLProgressElement::~HTMLProgressElement()
57
PassRefPtr<HTMLProgressElement> HTMLProgressElement::create(const QualifiedName& tagName, Document* document)
59
RefPtr<HTMLProgressElement> progress = adoptRef(new HTMLProgressElement(tagName, document));
60
progress->createShadowSubtree();
64
RenderObject* HTMLProgressElement::createRenderer(RenderArena* arena, RenderStyle* style)
66
if (!style->hasAppearance() || hasAuthorShadowRoot())
67
return RenderObject::createObject(this, style);
69
return new (arena) RenderProgress(this);
72
bool HTMLProgressElement::childShouldCreateRenderer(const NodeRenderingContext& childContext) const
74
return childContext.isOnUpperEncapsulationBoundary() && HTMLElement::childShouldCreateRenderer(childContext);
77
RenderProgress* HTMLProgressElement::renderProgress() const
79
if (renderer() && renderer()->isProgress())
80
return static_cast<RenderProgress*>(renderer());
82
RenderObject* renderObject = userAgentShadowRoot()->firstChild()->renderer();
83
ASSERT(!renderObject || renderObject->isProgress());
84
return static_cast<RenderProgress*>(renderObject);
87
void HTMLProgressElement::willAddAuthorShadowRoot()
89
m_hasAuthorShadowRoot = true;
92
bool HTMLProgressElement::supportsFocus() const
94
return Node::supportsFocus() && !disabled();
97
void HTMLProgressElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
99
if (name == valueAttr)
100
didElementStateChange();
101
else if (name == maxAttr)
102
didElementStateChange();
104
LabelableElement::parseAttribute(name, value);
107
void HTMLProgressElement::attach()
109
LabelableElement::attach();
110
if (RenderProgress* render = renderProgress())
111
render->updateFromElement();
114
double HTMLProgressElement::value() const
116
double value = parseToDoubleForNumberType(fastGetAttribute(valueAttr));
117
return !isfinite(value) || value < 0 ? 0 : std::min(value, max());
120
void HTMLProgressElement::setValue(double value, ExceptionCode& ec)
122
if (!isfinite(value)) {
123
ec = NOT_SUPPORTED_ERR;
126
setAttribute(valueAttr, String::number(value >= 0 ? value : 0));
129
double HTMLProgressElement::max() const
131
double max = parseToDoubleForNumberType(getAttribute(maxAttr));
132
return !isfinite(max) || max <= 0 ? 1 : max;
135
void HTMLProgressElement::setMax(double max, ExceptionCode& ec)
137
if (!isfinite(max)) {
138
ec = NOT_SUPPORTED_ERR;
141
setAttribute(maxAttr, String::number(max > 0 ? max : 1));
144
double HTMLProgressElement::position() const
146
if (!isDeterminate())
147
return HTMLProgressElement::IndeterminatePosition;
148
return value() / max();
151
bool HTMLProgressElement::isDeterminate() const
153
return fastHasAttribute(valueAttr);
156
void HTMLProgressElement::didElementStateChange()
158
m_value->setWidthPercentage(position() * 100);
159
if (RenderProgress* render = renderProgress()) {
160
bool wasDeterminate = render->isDeterminate();
161
render->updateFromElement();
162
if (wasDeterminate != isDeterminate()) {
163
setNeedsStyleRecalc();
164
invalidateParentDistributionIfNecessary(this, SelectRuleFeatureSet::RuleFeatureIndeterminate);
169
void HTMLProgressElement::createShadowSubtree()
171
ASSERT(!userAgentShadowRoot());
174
RefPtr<ShadowRoot> root = ShadowRoot::create(this, ShadowRoot::UserAgentShadowRoot, ASSERT_NO_EXCEPTION);
176
RefPtr<ProgressInnerElement> inner = ProgressInnerElement::create(document());
177
root->appendChild(inner);
179
RefPtr<ProgressBarElement> bar = ProgressBarElement::create(document());
180
RefPtr<ProgressValueElement> value = ProgressValueElement::create(document());
181
m_value = value.get();
182
m_value->setWidthPercentage(HTMLProgressElement::IndeterminatePosition * 100);
183
bar->appendChild(m_value, ASSERT_NO_EXCEPTION);
185
inner->appendChild(bar, ASSERT_NO_EXCEPTION);