Home | History | Annotate | Download | only in html
      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 const AtomicString& HTMLProgressElement::formControlType() const
     68 {
     69     DEFINE_STATIC_LOCAL(const AtomicString, progress, ("progress"));
     70     return progress;
     71 }
     72 
     73 void HTMLProgressElement::parseMappedAttribute(Attribute* attribute)
     74 {
     75     if (attribute->name() == valueAttr)
     76         didElementStateChange();
     77     else if (attribute->name() == maxAttr)
     78         didElementStateChange();
     79     else
     80         HTMLFormControlElement::parseMappedAttribute(attribute);
     81 }
     82 
     83 void HTMLProgressElement::attach()
     84 {
     85     HTMLFormControlElement::attach();
     86     didElementStateChange();
     87 }
     88 
     89 double HTMLProgressElement::value() const
     90 {
     91     const AtomicString& valueString = getAttribute(valueAttr);
     92     double value;
     93     bool ok = parseToDoubleForNumberType(valueString, &value);
     94     if (!ok || value < 0)
     95         return valueString.isNull() ? 1 : 0;
     96     return (value > max()) ? max() : value;
     97 }
     98 
     99 void HTMLProgressElement::setValue(double value, ExceptionCode& ec)
    100 {
    101     if (!isfinite(value)) {
    102         ec = NOT_SUPPORTED_ERR;
    103         return;
    104     }
    105     setAttribute(valueAttr, String::number(value >= 0 ? value : 0));
    106 }
    107 
    108 double HTMLProgressElement::max() const
    109 {
    110     double max;
    111     bool ok = parseToDoubleForNumberType(getAttribute(maxAttr), &max);
    112     if (!ok || max <= 0)
    113         return 1;
    114     return max;
    115 }
    116 
    117 void HTMLProgressElement::setMax(double max, ExceptionCode& ec)
    118 {
    119     if (!isfinite(max)) {
    120         ec = NOT_SUPPORTED_ERR;
    121         return;
    122     }
    123     setAttribute(maxAttr, String::number(max > 0 ? max : 1));
    124 }
    125 
    126 double HTMLProgressElement::position() const
    127 {
    128     if (!hasAttribute(valueAttr))
    129         return HTMLProgressElement::IndeterminatePosition;
    130     return value() / max();
    131 }
    132 
    133 void HTMLProgressElement::didElementStateChange()
    134 {
    135     m_value->setWidthPercentage(position()*100);
    136     if (renderer())
    137         renderer()->updateFromElement();
    138 }
    139 
    140 void HTMLProgressElement::createShadowSubtree()
    141 {
    142     RefPtr<ProgressBarElement> bar = ProgressBarElement::create(document());
    143     m_value = ProgressValueElement::create(document());
    144     ExceptionCode ec = 0;
    145     bar->appendChild(m_value, ec);
    146     ensureShadowRoot()->appendChild(bar, ec);
    147 }
    148 
    149 } // namespace
    150 #endif
    151