Diff
Modified: trunk/LayoutTests/ChangeLog (137560 => 137561)
--- trunk/LayoutTests/ChangeLog 2012-12-13 02:49:54 UTC (rev 137560)
+++ trunk/LayoutTests/ChangeLog 2012-12-13 03:02:04 UTC (rev 137561)
@@ -1,3 +1,16 @@
+2012-12-12 Kunihiko Sakamoto <ksakam...@chromium.org>
+
+ Milliseconds field of date/time input UI should respect step attribute
+ https://bugs.webkit.org/show_bug.cgi?id=104628
+
+ Reviewed by Kent Tamura.
+
+ * fast/forms/time-multiple-fields/time-multiple-fields-stepup-stepdown-from-renderer-expected.txt:
+ * fast/forms/time-multiple-fields/time-multiple-fields-stepup-stepdown-from-renderer.html:
+ Changed to use eventSender.keyDown() instead of making keydown event because we need delete-key handling.
+ Added new helper function test() and changed stepUp/stepDown to use it.
+ Added test cases for milliseconds field with various step values and step baees.
+
2012-12-12 Julien Chaffraix <jchaffr...@webkit.org>
[CSS Grid Layout] Include paddings and borders into the grid element's logical height / width
Modified: trunk/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-stepup-stepdown-from-renderer-expected.txt (137560 => 137561)
--- trunk/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-stepup-stepdown-from-renderer-expected.txt 2012-12-13 02:49:54 UTC (rev 137560)
+++ trunk/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-stepup-stepdown-from-renderer-expected.txt 2012-12-13 03:02:04 UTC (rev 137561)
@@ -3,12 +3,33 @@
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-Function arguments are (value, step, {min or max}, [stepCount]).
+Function arguments are (value, step, min, max, [keySequence]).
Normal cases
-PASS stepUp("07:13", null, null) is "07:14"
-PASS stepDown("07:13", null, null) is "07:12"
-PASS stepUp("07:13", null, null, 10) is "07:23"
-PASS stepDown("07:13", null, null, 11) is "07:02"
+PASS stepUp("07:13", null, null, null) is "07:14"
+PASS stepDown("07:13", null, null, null) is "07:12"
+PASS test("07:13", null, null, null, ["upArrow", "upArrow", "upArrow"]) is "07:16"
+PASS test("07:13", null, null, null, ["downArrow", "downArrow", "downArrow"]) is "07:10"
+Milliseconds
+PASS stepUp("07:13:00.000", 0.001, null, null) is "07:13:00.001"
+PASS stepDown("07:13:00.001", 0.001, null, null) is "07:13"
+PASS stepUp("07:13:00.999", 0.001, null, null) is "07:13"
+PASS stepDown("07:13:00.000", 0.001, null, null) is "07:13:00.999"
+PASS stepUp("07:13:00.000", 0.250, null, null) is "07:13:00.250"
+PASS stepDown("07:13:00.500", 0.250, null, null) is "07:13:00.250"
+PASS stepUp("07:13:00.750", 0.250, null, null) is "07:13"
+PASS stepDown("07:13:00.000", 0.250, null, null) is "07:13:00.750"
+PASS stepUp("07:13:00.099", 0.100, null, null) is "07:13:00.100"
+PASS stepDown("07:13:00.101", 0.100, null, null) is "07:13:00.100"
+PASS stepUp("07:13:00.500", 0.0001, null, null) is "07:13:00.501"
+PASS stepDown("07:13:00.500", 0.0001, null, null) is "07:13:00.499"
+PASS stepUp("07:13:00.500", 0, null, null) is "07:13:00.501"
+PASS stepDown("07:13:00.500", 0, null, null) is "07:13:00.499"
+PASS stepUp("07:13:00.500", 0.100, "00:00:00.050", null) is "07:13:00.550"
+PASS stepDown("07:13:00.500", 0.100, "00:00:00.050", null) is "07:13:00.450"
+PASS test("07:13:00.500", 0.100, null, null, ["delete", "upArrow"]) is "07:13"
+PASS test("07:13:00.500", 0.100, null, null, ["delete", "downArrow"]) is "07:13:00.900"
+PASS test("07:13:00.500", 0.100, "00:00:00.050", null, ["delete", "upArrow"]) is "07:13:00.050"
+PASS test("07:13:00.500", 0.100, "00:00:00.050", null, ["delete", "downArrow"]) is "07:13:00.950"
PASS successfullyParsed is true
Modified: trunk/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-stepup-stepdown-from-renderer.html (137560 => 137561)
--- trunk/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-stepup-stepdown-from-renderer.html 2012-12-13 02:49:54 UTC (rev 137560)
+++ trunk/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-stepup-stepdown-from-renderer.html 2012-12-13 03:02:04 UTC (rev 137561)
@@ -12,10 +12,11 @@
document.body.appendChild(input);
-function sendKey(keyName) {
- var event = document.createEvent('KeyboardEvent');
- event.initKeyboardEvent('keydown', true, true, document.defaultView, keyName);
- input.dispatchEvent(event);
+function keyDown(key, modifiers)
+{
+ if (!window.eventSender)
+ return;
+ eventSender.keyDown(key, modifiers);
}
function setInputAttributes(min, max, step, value) {
@@ -25,43 +26,56 @@
input.value = value;
}
-function stepUp(value, step, max, optionalStepCount) {
- setInputAttributes(null, max, step, value);
- if (typeof optionalStepCount != "undefined")
- if (optionalStepCount < 0)
- for (var i = 0; i < -optionalStepCount; i++)
- sendKey('Down');
- else
- for (var i = 0; i < optionalStepCount; i++)
- sendKey('Up');
- else
- sendKey('Up');
+function test(value, step, min, max, keySequence) {
+ setInputAttributes(min, max, step, value);
+ for (var i = 0; i < keySequence.length; i++)
+ keyDown(keySequence[i]);
return input.value;
}
-function stepDown(value, step, min, optionalStepCount) {
- setInputAttributes(min, null, step, value);
- if (typeof optionalStepCount != "undefined")
- if (optionalStepCount < 0)
- for (var i = 0; i < -optionalStepCount; i++)
- sendKey('Up');
- else
- for (var i = 0; i < optionalStepCount; i++)
- sendKey('Down');
- else
- sendKey('Down');
- return input.value;
+function stepUp(value, step, min, max) {
+ return test(value,step, min, max, ['upArrow']);
}
+function stepDown(value, step, min, max) {
+ return test(value,step, min, max, ['downArrow']);
+}
+
input.type = 'time';
input.focus();
-sendKey('Right');
-debug('Function arguments are (value, step, {min or max}, [stepCount]).');
+keyDown('rightArrow');
+debug('Function arguments are (value, step, min, max, [keySequence]).');
debug('Normal cases');
-shouldBe('stepUp("07:13", null, null)', '"07:14"');
-shouldBe('stepDown("07:13", null, null)', '"07:12"');
-shouldBe('stepUp("07:13", null, null, 10)', '"07:23"');
-shouldBe('stepDown("07:13", null, null, 11)', '"07:02"');
+shouldBeEqualToString('stepUp("07:13", null, null, null)', '07:14');
+shouldBeEqualToString('stepDown("07:13", null, null, null)', '07:12');
+shouldBeEqualToString('test("07:13", null, null, null, ["upArrow", "upArrow", "upArrow"])', '07:16');
+shouldBeEqualToString('test("07:13", null, null, null, ["downArrow", "downArrow", "downArrow"])', '07:10');
+
+debug('Milliseconds');
+input.step = 0.001;
+keyDown('rightArrow');
+keyDown('rightArrow');
+shouldBeEqualToString('stepUp("07:13:00.000", 0.001, null, null)', '07:13:00.001');
+shouldBeEqualToString('stepDown("07:13:00.001", 0.001, null, null)', '07:13');
+shouldBeEqualToString('stepUp("07:13:00.999", 0.001, null, null)', '07:13');
+shouldBeEqualToString('stepDown("07:13:00.000", 0.001, null, null)', '07:13:00.999');
+shouldBeEqualToString('stepUp("07:13:00.000", 0.250, null, null)', '07:13:00.250');
+shouldBeEqualToString('stepDown("07:13:00.500", 0.250, null, null)', '07:13:00.250');
+shouldBeEqualToString('stepUp("07:13:00.750", 0.250, null, null)', '07:13');
+shouldBeEqualToString('stepDown("07:13:00.000", 0.250, null, null)', '07:13:00.750');
+shouldBeEqualToString('stepUp("07:13:00.099", 0.100, null, null)', '07:13:00.100');
+shouldBeEqualToString('stepDown("07:13:00.101", 0.100, null, null)', '07:13:00.100');
+shouldBeEqualToString('stepUp("07:13:00.500", 0.0001, null, null)', '07:13:00.501');
+shouldBeEqualToString('stepDown("07:13:00.500", 0.0001, null, null)', '07:13:00.499');
+shouldBeEqualToString('stepUp("07:13:00.500", 0, null, null)', '07:13:00.501');
+shouldBeEqualToString('stepDown("07:13:00.500", 0, null, null)', '07:13:00.499');
+shouldBeEqualToString('stepUp("07:13:00.500", 0.100, "00:00:00.050", null)', '07:13:00.550');
+shouldBeEqualToString('stepDown("07:13:00.500", 0.100, "00:00:00.050", null)', '07:13:00.450');
+shouldBeEqualToString('test("07:13:00.500", 0.100, null, null, ["delete", "upArrow"])', '07:13');
+shouldBeEqualToString('test("07:13:00.500", 0.100, null, null, ["delete", "downArrow"])', '07:13:00.900');
+shouldBeEqualToString('test("07:13:00.500", 0.100, "00:00:00.050", null, ["delete", "upArrow"])', '07:13:00.050');
+shouldBeEqualToString('test("07:13:00.500", 0.100, "00:00:00.050", null, ["delete", "downArrow"])', '07:13:00.950');
+
debug('');
document.body.removeChild(input);
</script>
Modified: trunk/Source/WebCore/ChangeLog (137560 => 137561)
--- trunk/Source/WebCore/ChangeLog 2012-12-13 02:49:54 UTC (rev 137560)
+++ trunk/Source/WebCore/ChangeLog 2012-12-13 03:02:04 UTC (rev 137561)
@@ -1,3 +1,32 @@
+2012-12-12 Kunihiko Sakamoto <ksakam...@chromium.org>
+
+ Milliseconds field of date/time input UI should respect step attribute
+ https://bugs.webkit.org/show_bug.cgi?id=104628
+
+ Reviewed by Kent Tamura.
+
+ This patch makes step-up/-down UI of the milliseconds fields respect step attribute
+ in a special case when the step is divisible by 1000 milliseconds.
+
+ Test: fast/forms/time-multiple-fields/time-multiple-fields-stepup-stepdown-from-renderer.html
+
+ * html/shadow/DateTimeEditElement.cpp:
+ (WebCore::DateTimeEditBuilder::visitField):
+ If step of the element (in milliseconds) is divisible by 1000, use it as the step of the milliseconds field. Otherwise, the millisecond field has step 1.
+ * html/shadow/DateTimeFieldElements.cpp:
+ (WebCore::DateTimeMillisecondFieldElement::DateTimeMillisecondFieldElement): Add step and stepBase arguments.
+ (WebCore::DateTimeMillisecondFieldElement::create): Ditto.
+ * html/shadow/DateTimeFieldElements.h:
+ (DateTimeMillisecondFieldElement): Ditto.
+ * html/shadow/DateTimeNumericFieldElement.cpp:
+ (WebCore::DateTimeNumericFieldElement::DateTimeNumericFieldElement): Ditto.
+ (WebCore::DateTimeNumericFieldElement::stepDown): Changed to compute next allowed value using roundDown().
+ (WebCore::DateTimeNumericFieldElement::stepUp): Changed to compute next allowed value using roundUp().
+ (WebCore::DateTimeNumericFieldElement::roundDown): Added.
+ (WebCore::DateTimeNumericFieldElement::roundUp): Added.
+ * html/shadow/DateTimeNumericFieldElement.h:
+ (DateTimeNumericFieldElement): Add m_step and m_stepBase fields.
+
2012-12-12 Julien Chaffraix <jchaffr...@webkit.org>
[CSS Grid Layout] Include paddings and borders into the grid element's logical height / width
Modified: trunk/Source/WebCore/html/shadow/DateTimeEditElement.cpp (137560 => 137561)
--- trunk/Source/WebCore/html/shadow/DateTimeEditElement.cpp 2012-12-13 02:49:54 UTC (rev 137560)
+++ trunk/Source/WebCore/html/shadow/DateTimeEditElement.cpp 2012-12-13 03:02:04 UTC (rev 137561)
@@ -213,7 +213,16 @@
}
case DateTimeFormat::FieldTypeFractionalSecond: {
- RefPtr<DateTimeNumericFieldElement> field = DateTimeMillisecondFieldElement::create(document, m_editElement);
+ ASSERT(!m_parameters.stepRange.step().isZero());
+ int step = 1;
+ int stepBase = 0;
+ const Decimal decimalMsPerSecond(static_cast<int>(msPerSecond));
+
+ if (decimalMsPerSecond.remainder(m_parameters.stepRange.step()).isZero() && m_parameters.stepRange.step().remainder(Decimal(1)).isZero()) {
+ step = static_cast<int>(m_parameters.stepRange.step().toDouble());
+ stepBase = static_cast<int>(m_parameters.stepRange.stepBase().remainder(decimalMsPerSecond).toDouble());
+ }
+ RefPtr<DateTimeNumericFieldElement> field = DateTimeMillisecondFieldElement::create(document, m_editElement, step, stepBase);
m_editElement.addField(field);
if (shouldMillisecondFieldReadOnly()) {
field->setValueAsDate(m_dateValue);
Modified: trunk/Source/WebCore/html/shadow/DateTimeFieldElements.cpp (137560 => 137561)
--- trunk/Source/WebCore/html/shadow/DateTimeFieldElements.cpp 2012-12-13 02:49:54 UTC (rev 137560)
+++ trunk/Source/WebCore/html/shadow/DateTimeFieldElements.cpp 2012-12-13 03:02:04 UTC (rev 137561)
@@ -217,15 +217,15 @@
// ----------------------------
-DateTimeMillisecondFieldElement::DateTimeMillisecondFieldElement(Document* document, FieldOwner& fieldOwner)
- : DateTimeNumericFieldElement(document, fieldOwner, 0, 999, "---")
+DateTimeMillisecondFieldElement::DateTimeMillisecondFieldElement(Document* document, FieldOwner& fieldOwner, int step, int stepBase)
+ : DateTimeNumericFieldElement(document, fieldOwner, 0, 999, "---", step, stepBase)
{
}
-PassRefPtr<DateTimeMillisecondFieldElement> DateTimeMillisecondFieldElement::create(Document* document, FieldOwner& fieldOwner)
+PassRefPtr<DateTimeMillisecondFieldElement> DateTimeMillisecondFieldElement::create(Document* document, FieldOwner& fieldOwner, int step, int stepBase)
{
DEFINE_STATIC_LOCAL(AtomicString, millisecondPsuedoId, ("-webkit-datetime-edit-millisecond-field", AtomicString::ConstructFromLiteral));
- RefPtr<DateTimeMillisecondFieldElement> field = adoptRef(new DateTimeMillisecondFieldElement(document, fieldOwner));
+ RefPtr<DateTimeMillisecondFieldElement> field = adoptRef(new DateTimeMillisecondFieldElement(document, fieldOwner, step, stepBase));
field->initialize(millisecondPsuedoId, AXMillisecondFieldText());
return field.release();
}
Modified: trunk/Source/WebCore/html/shadow/DateTimeFieldElements.h (137560 => 137561)
--- trunk/Source/WebCore/html/shadow/DateTimeFieldElements.h 2012-12-13 02:49:54 UTC (rev 137560)
+++ trunk/Source/WebCore/html/shadow/DateTimeFieldElements.h 2012-12-13 03:02:04 UTC (rev 137561)
@@ -91,10 +91,10 @@
WTF_MAKE_NONCOPYABLE(DateTimeMillisecondFieldElement);
public:
- static PassRefPtr<DateTimeMillisecondFieldElement> create(Document*, FieldOwner&);
+ static PassRefPtr<DateTimeMillisecondFieldElement> create(Document*, FieldOwner&, int step, int stepBase);
private:
- DateTimeMillisecondFieldElement(Document*, FieldOwner&);
+ DateTimeMillisecondFieldElement(Document*, FieldOwner&, int step, int stepBase);
// DateTimeFieldElement functions.
virtual void populateDateTimeFieldsState(DateTimeFieldsState&) OVERRIDE FINAL;
Modified: trunk/Source/WebCore/html/shadow/DateTimeNumericFieldElement.cpp (137560 => 137561)
--- trunk/Source/WebCore/html/shadow/DateTimeNumericFieldElement.cpp 2012-12-13 02:49:54 UTC (rev 137560)
+++ trunk/Source/WebCore/html/shadow/DateTimeNumericFieldElement.cpp 2012-12-13 03:02:04 UTC (rev 137561)
@@ -59,14 +59,18 @@
// ----------------------------
-DateTimeNumericFieldElement::DateTimeNumericFieldElement(Document* document, FieldOwner& fieldOwner, int minimum, int maximum, const String& placeholder)
+DateTimeNumericFieldElement::DateTimeNumericFieldElement(Document* document, FieldOwner& fieldOwner, int minimum, int maximum, const String& placeholder, int step, int stepBase)
: DateTimeFieldElement(document, fieldOwner)
, m_lastDigitCharTime(0)
, m_placeholder(placeholder)
, m_range(minimum, maximum)
, m_value(0)
, m_hasValue(false)
+ , m_step(step)
+ , m_stepBase(stepBase)
{
+ ASSERT(m_step);
+
// We show a direction-neutral string such as "--" as a placeholder. It
// should follow the direction of numeric values.
if (localeForOwner().isRTL()) {
@@ -182,18 +186,18 @@
void DateTimeNumericFieldElement::stepDown()
{
- if (m_hasValue)
- setValueAsInteger(m_value == m_range.minimum ? m_range.maximum : clampValue(m_value - 1), DispatchEvent);
- else
- setValueAsInteger(defaultValueForStepDown(), DispatchEvent);
+ int newValue = roundDown(m_hasValue ? m_value - 1 : defaultValueForStepDown());
+ if (!m_range.isInRange(newValue))
+ newValue = roundDown(m_range.maximum);
+ setValueAsInteger(newValue, DispatchEvent);
}
void DateTimeNumericFieldElement::stepUp()
{
- if (m_hasValue)
- setValueAsInteger(m_value == m_range.maximum ? m_range.minimum : clampValue(m_value + 1), DispatchEvent);
- else
- setValueAsInteger(defaultValueForStepUp(), DispatchEvent);
+ int newValue = roundUp(m_hasValue ? m_value + 1 : defaultValueForStepUp());
+ if (!m_range.isInRange(newValue))
+ newValue = roundUp(m_range.minimum);
+ setValueAsInteger(newValue, DispatchEvent);
}
String DateTimeNumericFieldElement::value() const
@@ -211,6 +215,26 @@
return m_hasValue ? value() : m_placeholder;
}
+int DateTimeNumericFieldElement::roundDown(int n) const
+{
+ n -= m_stepBase;
+ if (n >= 0)
+ n = n / m_step * m_step;
+ else
+ n = -((-n + m_step - 1) / m_step * m_step);
+ return n + m_stepBase;
+}
+
+int DateTimeNumericFieldElement::roundUp(int n) const
+{
+ n -= m_stepBase;
+ if (n >= 0)
+ n = (n + m_step - 1) / m_step * m_step;
+ else
+ n = -(-n / m_step * m_step);
+ return n + m_stepBase;
+}
+
} // namespace WebCore
#endif
Modified: trunk/Source/WebCore/html/shadow/DateTimeNumericFieldElement.h (137560 => 137561)
--- trunk/Source/WebCore/html/shadow/DateTimeNumericFieldElement.h 2012-12-13 02:49:54 UTC (rev 137560)
+++ trunk/Source/WebCore/html/shadow/DateTimeNumericFieldElement.h 2012-12-13 03:02:04 UTC (rev 137561)
@@ -51,7 +51,7 @@
int minimum;
};
- DateTimeNumericFieldElement(Document*, FieldOwner&, int minimum, int maximum, const String& placeholder);
+ DateTimeNumericFieldElement(Document*, FieldOwner&, int minimum, int maximum, const String& placeholder, int step = 1, int stepBase = 0);
int clampValue(int value) const { return m_range.clampValue(value); }
virtual int clampValueForHardLimits(int) const;
@@ -78,12 +78,16 @@
virtual String value() const OVERRIDE FINAL;
String formatValue(int) const;
+ int roundUp(int) const;
+ int roundDown(int) const;
DOMTimeStamp m_lastDigitCharTime;
const String m_placeholder;
const Range m_range;
int m_value;
bool m_hasValue;
+ int m_step;
+ int m_stepBase;
};
} // namespace WebCore