Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / html / forms / BaseMultipleFieldsDateAndTimeInputType.cpp
index e595534..32c5ab6 100644 (file)
 #if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
 #include "core/html/forms/BaseMultipleFieldsDateAndTimeInputType.h"
 
-#include "CSSValueKeywords.h"
-#include "RuntimeEnabledFeatures.h"
+#include "core/CSSValueKeywords.h"
 #include "core/dom/shadow/ShadowRoot.h"
 #include "core/events/KeyboardEvent.h"
+#include "core/events/ScopedEventQueue.h"
 #include "core/html/HTMLDataListElement.h"
 #include "core/html/HTMLInputElement.h"
 #include "core/html/HTMLOptionElement.h"
 #include "core/html/forms/DateTimeFieldsState.h"
 #include "core/html/forms/FormController.h"
-#include "core/html/shadow/PickerIndicatorElement.h"
 #include "core/html/shadow/ShadowElementNames.h"
 #include "core/page/FocusController.h"
 #include "core/page/Page.h"
 #include "core/rendering/RenderTheme.h"
 #include "platform/DateComponents.h"
+#include "platform/RuntimeEnabledFeatures.h"
 #include "platform/text/DateTimeFormat.h"
 #include "platform/text/PlatformLocale.h"
 #include "wtf/DateMath.h"
 
-namespace WebCore {
+namespace blink {
 
 class DateTimeFormatValidator : public DateTimeFormat::TokenHandler {
 public:
@@ -159,9 +159,12 @@ void BaseMultipleFieldsDateAndTimeInputType::didBlurFromControl()
 
     if (containsFocusedShadowElement())
         return;
-    RefPtr<HTMLInputElement> protector(element());
+    EventQueueScope scope;
+    RefPtrWillBeRawPtr<HTMLInputElement> protector(element());
     // Remove focus ring by CSS "focus" pseudo class.
     element().setFocus(false);
+    if (SpinButtonElement *spinButton = spinButtonElement())
+        spinButton->releaseCapture();
 }
 
 void BaseMultipleFieldsDateAndTimeInputType::didFocusOnControl()
@@ -178,7 +181,7 @@ void BaseMultipleFieldsDateAndTimeInputType::didFocusOnControl()
 
 void BaseMultipleFieldsDateAndTimeInputType::editControlValueChanged()
 {
-    RefPtr<HTMLInputElement> input(element());
+    RefPtrWillBeRawPtr<HTMLInputElement> input(element());
     String oldValue = input->value();
     String newValue = sanitizeValue(dateTimeEditElement()->value());
     // Even if oldValue is null and newValue is "", we should assume they are same.
@@ -186,9 +189,8 @@ void BaseMultipleFieldsDateAndTimeInputType::editControlValueChanged()
         input->setNeedsValidityCheck();
     } else {
         input->setValueInternal(newValue, DispatchNoEvent);
-        input->setNeedsStyleRecalc();
+        input->setNeedsStyleRecalc(SubtreeStyleChange);
         input->dispatchFormControlInputEvent();
-        input->dispatchFormControlChangeEvent();
     }
     input->notifyFormStateChanged();
     input->updateClearButtonVisibility();
@@ -241,6 +243,12 @@ void BaseMultipleFieldsDateAndTimeInputType::spinButtonStepUp()
         edit->stepUp();
 }
 
+void BaseMultipleFieldsDateAndTimeInputType::spinButtonDidReleaseMouseCapture(SpinButtonElement::EventDispatch eventDispatch)
+{
+    if (eventDispatch == SpinButtonElement::EventDispatchAllowed)
+        element().dispatchFormControlChangeEvent();
+}
+
 bool BaseMultipleFieldsDateAndTimeInputType::isPickerIndicatorOwnerDisabledOrReadOnly() const
 {
     return element().isDisabledOrReadOnly();
@@ -260,6 +268,16 @@ void BaseMultipleFieldsDateAndTimeInputType::pickerIndicatorChooseValue(const St
     unsigned end;
     if (date.parseDate(value, 0, end) && end == value.length())
         edit->setOnlyYearMonthDay(date);
+    element().dispatchFormControlChangeEvent();
+}
+
+void BaseMultipleFieldsDateAndTimeInputType::pickerIndicatorChooseValue(double value)
+{
+    ASSERT(std::isfinite(value) || std::isnan(value));
+    if (std::isnan(value))
+        element().setValue(emptyString(), DispatchInputAndChangeEvent);
+    else
+        element().setValueAsNumber(value, ASSERT_NO_EXCEPTION, DispatchInputAndChangeEvent);
 }
 
 bool BaseMultipleFieldsDateAndTimeInputType::setupDateTimeChooserParameters(DateTimeChooserParameters& parameters)
@@ -277,6 +295,7 @@ BaseMultipleFieldsDateAndTimeInputType::BaseMultipleFieldsDateAndTimeInputType(H
 
 BaseMultipleFieldsDateAndTimeInputType::~BaseMultipleFieldsDateAndTimeInputType()
 {
+#if !ENABLE(OILPAN)
     if (SpinButtonElement* element = spinButtonElement())
         element->removeSpinButtonOwner();
     if (ClearButtonElement* element = clearButtonElement())
@@ -285,11 +304,12 @@ BaseMultipleFieldsDateAndTimeInputType::~BaseMultipleFieldsDateAndTimeInputType(
         element->removeEditControlOwner();
     if (PickerIndicatorElement* element = pickerIndicatorElement())
         element->removePickerIndicatorOwner();
+#endif
 }
 
 String BaseMultipleFieldsDateAndTimeInputType::badInputText() const
 {
-    return locale().queryString(WebKit::WebLocalizedString::ValidationBadInputForDateTime);
+    return locale().queryString(blink::WebLocalizedString::ValidationBadInputForDateTime);
 }
 
 void BaseMultipleFieldsDateAndTimeInputType::blur()
@@ -306,7 +326,7 @@ PassRefPtr<RenderStyle> BaseMultipleFieldsDateAndTimeInputType::customStyleForRe
         newDisplay = INLINE_FLEX;
     else if (originalDisplay == BLOCK)
         newDisplay = FLEX;
-    TextDirection contentDirection = element().locale().isRTL() ? RTL : LTR;
+    TextDirection contentDirection = computedTextDirection();
     if (originalStyle->direction() == contentDirection && originalDisplay == newDisplay)
         return originalStyle;
 
@@ -331,22 +351,15 @@ void BaseMultipleFieldsDateAndTimeInputType::createShadowSubtree()
     ContainerNode* container = element().userAgentShadowRoot();
 
     container->appendChild(DateTimeEditElement::create(document, *this));
-    updateInnerTextValue();
+    element().updateView();
     container->appendChild(ClearButtonElement::create(document, *this));
     container->appendChild(SpinButtonElement::create(document, *this));
 
-    bool shouldAddPickerIndicator = false;
-    if (InputType::themeSupportsDataListUI(this))
-        shouldAddPickerIndicator = true;
-    if (RenderTheme::theme().supportsCalendarPicker(formControlType())) {
-        shouldAddPickerIndicator = true;
+    if (RenderTheme::theme().supportsCalendarPicker(formControlType()))
         m_pickerIndicatorIsAlwaysVisible = true;
-    }
-    if (shouldAddPickerIndicator) {
-        container->appendChild(PickerIndicatorElement::create(document, *this));
-        m_pickerIndicatorIsVisible = true;
-        updatePickerIndicatorVisibility();
-    }
+    container->appendChild(PickerIndicatorElement::create(document, *this));
+    m_pickerIndicatorIsVisible = true;
+    updatePickerIndicatorVisibility();
 }
 
 void BaseMultipleFieldsDateAndTimeInputType::destroyShadowSubtree()
@@ -371,15 +384,15 @@ void BaseMultipleFieldsDateAndTimeInputType::destroyShadowSubtree()
     m_isDestroyingShadowSubtree = false;
 }
 
-void BaseMultipleFieldsDateAndTimeInputType::handleFocusEvent(Element* oldFocusedElement, FocusDirection direction)
+void BaseMultipleFieldsDateAndTimeInputType::handleFocusEvent(Element* oldFocusedElement, FocusType type)
 {
     DateTimeEditElement* edit = dateTimeEditElement();
     if (!edit || m_isDestroyingShadowSubtree)
         return;
-    if (direction == FocusDirectionBackward) {
+    if (type == FocusTypeBackward) {
         if (element().document().page())
-            element().document().page()->focusController().advanceFocus(direction);
-    } else if (direction == FocusDirectionNone || direction == FocusDirectionMouse || direction == FocusDirectionPage) {
+            element().document().page()->focusController().advanceFocus(type);
+    } else if (type == FocusTypeNone || type == FocusTypeMouse || type == FocusTypePage) {
         edit->focusByOwner(oldFocusedElement);
     } else {
         edit->focusByOwner();
@@ -435,9 +448,14 @@ AtomicString BaseMultipleFieldsDateAndTimeInputType::localeIdentifier() const
     return element().computeInheritedLanguage();
 }
 
+void BaseMultipleFieldsDateAndTimeInputType::editControlDidChangeValueByKeyboard()
+{
+    element().dispatchFormControlChangeEvent();
+}
+
 void BaseMultipleFieldsDateAndTimeInputType::minOrMaxAttributeChanged()
 {
-    updateInnerTextValue();
+    updateView();
 }
 
 void BaseMultipleFieldsDateAndTimeInputType::readonlyAttributeChanged()
@@ -471,22 +489,17 @@ void BaseMultipleFieldsDateAndTimeInputType::setValue(const String& sanitizedVal
     InputType::setValue(sanitizedValue, valueChanged, eventBehavior);
     DateTimeEditElement* edit = dateTimeEditElement();
     if (valueChanged || (sanitizedValue.isEmpty() && edit && edit->anyEditableFieldsHaveValues())) {
-        updateInnerTextValue();
+        element().updateView();
         element().setNeedsValidityCheck();
     }
 }
 
-bool BaseMultipleFieldsDateAndTimeInputType::shouldUseInputMethod() const
-{
-    return false;
-}
-
 void BaseMultipleFieldsDateAndTimeInputType::stepAttributeChanged()
 {
-    updateInnerTextValue();
+    updateView();
 }
 
-void BaseMultipleFieldsDateAndTimeInputType::updateInnerTextValue()
+void BaseMultipleFieldsDateAndTimeInputType::updateView()
 {
     DateTimeEditElement* edit = dateTimeEditElement();
     if (!edit)
@@ -495,12 +508,18 @@ void BaseMultipleFieldsDateAndTimeInputType::updateInnerTextValue()
     DateTimeEditElement::LayoutParameters layoutParameters(element().locale(), createStepRange(AnyIsDefaultStep));
 
     DateComponents date;
-    const bool hasValue = parseToDateComponents(element().value(), &date);
+    bool hasValue = false;
+    if (!element().suggestedValue().isNull())
+        hasValue = parseToDateComponents(element().suggestedValue(), &date);
+    else
+        hasValue = parseToDateComponents(element().value(), &date);
     if (!hasValue)
         setMillisecondToDateComponents(layoutParameters.stepRange.minimum().toDouble(), &date);
 
     setupLayoutParameters(layoutParameters, date);
 
+    DEFINE_STATIC_LOCAL(AtomicString, datetimeformatAttr, ("datetimeformat", AtomicString::ConstructFromLiteral));
+    edit->setAttribute(datetimeformatAttr, AtomicString(layoutParameters.dateTimeFormat), ASSERT_NO_EXCEPTION);
     const AtomicString pattern = edit->fastGetAttribute(HTMLNames::patternAttr);
     if (!pattern.isEmpty())
         layoutParameters.dateTimeFormat = pattern;
@@ -518,7 +537,7 @@ void BaseMultipleFieldsDateAndTimeInputType::updateInnerTextValue()
 void BaseMultipleFieldsDateAndTimeInputType::valueAttributeChanged()
 {
     if (!element().hasDirtyValue())
-        updateInnerTextValue();
+        updateView();
 }
 
 void BaseMultipleFieldsDateAndTimeInputType::listAttributeTargetChanged()
@@ -532,18 +551,10 @@ void BaseMultipleFieldsDateAndTimeInputType::updatePickerIndicatorVisibility()
         showPickerIndicator();
         return;
     }
-    if (RuntimeEnabledFeatures::dataListElementEnabled()) {
-        if (HTMLDataListElement* dataList = element().dataList()) {
-            RefPtr<HTMLCollection> options = dataList->options();
-            for (unsigned i = 0; HTMLOptionElement* option = toHTMLOptionElement(options->item(i)); ++i) {
-                if (element().isValidValue(option->value())) {
-                    showPickerIndicator();
-                    return;
-                }
-            }
-        }
+    if (element().hasValidDataListOptions())
+        showPickerIndicator();
+    else
         hidePickerIndicator();
-    }
 }
 
 void BaseMultipleFieldsDateAndTimeInputType::hidePickerIndicator()
@@ -584,7 +595,7 @@ bool BaseMultipleFieldsDateAndTimeInputType::shouldClearButtonRespondToMouseEven
 
 void BaseMultipleFieldsDateAndTimeInputType::clearValue()
 {
-    RefPtr<HTMLInputElement> input(element());
+    RefPtrWillBeRawPtr<HTMLInputElement> input(element());
     input->setValue("", DispatchInputAndChangeEvent);
     input->updateClearButtonVisibility();
 }
@@ -595,12 +606,20 @@ void BaseMultipleFieldsDateAndTimeInputType::updateClearButtonVisibility()
     if (!clearButton)
         return;
 
-    if (element().isRequired() || !dateTimeEditElement()->anyEditableFieldsHaveValues())
-        clearButton->setInlineStyleProperty(CSSPropertyVisibility, CSSValueHidden);
-    else
-        clearButton->removeInlineStyleProperty(CSSPropertyVisibility);
+    if (element().isRequired() || !dateTimeEditElement()->anyEditableFieldsHaveValues()) {
+        clearButton->setInlineStyleProperty(CSSPropertyOpacity, 0.0, CSSPrimitiveValue::CSS_NUMBER);
+        clearButton->setInlineStyleProperty(CSSPropertyPointerEvents, CSSValueNone);
+    } else {
+        clearButton->removeInlineStyleProperty(CSSPropertyOpacity);
+        clearButton->removeInlineStyleProperty(CSSPropertyPointerEvents);
+    }
+}
+
+TextDirection BaseMultipleFieldsDateAndTimeInputType::computedTextDirection()
+{
+    return element().locale().isRTL() ? RTL : LTR;
 }
 
-} // namespace WebCore
+} // namespace blink
 
 #endif