WebCore/html/HTMLMeterElement.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     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(METER_TAG)
       
    23 #include "HTMLMeterElement.h"
       
    24 
       
    25 #include "Attribute.h"
       
    26 #include "EventNames.h"
       
    27 #include "ExceptionCode.h"
       
    28 #include "FormDataList.h"
       
    29 #include "HTMLFormElement.h"
       
    30 #include "HTMLNames.h"
       
    31 #include "LegacyHTMLTreeBuilder.h"
       
    32 #include "RenderMeter.h"
       
    33 #include <wtf/StdLibExtras.h>
       
    34 
       
    35 namespace WebCore {
       
    36 
       
    37 using namespace HTMLNames;
       
    38 
       
    39 // FIXME: This constructor should take an explicit form element pointer passed from the
       
    40 // parser like the constructors for all the other classes derived from HTMLFormControlElement.
       
    41 HTMLMeterElement::HTMLMeterElement(const QualifiedName& tagName, Document* document)
       
    42     : HTMLFormControlElement(tagName, document, 0)
       
    43 {
       
    44     ASSERT(hasTagName(meterTag));
       
    45 }
       
    46 
       
    47 PassRefPtr<HTMLMeterElement> HTMLMeterElement::create(const QualifiedName& tagName, Document* document)
       
    48 {
       
    49     return adoptRef(new HTMLMeterElement(tagName, document));
       
    50 }
       
    51 
       
    52 RenderObject* HTMLMeterElement::createRenderer(RenderArena* arena, RenderStyle*)
       
    53 {
       
    54     return new (arena) RenderMeter(this);
       
    55 }
       
    56 
       
    57 const AtomicString& HTMLMeterElement::formControlType() const
       
    58 {
       
    59     DEFINE_STATIC_LOCAL(const AtomicString, meter, ("meter"));
       
    60     return meter;
       
    61 }
       
    62 
       
    63 void HTMLMeterElement::parseMappedAttribute(Attribute* attribute)
       
    64 {
       
    65     if (attribute->name() == valueAttr || attribute->name() == minAttr || attribute->name() == maxAttr || attribute->name() == lowAttr || attribute->name() == highAttr || attribute->name() == optimumAttr) {
       
    66         if (renderer())
       
    67             renderer()->updateFromElement();
       
    68     } else
       
    69         HTMLFormControlElement::parseMappedAttribute(attribute);
       
    70 }
       
    71 
       
    72 double HTMLMeterElement::min() const
       
    73 {
       
    74     double min = 0;
       
    75     parseToDoubleForNumberType(getAttribute(minAttr), &min);
       
    76     return min;
       
    77 }
       
    78 
       
    79 void HTMLMeterElement::setMin(double min, ExceptionCode& ec)
       
    80 {
       
    81     if (!isfinite(min)) {
       
    82         ec = NOT_SUPPORTED_ERR;
       
    83         return;
       
    84     }
       
    85     setAttribute(minAttr, String::number(min));
       
    86 }
       
    87 
       
    88 double HTMLMeterElement::max() const
       
    89 {
       
    90     double max = std::max(1.0, min());
       
    91     parseToDoubleForNumberType(getAttribute(maxAttr), &max);
       
    92     return std::max(max, min());
       
    93 }
       
    94 
       
    95 void HTMLMeterElement::setMax(double max, ExceptionCode& ec)
       
    96 {
       
    97     if (!isfinite(max)) {
       
    98         ec = NOT_SUPPORTED_ERR;
       
    99         return;
       
   100     }
       
   101     setAttribute(maxAttr, String::number(max));
       
   102 }
       
   103 
       
   104 double HTMLMeterElement::value() const
       
   105 {
       
   106     double value = 0;
       
   107     parseToDoubleForNumberType(getAttribute(valueAttr), &value);
       
   108     return std::min(std::max(value, min()), max());
       
   109 }
       
   110 
       
   111 void HTMLMeterElement::setValue(double value, ExceptionCode& ec)
       
   112 {
       
   113     if (!isfinite(value)) {
       
   114         ec = NOT_SUPPORTED_ERR;
       
   115         return;
       
   116     }
       
   117     setAttribute(valueAttr, String::number(value));
       
   118 }
       
   119 
       
   120 double HTMLMeterElement::low() const
       
   121 {
       
   122     double low = min();
       
   123     parseToDoubleForNumberType(getAttribute(lowAttr), &low);
       
   124     return std::min(std::max(low, min()), max());
       
   125 }
       
   126 
       
   127 void HTMLMeterElement::setLow(double low, ExceptionCode& ec)
       
   128 {
       
   129     if (!isfinite(low)) {
       
   130         ec = NOT_SUPPORTED_ERR;
       
   131         return;
       
   132     }
       
   133     setAttribute(lowAttr, String::number(low));
       
   134 }
       
   135 
       
   136 double HTMLMeterElement::high() const
       
   137 {
       
   138     double high = max();
       
   139     parseToDoubleForNumberType(getAttribute(highAttr), &high);
       
   140     return std::min(std::max(high, low()), max());
       
   141 }
       
   142 
       
   143 void HTMLMeterElement::setHigh(double high, ExceptionCode& ec)
       
   144 {
       
   145     if (!isfinite(high)) {
       
   146         ec = NOT_SUPPORTED_ERR;
       
   147         return;
       
   148     }
       
   149     setAttribute(highAttr, String::number(high));
       
   150 }
       
   151 
       
   152 double HTMLMeterElement::optimum() const
       
   153 {
       
   154     double optimum = (max() + min()) / 2;
       
   155     parseToDoubleForNumberType(getAttribute(optimumAttr), &optimum);
       
   156     return std::min(std::max(optimum, min()), max());
       
   157 }
       
   158 
       
   159 void HTMLMeterElement::setOptimum(double optimum, ExceptionCode& ec)
       
   160 {
       
   161     if (!isfinite(optimum)) {
       
   162         ec = NOT_SUPPORTED_ERR;
       
   163         return;
       
   164     }
       
   165     setAttribute(optimumAttr, String::number(optimum));
       
   166 }
       
   167 
       
   168 HTMLMeterElement::GaugeRegion HTMLMeterElement::gaugeRegion() const
       
   169 {
       
   170     double lowValue = low();
       
   171     double highValue = high();
       
   172     double theValue = value();
       
   173     double optimumValue = optimum();
       
   174 
       
   175     if (optimumValue <= lowValue) {
       
   176         // The optimum range stays under low
       
   177         if (theValue <= lowValue)
       
   178             return GaugeRegionOptimum;
       
   179         if (theValue <= highValue)
       
   180             return GaugeRegionSuboptimal;
       
   181         return GaugeRegionEvenLessGood;
       
   182     }
       
   183     
       
   184     if (highValue <= optimumValue) {
       
   185         // The optimum range stays over high
       
   186         if (highValue <= theValue)
       
   187             return GaugeRegionOptimum;
       
   188         if (lowValue <= theValue)
       
   189             return GaugeRegionSuboptimal;
       
   190         return GaugeRegionEvenLessGood;
       
   191     }
       
   192 
       
   193     // The optimum range stays between high and low
       
   194     if (lowValue < theValue && theValue < highValue)
       
   195         return GaugeRegionOptimum;
       
   196     if (theValue == min() || max() == theValue)
       
   197         return GaugeRegionEvenLessGood;
       
   198     return GaugeRegionSuboptimal;
       
   199 }
       
   200 
       
   201 } // namespace
       
   202 #endif