Changeset 92589 in webkit


Ignore:
Timestamp:
Aug 8, 2011 2:16:54 AM (13 years ago)
Author:
commit-queue@webkit.org
Message:

Source/WebCore: The input[type=number] element should be as wide as necessary to show the widest possible value.
https://bugs.webkit.org/show_bug.cgi?id=60673

Patch by Shinya Kawanaka <shinyak@google.com> on 2011-08-08
Reviewed by Kent Tamura.

The size of input[type=number] is calculated from min/max/step attributes to show the widest possible value.
If min or max attribute is absent, the default size is used.
Also, if its css width is not auto, the width is used with priority.

If min/max/attribute is set dynamically, the size of the input[type=number] will be recalculated.

Test: fast/forms/input-number-size.html

  • html/HTMLInputElement.cpp:

(WebCore::HTMLInputElement::parseMappedAttribute):

Added stepAttributeChanged handler.

(WebCore::HTMLInputElement::sizeShouldIncludeDecoration):

Returns true if a renderer should include decoration (e.g. inner spinbox).
Also returns the preferred size of the input.

  • html/HTMLInputElement.h:
  • html/InputType.cpp:

(WebCore::InputType::sizeShouldIncludeDecoration):

Same as WebCore::HTMLInputElement::sizeShouldIncludeDecoration.

(WebCore::InputType::stepAttributeChanged):

Will be called When step attribute is changed.
Sets a flag to recalculate layout.

  • html/InputType.h:
  • html/NumberInputType.cpp:

(WebCore::lengthBeforeDecimalPoint):

Calculates the width before the decimal point.

(WebCore::NumberInputType::sizeShouldIncludeDecoration):

Same as WebCore::HTMLInputElement::sizeShouldIncludeDecoration.
However, this will calculate the preferred size from min/max/step attribute.

(WebCore::NumberInputType::minOrMaxAttributeChanged):

Sets a flag to recalculate layout.

(WebCore::NumberInputType::stepAttributeChanged): ditto.

  • html/NumberInputType.h:
  • rendering/RenderTextControlSingleLine.cpp:

(WebCore::RenderTextControlSingleLine::preferredContentWidth):

Uses preferredSize instead of size.
Also, adds innerSpinButtonElement size to width if sizeShouldIncludeDecoration returns true.

LayoutTests: Added the test to check the width of input[type=number].
https://bugs.webkit.org/show_bug.cgi?id=60673

Patch by Shinya Kawanaka <shinyak@google.com> on 2011-08-08
Reviewed by Kent Tamura.

  • fast/forms/input-number-size-expected.txt: Added.
  • fast/forms/input-number-size.html: Added.
Location:
trunk
Files:
2 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r92586 r92589  
     12011-08-08  Shinya Kawanaka  <shinyak@google.com>
     2
     3        Added the test to check the width of input[type=number].
     4        https://bugs.webkit.org/show_bug.cgi?id=60673
     5
     6        Reviewed by Kent Tamura.
     7
     8        * fast/forms/input-number-size-expected.txt: Added.
     9        * fast/forms/input-number-size.html: Added.
     10
    1112011-08-07  Zoltan Horvath  <zoltan@webkit.org>
    212
  • trunk/Source/WebCore/ChangeLog

    r92588 r92589  
     12011-08-08  Shinya Kawanaka  <shinyak@google.com>
     2
     3        The input[type=number] element should be as wide as necessary to show the widest possible value.
     4        https://bugs.webkit.org/show_bug.cgi?id=60673
     5
     6        Reviewed by Kent Tamura.
     7
     8        The size of input[type=number] is calculated from min/max/step attributes to show the widest possible value.
     9        If min or max attribute is absent, the default size is used.
     10        Also, if its css width is not auto, the width is used with priority.
     11
     12        If min/max/attribute is set dynamically, the size of the input[type=number] will be recalculated.
     13
     14        Test: fast/forms/input-number-size.html
     15
     16        * html/HTMLInputElement.cpp:
     17        (WebCore::HTMLInputElement::parseMappedAttribute):
     18           Added stepAttributeChanged handler.
     19        (WebCore::HTMLInputElement::sizeShouldIncludeDecoration):
     20           Returns true if a renderer should include decoration (e.g. inner spinbox).
     21           Also returns the preferred size of the input.
     22        * html/HTMLInputElement.h:
     23        * html/InputType.cpp:
     24        (WebCore::InputType::sizeShouldIncludeDecoration):
     25           Same as WebCore::HTMLInputElement::sizeShouldIncludeDecoration.
     26        (WebCore::InputType::stepAttributeChanged):
     27           Will be called When step attribute is changed.
     28           Sets a flag to recalculate layout.
     29        * html/InputType.h:
     30        * html/NumberInputType.cpp:
     31        (WebCore::lengthBeforeDecimalPoint):
     32           Calculates the width before the decimal point.
     33        (WebCore::NumberInputType::sizeShouldIncludeDecoration):
     34           Same as WebCore::HTMLInputElement::sizeShouldIncludeDecoration.
     35           However, this will calculate the preferred size from min/max/step attribute.
     36        (WebCore::NumberInputType::minOrMaxAttributeChanged):
     37           Sets a flag to recalculate layout.
     38        (WebCore::NumberInputType::stepAttributeChanged): ditto.
     39        * html/NumberInputType.h:
     40        * rendering/RenderTextControlSingleLine.cpp:
     41        (WebCore::RenderTextControlSingleLine::preferredContentWidth):
     42           Uses preferredSize instead of size.
     43           Also, adds innerSpinButtonElement size to width if sizeShouldIncludeDecoration returns true.
     44
    1452011-08-08  Kenichi Ishibashi  <bashi@chromium.org>
    246
  • trunk/Source/WebCore/html/HTMLInputElement.cpp

    r92533 r92589  
    5151#include "LocalizedStrings.h"
    5252#include "MouseEvent.h"
     53#include "NumberInputType.h"
    5354#include "Page.h"
    5455#include "PlatformMouseEvent.h"
     
    805806        m_inputType->multipleAttributeChanged();
    806807        setNeedsValidityCheck();
    807     } else if (attr->name() == patternAttr || attr->name() == precisionAttr || attr->name() == stepAttr)
     808    } else if (attr->name() == stepAttr) {
     809        m_inputType->stepAttributeChanged();
     810        setNeedsValidityCheck();
     811    } else if (attr->name() == patternAttr || attr->name() == precisionAttr)
    808812        setNeedsValidityCheck();
    809813    else if (attr->name() == disabledAttr) {
     
    993997{
    994998    return m_size;
     999}
     1000
     1001bool HTMLInputElement::sizeShouldIncludeDecoration(int& preferredSize) const
     1002{
     1003    return m_inputType->sizeShouldIncludeDecoration(defaultSize, preferredSize);
    9951004}
    9961005
  • trunk/Source/WebCore/html/HTMLInputElement.h

    r91549 r92589  
    132132
    133133    int size() const;
     134    bool sizeShouldIncludeDecoration(int& preferredSize) const;
    134135
    135136    void setType(const String&);
  • trunk/Source/WebCore/html/InputType.cpp

    r92533 r92589  
    250250}
    251251
     252bool InputType::sizeShouldIncludeDecoration(int defaultSize, int& preferredSize) const
     253{
     254    preferredSize = element()->size();
     255    return false;
     256}
     257
    252258bool InputType::stepMismatch(const String&, double) const
    253259{
     
    454460}
    455461
     462void InputType::stepAttributeChanged()
     463{
     464}
     465
    456466bool InputType::canBeSuccessfulSubmitButton()
    457467{
  • trunk/Source/WebCore/html/InputType.h

    r92533 r92589  
    144144    virtual double minimum() const;
    145145    virtual double maximum() const;
     146    virtual bool sizeShouldIncludeDecoration(int defaultSize, int& preferredSize) const;
    146147    virtual bool stepMismatch(const String&, double step) const;
    147148    virtual double stepBase() const;
     
    207208    virtual void attach();
    208209    virtual void minOrMaxAttributeChanged();
     210    virtual void stepAttributeChanged();
    209211    virtual void altAttributeChanged();
    210212    virtual void srcAttributeChanged();
  • trunk/Source/WebCore/html/NumberInputType.cpp

    r89194 r92589  
    5454static const double numberStepScaleFactor = 1.0;
    5555
     56static unsigned lengthBeforeDecimalPoint(double value)
     57{
     58    // If value is negative, '-' should be counted.
     59
     60    double absoluteValue = fabs(value);
     61    if (absoluteValue < 1)
     62        return value < 0 ? 2 : 1;
     63
     64    unsigned length = static_cast<unsigned>(log10(floor(absoluteValue))) + 1;
     65    if (value < 0)
     66        length += 1;
     67
     68    return length;
     69}
     70
    5671PassOwnPtr<InputType> NumberInputType::create(HTMLInputElement* element)
    5772{
     
    122137}
    123138
     139bool NumberInputType::sizeShouldIncludeDecoration(int defaultSize, int& preferredSize) const
     140{
     141    preferredSize = defaultSize;
     142
     143    unsigned minValueDecimalPlaces;
     144    double minValueDouble;
     145    String minValue = element()->fastGetAttribute(minAttr);
     146    if (!parseToDoubleForNumberTypeWithDecimalPlaces(minValue, &minValueDouble, &minValueDecimalPlaces))
     147        return false;
     148
     149    unsigned maxValueDecimalPlaces;
     150    double maxValueDouble;
     151    String maxValue = element()->fastGetAttribute(maxAttr);
     152    if (!parseToDoubleForNumberTypeWithDecimalPlaces(maxValue, &maxValueDouble, &maxValueDecimalPlaces))
     153        return false;
     154
     155    if (maxValueDouble < minValueDouble) {
     156        maxValueDouble = minValueDouble;
     157        maxValueDecimalPlaces = maxValueDecimalPlaces;
     158    }
     159
     160    unsigned stepValueDecimalPlaces;
     161    double stepValueDouble;
     162    String stepValue = element()->fastGetAttribute(stepAttr);
     163    if (equalIgnoringCase(stepValue, "any"))
     164        return false;
     165    if (!parseToDoubleForNumberTypeWithDecimalPlaces(stepValue, &stepValueDouble, &stepValueDecimalPlaces)) {
     166        stepValueDouble = 1;
     167        stepValueDecimalPlaces = 0;
     168    }
     169
     170    unsigned length = lengthBeforeDecimalPoint(minValueDouble);
     171    length = max(length, lengthBeforeDecimalPoint(maxValueDouble));
     172    length = max(length, lengthBeforeDecimalPoint(stepValueDouble));
     173
     174    unsigned lengthAfterDecimalPoint = minValueDecimalPlaces;
     175    lengthAfterDecimalPoint = max(lengthAfterDecimalPoint, maxValueDecimalPlaces);
     176    lengthAfterDecimalPoint = max(lengthAfterDecimalPoint, stepValueDecimalPlaces);
     177
     178    // '.' should be counted if the value has decimal places.
     179    if (lengthAfterDecimalPoint > 0)
     180        length += lengthAfterDecimalPoint + 1;
     181
     182    preferredSize = length;
     183    return true;
     184}
     185
    124186bool NumberInputType::isSteppable() const
    125187{
     
    275337}
    276338
     339void NumberInputType::minOrMaxAttributeChanged()
     340{
     341    InputType::minOrMaxAttributeChanged();
     342
     343    if (element()->renderer())
     344        element()->renderer()->setNeedsLayoutAndPrefWidthsRecalc();
     345}
     346
     347void NumberInputType::stepAttributeChanged()
     348{
     349    InputType::stepAttributeChanged();
     350
     351    if (element()->renderer())
     352        element()->renderer()->setNeedsLayoutAndPrefWidthsRecalc();
     353}
     354
    277355} // namespace WebCore
  • trunk/Source/WebCore/html/NumberInputType.h

    r89194 r92589  
    5252    virtual double minimum() const;
    5353    virtual double maximum() const;
     54    virtual bool sizeShouldIncludeDecoration(int defaultSize, int& preferredSize) const;
    5455    virtual bool isSteppable() const;
    5556    virtual bool stepMismatch(const String&, double) const;
     
    7374    virtual bool supportsPlaceholder() const;
    7475    virtual bool isNumberField() const;
     76    virtual void minOrMaxAttributeChanged();
     77    virtual void stepAttributeChanged();
    7578};
    7679
  • trunk/Source/WebCore/rendering/RenderTextControlSingleLine.cpp

    r91550 r92589  
    390390    return RenderTextControl::getAvgCharWidth(family);
    391391}
    392    
     392
    393393int RenderTextControlSingleLine::preferredContentWidth(float charWidth) const
    394394{
    395     int factor = inputElement()->size();
     395    int factor;
     396    bool includesDecoration = inputElement()->sizeShouldIncludeDecoration(factor);
    396397    if (factor <= 0)
    397398        factor = 20;
     
    423424        result += cancelRenderer->borderLeft() + cancelRenderer->borderRight() +
    424425                  cancelRenderer->paddingLeft() + cancelRenderer->paddingRight();
     426
     427    if (includesDecoration) {
     428        HTMLElement* spinButton = innerSpinButtonElement();
     429        if (RenderBox* spinRenderer = spinButton ? spinButton->renderBox() : 0) {
     430            result += spinRenderer->borderLeft() + spinRenderer->borderRight() +
     431                  spinRenderer->paddingLeft() + spinRenderer->paddingRight();
     432            // Since the width of spinRenderer is not calculated yet, spinRenderer->width() returns 0.
     433            // So computedStyle()->width() is used instead.
     434            result += spinButton->computedStyle()->width().value();
     435        }
     436    }
    425437
    426438#if ENABLE(INPUT_SPEECH)
Note: See TracChangeset for help on using the changeset viewer.