blob: 987b57301b67d5b66a82863f03f9c90177d3c6cf [file] [log] [blame]
yael.aharon@nokia.com93e750a2010-03-15 01:00:36 +00001/*
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"
yael.aharon@nokia.com93e750a2010-03-15 01:00:36 +000022#include "HTMLProgressElement.h"
23
antti@apple.com71ed9352014-01-10 17:45:19 +000024#include "ElementIterator.h"
yael.aharon@nokia.com93e750a2010-03-15 01:00:36 +000025#include "HTMLNames.h"
darin@apple.com2f2a9802010-09-13 23:42:02 +000026#include "HTMLParserIdioms.h"
morrita@google.combcbb2082011-04-06 17:03:26 +000027#include "ProgressShadowElement.h"
yael.aharon@nokia.com93e750a2010-03-15 01:00:36 +000028#include "RenderProgress.h"
tkent@chromium.org553b1722011-04-08 06:03:31 +000029#include "ShadowRoot.h"
yael.aharon@nokia.com93e750a2010-03-15 01:00:36 +000030
31namespace WebCore {
32
33using namespace HTMLNames;
34
morrita@google.comcd7fb9d2011-04-18 17:14:03 +000035const double HTMLProgressElement::IndeterminatePosition = -1;
36const double HTMLProgressElement::InvalidPosition = -2;
37
weinig@apple.com49178832013-09-15 00:39:29 +000038HTMLProgressElement::HTMLProgressElement(const QualifiedName& tagName, Document& document)
commit-queue@webkit.orgd18af502012-03-16 15:01:16 +000039 : LabelableElement(tagName, document)
haraken@chromium.org3a27df52012-08-20 01:31:23 +000040 , m_value(0)
yael.aharon@nokia.com93e750a2010-03-15 01:00:36 +000041{
42 ASSERT(hasTagName(progressTag));
antti@apple.com0f2ac5b2013-08-18 20:01:20 +000043 setHasCustomStyleResolveCallbacks();
yael.aharon@nokia.com93e750a2010-03-15 01:00:36 +000044}
45
dbates@webkit.orgf21f3ae2017-10-19 23:48:45 +000046HTMLProgressElement::~HTMLProgressElement() = default;
morrita@google.combcbb2082011-04-06 17:03:26 +000047
weinig@apple.com02f433a2015-01-06 22:32:48 +000048Ref<HTMLProgressElement> HTMLProgressElement::create(const QualifiedName& tagName, Document& document)
yael.aharon@nokia.com93e750a2010-03-15 01:00:36 +000049{
weinig@apple.com02f433a2015-01-06 22:32:48 +000050 Ref<HTMLProgressElement> progress = adoptRef(*new HTMLProgressElement(tagName, document));
esprehn@chromium.org933723d2013-01-29 07:47:20 +000051 progress->ensureUserAgentShadowRoot();
akling@apple.comdbdca2f2014-11-22 09:12:01 +000052 return progress;
yael.aharon@nokia.com93e750a2010-03-15 01:00:36 +000053}
54
antti@apple.com454418f2016-04-25 19:49:23 +000055RenderPtr<RenderElement> HTMLProgressElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&)
yael.aharon@nokia.com93e750a2010-03-15 01:00:36 +000056{
antti@apple.com454418f2016-04-25 19:49:23 +000057 if (!style.hasAppearance())
aestes@apple.com13aae082016-01-02 08:03:08 +000058 return RenderElement::createFor(*this, WTFMove(style));
shinyak@chromium.orgc44aafa2012-08-06 12:00:14 +000059
aestes@apple.com13aae082016-01-02 08:03:08 +000060 return createRenderer<RenderProgress>(*this, WTFMove(style));
yael.aharon@nokia.com93e750a2010-03-15 01:00:36 +000061}
62
weinig@apple.comda898c32013-11-11 04:02:09 +000063bool HTMLProgressElement::childShouldCreateRenderer(const Node& child) const
morrita@google.combeaa6642012-02-24 09:59:07 +000064{
antti@apple.comdacd6de2013-08-20 22:52:55 +000065 return hasShadowRootParent(child) && HTMLElement::childShouldCreateRenderer(child);
morrita@google.combeaa6642012-02-24 09:59:07 +000066}
67
shinyak@chromium.orgc44aafa2012-08-06 12:00:14 +000068RenderProgress* HTMLProgressElement::renderProgress() const
69{
cdumez@apple.com3abcc792014-10-20 03:42:03 +000070 if (is<RenderProgress>(renderer()))
71 return downcast<RenderProgress>(renderer());
72 return downcast<RenderProgress>(descendantsOfType<Element>(*userAgentShadowRoot()).first()->renderer());
shinyak@chromium.orgc44aafa2012-08-06 12:00:14 +000073}
74
akling@apple.com43e9d042012-11-18 16:55:06 +000075void HTMLProgressElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
yael.aharon@nokia.com93e750a2010-03-15 01:00:36 +000076{
akling@apple.com43e9d042012-11-18 16:55:06 +000077 if (name == valueAttr)
morrita@google.com3e2d4002011-02-01 04:05:52 +000078 didElementStateChange();
akling@apple.com43e9d042012-11-18 16:55:06 +000079 else if (name == maxAttr)
morrita@google.com3e2d4002011-02-01 04:05:52 +000080 didElementStateChange();
81 else
akling@apple.com43e9d042012-11-18 16:55:06 +000082 LabelableElement::parseAttribute(name, value);
yael.aharon@nokia.com93e750a2010-03-15 01:00:36 +000083}
84
antti@apple.com0f2ac5b2013-08-18 20:01:20 +000085void HTMLProgressElement::didAttachRenderers()
morrita@google.comb172c47a2010-12-08 04:21:20 +000086{
tasak@google.com5f12a092012-11-01 04:34:52 +000087 if (RenderProgress* render = renderProgress())
88 render->updateFromElement();
morrita@google.comb172c47a2010-12-08 04:21:20 +000089}
90
yael.aharon@nokia.com93e750a2010-03-15 01:00:36 +000091double HTMLProgressElement::value() const
92{
rniwa@webkit.orge999a052016-07-16 15:21:55 +000093 double value = parseToDoubleForNumberType(attributeWithoutSynchronization(valueAttr));
zandobersek@gmail.com8c24b7a2013-02-18 17:13:23 +000094 return !std::isfinite(value) || value < 0 ? 0 : std::min(value, max());
yael.aharon@nokia.com93e750a2010-03-15 01:00:36 +000095}
96
darin@apple.com66d41182016-10-29 02:32:20 +000097void HTMLProgressElement::setValue(double value)
yael.aharon@nokia.com93e750a2010-03-15 01:00:36 +000098{
darin@apple.com1d17a8f2017-10-08 22:17:46 +000099 setAttributeWithoutSynchronization(valueAttr, AtomicString::number(value));
yael.aharon@nokia.com93e750a2010-03-15 01:00:36 +0000100}
101
102double HTMLProgressElement::max() const
103{
rniwa@webkit.orge999a052016-07-16 15:21:55 +0000104 double max = parseToDoubleForNumberType(attributeWithoutSynchronization(maxAttr));
zandobersek@gmail.com8c24b7a2013-02-18 17:13:23 +0000105 return !std::isfinite(max) || max <= 0 ? 1 : max;
yael.aharon@nokia.com93e750a2010-03-15 01:00:36 +0000106}
107
darin@apple.com66d41182016-10-29 02:32:20 +0000108void HTMLProgressElement::setMax(double max)
yael.aharon@nokia.com93e750a2010-03-15 01:00:36 +0000109{
darin@apple.com1d17a8f2017-10-08 22:17:46 +0000110 if (max > 0)
111 setAttributeWithoutSynchronization(maxAttr, AtomicString::number(max));
yael.aharon@nokia.com93e750a2010-03-15 01:00:36 +0000112}
113
114double HTMLProgressElement::position() const
115{
dominicc@chromium.orgcc5eb842011-07-05 04:21:24 +0000116 if (!isDeterminate())
morrita@google.comcd7fb9d2011-04-18 17:14:03 +0000117 return HTMLProgressElement::IndeterminatePosition;
yael.aharon@nokia.com93e750a2010-03-15 01:00:36 +0000118 return value() / max();
119}
120
dominicc@chromium.orgcc5eb842011-07-05 04:21:24 +0000121bool HTMLProgressElement::isDeterminate() const
yael.aharon@nokia.com4cdb6b82011-06-14 13:22:18 +0000122{
rniwa@webkit.orgbda54a02016-07-18 00:39:37 +0000123 return hasAttributeWithoutSynchronization(valueAttr);
yael.aharon@nokia.com4cdb6b82011-06-14 13:22:18 +0000124}
125
morrita@google.com3e2d4002011-02-01 04:05:52 +0000126void HTMLProgressElement::didElementStateChange()
127{
dominicc@chromium.orgcc5eb842011-07-05 04:21:24 +0000128 m_value->setWidthPercentage(position() * 100);
shinyak@chromium.orgc44aafa2012-08-06 12:00:14 +0000129 if (RenderProgress* render = renderProgress()) {
yael.aharon@nokia.com4cdb6b82011-06-14 13:22:18 +0000130 bool wasDeterminate = render->isDeterminate();
shinyak@chromium.orgc44aafa2012-08-06 12:00:14 +0000131 render->updateFromElement();
morrita@google.com1531baa2013-01-08 17:29:32 +0000132 if (wasDeterminate != isDeterminate())
antti@apple.com1c455832016-10-18 12:28:55 +0000133 invalidateStyleForSubtree();
yael.aharon@nokia.com4cdb6b82011-06-14 13:22:18 +0000134 }
morrita@google.com3e2d4002011-02-01 04:05:52 +0000135}
136
dbates@webkit.org62df2762017-11-02 04:13:18 +0000137void HTMLProgressElement::didAddUserAgentShadowRoot(ShadowRoot& root)
morrita@google.com3e2d4002011-02-01 04:05:52 +0000138{
haraken@chromium.org3a27df52012-08-20 01:31:23 +0000139 ASSERT(!m_value);
shinyak@chromium.orgc44aafa2012-08-06 12:00:14 +0000140
cdumez@apple.comf45d2b52016-05-11 19:02:09 +0000141 auto inner = ProgressInnerElement::create(document());
dbates@webkit.org62df2762017-11-02 04:13:18 +0000142 root.appendChild(inner);
morrita@google.com6b18c3f2012-02-09 05:46:57 +0000143
cdumez@apple.comf45d2b52016-05-11 19:02:09 +0000144 auto bar = ProgressBarElement::create(document());
145 auto value = ProgressValueElement::create(document());
cdumez@apple.comc2ad8482015-09-10 18:02:15 +0000146 m_value = value.ptr();
tasak@google.com5f12a092012-11-01 04:34:52 +0000147 m_value->setWidthPercentage(HTMLProgressElement::IndeterminatePosition * 100);
darin@apple.com4a588ff2016-11-11 20:16:03 +0000148 bar->appendChild(value);
morrita@google.com6b18c3f2012-02-09 05:46:57 +0000149
darin@apple.com4a588ff2016-11-11 20:16:03 +0000150 inner->appendChild(bar);
morrita@google.com3e2d4002011-02-01 04:05:52 +0000151}
152
tkent@chromium.org7548f3e2013-03-26 08:26:04 +0000153bool HTMLProgressElement::shouldAppearIndeterminate() const
154{
155 return !isDeterminate();
156}
157
yael.aharon@nokia.com93e750a2010-03-15 01:00:36 +0000158} // namespace