Title: [92589] trunk
Revision
92589
Author
[email protected]
Date
2011-08-08 02:16:54 -0700 (Mon, 08 Aug 2011)

Log 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 <[email protected]> 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 <[email protected]> on 2011-08-08
Reviewed by Kent Tamura.

* fast/forms/input-number-size-expected.txt: Added.
* fast/forms/input-number-size.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (92588 => 92589)


--- trunk/LayoutTests/ChangeLog	2011-08-08 08:42:14 UTC (rev 92588)
+++ trunk/LayoutTests/ChangeLog	2011-08-08 09:16:54 UTC (rev 92589)
@@ -1,3 +1,13 @@
+2011-08-08  Shinya Kawanaka  <[email protected]>
+
+        Added the test to check the width of input[type=number].
+        https://bugs.webkit.org/show_bug.cgi?id=60673
+
+        Reviewed by Kent Tamura.
+
+        * fast/forms/input-number-size-expected.txt: Added.
+        * fast/forms/input-number-size.html: Added.
+
 2011-08-07  Zoltan Horvath  <[email protected]>
 
         [Qt] Skip divergent tests

Added: trunk/LayoutTests/fast/forms/input-number-size-expected.txt (0 => 92589)


--- trunk/LayoutTests/fast/forms/input-number-size-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/forms/input-number-size-expected.txt	2011-08-08 09:16:54 UTC (rev 92589)
@@ -0,0 +1,84 @@
+Test for size attribute of input
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS spinButtonWidth is >= 1
+The content area of the number input without min/max/step attribute should have the same width as text input
+PASS number.offsetWidth is text.offsetWidth
+
+The number whose width is specified should respect the setting
+PASS numberWithWidth.offsetWidth is 100
+PASS numberWithWidth.min = 0; numberWithWidth.max = 100; numberWithWidth.offsetWidth is 100
+
+The number input should ignore size attribute for layout
+PASS number.size = 10; number.offsetWidth is text.offsetWidth
+PASS number.size is 10
+PASS number.size = 100; number.offsetWidth is text.offsetWidth
+PASS number.size is 100
+
+If min or max is absent, the number input has the same width as input[type=text]
+PASS numberWidth(0, null, null) is text.offsetWidth
+PASS numberWidth(null, 100, null) is text.offsetWidth
+PASS numberWidth(null, null, 100) is text.offsetWidth
+
+If step is any, the input[type=text] has the same width as input[type=text]
+PASS numberWidth(0, 1, "any") is text.offsetWidth
+PASS numberWidth(0, 10, "any") is text.offsetWidth
+PASS numberWidth(0, 1.1, "any") is text.offsetWidth
+
+The case the inner spin button has border or padding.
+PASS numberWidth(0, 10, 1, "with-border") is textWidthPlusSpinButtonWidth(2) + borderWidth
+PASS numberWidth(0, 10, 1, "with-padding") is textWidthPlusSpinButtonWidth(2) + paddingWidth
+PASS numberWidth(0, 10, 1, "with-margin") is textWidthPlusSpinButtonWidth(2)
+PASS numberWidth(0, 10, 1, "with-border with-padding") is textWidthPlusSpinButtonWidth(2) + borderWidth + paddingWidth
+
+The default step does not need to be considered.
+PASS numberWidth(0, 1, null) is textWidthPlusSpinButtonWidth(1)
+PASS numberWidth(0, 100, null) is textWidthPlusSpinButtonWidth(3)
+PASS numberWidth(-100, 1, null) is textWidthPlusSpinButtonWidth(4)
+PASS numberWidth(0.0, 1.0, null) is textWidthPlusSpinButtonWidth(1)
+PASS numberWidth(0.5, 1.5, null) is textWidthPlusSpinButtonWidth(3)
+PASS numberWidth(-0.5, 1.5, null) is textWidthPlusSpinButtonWidth(4)
+PASS numberWidth(1e+10, 1e+10 + 1, null) is textWidthPlusSpinButtonWidth(11)
+PASS numberWidth(-1e+10, 1e+10 + 1, null) is textWidthPlusSpinButtonWidth(12)
+
+Check the width of a number input when min/max/step is changed variously
+PASS numberWidth(0, 1, 1) is textWidthPlusSpinButtonWidth(1)
+PASS numberWidth(0, 10, 1) is textWidthPlusSpinButtonWidth(2)
+PASS numberWidth(0, 100, 1) is textWidthPlusSpinButtonWidth(3)
+PASS numberWidth(0, 1000, 1) is textWidthPlusSpinButtonWidth(4)
+PASS numberWidth(0, 10000, 1) is textWidthPlusSpinButtonWidth(5)
+PASS numberWidth(0, 100000, 1) is textWidthPlusSpinButtonWidth(6)
+PASS numberWidth(0, 1000000, 1) is textWidthPlusSpinButtonWidth(7)
+PASS numberWidth(0, 10000000, 1) is textWidthPlusSpinButtonWidth(8)
+PASS numberWidth(0, 100000000, 1) is textWidthPlusSpinButtonWidth(9)
+PASS numberWidth(0, 1000000000, 1) is textWidthPlusSpinButtonWidth(10)
+PASS numberWidth(-1, 0, 1) is textWidthPlusSpinButtonWidth(2)
+PASS numberWidth(-10, 0, 1) is textWidthPlusSpinButtonWidth(3)
+PASS numberWidth(-100, 0, 1) is textWidthPlusSpinButtonWidth(4)
+PASS numberWidth(-1000, 0, 1) is textWidthPlusSpinButtonWidth(5)
+PASS numberWidth(-10000, 0, 1) is textWidthPlusSpinButtonWidth(6)
+PASS numberWidth(-100000, 0, 1) is textWidthPlusSpinButtonWidth(7)
+PASS numberWidth(-1000000, 0, 1) is textWidthPlusSpinButtonWidth(8)
+PASS numberWidth(-10000000, 0, 1) is textWidthPlusSpinButtonWidth(9)
+PASS numberWidth(-100000000, 0, 1) is textWidthPlusSpinButtonWidth(10)
+PASS numberWidth(-1000000000, 0, 1) is textWidthPlusSpinButtonWidth(11)
+PASS numberWidth(0, 1, 0.5) is textWidthPlusSpinButtonWidth(3)
+PASS numberWidth(0, 1, 0.05) is textWidthPlusSpinButtonWidth(4)
+PASS numberWidth(0, 1, 0.005) is textWidthPlusSpinButtonWidth(5)
+PASS numberWidth(0, 1, 0.0005) is textWidthPlusSpinButtonWidth(6)
+PASS numberWidth(0, 1, 0.00005) is textWidthPlusSpinButtonWidth(7)
+PASS numberWidth(0, 1, 0.000005) is textWidthPlusSpinButtonWidth(8)
+PASS numberWidth(0, 1, 0.0000005) is textWidthPlusSpinButtonWidth(9)
+PASS numberWidth(0.5, 1, 1) is textWidthPlusSpinButtonWidth(3)
+PASS numberWidth(0.05, 1, 1) is textWidthPlusSpinButtonWidth(4)
+PASS numberWidth(0.005, 1, 1) is textWidthPlusSpinButtonWidth(5)
+PASS numberWidth(1.5, 2, 1) is textWidthPlusSpinButtonWidth(3)
+PASS numberWidth(1.05, 2, 1) is textWidthPlusSpinButtonWidth(4)
+PASS numberWidth(1.005, 2, 1) is textWidthPlusSpinButtonWidth(5)
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/forms/input-number-size.html (0 => 92589)


--- trunk/LayoutTests/fast/forms/input-number-size.html	                        (rev 0)
+++ trunk/LayoutTests/fast/forms/input-number-size.html	2011-08-08 09:16:54 UTC (rev 92589)
@@ -0,0 +1,161 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href=""
+<script src=""
+<style>
+
+input.with-border::-webkit-inner-spin-button {
+     border: 10px solid;
+}
+input.with-padding::-webkit-inner-spin-button {
+     padding: 0 8px 0 8px;
+}
+input.with-margin::-webkit-inner-spin-button {
+     margin: 0 10px 0 10px;
+}
+
+input#number-without-spinbutton::-webkit-inner-spin-button {
+     display: none;
+     margin: 0;
+}
+input#number-with-width {
+     width: 100px;
+}
+
+</style>
+</head>
+<body>
+<p id="description"></p>
+<div id="console"></div>
+
+<script>
+description('Test for size attribute of input');
+
+var parent = document.createElement('div');
+document.body.appendChild(parent);
+parent.innerHTML = '<input type=text id=text>'
+  + '<input type="number" id=number>'
+  + '<input type="number" id="number-without-spinbutton" min="0" max="10" step="1">'
+  + '<input type="number" id="number-with-spinbutton" min="0" max="10" step="1">'
+  + '<input type="number" id="number-with-width">'
+var number = document.getElementById('number');
+var numberWithoutSpinButton = document.getElementById('number-without-spinbutton');
+var numberWithSpinButton = document.getElementById('number-with-spinbutton');
+var numberWithWidth = document.getElementById('number-with-width');
+var text = document.getElementById('text');
+
+// The width of spin button should differ by environment. So it should be calculated here.
+var spinButtonWidth = numberWithSpinButton.offsetWidth - numberWithoutSpinButton.offsetWidth;
+// spinButtonWidth should have menaningful width.
+shouldBeGreaterThanOrEqual('spinButtonWidth', '1');
+
+debug('The content area of the number input without min/max/step attribute should have the same width as text input');
+shouldBe('number.offsetWidth', 'text.offsetWidth');
+debug('');
+
+debug('The number whose width is specified should respect the setting');
+shouldBe('numberWithWidth.offsetWidth', '100');
+shouldBe('numberWithWidth.min = 0; numberWithWidth.max = 100; numberWithWidth.offsetWidth', '100');
+debug('');
+
+debug('The number input should ignore size attribute for layout');
+shouldBe('number.size = 10; number.offsetWidth', 'text.offsetWidth');
+shouldBe('number.size', '10');
+shouldBe('number.size = 100; number.offsetWidth', 'text.offsetWidth');
+shouldBe('number.size', '100');
+number.size = null;
+debug('');
+
+function numberWidth(min, max, step, className) {
+    number.className = className;
+    number.step = step;
+    number.min = min;
+    number.max = max;
+    return number.offsetWidth;
+}
+
+function textWidthPlusSpinButtonWidth(size) {
+    text.size = size;
+    return text.offsetWidth + spinButtonWidth;
+}
+
+debug('If min or max is absent, the number input has the same width as input[type=text]')
+shouldBe('numberWidth(0, null, null)', 'text.offsetWidth');
+shouldBe('numberWidth(null, 100, null)', 'text.offsetWidth');
+shouldBe('numberWidth(null, null, 100)', 'text.offsetWidth');
+debug('');
+
+debug('If step is any, the input[type=text] has the same width as input[type=text]')
+shouldBe('numberWidth(0, 1, "any")', 'text.offsetWidth');
+shouldBe('numberWidth(0, 10, "any")', 'text.offsetWidth');
+shouldBe('numberWidth(0, 1.1, "any")', 'text.offsetWidth');
+debug('');
+
+debug('The case the inner spin button has border or padding.');
+var borderWidth = 20;
+var paddingWidth = 16;
+shouldBe('numberWidth(0, 10, 1, "with-border")', 'textWidthPlusSpinButtonWidth(2) + borderWidth');
+shouldBe('numberWidth(0, 10, 1, "with-padding")', 'textWidthPlusSpinButtonWidth(2) + paddingWidth');
+shouldBe('numberWidth(0, 10, 1, "with-margin")', 'textWidthPlusSpinButtonWidth(2)');
+shouldBe('numberWidth(0, 10, 1, "with-border with-padding")', 'textWidthPlusSpinButtonWidth(2) + borderWidth + paddingWidth');
+debug('');
+
+debug('The default step does not need to be considered.')
+shouldBe('numberWidth(0, 1, null)', 'textWidthPlusSpinButtonWidth(1)');
+shouldBe('numberWidth(0, 100, null)', 'textWidthPlusSpinButtonWidth(3)');
+shouldBe('numberWidth(-100, 1, null)', 'textWidthPlusSpinButtonWidth(4)');
+shouldBe('numberWidth(0.0, 1.0, null)', 'textWidthPlusSpinButtonWidth(1)');
+shouldBe('numberWidth(0.5, 1.5, null)', 'textWidthPlusSpinButtonWidth(3)');
+shouldBe('numberWidth(-0.5, 1.5, null)', 'textWidthPlusSpinButtonWidth(4)');
+shouldBe('numberWidth(1e+10, 1e+10 + 1, null)', 'textWidthPlusSpinButtonWidth(11)');
+shouldBe('numberWidth(-1e+10, 1e+10 + 1, null)', 'textWidthPlusSpinButtonWidth(12)');
+debug('');
+
+debug('Check the width of a number input when min/max/step is changed variously')
+shouldBe('numberWidth(0, 1, 1)', 'textWidthPlusSpinButtonWidth(1)');
+shouldBe('numberWidth(0, 10, 1)', 'textWidthPlusSpinButtonWidth(2)');
+shouldBe('numberWidth(0, 100, 1)', 'textWidthPlusSpinButtonWidth(3)');
+shouldBe('numberWidth(0, 1000, 1)', 'textWidthPlusSpinButtonWidth(4)');
+shouldBe('numberWidth(0, 10000, 1)', 'textWidthPlusSpinButtonWidth(5)');
+shouldBe('numberWidth(0, 100000, 1)', 'textWidthPlusSpinButtonWidth(6)');
+shouldBe('numberWidth(0, 1000000, 1)', 'textWidthPlusSpinButtonWidth(7)');
+shouldBe('numberWidth(0, 10000000, 1)', 'textWidthPlusSpinButtonWidth(8)');
+shouldBe('numberWidth(0, 100000000, 1)', 'textWidthPlusSpinButtonWidth(9)');
+shouldBe('numberWidth(0, 1000000000, 1)', 'textWidthPlusSpinButtonWidth(10)');
+
+shouldBe('numberWidth(-1, 0, 1)', 'textWidthPlusSpinButtonWidth(2)');
+shouldBe('numberWidth(-10, 0, 1)', 'textWidthPlusSpinButtonWidth(3)');
+shouldBe('numberWidth(-100, 0, 1)', 'textWidthPlusSpinButtonWidth(4)');
+shouldBe('numberWidth(-1000, 0, 1)', 'textWidthPlusSpinButtonWidth(5)');
+shouldBe('numberWidth(-10000, 0, 1)', 'textWidthPlusSpinButtonWidth(6)');
+shouldBe('numberWidth(-100000, 0, 1)', 'textWidthPlusSpinButtonWidth(7)');
+shouldBe('numberWidth(-1000000, 0, 1)', 'textWidthPlusSpinButtonWidth(8)');
+shouldBe('numberWidth(-10000000, 0, 1)', 'textWidthPlusSpinButtonWidth(9)');
+shouldBe('numberWidth(-100000000, 0, 1)', 'textWidthPlusSpinButtonWidth(10)');
+shouldBe('numberWidth(-1000000000, 0, 1)', 'textWidthPlusSpinButtonWidth(11)');
+
+shouldBe('numberWidth(0, 1, 0.5)', 'textWidthPlusSpinButtonWidth(3)');
+shouldBe('numberWidth(0, 1, 0.05)', 'textWidthPlusSpinButtonWidth(4)');
+shouldBe('numberWidth(0, 1, 0.005)', 'textWidthPlusSpinButtonWidth(5)');
+shouldBe('numberWidth(0, 1, 0.0005)', 'textWidthPlusSpinButtonWidth(6)');
+shouldBe('numberWidth(0, 1, 0.00005)', 'textWidthPlusSpinButtonWidth(7)');
+shouldBe('numberWidth(0, 1, 0.000005)', 'textWidthPlusSpinButtonWidth(8)');
+shouldBe('numberWidth(0, 1, 0.0000005)', 'textWidthPlusSpinButtonWidth(9)');
+
+shouldBe('numberWidth(0.5, 1, 1)', 'textWidthPlusSpinButtonWidth(3)');
+shouldBe('numberWidth(0.05, 1, 1)', 'textWidthPlusSpinButtonWidth(4)');
+shouldBe('numberWidth(0.005, 1, 1)', 'textWidthPlusSpinButtonWidth(5)');
+shouldBe('numberWidth(1.5, 2, 1)', 'textWidthPlusSpinButtonWidth(3)');
+shouldBe('numberWidth(1.05, 2, 1)', 'textWidthPlusSpinButtonWidth(4)');
+shouldBe('numberWidth(1.005, 2, 1)', 'textWidthPlusSpinButtonWidth(5)');
+
+debug('')
+
+var successfullyParsed = true;
+</script>
+
+
+<script src=""
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (92588 => 92589)


--- trunk/Source/WebCore/ChangeLog	2011-08-08 08:42:14 UTC (rev 92588)
+++ trunk/Source/WebCore/ChangeLog	2011-08-08 09:16:54 UTC (rev 92589)
@@ -1,3 +1,47 @@
+2011-08-08  Shinya Kawanaka  <[email protected]>
+
+        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
+
+        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.
+
 2011-08-08  Kenichi Ishibashi  <[email protected]>
 
         Should not use C-style cast in CSSParser.cpp

Modified: trunk/Source/WebCore/html/HTMLInputElement.cpp (92588 => 92589)


--- trunk/Source/WebCore/html/HTMLInputElement.cpp	2011-08-08 08:42:14 UTC (rev 92588)
+++ trunk/Source/WebCore/html/HTMLInputElement.cpp	2011-08-08 09:16:54 UTC (rev 92589)
@@ -50,6 +50,7 @@
 #include "KeyboardEvent.h"
 #include "LocalizedStrings.h"
 #include "MouseEvent.h"
+#include "NumberInputType.h"
 #include "Page.h"
 #include "PlatformMouseEvent.h"
 #include "RenderTextControlSingleLine.h"
@@ -804,8 +805,11 @@
     } else if (attr->name() == multipleAttr) {
         m_inputType->multipleAttributeChanged();
         setNeedsValidityCheck();
-    } else if (attr->name() == patternAttr || attr->name() == precisionAttr || attr->name() == stepAttr)
+    } else if (attr->name() == stepAttr) {
+        m_inputType->stepAttributeChanged();
         setNeedsValidityCheck();
+    } else if (attr->name() == patternAttr || attr->name() == precisionAttr)
+        setNeedsValidityCheck();
     else if (attr->name() == disabledAttr) {
         m_inputType->disabledAttributeChanged();
         HTMLTextFormControlElement::parseMappedAttribute(attr);
@@ -994,6 +998,11 @@
     return m_size;
 }
 
+bool HTMLInputElement::sizeShouldIncludeDecoration(int& preferredSize) const
+{
+    return m_inputType->sizeShouldIncludeDecoration(defaultSize, preferredSize);
+}
+
 void HTMLInputElement::copyNonAttributeProperties(const Element* source)
 {
     const HTMLInputElement* sourceElement = static_cast<const HTMLInputElement*>(source);

Modified: trunk/Source/WebCore/html/HTMLInputElement.h (92588 => 92589)


--- trunk/Source/WebCore/html/HTMLInputElement.h	2011-08-08 08:42:14 UTC (rev 92588)
+++ trunk/Source/WebCore/html/HTMLInputElement.h	2011-08-08 09:16:54 UTC (rev 92589)
@@ -131,6 +131,7 @@
     virtual bool isIndeterminate() const { return indeterminate(); }
 
     int size() const;
+    bool sizeShouldIncludeDecoration(int& preferredSize) const;
 
     void setType(const String&);
 

Modified: trunk/Source/WebCore/html/InputType.cpp (92588 => 92589)


--- trunk/Source/WebCore/html/InputType.cpp	2011-08-08 08:42:14 UTC (rev 92588)
+++ trunk/Source/WebCore/html/InputType.cpp	2011-08-08 09:16:54 UTC (rev 92589)
@@ -249,6 +249,12 @@
     return 0;
 }
 
+bool InputType::sizeShouldIncludeDecoration(int defaultSize, int& preferredSize) const
+{
+    preferredSize = element()->size();
+    return false;
+}
+
 bool InputType::stepMismatch(const String&, double) const
 {
     // Non-supported types should be rejected by HTMLInputElement::getAllowedValueStep().
@@ -453,6 +459,10 @@
 {
 }
 
+void InputType::stepAttributeChanged()
+{
+}
+
 bool InputType::canBeSuccessfulSubmitButton()
 {
     return false;

Modified: trunk/Source/WebCore/html/InputType.h (92588 => 92589)


--- trunk/Source/WebCore/html/InputType.h	2011-08-08 08:42:14 UTC (rev 92588)
+++ trunk/Source/WebCore/html/InputType.h	2011-08-08 09:16:54 UTC (rev 92589)
@@ -143,6 +143,7 @@
     virtual double defaultValueForStepUp() const;
     virtual double minimum() const;
     virtual double maximum() const;
+    virtual bool sizeShouldIncludeDecoration(int defaultSize, int& preferredSize) const;
     virtual bool stepMismatch(const String&, double step) const;
     virtual double stepBase() const;
     virtual double stepBaseWithDecimalPlaces(unsigned*) const;
@@ -206,6 +207,7 @@
     virtual RenderObject* createRenderer(RenderArena*, RenderStyle*) const;
     virtual void attach();
     virtual void minOrMaxAttributeChanged();
+    virtual void stepAttributeChanged();
     virtual void altAttributeChanged();
     virtual void srcAttributeChanged();
     virtual void valueChanged();

Modified: trunk/Source/WebCore/html/NumberInputType.cpp (92588 => 92589)


--- trunk/Source/WebCore/html/NumberInputType.cpp	2011-08-08 08:42:14 UTC (rev 92588)
+++ trunk/Source/WebCore/html/NumberInputType.cpp	2011-08-08 09:16:54 UTC (rev 92589)
@@ -53,6 +53,21 @@
 static const double numberDefaultStep = 1.0;
 static const double numberStepScaleFactor = 1.0;
 
+static unsigned lengthBeforeDecimalPoint(double value)
+{
+    // If value is negative, '-' should be counted.
+
+    double absoluteValue = fabs(value);
+    if (absoluteValue < 1)
+        return value < 0 ? 2 : 1;
+
+    unsigned length = static_cast<unsigned>(log10(floor(absoluteValue))) + 1;
+    if (value < 0)
+        length += 1;
+
+    return length;
+}
+
 PassOwnPtr<InputType> NumberInputType::create(HTMLInputElement* element)
 {
     return adoptPtr(new NumberInputType(element));
@@ -121,6 +136,53 @@
     return parseToDouble(element()->fastGetAttribute(maxAttr), numeric_limits<float>::max());
 }
 
+bool NumberInputType::sizeShouldIncludeDecoration(int defaultSize, int& preferredSize) const
+{
+    preferredSize = defaultSize;
+
+    unsigned minValueDecimalPlaces;
+    double minValueDouble;
+    String minValue = element()->fastGetAttribute(minAttr);
+    if (!parseToDoubleForNumberTypeWithDecimalPlaces(minValue, &minValueDouble, &minValueDecimalPlaces))
+        return false;
+
+    unsigned maxValueDecimalPlaces;
+    double maxValueDouble;
+    String maxValue = element()->fastGetAttribute(maxAttr);
+    if (!parseToDoubleForNumberTypeWithDecimalPlaces(maxValue, &maxValueDouble, &maxValueDecimalPlaces))
+        return false;
+
+    if (maxValueDouble < minValueDouble) {
+        maxValueDouble = minValueDouble;
+        maxValueDecimalPlaces = maxValueDecimalPlaces;
+    }
+
+    unsigned stepValueDecimalPlaces;
+    double stepValueDouble;
+    String stepValue = element()->fastGetAttribute(stepAttr);
+    if (equalIgnoringCase(stepValue, "any"))
+        return false;
+    if (!parseToDoubleForNumberTypeWithDecimalPlaces(stepValue, &stepValueDouble, &stepValueDecimalPlaces)) {
+        stepValueDouble = 1;
+        stepValueDecimalPlaces = 0;
+    }
+
+    unsigned length = lengthBeforeDecimalPoint(minValueDouble);
+    length = max(length, lengthBeforeDecimalPoint(maxValueDouble));
+    length = max(length, lengthBeforeDecimalPoint(stepValueDouble));
+
+    unsigned lengthAfterDecimalPoint = minValueDecimalPlaces;
+    lengthAfterDecimalPoint = max(lengthAfterDecimalPoint, maxValueDecimalPlaces);
+    lengthAfterDecimalPoint = max(lengthAfterDecimalPoint, stepValueDecimalPlaces);
+
+    // '.' should be counted if the value has decimal places.
+    if (lengthAfterDecimalPoint > 0)
+        length += lengthAfterDecimalPoint + 1;
+
+    preferredSize = length;
+    return true;
+}
+
 bool NumberInputType::isSteppable() const
 {
     return true;
@@ -274,4 +336,20 @@
     return true;
 }
 
+void NumberInputType::minOrMaxAttributeChanged()
+{
+    InputType::minOrMaxAttributeChanged();
+
+    if (element()->renderer())
+        element()->renderer()->setNeedsLayoutAndPrefWidthsRecalc();
+}
+
+void NumberInputType::stepAttributeChanged()
+{
+    InputType::stepAttributeChanged();
+
+    if (element()->renderer())
+        element()->renderer()->setNeedsLayoutAndPrefWidthsRecalc();
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/html/NumberInputType.h (92588 => 92589)


--- trunk/Source/WebCore/html/NumberInputType.h	2011-08-08 08:42:14 UTC (rev 92588)
+++ trunk/Source/WebCore/html/NumberInputType.h	2011-08-08 09:16:54 UTC (rev 92589)
@@ -51,6 +51,7 @@
     virtual bool supportsRangeLimitation() const;
     virtual double minimum() const;
     virtual double maximum() const;
+    virtual bool sizeShouldIncludeDecoration(int defaultSize, int& preferredSize) const;
     virtual bool isSteppable() const;
     virtual bool stepMismatch(const String&, double) const;
     virtual double stepBase() const;
@@ -72,6 +73,8 @@
     virtual bool shouldRespectSpeechAttribute();
     virtual bool supportsPlaceholder() const;
     virtual bool isNumberField() const;
+    virtual void minOrMaxAttributeChanged();
+    virtual void stepAttributeChanged();
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/rendering/RenderTextControlSingleLine.cpp (92588 => 92589)


--- trunk/Source/WebCore/rendering/RenderTextControlSingleLine.cpp	2011-08-08 08:42:14 UTC (rev 92588)
+++ trunk/Source/WebCore/rendering/RenderTextControlSingleLine.cpp	2011-08-08 09:16:54 UTC (rev 92589)
@@ -389,10 +389,11 @@
 
     return RenderTextControl::getAvgCharWidth(family);
 }
-    
+
 int RenderTextControlSingleLine::preferredContentWidth(float charWidth) const
 {
-    int factor = inputElement()->size();
+    int factor;
+    bool includesDecoration = inputElement()->sizeShouldIncludeDecoration(factor);
     if (factor <= 0)
         factor = 20;
 
@@ -423,6 +424,17 @@
         result += cancelRenderer->borderLeft() + cancelRenderer->borderRight() +
                   cancelRenderer->paddingLeft() + cancelRenderer->paddingRight();
 
+    if (includesDecoration) {
+        HTMLElement* spinButton = innerSpinButtonElement();
+        if (RenderBox* spinRenderer = spinButton ? spinButton->renderBox() : 0) {
+            result += spinRenderer->borderLeft() + spinRenderer->borderRight() +
+                  spinRenderer->paddingLeft() + spinRenderer->paddingRight();
+            // Since the width of spinRenderer is not calculated yet, spinRenderer->width() returns 0.
+            // So computedStyle()->width() is used instead.
+            result += spinButton->computedStyle()->width().value();
+        }
+    }
+
 #if ENABLE(INPUT_SPEECH)
     HTMLElement* speechButton = speechButtonElement();
     if (RenderBox* speechRenderer = speechButton ? speechButton->renderBox() : 0) {
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to