15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version. 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful, 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details. 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB. If not, write to 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA. 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLProgressElement.h" 2453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 25197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ExceptionMessages.h" 26197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ExceptionState.h" 27197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/ExceptionStatePlaceholder.h" 285d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/HTMLNames.h" 2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/ExceptionCode.h" 30e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)#include "core/dom/shadow/ShadowRoot.h" 31197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/frame/UseCounter.h" 3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/parser/HTMLParserIdioms.h" 3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/shadow/ProgressShadowElement.h" 3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderProgress.h" 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 36c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace HTMLNames; 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const double HTMLProgressElement::IndeterminatePosition = -1; 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const double HTMLProgressElement::InvalidPosition = -2; 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)HTMLProgressElement::HTMLProgressElement(Document& document) 4451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) : LabelableElement(progressTag, document) 45d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) , m_value(nullptr) 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 47197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch UseCounter::count(document, UseCounter::ProgressElement); 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)HTMLProgressElement::~HTMLProgressElement() 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 54323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)PassRefPtrWillBeRawPtr<HTMLProgressElement> HTMLProgressElement::create(Document& document) 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 565d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) RefPtrWillBeRawPtr<HTMLProgressElement> progress = adoptRefWillBeNoop(new HTMLProgressElement(document)); 57926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) progress->ensureUserAgentShadowRoot(); 58926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return progress.release(); 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 61591b958dee2cf159d33a0b931e6231072eaf38d5Ben MurdochRenderObject* HTMLProgressElement::createRenderer(RenderStyle* style) 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!style->hasAppearance() || hasAuthorShadowRoot()) 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return RenderObject::createObject(this, style); 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 66f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles) return new RenderProgress(this); 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)RenderProgress* HTMLProgressElement::renderProgress() const 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (renderer() && renderer()->isProgress()) 7206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return toRenderProgress(renderer()); 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RenderObject* renderObject = userAgentShadowRoot()->firstChild()->renderer(); 75926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT_WITH_SECURITY_IMPLICATION(!renderObject || renderObject->isProgress()); 7606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) return toRenderProgress(renderObject); 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 79926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void HTMLProgressElement::parseAttribute(const QualifiedName& name, const AtomicString& value) 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 81926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (name == valueAttr) 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) didElementStateChange(); 83926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) else if (name == maxAttr) 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) didElementStateChange(); 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 86926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) LabelableElement::parseAttribute(name, value); 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 89521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)void HTMLProgressElement::attach(const AttachContext& context) 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 91521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) LabelableElement::attach(context); 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (RenderProgress* render = renderProgress()) 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) render->updateFromElement(); 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)double HTMLProgressElement::value() const 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 9851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) double value = getFloatingPointAttribute(valueAttr); 99323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // Otherwise, if the parsed value was greater than or equal to the maximum 100323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // value, then the current value of the progress bar is the maximum value 101323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // of the progress bar. Otherwise, if parsing the value attribute's value 102323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // resulted in an error, or a number less than or equal to zero, then the 103323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // current value of the progress bar is zero. 104926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return !std::isfinite(value) || value < 0 ? 0 : std::min(value, max()); 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 107323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)void HTMLProgressElement::setValue(double value) 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 10951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) setFloatingPointAttribute(valueAttr, std::max(value, 0.)); 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)double HTMLProgressElement::max() const 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 11451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) double max = getFloatingPointAttribute(maxAttr); 115323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // Otherwise, if the element has no max attribute, or if it has one but 116323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // parsing it resulted in an error, or if the parsed value was less than or 117323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) // equal to zero, then the maximum value of the progress bar is 1.0. 118926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return !std::isfinite(max) || max <= 0 ? 1 : max; 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 121323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)void HTMLProgressElement::setMax(double max) 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 12351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) // FIXME: The specification says we should ignore the input value if it is inferior or equal to 0. 12451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) setFloatingPointAttribute(maxAttr, max > 0 ? max : 1); 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)double HTMLProgressElement::position() const 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!isDeterminate()) 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return HTMLProgressElement::IndeterminatePosition; 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return value() / max(); 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool HTMLProgressElement::isDeterminate() const 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return fastHasAttribute(valueAttr); 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 13802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void HTMLProgressElement::didElementStateChange() 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_value->setWidthPercentage(position() * 100); 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (RenderProgress* render = renderProgress()) { 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool wasDeterminate = render->isDeterminate(); 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) render->updateFromElement(); 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (wasDeterminate != isDeterminate()) 1467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci pseudoStateChanged(CSSSelector::PseudoIndeterminate); 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void HTMLProgressElement::didAddUserAgentShadowRoot(ShadowRoot& root) 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!m_value); 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 154d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) RefPtrWillBeRawPtr<ProgressInnerElement> inner = ProgressInnerElement::create(document()); 15509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) inner->setShadowPseudoId(AtomicString("-webkit-progress-inner-element", AtomicString::ConstructFromLiteral)); 15651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles) root.appendChild(inner); 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 158d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) RefPtrWillBeRawPtr<ProgressBarElement> bar = ProgressBarElement::create(document()); 15909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) bar->setShadowPseudoId(AtomicString("-webkit-progress-bar", AtomicString::ConstructFromLiteral)); 160d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) RefPtrWillBeRawPtr<ProgressValueElement> value = ProgressValueElement::create(document()); 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_value = value.get(); 16209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) m_value->setShadowPseudoId(AtomicString("-webkit-progress-value", AtomicString::ConstructFromLiteral)); 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_value->setWidthPercentage(HTMLProgressElement::IndeterminatePosition * 100); 164e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) bar->appendChild(m_value); 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 166e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) inner->appendChild(bar); 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 16953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)bool HTMLProgressElement::shouldAppearIndeterminate() const 17053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 17153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return !isDeterminate(); 17253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 17353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 174d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void HTMLProgressElement::trace(Visitor* visitor) 175d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){ 176d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) visitor->trace(m_value); 177d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) LabelableElement::trace(visitor); 178d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)} 179d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace 181