Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / html / forms / BaseMultipleFieldsDateAndTimeInputType.cpp
1 /*
2  * Copyright (C) 2010 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include "config.h"
32 #if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
33 #include "core/html/forms/BaseMultipleFieldsDateAndTimeInputType.h"
34
35 #include "CSSValueKeywords.h"
36 #include "RuntimeEnabledFeatures.h"
37 #include "core/dom/shadow/ShadowRoot.h"
38 #include "core/events/KeyboardEvent.h"
39 #include "core/html/HTMLDataListElement.h"
40 #include "core/html/HTMLInputElement.h"
41 #include "core/html/HTMLOptionElement.h"
42 #include "core/html/forms/DateTimeFieldsState.h"
43 #include "core/html/forms/FormController.h"
44 #include "core/html/shadow/ShadowElementNames.h"
45 #include "core/page/FocusController.h"
46 #include "core/page/Page.h"
47 #include "core/rendering/RenderTheme.h"
48 #include "platform/DateComponents.h"
49 #include "platform/text/DateTimeFormat.h"
50 #include "platform/text/PlatformLocale.h"
51 #include "wtf/DateMath.h"
52
53 namespace WebCore {
54
55 class DateTimeFormatValidator : public DateTimeFormat::TokenHandler {
56 public:
57     DateTimeFormatValidator()
58         : m_hasYear(false)
59         , m_hasMonth(false)
60         , m_hasWeek(false)
61         , m_hasDay(false)
62         , m_hasAMPM(false)
63         , m_hasHour(false)
64         , m_hasMinute(false)
65         , m_hasSecond(false) { }
66
67     virtual void visitField(DateTimeFormat::FieldType, int) OVERRIDE FINAL;
68     virtual void visitLiteral(const String&) OVERRIDE FINAL { }
69
70     bool validateFormat(const String& format, const BaseMultipleFieldsDateAndTimeInputType&);
71
72 private:
73     bool m_hasYear;
74     bool m_hasMonth;
75     bool m_hasWeek;
76     bool m_hasDay;
77     bool m_hasAMPM;
78     bool m_hasHour;
79     bool m_hasMinute;
80     bool m_hasSecond;
81 };
82
83 void DateTimeFormatValidator::visitField(DateTimeFormat::FieldType fieldType, int)
84 {
85     switch (fieldType) {
86     case DateTimeFormat::FieldTypeYear:
87         m_hasYear = true;
88         break;
89     case DateTimeFormat::FieldTypeMonth: // Fallthrough.
90     case DateTimeFormat::FieldTypeMonthStandAlone:
91         m_hasMonth = true;
92         break;
93     case DateTimeFormat::FieldTypeWeekOfYear:
94         m_hasWeek = true;
95         break;
96     case DateTimeFormat::FieldTypeDayOfMonth:
97         m_hasDay = true;
98         break;
99     case DateTimeFormat::FieldTypePeriod:
100         m_hasAMPM = true;
101         break;
102     case DateTimeFormat::FieldTypeHour11: // Fallthrough.
103     case DateTimeFormat::FieldTypeHour12:
104         m_hasHour = true;
105         break;
106     case DateTimeFormat::FieldTypeHour23: // Fallthrough.
107     case DateTimeFormat::FieldTypeHour24:
108         m_hasHour = true;
109         m_hasAMPM = true;
110         break;
111     case DateTimeFormat::FieldTypeMinute:
112         m_hasMinute = true;
113         break;
114     case DateTimeFormat::FieldTypeSecond:
115         m_hasSecond = true;
116         break;
117     default:
118         break;
119     }
120 }
121
122 bool DateTimeFormatValidator::validateFormat(const String& format, const BaseMultipleFieldsDateAndTimeInputType& inputType)
123 {
124     if (!DateTimeFormat::parse(format, *this))
125         return false;
126     return inputType.isValidFormat(m_hasYear, m_hasMonth, m_hasWeek, m_hasDay, m_hasAMPM, m_hasHour, m_hasMinute, m_hasSecond);
127 }
128
129 DateTimeEditElement* BaseMultipleFieldsDateAndTimeInputType::dateTimeEditElement() const
130 {
131     return toDateTimeEditElement(element().userAgentShadowRoot()->getElementById(ShadowElementNames::dateTimeEdit()));
132 }
133
134 SpinButtonElement* BaseMultipleFieldsDateAndTimeInputType::spinButtonElement() const
135 {
136     return toSpinButtonElement(element().userAgentShadowRoot()->getElementById(ShadowElementNames::spinButton()));
137 }
138
139 ClearButtonElement* BaseMultipleFieldsDateAndTimeInputType::clearButtonElement() const
140 {
141     return toClearButtonElement(element().userAgentShadowRoot()->getElementById(ShadowElementNames::clearButton()));
142 }
143
144 PickerIndicatorElement* BaseMultipleFieldsDateAndTimeInputType::pickerIndicatorElement() const
145 {
146     return toPickerIndicatorElement(element().userAgentShadowRoot()->getElementById(ShadowElementNames::pickerIndicator()));
147 }
148
149 inline bool BaseMultipleFieldsDateAndTimeInputType::containsFocusedShadowElement() const
150 {
151     return element().userAgentShadowRoot()->contains(element().document().focusedElement());
152 }
153
154 void BaseMultipleFieldsDateAndTimeInputType::didBlurFromControl()
155 {
156     // We don't need to call blur(). This function is called when control
157     // lost focus.
158
159     if (containsFocusedShadowElement())
160         return;
161     RefPtr<HTMLInputElement> protector(element());
162     // Remove focus ring by CSS "focus" pseudo class.
163     element().setFocus(false);
164 }
165
166 void BaseMultipleFieldsDateAndTimeInputType::didFocusOnControl()
167 {
168     // We don't need to call focus(). This function is called when control
169     // got focus.
170
171     if (!containsFocusedShadowElement())
172         return;
173     // Add focus ring by CSS "focus" pseudo class.
174     // FIXME: Setting the focus flag to non-focused element is too tricky.
175     element().setFocus(true);
176 }
177
178 void BaseMultipleFieldsDateAndTimeInputType::editControlValueChanged()
179 {
180     RefPtr<HTMLInputElement> input(element());
181     String oldValue = input->value();
182     String newValue = sanitizeValue(dateTimeEditElement()->value());
183     // Even if oldValue is null and newValue is "", we should assume they are same.
184     if ((oldValue.isEmpty() && newValue.isEmpty()) || oldValue == newValue) {
185         input->setNeedsValidityCheck();
186     } else {
187         input->setValueInternal(newValue, DispatchNoEvent);
188         input->setNeedsStyleRecalc(SubtreeStyleChange);
189         input->dispatchFormControlInputEvent();
190         input->dispatchFormControlChangeEvent();
191     }
192     input->notifyFormStateChanged();
193     input->updateClearButtonVisibility();
194 }
195
196 bool BaseMultipleFieldsDateAndTimeInputType::hasCustomFocusLogic() const
197 {
198     return false;
199 }
200
201 bool BaseMultipleFieldsDateAndTimeInputType::isEditControlOwnerDisabled() const
202 {
203     return element().isDisabledFormControl();
204 }
205
206 bool BaseMultipleFieldsDateAndTimeInputType::isEditControlOwnerReadOnly() const
207 {
208     return element().isReadOnly();
209 }
210
211 void BaseMultipleFieldsDateAndTimeInputType::focusAndSelectSpinButtonOwner()
212 {
213     if (DateTimeEditElement* edit = dateTimeEditElement())
214         edit->focusIfNoFocus();
215 }
216
217 bool BaseMultipleFieldsDateAndTimeInputType::shouldSpinButtonRespondToMouseEvents()
218 {
219     return !element().isDisabledOrReadOnly();
220 }
221
222 bool BaseMultipleFieldsDateAndTimeInputType::shouldSpinButtonRespondToWheelEvents()
223 {
224     if (!shouldSpinButtonRespondToMouseEvents())
225         return false;
226     if (DateTimeEditElement* edit = dateTimeEditElement())
227         return edit->hasFocusedField();
228     return false;
229 }
230
231 void BaseMultipleFieldsDateAndTimeInputType::spinButtonStepDown()
232 {
233     if (DateTimeEditElement* edit = dateTimeEditElement())
234         edit->stepDown();
235 }
236
237 void BaseMultipleFieldsDateAndTimeInputType::spinButtonStepUp()
238 {
239     if (DateTimeEditElement* edit = dateTimeEditElement())
240         edit->stepUp();
241 }
242
243 bool BaseMultipleFieldsDateAndTimeInputType::isPickerIndicatorOwnerDisabledOrReadOnly() const
244 {
245     return element().isDisabledOrReadOnly();
246 }
247
248 void BaseMultipleFieldsDateAndTimeInputType::pickerIndicatorChooseValue(const String& value)
249 {
250     if (element().isValidValue(value)) {
251         element().setValue(value, DispatchInputAndChangeEvent);
252         return;
253     }
254
255     DateTimeEditElement* edit = this->dateTimeEditElement();
256     if (!edit)
257         return;
258     DateComponents date;
259     unsigned end;
260     if (date.parseDate(value, 0, end) && end == value.length())
261         edit->setOnlyYearMonthDay(date);
262 }
263
264 void BaseMultipleFieldsDateAndTimeInputType::pickerIndicatorChooseValue(double value)
265 {
266     ASSERT(std::isfinite(value) || std::isnan(value));
267     if (std::isnan(value))
268         element().setValue(emptyString(), DispatchInputAndChangeEvent);
269     else
270         element().setValueAsNumber(value, ASSERT_NO_EXCEPTION, DispatchInputAndChangeEvent);
271 }
272
273 bool BaseMultipleFieldsDateAndTimeInputType::setupDateTimeChooserParameters(DateTimeChooserParameters& parameters)
274 {
275     return element().setupDateTimeChooserParameters(parameters);
276 }
277
278 BaseMultipleFieldsDateAndTimeInputType::BaseMultipleFieldsDateAndTimeInputType(HTMLInputElement& element)
279     : BaseDateAndTimeInputType(element)
280     , m_isDestroyingShadowSubtree(false)
281     , m_pickerIndicatorIsVisible(false)
282     , m_pickerIndicatorIsAlwaysVisible(false)
283 {
284 }
285
286 BaseMultipleFieldsDateAndTimeInputType::~BaseMultipleFieldsDateAndTimeInputType()
287 {
288     if (SpinButtonElement* element = spinButtonElement())
289         element->removeSpinButtonOwner();
290     if (ClearButtonElement* element = clearButtonElement())
291         element->removeClearButtonOwner();
292     if (DateTimeEditElement* element = dateTimeEditElement())
293         element->removeEditControlOwner();
294     if (PickerIndicatorElement* element = pickerIndicatorElement())
295         element->removePickerIndicatorOwner();
296 }
297
298 String BaseMultipleFieldsDateAndTimeInputType::badInputText() const
299 {
300     return locale().queryString(blink::WebLocalizedString::ValidationBadInputForDateTime);
301 }
302
303 void BaseMultipleFieldsDateAndTimeInputType::blur()
304 {
305     if (DateTimeEditElement* edit = dateTimeEditElement())
306         edit->blurByOwner();
307 }
308
309 PassRefPtr<RenderStyle> BaseMultipleFieldsDateAndTimeInputType::customStyleForRenderer(PassRefPtr<RenderStyle> originalStyle)
310 {
311     EDisplay originalDisplay = originalStyle->display();
312     EDisplay newDisplay = originalDisplay;
313     if (originalDisplay == INLINE || originalDisplay == INLINE_BLOCK)
314         newDisplay = INLINE_FLEX;
315     else if (originalDisplay == BLOCK)
316         newDisplay = FLEX;
317     TextDirection contentDirection = element().locale().isRTL() ? RTL : LTR;
318     if (originalStyle->direction() == contentDirection && originalDisplay == newDisplay)
319         return originalStyle;
320
321     RefPtr<RenderStyle> style = RenderStyle::clone(originalStyle.get());
322     style->setDirection(contentDirection);
323     style->setDisplay(newDisplay);
324     style->setUnique();
325     return style.release();
326 }
327
328 void BaseMultipleFieldsDateAndTimeInputType::createShadowSubtree()
329 {
330     ASSERT(element().shadow());
331
332     // Element must not have a renderer here, because if it did
333     // DateTimeEditElement::customStyleForRenderer() is called in appendChild()
334     // before the field wrapper element is created.
335     // FIXME: This code should not depend on such craziness.
336     ASSERT(!element().renderer());
337
338     Document& document = element().document();
339     ContainerNode* container = element().userAgentShadowRoot();
340
341     container->appendChild(DateTimeEditElement::create(document, *this));
342     element().updateView();
343     container->appendChild(ClearButtonElement::create(document, *this));
344     container->appendChild(SpinButtonElement::create(document, *this));
345
346     bool shouldAddPickerIndicator = false;
347     if (InputType::themeSupportsDataListUI(this))
348         shouldAddPickerIndicator = true;
349     if (RenderTheme::theme().supportsCalendarPicker(formControlType())) {
350         shouldAddPickerIndicator = true;
351         m_pickerIndicatorIsAlwaysVisible = true;
352     }
353     if (shouldAddPickerIndicator) {
354         container->appendChild(PickerIndicatorElement::create(document, *this));
355         m_pickerIndicatorIsVisible = true;
356         updatePickerIndicatorVisibility();
357     }
358 }
359
360 void BaseMultipleFieldsDateAndTimeInputType::destroyShadowSubtree()
361 {
362     ASSERT(!m_isDestroyingShadowSubtree);
363     m_isDestroyingShadowSubtree = true;
364     if (SpinButtonElement* element = spinButtonElement())
365         element->removeSpinButtonOwner();
366     if (ClearButtonElement* element = clearButtonElement())
367         element->removeClearButtonOwner();
368     if (DateTimeEditElement* element = dateTimeEditElement())
369         element->removeEditControlOwner();
370     if (PickerIndicatorElement* element = pickerIndicatorElement())
371         element->removePickerIndicatorOwner();
372
373     // If a field element has focus, set focus back to the <input> itself before
374     // deleting the field. This prevents unnecessary focusout/blur events.
375     if (containsFocusedShadowElement())
376         element().focus();
377
378     BaseDateAndTimeInputType::destroyShadowSubtree();
379     m_isDestroyingShadowSubtree = false;
380 }
381
382 void BaseMultipleFieldsDateAndTimeInputType::handleFocusEvent(Element* oldFocusedElement, FocusType type)
383 {
384     DateTimeEditElement* edit = dateTimeEditElement();
385     if (!edit || m_isDestroyingShadowSubtree)
386         return;
387     if (type == FocusTypeBackward) {
388         if (element().document().page())
389             element().document().page()->focusController().advanceFocus(type);
390     } else if (type == FocusTypeNone || type == FocusTypeMouse || type == FocusTypePage) {
391         edit->focusByOwner(oldFocusedElement);
392     } else {
393         edit->focusByOwner();
394     }
395 }
396
397 void BaseMultipleFieldsDateAndTimeInputType::forwardEvent(Event* event)
398 {
399     if (SpinButtonElement* element = spinButtonElement()) {
400         element->forwardEvent(event);
401         if (event->defaultHandled())
402             return;
403     }
404
405     if (DateTimeEditElement* edit = dateTimeEditElement())
406         edit->defaultEventHandler(event);
407 }
408
409 void BaseMultipleFieldsDateAndTimeInputType::disabledAttributeChanged()
410 {
411     spinButtonElement()->releaseCapture();
412     clearButtonElement()->releaseCapture();
413     if (DateTimeEditElement* edit = dateTimeEditElement())
414         edit->disabledStateChanged();
415 }
416
417 void BaseMultipleFieldsDateAndTimeInputType::requiredAttributeChanged()
418 {
419     clearButtonElement()->releaseCapture();
420     updateClearButtonVisibility();
421 }
422
423 void BaseMultipleFieldsDateAndTimeInputType::handleKeydownEvent(KeyboardEvent* event)
424 {
425     if (m_pickerIndicatorIsVisible
426         && ((event->keyIdentifier() == "Down" && event->getModifierState("Alt")) || (RenderTheme::theme().shouldOpenPickerWithF4Key() && event->keyIdentifier() == "F4"))) {
427         if (PickerIndicatorElement* element = pickerIndicatorElement())
428             element->openPopup();
429         event->setDefaultHandled();
430     } else {
431         forwardEvent(event);
432     }
433 }
434
435 bool BaseMultipleFieldsDateAndTimeInputType::hasBadInput() const
436 {
437     DateTimeEditElement* edit = dateTimeEditElement();
438     return element().value().isEmpty() && edit && edit->anyEditableFieldsHaveValues();
439 }
440
441 AtomicString BaseMultipleFieldsDateAndTimeInputType::localeIdentifier() const
442 {
443     return element().computeInheritedLanguage();
444 }
445
446 void BaseMultipleFieldsDateAndTimeInputType::minOrMaxAttributeChanged()
447 {
448     updateView();
449 }
450
451 void BaseMultipleFieldsDateAndTimeInputType::readonlyAttributeChanged()
452 {
453     spinButtonElement()->releaseCapture();
454     clearButtonElement()->releaseCapture();
455     if (DateTimeEditElement* edit = dateTimeEditElement())
456         edit->readOnlyStateChanged();
457 }
458
459 void BaseMultipleFieldsDateAndTimeInputType::restoreFormControlState(const FormControlState& state)
460 {
461     DateTimeEditElement* edit = dateTimeEditElement();
462     if (!edit)
463         return;
464     DateTimeFieldsState dateTimeFieldsState = DateTimeFieldsState::restoreFormControlState(state);
465     edit->setValueAsDateTimeFieldsState(dateTimeFieldsState);
466     element().setValueInternal(sanitizeValue(edit->value()), DispatchNoEvent);
467     updateClearButtonVisibility();
468 }
469
470 FormControlState BaseMultipleFieldsDateAndTimeInputType::saveFormControlState() const
471 {
472     if (DateTimeEditElement* edit = dateTimeEditElement())
473         return edit->valueAsDateTimeFieldsState().saveFormControlState();
474     return FormControlState();
475 }
476
477 void BaseMultipleFieldsDateAndTimeInputType::setValue(const String& sanitizedValue, bool valueChanged, TextFieldEventBehavior eventBehavior)
478 {
479     InputType::setValue(sanitizedValue, valueChanged, eventBehavior);
480     DateTimeEditElement* edit = dateTimeEditElement();
481     if (valueChanged || (sanitizedValue.isEmpty() && edit && edit->anyEditableFieldsHaveValues())) {
482         element().updateView();
483         element().setNeedsValidityCheck();
484     }
485 }
486
487 bool BaseMultipleFieldsDateAndTimeInputType::shouldUseInputMethod() const
488 {
489     return false;
490 }
491
492 void BaseMultipleFieldsDateAndTimeInputType::stepAttributeChanged()
493 {
494     updateView();
495 }
496
497 void BaseMultipleFieldsDateAndTimeInputType::updateView()
498 {
499     DateTimeEditElement* edit = dateTimeEditElement();
500     if (!edit)
501         return;
502
503     DateTimeEditElement::LayoutParameters layoutParameters(element().locale(), createStepRange(AnyIsDefaultStep));
504
505     DateComponents date;
506     const bool hasValue = parseToDateComponents(element().value(), &date);
507     if (!hasValue)
508         setMillisecondToDateComponents(layoutParameters.stepRange.minimum().toDouble(), &date);
509
510     setupLayoutParameters(layoutParameters, date);
511
512     const AtomicString pattern = edit->fastGetAttribute(HTMLNames::patternAttr);
513     if (!pattern.isEmpty())
514         layoutParameters.dateTimeFormat = pattern;
515
516     if (!DateTimeFormatValidator().validateFormat(layoutParameters.dateTimeFormat, *this))
517         layoutParameters.dateTimeFormat = layoutParameters.fallbackDateTimeFormat;
518
519     if (hasValue)
520         edit->setValueAsDate(layoutParameters, date);
521     else
522         edit->setEmptyValue(layoutParameters, date);
523     updateClearButtonVisibility();
524 }
525
526 void BaseMultipleFieldsDateAndTimeInputType::valueAttributeChanged()
527 {
528     if (!element().hasDirtyValue())
529         updateView();
530 }
531
532 void BaseMultipleFieldsDateAndTimeInputType::listAttributeTargetChanged()
533 {
534     updatePickerIndicatorVisibility();
535 }
536
537 void BaseMultipleFieldsDateAndTimeInputType::updatePickerIndicatorVisibility()
538 {
539     if (m_pickerIndicatorIsAlwaysVisible) {
540         showPickerIndicator();
541         return;
542     }
543     if (element().hasValidDataListOptions())
544         showPickerIndicator();
545     else
546         hidePickerIndicator();
547 }
548
549 void BaseMultipleFieldsDateAndTimeInputType::hidePickerIndicator()
550 {
551     if (!m_pickerIndicatorIsVisible)
552         return;
553     m_pickerIndicatorIsVisible = false;
554     ASSERT(pickerIndicatorElement());
555     pickerIndicatorElement()->setInlineStyleProperty(CSSPropertyDisplay, CSSValueNone);
556 }
557
558 void BaseMultipleFieldsDateAndTimeInputType::showPickerIndicator()
559 {
560     if (m_pickerIndicatorIsVisible)
561         return;
562     m_pickerIndicatorIsVisible = true;
563     ASSERT(pickerIndicatorElement());
564     pickerIndicatorElement()->removeInlineStyleProperty(CSSPropertyDisplay);
565 }
566
567 bool BaseMultipleFieldsDateAndTimeInputType::shouldHaveSecondField(const DateComponents& date) const
568 {
569     StepRange stepRange = createStepRange(AnyIsDefaultStep);
570     return date.second() || date.millisecond()
571         || !stepRange.minimum().remainder(static_cast<int>(msPerMinute)).isZero()
572         || !stepRange.step().remainder(static_cast<int>(msPerMinute)).isZero();
573 }
574
575 void BaseMultipleFieldsDateAndTimeInputType::focusAndSelectClearButtonOwner()
576 {
577     element().focus();
578 }
579
580 bool BaseMultipleFieldsDateAndTimeInputType::shouldClearButtonRespondToMouseEvents()
581 {
582     return !element().isDisabledOrReadOnly() && !element().isRequired();
583 }
584
585 void BaseMultipleFieldsDateAndTimeInputType::clearValue()
586 {
587     RefPtr<HTMLInputElement> input(element());
588     input->setValue("", DispatchInputAndChangeEvent);
589     input->updateClearButtonVisibility();
590 }
591
592 void BaseMultipleFieldsDateAndTimeInputType::updateClearButtonVisibility()
593 {
594     ClearButtonElement* clearButton = clearButtonElement();
595     if (!clearButton)
596         return;
597
598     if (element().isRequired() || !dateTimeEditElement()->anyEditableFieldsHaveValues()) {
599         clearButton->setInlineStyleProperty(CSSPropertyOpacity, 0.0, CSSPrimitiveValue::CSS_NUMBER);
600         clearButton->setInlineStyleProperty(CSSPropertyPointerEvents, CSSValueNone);
601     } else {
602         clearButton->removeInlineStyleProperty(CSSPropertyOpacity);
603         clearButton->removeInlineStyleProperty(CSSPropertyPointerEvents);
604     }
605 }
606
607 } // namespace WebCore
608
609 #endif