Add clear button to date/time input types
https://bugs.webkit.org/show_bug.cgi?id=111319

Reviewed by Kent Tamura.

Source/WebCore:

We want to remove the clear button from the calendar picker (Bug 109439)
so we are adding the clear button to the right side of the input element.

Tests: fast/forms/date-multiple-fields/date-multiple-fields-clearbutton-change-and-input-events.html
       fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-clearbutton-change-and-input-events.html
       fast/forms/month-multiple-fields/month-multiple-fields-clearbutton-change-and-input-events.html
       fast/forms/time-multiple-fields/time-multiple-fields-clearbutton-change-and-input-events.html
       fast/forms/week-multiple-fields/week-multiple-fields-clearbutton-change-and-input-events.html

* CMakeLists.txt: Added ClearButtonElement.cpp
* GNUmakefile.list.am: Ditto.
* Target.pri: Ditto.
* WebCore.gypi: Ditto.
* WebCore.vcproj/WebCore.vcproj: Ditto.
* WebCore.vcxproj/WebCore.vcxproj: Ditto.
* WebCore.vcxproj/WebCore.vcxproj.filters: Ditto.
* WebCore.xcodeproj/project.pbxproj: Ditto.
* css/html.css:
(input::-webkit-clear-button): Styles for the clear button.
* html/BaseMultipleFieldsDateAndTimeInputType.cpp:
(WebCore::BaseMultipleFieldsDateAndTimeInputType::editControlValueChanged):
(WebCore::BaseMultipleFieldsDateAndTimeInputType::BaseMultipleFieldsDateAndTimeInputType):
(WebCore::BaseMultipleFieldsDateAndTimeInputType::~BaseMultipleFieldsDateAndTimeInputType):
(WebCore::BaseMultipleFieldsDateAndTimeInputType::createShadowSubtree):
(WebCore::BaseMultipleFieldsDateAndTimeInputType::destroyShadowSubtree):
(WebCore::BaseMultipleFieldsDateAndTimeInputType::disabledAttributeChanged):
(WebCore::BaseMultipleFieldsDateAndTimeInputType::requiredAttributeChanged): Hide clear button if the value is required.
(WebCore):
(WebCore::BaseMultipleFieldsDateAndTimeInputType::readonlyAttributeChanged):
(WebCore::BaseMultipleFieldsDateAndTimeInputType::updateInnerTextValue):
(WebCore::BaseMultipleFieldsDateAndTimeInputType::focusAndSelectClearButtonOwner): Called on mouse down on clear button.
(WebCore::BaseMultipleFieldsDateAndTimeInputType::shouldClearButtonRespondToMouseEvents):
(WebCore::BaseMultipleFieldsDateAndTimeInputType::clearValue):
(WebCore::BaseMultipleFieldsDateAndTimeInputType::updateClearButtonVisibility): We want to hide the clear button if the value is required or the value is empty.
* html/BaseMultipleFieldsDateAndTimeInputType.h:
(BaseMultipleFieldsDateAndTimeInputType):
* html/HTMLInputElement.cpp:
(WebCore::HTMLInputElement::updateClearButtonVisibility):
(WebCore):
(WebCore::HTMLInputElement::requiredAttributeChanged):
* html/HTMLInputElement.h:
(HTMLInputElement):
* html/InputType.cpp:
(WebCore::InputType::requiredAttributeChanged): Notifies the InputType that the required attribute has changed.
(WebCore):
(WebCore::InputType::updateClearButtonVisibility):
* html/InputType.h:
(InputType):
* html/shadow/ClearButtonElement.cpp: Added.
(WebCore):
(WebCore::ClearButtonElement::ClearButtonElement):
(WebCore::ClearButtonElement::create):
(WebCore::ClearButtonElement::detach):
(WebCore::ClearButtonElement::releaseCapture): Stop capturing mouse events.
(WebCore::ClearButtonElement::defaultEventHandler):
* html/shadow/ClearButtonElement.h: Added.
(WebCore):
(ClearButtonElement):
(ClearButtonOwner):
(WebCore::ClearButtonElement::ClearButtonOwner::~ClearButtonOwner):
(WebCore::ClearButtonElement::removeClearButtonOwner):
(WebCore::ClearButtonElement::isMouseFocusable):

LayoutTests:

* fast/forms/date-multiple-fields/date-multiple-fields-clearbutton-change-and-input-events-expected.txt: Added.
* fast/forms/date-multiple-fields/date-multiple-fields-clearbutton-change-and-input-events.html: Added.
* fast/forms/date-multiple-fields/date-multiple-fields-mouse-events-expected.txt:
* fast/forms/date-multiple-fields/date-multiple-fields-mouse-events.html:
* fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-clearbutton-change-and-input-events-expected.txt: Added.
* fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-clearbutton-change-and-input-events.html: Added.
* fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-mouse-events-expected.txt:
* fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-mouse-events.html:
* fast/forms/month-multiple-fields/month-multiple-fields-clearbutton-change-and-input-events-expected.txt: Added.
* fast/forms/month-multiple-fields/month-multiple-fields-clearbutton-change-and-input-events.html: Added.
* fast/forms/month-multiple-fields/month-multiple-fields-mouse-events-expected.txt:
* fast/forms/month-multiple-fields/month-multiple-fields-mouse-events.html:
* fast/forms/resources/common-clearbutton-change-and-input-events.js: Added.
(.testInput.onchange):
(.testInput.oninput):
(testClearButtonChangeAndInputEvents):
* fast/forms/time-multiple-fields/time-multiple-fields-clearbutton-change-and-input-events-expected.txt: Added.
* fast/forms/time-multiple-fields/time-multiple-fields-clearbutton-change-and-input-events.html: Added.
* fast/forms/time-multiple-fields/time-multiple-fields-mouse-events-expected.txt:
* fast/forms/time-multiple-fields/time-multiple-fields-mouse-events.html:
* fast/forms/time-multiple-fields/time-multiple-fields-narrow-width-scroll.html:
* fast/forms/week-multiple-fields/week-multiple-fields-clearbutton-change-and-input-events-expected.txt: Added.
* fast/forms/week-multiple-fields/week-multiple-fields-clearbutton-change-and-input-events.html: Added.
* fast/forms/week-multiple-fields/week-multiple-fields-mouse-events-expected.txt:
* fast/forms/week-multiple-fields/week-multiple-fields-mouse-events.html:
* platform/chromium/TestExpectations:


git-svn-id: svn://svn.chromium.org/blink/trunk@145055 bbb929c8-8fbe-4397-9dbb-9b2b20218538
diff --git a/Source/WebCore/CMakeLists.txt b/Source/WebCore/CMakeLists.txt
index 02882ae..de58a2a 100644
--- a/Source/WebCore/CMakeLists.txt
+++ b/Source/WebCore/CMakeLists.txt
@@ -1569,6 +1569,7 @@
     html/parser/XSSAuditor.cpp
     html/parser/XSSAuditorDelegate.cpp
 
+    html/shadow/ClearButtonElement.cpp
     html/shadow/ContentDistributor.cpp
     html/shadow/ContentSelectorQuery.cpp
     html/shadow/DateTimeEditElement.cpp
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 91b2911..89c97ac 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,73 @@
+2013-03-07  Keishi Hattori  <keishi@webkit.org>
+
+        Add clear button to date/time input types
+        https://bugs.webkit.org/show_bug.cgi?id=111319
+
+        Reviewed by Kent Tamura.
+
+        We want to remove the clear button from the calendar picker (Bug 109439)
+        so we are adding the clear button to the right side of the input element.
+
+        Tests: fast/forms/date-multiple-fields/date-multiple-fields-clearbutton-change-and-input-events.html
+               fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-clearbutton-change-and-input-events.html
+               fast/forms/month-multiple-fields/month-multiple-fields-clearbutton-change-and-input-events.html
+               fast/forms/time-multiple-fields/time-multiple-fields-clearbutton-change-and-input-events.html
+               fast/forms/week-multiple-fields/week-multiple-fields-clearbutton-change-and-input-events.html
+
+        * CMakeLists.txt: Added ClearButtonElement.cpp
+        * GNUmakefile.list.am: Ditto.
+        * Target.pri: Ditto.
+        * WebCore.gypi: Ditto.
+        * WebCore.vcproj/WebCore.vcproj: Ditto.
+        * WebCore.vcxproj/WebCore.vcxproj: Ditto.
+        * WebCore.vcxproj/WebCore.vcxproj.filters: Ditto.
+        * WebCore.xcodeproj/project.pbxproj: Ditto.
+        * css/html.css:
+        (input::-webkit-clear-button): Styles for the clear button.
+        * html/BaseMultipleFieldsDateAndTimeInputType.cpp:
+        (WebCore::BaseMultipleFieldsDateAndTimeInputType::editControlValueChanged):
+        (WebCore::BaseMultipleFieldsDateAndTimeInputType::BaseMultipleFieldsDateAndTimeInputType):
+        (WebCore::BaseMultipleFieldsDateAndTimeInputType::~BaseMultipleFieldsDateAndTimeInputType):
+        (WebCore::BaseMultipleFieldsDateAndTimeInputType::createShadowSubtree):
+        (WebCore::BaseMultipleFieldsDateAndTimeInputType::destroyShadowSubtree):
+        (WebCore::BaseMultipleFieldsDateAndTimeInputType::disabledAttributeChanged):
+        (WebCore::BaseMultipleFieldsDateAndTimeInputType::requiredAttributeChanged): Hide clear button if the value is required.
+        (WebCore):
+        (WebCore::BaseMultipleFieldsDateAndTimeInputType::readonlyAttributeChanged):
+        (WebCore::BaseMultipleFieldsDateAndTimeInputType::updateInnerTextValue):
+        (WebCore::BaseMultipleFieldsDateAndTimeInputType::focusAndSelectClearButtonOwner): Called on mouse down on clear button.
+        (WebCore::BaseMultipleFieldsDateAndTimeInputType::shouldClearButtonRespondToMouseEvents):
+        (WebCore::BaseMultipleFieldsDateAndTimeInputType::clearValue):
+        (WebCore::BaseMultipleFieldsDateAndTimeInputType::updateClearButtonVisibility): We want to hide the clear button if the value is required or the value is empty.
+        * html/BaseMultipleFieldsDateAndTimeInputType.h:
+        (BaseMultipleFieldsDateAndTimeInputType):
+        * html/HTMLInputElement.cpp:
+        (WebCore::HTMLInputElement::updateClearButtonVisibility):
+        (WebCore):
+        (WebCore::HTMLInputElement::requiredAttributeChanged):
+        * html/HTMLInputElement.h:
+        (HTMLInputElement):
+        * html/InputType.cpp:
+        (WebCore::InputType::requiredAttributeChanged): Notifies the InputType that the required attribute has changed.
+        (WebCore):
+        (WebCore::InputType::updateClearButtonVisibility):
+        * html/InputType.h:
+        (InputType):
+        * html/shadow/ClearButtonElement.cpp: Added.
+        (WebCore):
+        (WebCore::ClearButtonElement::ClearButtonElement):
+        (WebCore::ClearButtonElement::create):
+        (WebCore::ClearButtonElement::detach):
+        (WebCore::ClearButtonElement::releaseCapture): Stop capturing mouse events.
+        (WebCore::ClearButtonElement::defaultEventHandler):
+        * html/shadow/ClearButtonElement.h: Added.
+        (WebCore):
+        (ClearButtonElement):
+        (ClearButtonOwner):
+        (WebCore::ClearButtonElement::ClearButtonOwner::~ClearButtonOwner):
+        (WebCore::ClearButtonElement::removeClearButtonOwner):
+        (WebCore::ClearButtonElement::isMouseFocusable):
+
 2013-03-07  Eugene Klyuchnikov  <eustas@chromium.org>
 
         Web Inspector: Refactorings: Prepare SuggestBox for reuse.
diff --git a/Source/WebCore/GNUmakefile.list.am b/Source/WebCore/GNUmakefile.list.am
index f859f0b..9f456fd 100644
--- a/Source/WebCore/GNUmakefile.list.am
+++ b/Source/WebCore/GNUmakefile.list.am
@@ -3661,6 +3661,8 @@
 	Source/WebCore/html/parser/XSSAuditorDelegate.h \
 	Source/WebCore/html/shadow/PickerIndicatorElement.cpp \
 	Source/WebCore/html/shadow/PickerIndicatorElement.h \
+	Source/WebCore/html/shadow/ClearButtonElement.cpp \
+	Source/WebCore/html/shadow/ClearButtonElement.h \
 	Source/WebCore/html/shadow/ContentDistributor.cpp \
 	Source/WebCore/html/shadow/ContentDistributor.h \
 	Source/WebCore/html/shadow/ContentSelectorQuery.cpp \
diff --git a/Source/WebCore/Target.pri b/Source/WebCore/Target.pri
index 41c0eb7..1b655fb 100644
--- a/Source/WebCore/Target.pri
+++ b/Source/WebCore/Target.pri
@@ -751,6 +751,7 @@
     html/parser/TextViewSourceParser.cpp \
     html/parser/XSSAuditor.cpp \
     html/parser/XSSAuditorDelegate.cpp \
+    html/shadow/ClearButtonElement.cpp \
     html/shadow/ContentDistributor.cpp \
     html/shadow/ContentSelectorQuery.cpp \
     html/shadow/DateTimeEditElement.cpp \
diff --git a/Source/WebCore/WebCore.gypi b/Source/WebCore/WebCore.gypi
index d2c3497..fcc1dbe 100644
--- a/Source/WebCore/WebCore.gypi
+++ b/Source/WebCore/WebCore.gypi
@@ -3547,6 +3547,8 @@
             'html/parser/XSSAuditorDelegate.h',
             'html/shadow/PickerIndicatorElement.cpp',
             'html/shadow/PickerIndicatorElement.h',
+            'html/shadow/ClearButtonElement.cpp',
+            'html/shadow/ClearButtonElement.h',
             'html/shadow/ContentDistributor.cpp',
             'html/shadow/ContentDistributor.h',
             'html/shadow/ContentSelectorQuery.cpp',
diff --git a/Source/WebCore/WebCore.vcproj/WebCore.vcproj b/Source/WebCore/WebCore.vcproj/WebCore.vcproj
index 8443f9e..edd0015 100755
--- a/Source/WebCore/WebCore.vcproj/WebCore.vcproj
+++ b/Source/WebCore/WebCore.vcproj/WebCore.vcproj
@@ -65246,6 +65246,14 @@
 				Name="shadow"
 				>
 				<File
+					RelativePath="..\html\shadow\ClearButtonElement.cpp"
+					>
+				</File>
+				<File
+					RelativePath="..\html\shadow\ClearButtonElement.h"
+					>
+				</File>
+				<File
 					RelativePath="..\html\shadow\ContentDistributor.cpp"
 					>
 				</File>
diff --git a/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj b/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj
index f7c69e8..c1eff3b 100644
--- a/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj
+++ b/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj
@@ -6939,6 +6939,7 @@
     <ClCompile Include="..\html\parser\TextViewSourceParser.cpp" />
     <ClCompile Include="..\html\parser\XSSAuditor.cpp" />
     <ClCompile Include="..\html\parser\XSSAuditorDelegate.cpp" />
+    <ClCompile Include="..\html\shadow\ClearButtonElement.cpp" />
     <ClCompile Include="..\html\shadow\ContentDistributor.cpp" />
     <ClCompile Include="..\html\shadow\ContentSelectorQuery.cpp" />
     <ClCompile Include="..\html\shadow\DateTimeEditElement.cpp" />
@@ -10399,6 +10400,7 @@
     <ClInclude Include="..\html\parser\TextViewSourceParser.h" />
     <ClInclude Include="..\html\parser\XSSAuditor.h" />
     <ClInclude Include="..\html\parser\XSSAuditorDelegate.h" />
+    <ClInclude Include="..\html\shadow\ClearButtonElement.h" />
     <ClInclude Include="..\html\shadow\ContentDistributor.h" />
     <ClInclude Include="..\html\shadow\ContentSelectorQuery.h" />
     <ClInclude Include="..\html\shadow\DateTimeEditElement.h" />
diff --git a/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters b/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters
index 7839c0c..c6c9900 100644
--- a/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters
+++ b/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters
@@ -5700,6 +5700,9 @@
     <ClCompile Include="..\html\parser\XSSAuditorDelegate.cpp">
       <Filter>html\parser</Filter>
     </ClCompile>
+    <ClCompile Include="..\html\shadow\ClearButtonElement.cpp">
+      <Filter>html\shadow</Filter>
+    </ClCompile>
     <ClCompile Include="..\html\shadow\ContentDistributor.cpp">
       <Filter>html\shadow</Filter>
     </ClCompile>
@@ -12645,6 +12648,9 @@
     <ClInclude Include="..\html\parser\XSSAuditorDelegate.h">
       <Filter>html\parser</Filter>
     </ClInclude>
+    <ClInclude Include="..\html\shadow\ClearButtonElement.h">
+      <Filter>html\shadow</Filter>
+    </ClInclude>
     <ClInclude Include="..\html\shadow\ContentDistributor.h">
       <Filter>html\shadow</Filter>
     </ClInclude>
diff --git a/Source/WebCore/WebCore.xcodeproj/project.pbxproj b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
index 8d8fb0a..7c993c2 100644
--- a/Source/WebCore/WebCore.xcodeproj/project.pbxproj
+++ b/Source/WebCore/WebCore.xcodeproj/project.pbxproj
@@ -5936,6 +5936,8 @@
 		C375D7FD16639519006184AB /* TypeAhead.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C375D7FB16639519006184AB /* TypeAhead.cpp */; };
 		C375D7FE16639519006184AB /* TypeAhead.h in Headers */ = {isa = PBXBuildFile; fileRef = C375D7FC16639519006184AB /* TypeAhead.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		C37CDEBD149EF2030042090D /* ColorChooserClient.h in Headers */ = {isa = PBXBuildFile; fileRef = C37CDEBC149EF2030042090D /* ColorChooserClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		C37DF8EF16E746710079A0EB /* ClearButtonElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C37DF8ED16E746710079A0EB /* ClearButtonElement.cpp */; };
+		C37DF8F016E746710079A0EB /* ClearButtonElement.h in Headers */ = {isa = PBXBuildFile; fileRef = C37DF8EE16E746710079A0EB /* ClearButtonElement.h */; };
 		C3CF17A415B0063F00276D39 /* IdTargetObserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C3CF17A015B0063F00276D39 /* IdTargetObserver.cpp */; };
 		C3CF17A515B0063F00276D39 /* IdTargetObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = C3CF17A115B0063F00276D39 /* IdTargetObserver.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		C3CF17A615B0063F00276D39 /* IdTargetObserverRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C3CF17A215B0063F00276D39 /* IdTargetObserverRegistry.cpp */; };
@@ -13564,6 +13566,8 @@
 		C375D7FB16639519006184AB /* TypeAhead.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TypeAhead.cpp; sourceTree = "<group>"; };
 		C375D7FC16639519006184AB /* TypeAhead.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypeAhead.h; sourceTree = "<group>"; };
 		C37CDEBC149EF2030042090D /* ColorChooserClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ColorChooserClient.h; sourceTree = "<group>"; };
+		C37DF8ED16E746710079A0EB /* ClearButtonElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ClearButtonElement.cpp; sourceTree = "<group>"; };
+		C37DF8EE16E746710079A0EB /* ClearButtonElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ClearButtonElement.h; sourceTree = "<group>"; };
 		C3CF17A015B0063F00276D39 /* IdTargetObserver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IdTargetObserver.cpp; sourceTree = "<group>"; };
 		C3CF17A115B0063F00276D39 /* IdTargetObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IdTargetObserver.h; sourceTree = "<group>"; };
 		C3CF17A215B0063F00276D39 /* IdTargetObserverRegistry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IdTargetObserverRegistry.cpp; sourceTree = "<group>"; };
@@ -15611,6 +15615,8 @@
 		4150F9ED12B6E0990008C860 /* shadow */ = {
 			isa = PBXGroup;
 			children = (
+				C37DF8ED16E746710079A0EB /* ClearButtonElement.cpp */,
+				C37DF8EE16E746710079A0EB /* ClearButtonElement.h */,
 				57B7919F14C6A62900F202D1 /* ContentDistributor.cpp */,
 				57B791A014C6A62900F202D1 /* ContentDistributor.h */,
 				57B791A114C6A62900F202D1 /* ContentSelectorQuery.cpp */,
@@ -23474,6 +23480,7 @@
 				14D824080AF93AEB0004F057 /* ChromeClient.h in Headers */,
 				4ACBC0BF12713CBD0094F9B2 /* ClassList.h in Headers */,
 				BC904B770D10998F00680D32 /* ClassNodeList.h in Headers */,
+				C37DF8F016E746710079A0EB /* ClearButtonElement.h in Headers */,
 				BCC0657E0F3CE1B700CD2D87 /* ClientRect.h in Headers */,
 				BCC065810F3CE1B700CD2D87 /* ClientRectList.h in Headers */,
 				85031B3E0A44EFC700F992E0 /* Clipboard.h in Headers */,
@@ -27181,6 +27188,7 @@
 				ABAF22080C03B1C700B0BCF0 /* ChromeMac.mm in Sources */,
 				4ACBC0BE12713CBD0094F9B2 /* ClassList.cpp in Sources */,
 				BC904B760D10998F00680D32 /* ClassNodeList.cpp in Sources */,
+				C37DF8EF16E746710079A0EB /* ClearButtonElement.cpp in Sources */,
 				BCC0657D0F3CE1B700CD2D87 /* ClientRect.cpp in Sources */,
 				BCC065800F3CE1B700CD2D87 /* ClientRectList.cpp in Sources */,
 				A784941B0B5FE507001E237A /* Clipboard.cpp in Sources */,
diff --git a/Source/WebCore/css/html.css b/Source/WebCore/css/html.css
index 9ccb945..85f1a11 100644
--- a/Source/WebCore/css/html.css
+++ b/Source/WebCore/css/html.css
@@ -450,6 +450,14 @@
     direction: ltr;
 }
 
+input::-webkit-clear-button {
+    -webkit-appearance: searchfield-cancel-button;
+    display: inline-block;
+    -webkit-box-flex: 0;
+    -webkit-user-modify: read-only !important;
+    margin-left: 2px;
+}
+
 input[type="search"]::-webkit-search-cancel-button {
     -webkit-appearance: searchfield-cancel-button;
     display: block;
diff --git a/Source/WebCore/html/BaseMultipleFieldsDateAndTimeInputType.cpp b/Source/WebCore/html/BaseMultipleFieldsDateAndTimeInputType.cpp
index fb98b58..f385a8d 100644
--- a/Source/WebCore/html/BaseMultipleFieldsDateAndTimeInputType.cpp
+++ b/Source/WebCore/html/BaseMultipleFieldsDateAndTimeInputType.cpp
@@ -86,6 +86,7 @@
         input->dispatchFormControlChangeEvent();
     }
     input->notifyFormStateChanged();
+    input->updateClearButtonVisibility();
 }
 
 bool BaseMultipleFieldsDateAndTimeInputType::hasCustomFocusLogic() const
@@ -162,6 +163,7 @@
     : BaseDateAndTimeInputType(element)
     , m_dateTimeEditElement(0)
     , m_spinButtonElement(0)
+    , m_clearButton(0)
     , m_pickerIndicatorElement(0)
     , m_pickerIndicatorIsVisible(false)
     , m_pickerIndicatorIsAlwaysVisible(false)
@@ -172,6 +174,8 @@
 {
     if (m_spinButtonElement)
         m_spinButtonElement->removeSpinButtonOwner();
+    if (m_clearButton)
+        m_clearButton->removeClearButtonOwner();
     if (m_dateTimeEditElement)
         m_dateTimeEditElement->removeEditControlOwner();
     if (m_pickerIndicatorElement)
@@ -219,6 +223,10 @@
     container->appendChild(m_dateTimeEditElement);
     updateInnerTextValue();
 
+    RefPtr<ClearButtonElement> clearButton = ClearButtonElement::create(document, *this);
+    m_clearButton = clearButton.get();
+    container->appendChild(clearButton);
+
     RefPtr<SpinButtonElement> spinButton = SpinButtonElement::create(document, *this);
     m_spinButtonElement = spinButton.get();
     container->appendChild(spinButton);
@@ -248,6 +256,10 @@
         m_spinButtonElement->removeSpinButtonOwner();
         m_spinButtonElement = 0;
     }
+    if (m_clearButton) {
+        m_clearButton->removeClearButtonOwner();
+        m_clearButton = 0;
+    }
     if (m_dateTimeEditElement) {
         m_dateTimeEditElement->removeEditControlOwner();
         m_dateTimeEditElement = 0;
@@ -287,10 +299,17 @@
 void BaseMultipleFieldsDateAndTimeInputType::disabledAttributeChanged()
 {
     m_spinButtonElement->releaseCapture();
+    m_clearButton->releaseCapture();
     if (m_dateTimeEditElement)
         m_dateTimeEditElement->disabledStateChanged();
 }
 
+void BaseMultipleFieldsDateAndTimeInputType::requiredAttributeChanged()
+{
+    m_clearButton->releaseCapture();
+    updateClearButtonVisibility();
+}
+
 void BaseMultipleFieldsDateAndTimeInputType::handleKeydownEvent(KeyboardEvent* event)
 {
     Document* document = element()->document();
@@ -332,6 +351,7 @@
 void BaseMultipleFieldsDateAndTimeInputType::readonlyAttributeChanged()
 {
     m_spinButtonElement->releaseCapture();
+    m_clearButton->releaseCapture();
     if (m_dateTimeEditElement)
         m_dateTimeEditElement->readOnlyStateChanged();
 }
@@ -394,6 +414,7 @@
         m_dateTimeEditElement->setValueAsDate(layoutParameters, date);
     else
         m_dateTimeEditElement->setEmptyValue(layoutParameters, date);
+    updateClearButtonVisibility();
 }
 
 #if ENABLE(DATALIST_ELEMENT)
@@ -449,6 +470,34 @@
         || !stepRange.step().remainder(static_cast<int>(msPerMinute)).isZero();
 }
 
+void BaseMultipleFieldsDateAndTimeInputType::focusAndSelectClearButtonOwner()
+{
+    element()->focus();
+}
+
+bool BaseMultipleFieldsDateAndTimeInputType::shouldClearButtonRespondToMouseEvents()
+{
+    return !element()->isDisabledOrReadOnly() && !element()->isRequired();
+}
+
+void BaseMultipleFieldsDateAndTimeInputType::clearValue()
+{
+    RefPtr<HTMLInputElement> input(element());
+    input->setValue("", DispatchInputAndChangeEvent);
+    input->updateClearButtonVisibility();
+}
+
+void BaseMultipleFieldsDateAndTimeInputType::updateClearButtonVisibility()
+{
+    if (!m_clearButton)
+        return;
+
+    if (element()->isRequired() || !m_dateTimeEditElement->anyEditableFieldsHaveValues())
+        m_clearButton->setInlineStyleProperty(CSSPropertyVisibility, CSSValueHidden);
+    else
+        m_clearButton->removeInlineStyleProperty(CSSPropertyVisibility);
+}
+
 } // namespace WebCore
 
 #endif
diff --git a/Source/WebCore/html/BaseMultipleFieldsDateAndTimeInputType.h b/Source/WebCore/html/BaseMultipleFieldsDateAndTimeInputType.h
index eb518f0..fe0b84c 100644
--- a/Source/WebCore/html/BaseMultipleFieldsDateAndTimeInputType.h
+++ b/Source/WebCore/html/BaseMultipleFieldsDateAndTimeInputType.h
@@ -34,6 +34,7 @@
 #if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
 #include "BaseDateAndTimeInputType.h"
 
+#include "ClearButtonElement.h"
 #include "DateTimeEditElement.h"
 #include "PickerIndicatorElement.h"
 #include "SpinButtonElement.h"
@@ -46,7 +47,8 @@
     : public BaseDateAndTimeInputType
     , protected DateTimeEditElement::EditControlOwner
     , protected PickerIndicatorElement::PickerIndicatorOwner
-    , protected SpinButtonElement::SpinButtonOwner {
+    , protected SpinButtonElement::SpinButtonOwner
+    , protected ClearButtonElement::ClearButtonOwner {
 protected:
     BaseMultipleFieldsDateAndTimeInputType(HTMLInputElement*);
     virtual ~BaseMultipleFieldsDateAndTimeInputType();
@@ -75,6 +77,11 @@
     virtual void pickerIndicatorChooseValue(const String&) OVERRIDE FINAL;
     virtual bool setupDateTimeChooserParameters(DateTimeChooserParameters&) OVERRIDE FINAL;
 
+    // ClearButtonElement::ClearButtonOwner functions.
+    virtual void focusAndSelectClearButtonOwner() OVERRIDE;
+    virtual bool shouldClearButtonRespondToMouseEvents() OVERRIDE;
+    virtual void clearValue() OVERRIDE;
+
     // InputType functions
     virtual String badInputText() const OVERRIDE;
     virtual void blur() OVERRIDE FINAL;
@@ -91,6 +98,7 @@
     virtual bool isMouseFocusable() const OVERRIDE FINAL;
     virtual void minOrMaxAttributeChanged() OVERRIDE FINAL;
     virtual void readonlyAttributeChanged() OVERRIDE FINAL;
+    virtual void requiredAttributeChanged() OVERRIDE FINAL;
     virtual void restoreFormControlState(const FormControlState&) OVERRIDE FINAL;
     virtual FormControlState saveFormControlState() const OVERRIDE FINAL;
     virtual void setValue(const String&, bool valueChanged, TextFieldEventBehavior) OVERRIDE FINAL;
@@ -98,6 +106,7 @@
     virtual void stepAttributeChanged() OVERRIDE FINAL;
     virtual void updateInnerTextValue() OVERRIDE FINAL;
     virtual void listAttributeTargetChanged() OVERRIDE FINAL;
+    virtual void updateClearButtonVisibility() OVERRIDE FINAL;
 
     void showPickerIndicator();
     void hidePickerIndicator();
@@ -105,6 +114,7 @@
 
     DateTimeEditElement* m_dateTimeEditElement;
     SpinButtonElement* m_spinButtonElement;
+    ClearButtonElement* m_clearButton;
     PickerIndicatorElement* m_pickerIndicatorElement;
     bool m_pickerIndicatorIsVisible;
     bool m_pickerIndicatorIsAlwaysVisible;
diff --git a/Source/WebCore/html/HTMLInputElement.cpp b/Source/WebCore/html/HTMLInputElement.cpp
index 302f749..3a8d8b3 100644
--- a/Source/WebCore/html/HTMLInputElement.cpp
+++ b/Source/WebCore/html/HTMLInputElement.cpp
@@ -1466,6 +1466,11 @@
     dispatchEvent(Event::create(eventNames().searchEvent, true, false));
 }
 
+void HTMLInputElement::updateClearButtonVisibility()
+{
+    m_inputType->updateClearButtonVisibility();
+}
+
 void HTMLInputElement::documentDidResumeFromPageCache()
 {
     ASSERT(needsSuspensionCallback());
@@ -1550,6 +1555,7 @@
     HTMLTextFormControlElement::requiredAttributeChanged();
     if (CheckedRadioButtons* buttons = checkedRadioButtons())
         buttons->requiredAttributeChanged(this);
+    m_inputType->requiredAttributeChanged();
 }
 
 #if ENABLE(INPUT_TYPE_COLOR)
diff --git a/Source/WebCore/html/HTMLInputElement.h b/Source/WebCore/html/HTMLInputElement.h
index 4495248..f7afe52 100644
--- a/Source/WebCore/html/HTMLInputElement.h
+++ b/Source/WebCore/html/HTMLInputElement.h
@@ -239,6 +239,8 @@
     void addSearchResult();
     void onSearch();
 
+    void updateClearButtonVisibility();
+
     virtual bool willRespondToMouseClickEvents() OVERRIDE;
 
 #if ENABLE(DATALIST_ELEMENT)
diff --git a/Source/WebCore/html/InputType.cpp b/Source/WebCore/html/InputType.cpp
index b086d8a..38764e4 100644
--- a/Source/WebCore/html/InputType.cpp
+++ b/Source/WebCore/html/InputType.cpp
@@ -912,6 +912,10 @@
 {
 }
 
+void InputType::requiredAttributeChanged()
+{
+}
+
 void InputType::subtreeHasChanged()
 {
     ASSERT_NOT_REACHED();
@@ -941,6 +945,10 @@
 }
 #endif
 
+void InputType::updateClearButtonVisibility()
+{
+}
+
 bool InputType::supportsIndeterminateAppearance() const
 {
     return false;
diff --git a/Source/WebCore/html/InputType.h b/Source/WebCore/html/InputType.h
index e946585..5878034 100644
--- a/Source/WebCore/html/InputType.h
+++ b/Source/WebCore/html/InputType.h
@@ -275,11 +275,13 @@
     virtual void multipleAttributeChanged();
     virtual void disabledAttributeChanged();
     virtual void readonlyAttributeChanged();
+    virtual void requiredAttributeChanged();
     virtual String defaultToolTip() const;
 #if ENABLE(DATALIST_ELEMENT)
     virtual void listAttributeTargetChanged();
     virtual Decimal findClosestTickMarkValue(const Decimal&);
 #endif
+    virtual void updateClearButtonVisibility();
 
     // Parses the specified string for the type, and return
     // the Decimal value for the parsing result if the parsing
diff --git a/Source/WebCore/html/shadow/ClearButtonElement.cpp b/Source/WebCore/html/shadow/ClearButtonElement.cpp
new file mode 100644
index 0000000..48d27ea
--- /dev/null
+++ b/Source/WebCore/html/shadow/ClearButtonElement.cpp
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ClearButtonElement.h"
+
+#include "Frame.h"
+#include "MouseEvent.h"
+#include "RenderView.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+inline ClearButtonElement::ClearButtonElement(Document* document, ClearButtonOwner& clearButtonOwner)
+    : HTMLDivElement(divTag, document)
+    , m_clearButtonOwner(&clearButtonOwner)
+    , m_capturing(false)
+{
+    setPseudo(AtomicString("-webkit-clear-button", AtomicString::ConstructFromLiteral));
+}
+
+PassRefPtr<ClearButtonElement> ClearButtonElement::create(Document* document, ClearButtonOwner& clearButtonOwner)
+{
+    return adoptRef(new ClearButtonElement(document, clearButtonOwner));
+}
+
+void ClearButtonElement::detach()
+{
+    if (m_capturing) {
+        if (Frame* frame = document()->frame())
+            frame->eventHandler()->setCapturingMouseEventsNode(0);
+    }
+    HTMLDivElement::detach();
+}
+
+void ClearButtonElement::releaseCapture()
+{
+    if (!m_capturing)
+        return;
+
+    if (Frame* frame = document()->frame()) {
+        frame->eventHandler()->setCapturingMouseEventsNode(0);
+        m_capturing = false;
+    }
+}
+
+void ClearButtonElement::defaultEventHandler(Event* event)
+{
+    if (!m_clearButtonOwner) {
+        if (!event->defaultHandled())
+            HTMLDivElement::defaultEventHandler(event);
+        return;
+    }
+
+    if (!m_clearButtonOwner->shouldClearButtonRespondToMouseEvents()) {
+        if (!event->defaultHandled())
+            HTMLDivElement::defaultEventHandler(event);
+        return;
+    }
+
+    if (event->type() == eventNames().mousedownEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton) {
+        if (renderer() && renderer()->visibleToHitTesting()) {
+            if (Frame* frame = document()->frame()) {
+                frame->eventHandler()->setCapturingMouseEventsNode(this);
+                m_capturing = true;
+            }
+        }
+        m_clearButtonOwner->focusAndSelectClearButtonOwner();
+        event->setDefaultHandled();
+    }
+    if (event->type() == eventNames().mouseupEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton) {
+        if (m_capturing) {
+            if (Frame* frame = document()->frame()) {
+                frame->eventHandler()->setCapturingMouseEventsNode(0);
+                m_capturing = false;
+            }
+            if (hovered()) {
+                m_clearButtonOwner->clearValue();
+                event->setDefaultHandled();
+            }
+        }
+    }
+
+    if (!event->defaultHandled())
+        HTMLDivElement::defaultEventHandler(event);
+}
+
+}
diff --git a/Source/WebCore/html/shadow/ClearButtonElement.h b/Source/WebCore/html/shadow/ClearButtonElement.h
new file mode 100644
index 0000000..6100a611
--- /dev/null
+++ b/Source/WebCore/html/shadow/ClearButtonElement.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef ClearButtonElement_h
+#define ClearButtonElement_h
+
+#include "HTMLDivElement.h"
+#include <wtf/Forward.h>
+
+namespace WebCore {
+
+class ClearButtonElement : public HTMLDivElement {
+public:
+    class ClearButtonOwner {
+    public:
+        virtual ~ClearButtonOwner() { }
+        virtual void focusAndSelectClearButtonOwner() = 0;
+        virtual bool shouldClearButtonRespondToMouseEvents() = 0;
+        virtual void clearValue() = 0;
+    };
+
+    static PassRefPtr<ClearButtonElement> create(Document*, ClearButtonOwner&);
+    void releaseCapture();
+    void removeClearButtonOwner() { m_clearButtonOwner = 0; }
+
+private:
+    ClearButtonElement(Document*, ClearButtonOwner&);
+    virtual void detach();
+    virtual bool isMouseFocusable() const { return false; }
+    virtual void defaultEventHandler(Event*);
+
+    ClearButtonOwner* m_clearButtonOwner;
+    bool m_capturing;
+};
+
+} // namespace
+
+#endif // ClearButtonElement_h