Diff
Modified: trunk/LayoutTests/ChangeLog (134389 => 134390)
--- trunk/LayoutTests/ChangeLog 2012-11-13 10:13:54 UTC (rev 134389)
+++ trunk/LayoutTests/ChangeLog 2012-11-13 10:18:33 UTC (rev 134390)
@@ -1,3 +1,13 @@
+2012-11-12 Kent Tamura <[email protected]>
+
+ Unable to set valid time value to input[type=time] with user interaction in some cases
+ https://bugs.webkit.org/show_bug.cgi?id=102048
+
+ Reviewed by Kentaro Hara.
+
+ * fast/forms/time-multiple-fields/time-multiple-fields-readonly-subfield-expected.txt: Added.
+ * fast/forms/time-multiple-fields/time-multiple-fields-readonly-subfield.html: Added.
+
2012-11-13 Yury Semikhatsky <[email protected]>
Memory instrumentation: MemoryBlock name should not include full path to the block
Added: trunk/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-readonly-subfield-expected.txt (0 => 134390)
--- trunk/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-readonly-subfield-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-readonly-subfield-expected.txt 2012-11-13 10:18:33 UTC (rev 134390)
@@ -0,0 +1,40 @@
+Sub-fields in input[type=time] should be read-only in some cases. This requires window.internals.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+createTimeInput argument order: min, step, value
+
+Milliseconds field:
+PASS isReadOnlyField(createTimeInput("00:00:00.500", step1sec, ""), pseudoMillisecond) is true
+PASS isReadOnlyField(createTimeInput("00:00:00.500", step1sec, "00:00:00.500"), pseudoMillisecond) is true
+PASS isReadOnlyField(createTimeInput("00:00:00.500", step1sec, "00:00:00.600"), pseudoMillisecond) is false
+PASS isReadOnlyField(createTimeInput("00:00:00.000", step1sec, "00:00:00.600"), pseudoMillisecond) is false
+Seconds field:
+PASS isReadOnlyField(createTimeInput("00:00:30", step1min, ""), pseudoSecond) is true
+PASS isReadOnlyField(createTimeInput("00:00:30", step1min, "00:00:30"), pseudoSecond) is true
+PASS isReadOnlyField(createTimeInput("00:00:30.500", step1min, "00:00:30.600"), pseudoSecond) is true
+PASS isReadOnlyField(createTimeInput("00:00:30", step1min, "00:00:35"), pseudoSecond) is false
+PASS isReadOnlyField(createTimeInput("00:00:00", step1min, "00:00:35"), pseudoSecond) is false
+Minutes field:
+PASS isReadOnlyField(createTimeInput("00:30", step1hour, ""), pseudoMinute) is true
+PASS isReadOnlyField(createTimeInput("00:30", step1hour, "00:30"), pseudoMinute) is true
+PASS isReadOnlyField(createTimeInput("00:30", step1hour, "00:35"), pseudoMinute) is false
+PASS isReadOnlyField(createTimeInput("00:00", step1hour, "00:35"), pseudoMinute) is false
+Hour field:
+PASS isReadOnlyField(createTimeInput("11:00", step1day, ""), pseudoHour) is true
+PASS isReadOnlyField(createTimeInput("11:00", step1day, ""), pseudoAMPM) is true
+PASS isReadOnlyField(createTimeInput("11:00", step1day, ""), pseudoMinute) is true
+PASS isReadOnlyField(createTimeInput("11:30", step1day, "11:30"), pseudoHour) is true
+PASS isReadOnlyField(createTimeInput("11:30", step1day, "11:30"), pseudoAMPM) is true
+PASS isReadOnlyField(createTimeInput("11:30", step1day, "11:30"), pseudoMinute) is true
+PASS isReadOnlyField(createTimeInput("11:30", step1day, "12:30"), pseudoHour) is false
+PASS isReadOnlyField(createTimeInput("11:30", step1day, "12:30"), pseudoAMPM) is false
+PASS isReadOnlyField(createTimeInput("11:30", step1day, "12:30"), pseudoMinute) is true
+PASS isReadOnlyField(createTimeInput("00:00", step1day, "12:30"), pseudoHour) is false
+PASS isReadOnlyField(createTimeInput("00:00", step1day, "12:30"), pseudoAMPM) is false
+PASS isReadOnlyField(createTimeInput("00:00", step1day, "12:30"), pseudoMinute) is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Property changes on: trunk/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-readonly-subfield-expected.txt
___________________________________________________________________
Added: svn:eol-style
Added: trunk/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-readonly-subfield.html (0 => 134390)
--- trunk/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-readonly-subfield.html (rev 0)
+++ trunk/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-readonly-subfield.html 2012-11-13 10:18:33 UTC (rev 134390)
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<body>
+<script src=""
+<script>
+function createTimeInput(min, step, value) {
+ var input = document.createElement('input');
+ input.type = 'time';
+ input.min = min;
+ input.step = step;
+ if (value)
+ input.value = value;
+ return input;
+}
+
+function isReadOnlyField(input, pseudo) {
+ var node = internals.youngestShadowRoot(input).querySelector('*[pseudo="' + pseudo + '"]');
+ if (!node)
+ testFailed('Requested node is missing.');
+ return node && node.hasAttribute('readonly');
+}
+
+var pseudoMillisecond = '-webkit-datetime-edit-millisecond-field';
+var pseudoSecond = '-webkit-datetime-edit-second-field';
+var pseudoMinute = '-webkit-datetime-edit-minute-field';
+var pseudoHour = '-webkit-datetime-edit-hour-field';
+var pseudoAMPM = '-webkit-datetime-edit-ampm-field';
+var step1sec = '1';
+var step1min = '60';
+var step1hour = '3600';
+var step1day = '86400';
+
+description('Sub-fields in input[type=time] should be read-only in some cases. This requires window.internals.');
+debug('createTimeInput argument order: min, step, value');
+debug('');
+
+debug('Milliseconds field:');
+shouldBeTrue('isReadOnlyField(createTimeInput("00:00:00.500", step1sec, ""), pseudoMillisecond)');
+shouldBeTrue('isReadOnlyField(createTimeInput("00:00:00.500", step1sec, "00:00:00.500"), pseudoMillisecond)');
+shouldBeFalse('isReadOnlyField(createTimeInput("00:00:00.500", step1sec, "00:00:00.600"), pseudoMillisecond)');
+shouldBeFalse('isReadOnlyField(createTimeInput("00:00:00.000", step1sec, "00:00:00.600"), pseudoMillisecond)');
+
+debug('Seconds field:');
+shouldBeTrue('isReadOnlyField(createTimeInput("00:00:30", step1min, ""), pseudoSecond)');
+shouldBeTrue('isReadOnlyField(createTimeInput("00:00:30", step1min, "00:00:30"), pseudoSecond)');
+shouldBeTrue('isReadOnlyField(createTimeInput("00:00:30.500", step1min, "00:00:30.600"), pseudoSecond)');
+shouldBeFalse('isReadOnlyField(createTimeInput("00:00:30", step1min, "00:00:35"), pseudoSecond)');
+shouldBeFalse('isReadOnlyField(createTimeInput("00:00:00", step1min, "00:00:35"), pseudoSecond)');
+
+debug('Minutes field:');
+shouldBeTrue('isReadOnlyField(createTimeInput("00:30", step1hour, ""), pseudoMinute)');
+shouldBeTrue('isReadOnlyField(createTimeInput("00:30", step1hour, "00:30"), pseudoMinute)');
+shouldBeFalse('isReadOnlyField(createTimeInput("00:30", step1hour, "00:35"), pseudoMinute)');
+shouldBeFalse('isReadOnlyField(createTimeInput("00:00", step1hour, "00:35"), pseudoMinute)');
+
+debug('Hour field:');
+shouldBeTrue('isReadOnlyField(createTimeInput("11:00", step1day, ""), pseudoHour)');
+shouldBeTrue('isReadOnlyField(createTimeInput("11:00", step1day, ""), pseudoAMPM)');
+shouldBeTrue('isReadOnlyField(createTimeInput("11:00", step1day, ""), pseudoMinute)');
+shouldBeTrue('isReadOnlyField(createTimeInput("11:30", step1day, "11:30"), pseudoHour)');
+shouldBeTrue('isReadOnlyField(createTimeInput("11:30", step1day, "11:30"), pseudoAMPM)');
+shouldBeTrue('isReadOnlyField(createTimeInput("11:30", step1day, "11:30"), pseudoMinute)');
+shouldBeFalse('isReadOnlyField(createTimeInput("11:30", step1day, "12:30"), pseudoHour)');
+shouldBeFalse('isReadOnlyField(createTimeInput("11:30", step1day, "12:30"), pseudoAMPM)');
+shouldBeTrue('isReadOnlyField(createTimeInput("11:30", step1day, "12:30"), pseudoMinute)');
+shouldBeFalse('isReadOnlyField(createTimeInput("00:00", step1day, "12:30"), pseudoHour)');
+shouldBeFalse('isReadOnlyField(createTimeInput("00:00", step1day, "12:30"), pseudoAMPM)');
+shouldBeFalse('isReadOnlyField(createTimeInput("00:00", step1day, "12:30"), pseudoMinute)');
+
+</script>
+<script src=""
+</body>
+
Property changes on: trunk/LayoutTests/fast/forms/time-multiple-fields/time-multiple-fields-readonly-subfield.html
___________________________________________________________________
Added: svn:eol-style
Modified: trunk/Source/WebCore/ChangeLog (134389 => 134390)
--- trunk/Source/WebCore/ChangeLog 2012-11-13 10:13:54 UTC (rev 134389)
+++ trunk/Source/WebCore/ChangeLog 2012-11-13 10:18:33 UTC (rev 134390)
@@ -1,3 +1,47 @@
+2012-11-12 Kent Tamura <[email protected]>
+
+ Unable to set valid time value to input[type=time] with user interaction in some cases
+ https://bugs.webkit.org/show_bug.cgi?id=102048
+
+ Reviewed by Kentaro Hara.
+
+ The implementations of shouldMillisecondFieldReadOnly,
+ shouldMinuteFieldReadOnly, and shouldSecondFieldReadOnly were
+ incorrect. We need to check if a part of the minimum value matches to
+ the corresponding part of the current value.
+
+ Also, we had better check hour field editability.
+
+ Test: fast/forms/time-multiple-fields/time-multiple-fields-readonly-subfield.html
+
+ * html/BaseMultipleFieldsDateAndTimeInputType.cpp:
+ (WebCore::BaseMultipleFieldsDateAndTimeInputType::shouldHaveSecondField):
+ Fix a problem that hh:mm:00.sss didn't create a seconds field.
+ * html/shadow/DateTimeEditElement.cpp:
+ (DateTimeEditBuilder): Add shouldHourFieldReadOnly declaration.
+ (WebCore::DateTimeEditBuilder::visitField):
+ Add shouldHourFieldReadOnly check to Hour11/Hour12/Hour23/Hour24/Period fields.
+ (WebCore::DateTimeEditBuilder::shouldHourFieldReadOnly):
+ Added. An hour field should be read-only if the step value is a multiple
+ of a day and the hour part of the minimum value matches to the hour part
+ of the value.
+ (WebCore::DateTimeEditBuilder::shouldMillisecondFieldReadOnly):
+ A millisecond field should be read-only if the step value is a multiple
+ of one second and the millisecond part of the minimum value matches to
+ the millisecond part of the value.
+ (WebCore::DateTimeEditBuilder::shouldMinuteFieldReadOnly):
+ A minute field should be read-only if the step value is a multiple of
+ one hour and the minute part of the minimum value matches to the minute
+ part of the value.
+ (WebCore::DateTimeEditBuilder::shouldSecondFieldReadOnly):
+ A second field should be read-only if the step value is a multiple of
+ one minute and the second part of the minimum value matches to the second
+ part of the value.
+ * platform/Decimal.cpp:
+ (WebCore::Decimal::remainder):
+ Fix a bug in case that the fractional part of quotient is >= 0.5. Also
+ make this matches to C99, C++11, ECMAScript behavior.
+
2012-11-13 Yury Semikhatsky <[email protected]>
Memory instrumentation: MemoryBlock name should not include full path to the block
Modified: trunk/Source/WebCore/html/BaseMultipleFieldsDateAndTimeInputType.cpp (134389 => 134390)
--- trunk/Source/WebCore/html/BaseMultipleFieldsDateAndTimeInputType.cpp 2012-11-13 10:13:54 UTC (rev 134389)
+++ trunk/Source/WebCore/html/BaseMultipleFieldsDateAndTimeInputType.cpp 2012-11-13 10:18:33 UTC (rev 134390)
@@ -409,7 +409,7 @@
bool BaseMultipleFieldsDateAndTimeInputType::shouldHaveSecondField(const DateComponents& date) const
{
StepRange stepRange = createStepRange(AnyIsDefaultStep);
- return date.second()
+ return date.second() || date.millisecond()
|| !stepRange.minimum().remainder(static_cast<int>(msPerMinute)).isZero()
|| !stepRange.step().remainder(static_cast<int>(msPerMinute)).isZero();
}
Modified: trunk/Source/WebCore/html/shadow/DateTimeEditElement.cpp (134389 => 134390)
--- trunk/Source/WebCore/html/shadow/DateTimeEditElement.cpp 2012-11-13 10:13:54 UTC (rev 134389)
+++ trunk/Source/WebCore/html/shadow/DateTimeEditElement.cpp 2012-11-13 10:18:33 UTC (rev 134390)
@@ -56,6 +56,7 @@
private:
bool needMillisecondField() const;
+ bool shouldHourFieldReadOnly() const;
bool shouldMillisecondFieldReadOnly() const;
bool shouldMinuteFieldReadOnly() const;
bool shouldSecondFieldReadOnly() const;
@@ -102,21 +103,45 @@
m_editElement.addField(DateTimeDayFieldElement::create(document, m_editElement, m_parameters.placeholderForDay));
return;
- case DateTimeFormat::FieldTypeHour11:
- m_editElement.addField(DateTimeHourFieldElement::create(document, m_editElement, 0, 11));
+ case DateTimeFormat::FieldTypeHour11: {
+ RefPtr<DateTimeFieldElement> field = DateTimeHourFieldElement::create(document, m_editElement, 0, 11);
+ m_editElement.addField(field);
+ if (shouldHourFieldReadOnly()) {
+ field->setValueAsDate(m_dateValue);
+ field->setReadOnly();
+ }
return;
+ }
- case DateTimeFormat::FieldTypeHour12:
- m_editElement.addField(DateTimeHourFieldElement::create(document, m_editElement, 1, 12));
+ case DateTimeFormat::FieldTypeHour12: {
+ RefPtr<DateTimeFieldElement> field = DateTimeHourFieldElement::create(document, m_editElement, 1, 12);
+ m_editElement.addField(field);
+ if (shouldHourFieldReadOnly()) {
+ field->setValueAsDate(m_dateValue);
+ field->setReadOnly();
+ }
return;
+ }
- case DateTimeFormat::FieldTypeHour23:
- m_editElement.addField(DateTimeHourFieldElement::create(document, m_editElement, 0, 23));
+ case DateTimeFormat::FieldTypeHour23: {
+ RefPtr<DateTimeFieldElement> field = DateTimeHourFieldElement::create(document, m_editElement, 0, 23);
+ m_editElement.addField(field);
+ if (shouldHourFieldReadOnly()) {
+ field->setValueAsDate(m_dateValue);
+ field->setReadOnly();
+ }
return;
+ }
- case DateTimeFormat::FieldTypeHour24:
- m_editElement.addField(DateTimeHourFieldElement::create(document, m_editElement, 1, 24));
+ case DateTimeFormat::FieldTypeHour24: {
+ RefPtr<DateTimeFieldElement> field = DateTimeHourFieldElement::create(document, m_editElement, 1, 24);
+ m_editElement.addField(field);
+ if (shouldHourFieldReadOnly()) {
+ field->setValueAsDate(m_dateValue);
+ field->setReadOnly();
+ }
return;
+ }
case DateTimeFormat::FieldTypeMinute: {
RefPtr<DateTimeNumericFieldElement> field = DateTimeMinuteFieldElement::create(document, m_editElement);
@@ -158,9 +183,15 @@
}
return;
- case DateTimeFormat::FieldTypePeriod:
- m_editElement.addField(DateTimeAMPMFieldElement::create(document, m_editElement, m_parameters.locale.timeAMPMLabels()));
+ case DateTimeFormat::FieldTypePeriod: {
+ RefPtr<DateTimeFieldElement> field = DateTimeAMPMFieldElement::create(document, m_editElement, m_parameters.locale.timeAMPMLabels());
+ m_editElement.addField(field);
+ if (shouldHourFieldReadOnly()) {
+ field->setValueAsDate(m_dateValue);
+ field->setReadOnly();
+ }
return;
+ }
case DateTimeFormat::FieldTypeSecond: {
RefPtr<DateTimeNumericFieldElement> field = DateTimeSecondFieldElement::create(document, m_editElement);
@@ -221,19 +252,31 @@
}
}
+bool DateTimeEditBuilder::shouldHourFieldReadOnly() const
+{
+ const Decimal decimalMsPerDay(static_cast<int>(msPerDay));
+ Decimal hourPartOfMinimum = (stepRange().minimum().abs().remainder(decimalMsPerDay) / static_cast<int>(msPerHour)).floor();
+ return hourPartOfMinimum == m_dateValue.hour() && stepRange().step().remainder(decimalMsPerDay).isZero();
+}
+
bool DateTimeEditBuilder::shouldMillisecondFieldReadOnly() const
{
- return !m_dateValue.millisecond() && stepRange().step().remainder(static_cast<int>(msPerSecond)).isZero();
+ const Decimal decimalMsPerSecond(static_cast<int>(msPerSecond));
+ return stepRange().minimum().abs().remainder(decimalMsPerSecond) == m_dateValue.millisecond() && stepRange().step().remainder(decimalMsPerSecond).isZero();
}
bool DateTimeEditBuilder::shouldMinuteFieldReadOnly() const
{
- return !m_dateValue.minute() && stepRange().step().remainder(static_cast<int>(msPerHour)).isZero();
+ const Decimal decimalMsPerHour(static_cast<int>(msPerHour));
+ Decimal minutePartOfMinimum = (stepRange().minimum().abs().remainder(decimalMsPerHour) / static_cast<int>(msPerMinute)).floor();
+ return minutePartOfMinimum == m_dateValue.minute() && stepRange().step().remainder(decimalMsPerHour).isZero();
}
bool DateTimeEditBuilder::shouldSecondFieldReadOnly() const
{
- return !m_dateValue.second() && stepRange().step().remainder(static_cast<int>(msPerMinute)).isZero();
+ const Decimal decimalMsPerMinute(static_cast<int>(msPerMinute));
+ Decimal secondPartOfMinimum = (stepRange().minimum().abs().remainder(decimalMsPerMinute) / static_cast<int>(msPerSecond)).floor();
+ return secondPartOfMinimum == m_dateValue.second() && stepRange().step().remainder(decimalMsPerMinute).isZero();
}
void DateTimeEditBuilder::visitLiteral(const String& text)
Modified: trunk/Source/WebCore/platform/Decimal.cpp (134389 => 134390)
--- trunk/Source/WebCore/platform/Decimal.cpp 2012-11-13 10:13:54 UTC (rev 134389)
+++ trunk/Source/WebCore/platform/Decimal.cpp 2012-11-13 10:18:33 UTC (rev 134390)
@@ -902,8 +902,8 @@
Decimal Decimal::remainder(const Decimal& rhs) const
{
- const Decimal quotient = (*this / rhs).round();
- return quotient.isSpecial() ? quotient : *this - quotient * rhs;
+ const Decimal quotient = *this / rhs;
+ return quotient.isSpecial() ? quotient : *this - (quotient.isNegative() ? quotient.ceiling() : quotient.floor()) * rhs;
}
Decimal Decimal::round() const
Modified: trunk/Source/WebKit/chromium/ChangeLog (134389 => 134390)
--- trunk/Source/WebKit/chromium/ChangeLog 2012-11-13 10:13:54 UTC (rev 134389)
+++ trunk/Source/WebKit/chromium/ChangeLog 2012-11-13 10:18:33 UTC (rev 134390)
@@ -1,3 +1,19 @@
+2012-11-12 Kent Tamura <[email protected]>
+
+ Unable to set valid time value to input[type=time] with user interaction in some cases
+ https://bugs.webkit.org/show_bug.cgi?id=102048
+
+ Reviewed by Kentaro Hara.
+
+ * tests/DecimalTest.cpp:
+ (TEST_F): Update and add tests.
+ 2.1 % 3 should be 2.1
+ 10 % -3 should be 1
+ -10 % -3 should be -1
+ 3.6 % 1.3 should be 1
+ 500 % 1000 should be 500
+ -500 % 1000 should be -500
+
2012-11-12 Min Qin <[email protected]>
Fix windowRect calculation for webplugin due to page scale factors
Modified: trunk/Source/WebKit/chromium/tests/DecimalTest.cpp (134389 => 134390)
--- trunk/Source/WebKit/chromium/tests/DecimalTest.cpp 2012-11-13 10:13:54 UTC (rev 134389)
+++ trunk/Source/WebKit/chromium/tests/DecimalTest.cpp 2012-11-13 10:18:33 UTC (rev 134390)
@@ -897,13 +897,17 @@
TEST_F(DecimalTest, Remainder)
{
- EXPECT_EQ(encode(9, -1, Negative), encode(21, -1, Positive).remainder(3));
+ EXPECT_EQ(encode(21, -1, Positive), encode(21, -1, Positive).remainder(3));
EXPECT_EQ(Decimal(1), Decimal(10).remainder(3));
+ EXPECT_EQ(Decimal(1), Decimal(10).remainder(-3));
EXPECT_EQ(encode(1, 0, Negative), Decimal(-10).remainder(3));
+ EXPECT_EQ(Decimal(-1), Decimal(-10).remainder(-3));
EXPECT_EQ(encode(2, -1, Positive), encode(102, -1, Positive).remainder(1));
EXPECT_EQ(encode(1, -1, Positive), Decimal(10).remainder(encode(3, -1, Positive)));
- EXPECT_EQ(encode(3, -1, Negative), encode(36, -1, Positive).remainder(encode(13, -1, Positive)));
+ EXPECT_EQ(Decimal(1), encode(36, -1, Positive).remainder(encode(13, -1, Positive)));
EXPECT_EQ(encode(1, 87, Positive), (encode(1234, 100, Positive).remainder(Decimal(3))));
+ EXPECT_EQ(Decimal(500), (Decimal(500).remainder(1000)));
+ EXPECT_EQ(Decimal(-500), (Decimal(-500).remainder(1000)));
}
TEST_F(DecimalTest, RemainderBigExponent)