Index: third_party/WebKit/Source/core/html/shadow/DateTimeEditElement.cpp |
diff --git a/third_party/WebKit/Source/core/html/shadow/DateTimeEditElement.cpp b/third_party/WebKit/Source/core/html/shadow/DateTimeEditElement.cpp |
deleted file mode 100644 |
index 484b3d58c19743a7dd68076cfdc7e18705c2932a..0000000000000000000000000000000000000000 |
--- a/third_party/WebKit/Source/core/html/shadow/DateTimeEditElement.cpp |
+++ /dev/null |
@@ -1,872 +0,0 @@ |
-/* |
- * Copyright (C) 2012 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 "core/html/shadow/DateTimeEditElement.h" |
- |
-#include "bindings/core/v8/ExceptionState.h" |
-#include "core/HTMLNames.h" |
-#include "core/dom/Document.h" |
-#include "core/dom/StyleChangeReason.h" |
-#include "core/dom/Text.h" |
-#include "core/events/MouseEvent.h" |
-#include "core/html/forms/DateTimeFieldsState.h" |
-#include "core/html/shadow/DateTimeFieldElements.h" |
-#include "core/html/shadow/ShadowElementNames.h" |
-#include "core/style/ComputedStyle.h" |
-#include "core/style/StyleInheritedData.h" |
-#include "platform/fonts/FontCache.h" |
-#include "platform/text/DateTimeFormat.h" |
-#include "platform/text/PlatformLocale.h" |
-#include "platform/wtf/DateMath.h" |
- |
-namespace blink { |
- |
-using namespace HTMLNames; |
-using namespace WTF::Unicode; |
- |
-class DateTimeEditBuilder : private DateTimeFormat::TokenHandler { |
- public: |
- // The argument objects must be alive until this object dies. |
- DateTimeEditBuilder(DateTimeEditElement&, |
- const DateTimeEditElement::LayoutParameters&, |
- const DateComponents&); |
- |
- bool Build(const String&); |
- |
- private: |
- bool NeedMillisecondField() const; |
- bool ShouldAMPMFieldDisabled() const; |
- bool ShouldDayOfMonthFieldDisabled() const; |
- bool ShouldHourFieldDisabled() const; |
- bool ShouldMillisecondFieldDisabled() const; |
- bool ShouldMinuteFieldDisabled() const; |
- bool ShouldSecondFieldDisabled() const; |
- bool ShouldYearFieldDisabled() const; |
- inline const StepRange& GetStepRange() const { |
- return parameters_.step_range; |
- } |
- DateTimeNumericFieldElement::Step CreateStep(double ms_per_field_unit, |
- double ms_per_field_size) const; |
- |
- // DateTimeFormat::TokenHandler functions. |
- void VisitField(DateTimeFormat::FieldType, int) final; |
- void VisitLiteral(const String&) final; |
- |
- DateTimeEditElement& EditElement() const; |
- |
- Member<DateTimeEditElement> edit_element_; |
- const DateComponents date_value_; |
- const DateTimeEditElement::LayoutParameters& parameters_; |
- DateTimeNumericFieldElement::Range day_range_; |
- DateTimeNumericFieldElement::Range hour23_range_; |
- DateTimeNumericFieldElement::Range minute_range_; |
- DateTimeNumericFieldElement::Range second_range_; |
- DateTimeNumericFieldElement::Range millisecond_range_; |
-}; |
- |
-DateTimeEditBuilder::DateTimeEditBuilder( |
- DateTimeEditElement& element, |
- const DateTimeEditElement::LayoutParameters& layout_parameters, |
- const DateComponents& date_value) |
- : edit_element_(&element), |
- date_value_(date_value), |
- parameters_(layout_parameters), |
- day_range_(1, 31), |
- hour23_range_(0, 23), |
- minute_range_(0, 59), |
- second_range_(0, 59), |
- millisecond_range_(0, 999) { |
- if (date_value_.GetType() == DateComponents::kDate || |
- date_value_.GetType() == DateComponents::kDateTimeLocal) { |
- if (parameters_.minimum.GetType() != DateComponents::kInvalid && |
- parameters_.maximum.GetType() != DateComponents::kInvalid && |
- parameters_.minimum.FullYear() == parameters_.maximum.FullYear() && |
- parameters_.minimum.Month() == parameters_.maximum.Month() && |
- parameters_.minimum.MonthDay() <= parameters_.maximum.MonthDay()) { |
- day_range_.minimum = parameters_.minimum.MonthDay(); |
- day_range_.maximum = parameters_.maximum.MonthDay(); |
- } |
- } |
- |
- if (date_value_.GetType() == DateComponents::kTime || |
- day_range_.IsSingleton()) { |
- if (parameters_.minimum.GetType() != DateComponents::kInvalid && |
- parameters_.maximum.GetType() != DateComponents::kInvalid && |
- parameters_.minimum.Hour() <= parameters_.maximum.Hour()) { |
- hour23_range_.minimum = parameters_.minimum.Hour(); |
- hour23_range_.maximum = parameters_.maximum.Hour(); |
- } |
- } |
- |
- if (hour23_range_.IsSingleton() && |
- parameters_.minimum.Minute() <= parameters_.maximum.Minute()) { |
- minute_range_.minimum = parameters_.minimum.Minute(); |
- minute_range_.maximum = parameters_.maximum.Minute(); |
- } |
- if (minute_range_.IsSingleton() && |
- parameters_.minimum.Second() <= parameters_.maximum.Second()) { |
- second_range_.minimum = parameters_.minimum.Second(); |
- second_range_.maximum = parameters_.maximum.Second(); |
- } |
- if (second_range_.IsSingleton() && |
- parameters_.minimum.Millisecond() <= parameters_.maximum.Millisecond()) { |
- millisecond_range_.minimum = parameters_.minimum.Millisecond(); |
- millisecond_range_.maximum = parameters_.maximum.Millisecond(); |
- } |
-} |
- |
-bool DateTimeEditBuilder::Build(const String& format_string) { |
- EditElement().ResetFields(); |
- return DateTimeFormat::Parse(format_string, *this); |
-} |
- |
-bool DateTimeEditBuilder::NeedMillisecondField() const { |
- return date_value_.Millisecond() || |
- !GetStepRange() |
- .Minimum() |
- .Remainder(static_cast<int>(kMsPerSecond)) |
- .IsZero() || |
- !GetStepRange() |
- .Step() |
- .Remainder(static_cast<int>(kMsPerSecond)) |
- .IsZero(); |
-} |
- |
-void DateTimeEditBuilder::VisitField(DateTimeFormat::FieldType field_type, |
- int count) { |
- const int kCountForAbbreviatedMonth = 3; |
- const int kCountForFullMonth = 4; |
- const int kCountForNarrowMonth = 5; |
- Document& document = EditElement().GetDocument(); |
- |
- switch (field_type) { |
- case DateTimeFormat::kFieldTypeDayOfMonth: { |
- DateTimeFieldElement* field = DateTimeDayFieldElement::Create( |
- document, EditElement(), parameters_.placeholder_for_day, day_range_); |
- EditElement().AddField(field); |
- if (ShouldDayOfMonthFieldDisabled()) { |
- field->SetValueAsDate(date_value_); |
- field->SetDisabled(); |
- } |
- return; |
- } |
- |
- case DateTimeFormat::kFieldTypeHour11: { |
- DateTimeNumericFieldElement::Step step = |
- CreateStep(kMsPerHour, kMsPerHour * 12); |
- DateTimeFieldElement* field = DateTimeHour11FieldElement::Create( |
- document, EditElement(), hour23_range_, step); |
- EditElement().AddField(field); |
- if (ShouldHourFieldDisabled()) { |
- field->SetValueAsDate(date_value_); |
- field->SetDisabled(); |
- } |
- return; |
- } |
- |
- case DateTimeFormat::kFieldTypeHour12: { |
- DateTimeNumericFieldElement::Step step = |
- CreateStep(kMsPerHour, kMsPerHour * 12); |
- DateTimeFieldElement* field = DateTimeHour12FieldElement::Create( |
- document, EditElement(), hour23_range_, step); |
- EditElement().AddField(field); |
- if (ShouldHourFieldDisabled()) { |
- field->SetValueAsDate(date_value_); |
- field->SetDisabled(); |
- } |
- return; |
- } |
- |
- case DateTimeFormat::kFieldTypeHour23: { |
- DateTimeNumericFieldElement::Step step = |
- CreateStep(kMsPerHour, kMsPerDay); |
- DateTimeFieldElement* field = DateTimeHour23FieldElement::Create( |
- document, EditElement(), hour23_range_, step); |
- EditElement().AddField(field); |
- if (ShouldHourFieldDisabled()) { |
- field->SetValueAsDate(date_value_); |
- field->SetDisabled(); |
- } |
- return; |
- } |
- |
- case DateTimeFormat::kFieldTypeHour24: { |
- DateTimeNumericFieldElement::Step step = |
- CreateStep(kMsPerHour, kMsPerDay); |
- DateTimeFieldElement* field = DateTimeHour24FieldElement::Create( |
- document, EditElement(), hour23_range_, step); |
- EditElement().AddField(field); |
- if (ShouldHourFieldDisabled()) { |
- field->SetValueAsDate(date_value_); |
- field->SetDisabled(); |
- } |
- return; |
- } |
- |
- case DateTimeFormat::kFieldTypeMinute: { |
- DateTimeNumericFieldElement::Step step = |
- CreateStep(kMsPerMinute, kMsPerHour); |
- DateTimeNumericFieldElement* field = DateTimeMinuteFieldElement::Create( |
- document, EditElement(), minute_range_, step); |
- EditElement().AddField(field); |
- if (ShouldMinuteFieldDisabled()) { |
- field->SetValueAsDate(date_value_); |
- field->SetDisabled(); |
- } |
- return; |
- } |
- |
- case DateTimeFormat::kFieldTypeMonth: // Fallthrough. |
- case DateTimeFormat::kFieldTypeMonthStandAlone: { |
- int min_month = 0, max_month = 11; |
- if (parameters_.minimum.GetType() != DateComponents::kInvalid && |
- parameters_.maximum.GetType() != DateComponents::kInvalid && |
- parameters_.minimum.FullYear() == parameters_.maximum.FullYear() && |
- parameters_.minimum.Month() <= parameters_.maximum.Month()) { |
- min_month = parameters_.minimum.Month(); |
- max_month = parameters_.maximum.Month(); |
- } |
- DateTimeFieldElement* field; |
- switch (count) { |
- case kCountForNarrowMonth: // Fallthrough. |
- case kCountForAbbreviatedMonth: |
- field = DateTimeSymbolicMonthFieldElement::Create( |
- document, EditElement(), |
- field_type == DateTimeFormat::kFieldTypeMonth |
- ? parameters_.locale.ShortMonthLabels() |
- : parameters_.locale.ShortStandAloneMonthLabels(), |
- min_month, max_month); |
- break; |
- case kCountForFullMonth: |
- field = DateTimeSymbolicMonthFieldElement::Create( |
- document, EditElement(), |
- field_type == DateTimeFormat::kFieldTypeMonth |
- ? parameters_.locale.MonthLabels() |
- : parameters_.locale.StandAloneMonthLabels(), |
- min_month, max_month); |
- break; |
- default: |
- field = DateTimeMonthFieldElement::Create( |
- document, EditElement(), parameters_.placeholder_for_month, |
- DateTimeNumericFieldElement::Range(min_month + 1, max_month + 1)); |
- break; |
- } |
- EditElement().AddField(field); |
- if (min_month == max_month && min_month == date_value_.Month() && |
- date_value_.GetType() != DateComponents::kMonth) { |
- field->SetValueAsDate(date_value_); |
- field->SetDisabled(); |
- } |
- return; |
- } |
- |
- case DateTimeFormat::kFieldTypePeriod: { |
- DateTimeFieldElement* field = DateTimeAMPMFieldElement::Create( |
- document, EditElement(), parameters_.locale.TimeAMPMLabels()); |
- EditElement().AddField(field); |
- if (ShouldAMPMFieldDisabled()) { |
- field->SetValueAsDate(date_value_); |
- field->SetDisabled(); |
- } |
- return; |
- } |
- |
- case DateTimeFormat::kFieldTypeSecond: { |
- DateTimeNumericFieldElement::Step step = |
- CreateStep(kMsPerSecond, kMsPerMinute); |
- DateTimeNumericFieldElement* field = DateTimeSecondFieldElement::Create( |
- document, EditElement(), second_range_, step); |
- EditElement().AddField(field); |
- if (ShouldSecondFieldDisabled()) { |
- field->SetValueAsDate(date_value_); |
- field->SetDisabled(); |
- } |
- |
- if (NeedMillisecondField()) { |
- VisitLiteral(parameters_.locale.LocalizedDecimalSeparator()); |
- VisitField(DateTimeFormat::kFieldTypeFractionalSecond, 3); |
- } |
- return; |
- } |
- |
- case DateTimeFormat::kFieldTypeFractionalSecond: { |
- DateTimeNumericFieldElement::Step step = CreateStep(1, kMsPerSecond); |
- DateTimeNumericFieldElement* field = |
- DateTimeMillisecondFieldElement::Create(document, EditElement(), |
- millisecond_range_, step); |
- EditElement().AddField(field); |
- if (ShouldMillisecondFieldDisabled()) { |
- field->SetValueAsDate(date_value_); |
- field->SetDisabled(); |
- } |
- return; |
- } |
- |
- case DateTimeFormat::kFieldTypeWeekOfYear: { |
- DateTimeNumericFieldElement::Range range( |
- DateComponents::kMinimumWeekNumber, |
- DateComponents::kMaximumWeekNumber); |
- if (parameters_.minimum.GetType() != DateComponents::kInvalid && |
- parameters_.maximum.GetType() != DateComponents::kInvalid && |
- parameters_.minimum.FullYear() == parameters_.maximum.FullYear() && |
- parameters_.minimum.Week() <= parameters_.maximum.Week()) { |
- range.minimum = parameters_.minimum.Week(); |
- range.maximum = parameters_.maximum.Week(); |
- } |
- EditElement().AddField( |
- DateTimeWeekFieldElement::Create(document, EditElement(), range)); |
- return; |
- } |
- |
- case DateTimeFormat::kFieldTypeYear: { |
- DateTimeYearFieldElement::Parameters year_params; |
- if (parameters_.minimum.GetType() == DateComponents::kInvalid) { |
- year_params.minimum_year = DateComponents::MinimumYear(); |
- year_params.min_is_specified = false; |
- } else { |
- year_params.minimum_year = parameters_.minimum.FullYear(); |
- year_params.min_is_specified = true; |
- } |
- if (parameters_.maximum.GetType() == DateComponents::kInvalid) { |
- year_params.maximum_year = DateComponents::MaximumYear(); |
- year_params.max_is_specified = false; |
- } else { |
- year_params.maximum_year = parameters_.maximum.FullYear(); |
- year_params.max_is_specified = true; |
- } |
- if (year_params.minimum_year > year_params.maximum_year) { |
- std::swap(year_params.minimum_year, year_params.maximum_year); |
- std::swap(year_params.min_is_specified, year_params.max_is_specified); |
- } |
- year_params.placeholder = parameters_.placeholder_for_year; |
- DateTimeFieldElement* field = DateTimeYearFieldElement::Create( |
- document, EditElement(), year_params); |
- EditElement().AddField(field); |
- if (ShouldYearFieldDisabled()) { |
- field->SetValueAsDate(date_value_); |
- field->SetDisabled(); |
- } |
- return; |
- } |
- |
- default: |
- return; |
- } |
-} |
- |
-bool DateTimeEditBuilder::ShouldAMPMFieldDisabled() const { |
- return ShouldHourFieldDisabled() || |
- (hour23_range_.minimum < 12 && hour23_range_.maximum < 12 && |
- date_value_.Hour() < 12) || |
- (hour23_range_.minimum >= 12 && hour23_range_.maximum >= 12 && |
- date_value_.Hour() >= 12); |
-} |
- |
-bool DateTimeEditBuilder::ShouldDayOfMonthFieldDisabled() const { |
- return day_range_.IsSingleton() && |
- day_range_.minimum == date_value_.MonthDay() && |
- date_value_.GetType() != DateComponents::kDate; |
-} |
- |
-bool DateTimeEditBuilder::ShouldHourFieldDisabled() const { |
- if (hour23_range_.IsSingleton() && |
- hour23_range_.minimum == date_value_.Hour() && |
- !(ShouldMinuteFieldDisabled() && ShouldSecondFieldDisabled() && |
- ShouldMillisecondFieldDisabled())) |
- return true; |
- |
- if (date_value_.GetType() == DateComponents::kTime) |
- return false; |
- DCHECK_EQ(date_value_.GetType(), DateComponents::kDateTimeLocal); |
- |
- if (ShouldDayOfMonthFieldDisabled()) { |
- DCHECK_EQ(parameters_.minimum.FullYear(), parameters_.maximum.FullYear()); |
- DCHECK_EQ(parameters_.minimum.Month(), parameters_.maximum.Month()); |
- return false; |
- } |
- |
- const Decimal decimal_ms_per_day(static_cast<int>(kMsPerDay)); |
- Decimal hour_part_of_minimum = |
- (GetStepRange().StepBase().Abs().Remainder(decimal_ms_per_day) / |
- static_cast<int>(kMsPerHour)) |
- .Floor(); |
- return hour_part_of_minimum == date_value_.Hour() && |
- GetStepRange().Step().Remainder(decimal_ms_per_day).IsZero(); |
-} |
- |
-bool DateTimeEditBuilder::ShouldMillisecondFieldDisabled() const { |
- if (millisecond_range_.IsSingleton() && |
- millisecond_range_.minimum == date_value_.Millisecond()) |
- return true; |
- |
- const Decimal decimal_ms_per_second(static_cast<int>(kMsPerSecond)); |
- return GetStepRange().StepBase().Abs().Remainder(decimal_ms_per_second) == |
- date_value_.Millisecond() && |
- GetStepRange().Step().Remainder(decimal_ms_per_second).IsZero(); |
-} |
- |
-bool DateTimeEditBuilder::ShouldMinuteFieldDisabled() const { |
- if (minute_range_.IsSingleton() && |
- minute_range_.minimum == date_value_.Minute()) |
- return true; |
- |
- const Decimal decimal_ms_per_hour(static_cast<int>(kMsPerHour)); |
- Decimal minute_part_of_minimum = |
- (GetStepRange().StepBase().Abs().Remainder(decimal_ms_per_hour) / |
- static_cast<int>(kMsPerMinute)) |
- .Floor(); |
- return minute_part_of_minimum == date_value_.Minute() && |
- GetStepRange().Step().Remainder(decimal_ms_per_hour).IsZero(); |
-} |
- |
-bool DateTimeEditBuilder::ShouldSecondFieldDisabled() const { |
- if (second_range_.IsSingleton() && |
- second_range_.minimum == date_value_.Second()) |
- return true; |
- |
- const Decimal decimal_ms_per_minute(static_cast<int>(kMsPerMinute)); |
- Decimal second_part_of_minimum = |
- (GetStepRange().StepBase().Abs().Remainder(decimal_ms_per_minute) / |
- static_cast<int>(kMsPerSecond)) |
- .Floor(); |
- return second_part_of_minimum == date_value_.Second() && |
- GetStepRange().Step().Remainder(decimal_ms_per_minute).IsZero(); |
-} |
- |
-bool DateTimeEditBuilder::ShouldYearFieldDisabled() const { |
- return parameters_.minimum.GetType() != DateComponents::kInvalid && |
- parameters_.maximum.GetType() != DateComponents::kInvalid && |
- parameters_.minimum.FullYear() == parameters_.maximum.FullYear() && |
- parameters_.minimum.FullYear() == date_value_.FullYear(); |
-} |
- |
-void DateTimeEditBuilder::VisitLiteral(const String& text) { |
- DEFINE_STATIC_LOCAL(AtomicString, text_pseudo_id, |
- ("-webkit-datetime-edit-text")); |
- DCHECK_GT(text.length(), 0u); |
- HTMLDivElement* element = HTMLDivElement::Create(EditElement().GetDocument()); |
- element->SetShadowPseudoId(text_pseudo_id); |
- if (parameters_.locale.IsRTL() && text.length()) { |
- CharDirection dir = Direction(text[0]); |
- if (dir == kSegmentSeparator || dir == kWhiteSpaceNeutral || |
- dir == kOtherNeutral) |
- element->AppendChild(Text::Create(EditElement().GetDocument(), |
- String(&kRightToLeftMarkCharacter, 1))); |
- } |
- element->AppendChild(Text::Create(EditElement().GetDocument(), text)); |
- EditElement().FieldsWrapperElement()->AppendChild(element); |
-} |
- |
-DateTimeEditElement& DateTimeEditBuilder::EditElement() const { |
- return *edit_element_; |
-} |
- |
-DateTimeNumericFieldElement::Step DateTimeEditBuilder::CreateStep( |
- double ms_per_field_unit, |
- double ms_per_field_size) const { |
- const Decimal ms_per_field_unit_decimal(static_cast<int>(ms_per_field_unit)); |
- const Decimal ms_per_field_size_decimal(static_cast<int>(ms_per_field_size)); |
- Decimal step_milliseconds = GetStepRange().Step(); |
- DCHECK(!ms_per_field_unit_decimal.IsZero()); |
- DCHECK(!ms_per_field_size_decimal.IsZero()); |
- DCHECK(!step_milliseconds.IsZero()); |
- |
- DateTimeNumericFieldElement::Step step(1, 0); |
- |
- if (step_milliseconds.Remainder(ms_per_field_size_decimal).IsZero()) |
- step_milliseconds = ms_per_field_size_decimal; |
- |
- if (ms_per_field_size_decimal.Remainder(step_milliseconds).IsZero() && |
- step_milliseconds.Remainder(ms_per_field_unit_decimal).IsZero()) { |
- step.step = static_cast<int>( |
- (step_milliseconds / ms_per_field_unit_decimal).ToDouble()); |
- step.step_base = static_cast<int>( |
- (GetStepRange().StepBase() / ms_per_field_unit_decimal) |
- .Floor() |
- .Remainder(ms_per_field_size_decimal / ms_per_field_unit_decimal) |
- .ToDouble()); |
- } |
- return step; |
-} |
- |
-// ---------------------------- |
- |
-DateTimeEditElement::EditControlOwner::~EditControlOwner() {} |
- |
-DateTimeEditElement::DateTimeEditElement(Document& document, |
- EditControlOwner& edit_control_owner) |
- : HTMLDivElement(document), edit_control_owner_(&edit_control_owner) { |
- SetHasCustomStyleCallbacks(); |
-} |
- |
-DateTimeEditElement::~DateTimeEditElement() {} |
- |
-DEFINE_TRACE(DateTimeEditElement) { |
- visitor->Trace(fields_); |
- visitor->Trace(edit_control_owner_); |
- HTMLDivElement::Trace(visitor); |
-} |
- |
-inline Element* DateTimeEditElement::FieldsWrapperElement() const { |
- DCHECK(FirstChild()); |
- return ToElementOrDie(FirstChild()); |
-} |
- |
-void DateTimeEditElement::AddField(DateTimeFieldElement* field) { |
- if (fields_.size() >= kMaximumNumberOfFields) |
- return; |
- fields_.push_back(field); |
- FieldsWrapperElement()->AppendChild(field); |
-} |
- |
-bool DateTimeEditElement::AnyEditableFieldsHaveValues() const { |
- for (const auto& field : fields_) { |
- if (!field->IsDisabled() && field->HasValue()) |
- return true; |
- } |
- return false; |
-} |
- |
-void DateTimeEditElement::BlurByOwner() { |
- if (DateTimeFieldElement* field = FocusedField()) |
- field->blur(); |
-} |
- |
-DateTimeEditElement* DateTimeEditElement::Create( |
- Document& document, |
- EditControlOwner& edit_control_owner) { |
- DateTimeEditElement* container = |
- new DateTimeEditElement(document, edit_control_owner); |
- container->SetShadowPseudoId(AtomicString("-webkit-datetime-edit")); |
- container->setAttribute(idAttr, ShadowElementNames::DateTimeEdit()); |
- return container; |
-} |
- |
-PassRefPtr<ComputedStyle> DateTimeEditElement::CustomStyleForLayoutObject() { |
- // FIXME: This is a kind of layout. We might want to introduce new |
- // layoutObject. |
- RefPtr<ComputedStyle> original_style = OriginalStyleForLayoutObject(); |
- RefPtr<ComputedStyle> style = ComputedStyle::Clone(*original_style); |
- float width = 0; |
- for (Node* child = FieldsWrapperElement()->FirstChild(); child; |
- child = child->nextSibling()) { |
- if (!child->IsElementNode()) |
- continue; |
- Element* child_element = ToElement(child); |
- if (child_element->IsDateTimeFieldElement()) { |
- // We need to pass the ComputedStyle of this element because child |
- // elements can't resolve inherited style at this timing. |
- width += static_cast<DateTimeFieldElement*>(child_element) |
- ->MaximumWidth(*style); |
- } else { |
- // ::-webkit-datetime-edit-text case. It has no |
- // border/padding/margin in html.css. |
- width += DateTimeFieldElement::ComputeTextWidth( |
- *style, child_element->textContent()); |
- } |
- } |
- style->SetWidth(Length(ceilf(width), kFixed)); |
- style->SetUnique(); |
- return style.Release(); |
-} |
- |
-void DateTimeEditElement::DidBlurFromField(WebFocusType focus_type) { |
- if (edit_control_owner_) |
- edit_control_owner_->DidBlurFromControl(focus_type); |
-} |
- |
-void DateTimeEditElement::DidFocusOnField(WebFocusType focus_type) { |
- if (edit_control_owner_) |
- edit_control_owner_->DidFocusOnControl(focus_type); |
-} |
- |
-void DateTimeEditElement::DisabledStateChanged() { |
- UpdateUIState(); |
-} |
- |
-DateTimeFieldElement* DateTimeEditElement::FieldAt(size_t field_index) const { |
- return field_index < fields_.size() ? fields_[field_index].Get() : 0; |
-} |
- |
-size_t DateTimeEditElement::FieldIndexOf( |
- const DateTimeFieldElement& field) const { |
- for (size_t field_index = 0; field_index < fields_.size(); ++field_index) { |
- if (fields_[field_index] == &field) |
- return field_index; |
- } |
- return kInvalidFieldIndex; |
-} |
- |
-void DateTimeEditElement::FocusIfNoFocus() { |
- if (FocusedFieldIndex() != kInvalidFieldIndex) |
- return; |
- FocusOnNextFocusableField(0); |
-} |
- |
-void DateTimeEditElement::FocusByOwner(Element* old_focused_element) { |
- if (old_focused_element && old_focused_element->IsDateTimeFieldElement()) { |
- DateTimeFieldElement* old_focused_field = |
- static_cast<DateTimeFieldElement*>(old_focused_element); |
- size_t index = FieldIndexOf(*old_focused_field); |
- GetDocument().UpdateStyleAndLayoutTreeForNode(old_focused_field); |
- if (index != kInvalidFieldIndex && old_focused_field->IsFocusable()) { |
- old_focused_field->focus(); |
- return; |
- } |
- } |
- FocusOnNextFocusableField(0); |
-} |
- |
-DateTimeFieldElement* DateTimeEditElement::FocusedField() const { |
- return FieldAt(FocusedFieldIndex()); |
-} |
- |
-size_t DateTimeEditElement::FocusedFieldIndex() const { |
- Element* const focused_field_element = GetDocument().FocusedElement(); |
- for (size_t field_index = 0; field_index < fields_.size(); ++field_index) { |
- if (fields_[field_index] == focused_field_element) |
- return field_index; |
- } |
- return kInvalidFieldIndex; |
-} |
- |
-void DateTimeEditElement::FieldValueChanged() { |
- if (edit_control_owner_) |
- edit_control_owner_->EditControlValueChanged(); |
-} |
- |
-bool DateTimeEditElement::FocusOnNextFocusableField(size_t start_index) { |
- GetDocument().UpdateStyleAndLayoutTreeIgnorePendingStylesheets(); |
- for (size_t field_index = start_index; field_index < fields_.size(); |
- ++field_index) { |
- if (fields_[field_index]->IsFocusable()) { |
- fields_[field_index]->focus(); |
- return true; |
- } |
- } |
- return false; |
-} |
- |
-bool DateTimeEditElement::FocusOnNextField(const DateTimeFieldElement& field) { |
- const size_t start_field_index = FieldIndexOf(field); |
- if (start_field_index == kInvalidFieldIndex) |
- return false; |
- return FocusOnNextFocusableField(start_field_index + 1); |
-} |
- |
-bool DateTimeEditElement::FocusOnPreviousField( |
- const DateTimeFieldElement& field) { |
- const size_t start_field_index = FieldIndexOf(field); |
- if (start_field_index == kInvalidFieldIndex) |
- return false; |
- GetDocument().UpdateStyleAndLayoutTreeIgnorePendingStylesheets(); |
- size_t field_index = start_field_index; |
- while (field_index > 0) { |
- --field_index; |
- if (fields_[field_index]->IsFocusable()) { |
- fields_[field_index]->focus(); |
- return true; |
- } |
- } |
- return false; |
-} |
- |
-bool DateTimeEditElement::IsDateTimeEditElement() const { |
- return true; |
-} |
- |
-bool DateTimeEditElement::IsDisabled() const { |
- return edit_control_owner_ && |
- edit_control_owner_->IsEditControlOwnerDisabled(); |
-} |
- |
-bool DateTimeEditElement::IsFieldOwnerDisabled() const { |
- return IsDisabled(); |
-} |
- |
-bool DateTimeEditElement::IsFieldOwnerReadOnly() const { |
- return IsReadOnly(); |
-} |
- |
-bool DateTimeEditElement::IsReadOnly() const { |
- return edit_control_owner_ && |
- edit_control_owner_->IsEditControlOwnerReadOnly(); |
-} |
- |
-void DateTimeEditElement::GetLayout(const LayoutParameters& layout_parameters, |
- const DateComponents& date_value) { |
- // TODO(tkent): We assume this function never dispatches events. However this |
- // can dispatch 'blur' event in Node::removeChild(). |
- |
- DEFINE_STATIC_LOCAL(AtomicString, fields_wrapper_pseudo_id, |
- ("-webkit-datetime-edit-fields-wrapper")); |
- if (!HasChildren()) { |
- HTMLDivElement* element = HTMLDivElement::Create(GetDocument()); |
- element->SetShadowPseudoId(fields_wrapper_pseudo_id); |
- AppendChild(element); |
- } |
- Element* fields_wrapper = FieldsWrapperElement(); |
- |
- size_t focused_field_index = this->FocusedFieldIndex(); |
- DateTimeFieldElement* const focused_field = FieldAt(focused_field_index); |
- const AtomicString focused_field_id = |
- focused_field ? focused_field->ShadowPseudoId() : g_null_atom; |
- |
- DateTimeEditBuilder builder(*this, layout_parameters, date_value); |
- Node* last_child_to_be_removed = fields_wrapper->LastChild(); |
- if (!builder.Build(layout_parameters.date_time_format) || fields_.IsEmpty()) { |
- last_child_to_be_removed = fields_wrapper->LastChild(); |
- builder.Build(layout_parameters.fallback_date_time_format); |
- } |
- |
- if (focused_field_index != kInvalidFieldIndex) { |
- for (size_t field_index = 0; field_index < fields_.size(); ++field_index) { |
- if (fields_[field_index]->ShadowPseudoId() == focused_field_id) { |
- focused_field_index = field_index; |
- break; |
- } |
- } |
- if (DateTimeFieldElement* field = |
- FieldAt(std::min(focused_field_index, fields_.size() - 1))) |
- field->focus(); |
- } |
- |
- if (last_child_to_be_removed) { |
- for (Node* child_node = fields_wrapper->FirstChild(); child_node; |
- child_node = fields_wrapper->FirstChild()) { |
- fields_wrapper->RemoveChild(child_node); |
- if (child_node == last_child_to_be_removed) |
- break; |
- } |
- SetNeedsStyleRecalc( |
- kSubtreeStyleChange, |
- StyleChangeReasonForTracing::Create(StyleChangeReason::kControl)); |
- } |
-} |
- |
-AtomicString DateTimeEditElement::LocaleIdentifier() const { |
- return edit_control_owner_ ? edit_control_owner_->LocaleIdentifier() |
- : g_null_atom; |
-} |
- |
-void DateTimeEditElement::FieldDidChangeValueByKeyboard() { |
- if (edit_control_owner_) |
- edit_control_owner_->EditControlDidChangeValueByKeyboard(); |
-} |
- |
-void DateTimeEditElement::ReadOnlyStateChanged() { |
- UpdateUIState(); |
-} |
- |
-void DateTimeEditElement::ResetFields() { |
- for (const auto& field : fields_) |
- field->RemoveEventHandler(); |
- fields_.Shrink(0); |
-} |
- |
-void DateTimeEditElement::DefaultEventHandler(Event* event) { |
- // In case of control owner forward event to control, e.g. DOM |
- // dispatchEvent method. |
- if (DateTimeFieldElement* field = FocusedField()) { |
- field->DefaultEventHandler(event); |
- if (event->DefaultHandled()) |
- return; |
- } |
- |
- HTMLDivElement::DefaultEventHandler(event); |
-} |
- |
-void DateTimeEditElement::SetValueAsDate( |
- const LayoutParameters& layout_parameters, |
- const DateComponents& date) { |
- GetLayout(layout_parameters, date); |
- for (const auto& field : fields_) |
- field->SetValueAsDate(date); |
-} |
- |
-void DateTimeEditElement::SetValueAsDateTimeFieldsState( |
- const DateTimeFieldsState& date_time_fields_state) { |
- for (const auto& field : fields_) |
- field->SetValueAsDateTimeFieldsState(date_time_fields_state); |
-} |
- |
-void DateTimeEditElement::SetEmptyValue( |
- const LayoutParameters& layout_parameters, |
- const DateComponents& date_for_read_only_field) { |
- GetLayout(layout_parameters, date_for_read_only_field); |
- for (const auto& field : fields_) |
- field->SetEmptyValue(DateTimeFieldElement::kDispatchNoEvent); |
-} |
- |
-bool DateTimeEditElement::HasFocusedField() { |
- return FocusedFieldIndex() != kInvalidFieldIndex; |
-} |
- |
-void DateTimeEditElement::SetOnlyYearMonthDay(const DateComponents& date) { |
- DCHECK_EQ(date.GetType(), DateComponents::kDate); |
- |
- if (!edit_control_owner_) |
- return; |
- |
- DateTimeFieldsState date_time_fields_state = ValueAsDateTimeFieldsState(); |
- date_time_fields_state.SetYear(date.FullYear()); |
- date_time_fields_state.SetMonth(date.Month() + 1); |
- date_time_fields_state.SetDayOfMonth(date.MonthDay()); |
- SetValueAsDateTimeFieldsState(date_time_fields_state); |
- edit_control_owner_->EditControlValueChanged(); |
-} |
- |
-void DateTimeEditElement::StepDown() { |
- if (DateTimeFieldElement* const field = FocusedField()) |
- field->StepDown(); |
-} |
- |
-void DateTimeEditElement::StepUp() { |
- if (DateTimeFieldElement* const field = FocusedField()) |
- field->StepUp(); |
-} |
- |
-void DateTimeEditElement::UpdateUIState() { |
- if (IsDisabled()) { |
- if (DateTimeFieldElement* field = FocusedField()) |
- field->blur(); |
- } |
-} |
- |
-String DateTimeEditElement::Value() const { |
- if (!edit_control_owner_) |
- return g_empty_string; |
- return edit_control_owner_->FormatDateTimeFieldsState( |
- ValueAsDateTimeFieldsState()); |
-} |
- |
-DateTimeFieldsState DateTimeEditElement::ValueAsDateTimeFieldsState() const { |
- DateTimeFieldsState date_time_fields_state; |
- for (const auto& field : fields_) |
- field->PopulateDateTimeFieldsState(date_time_fields_state); |
- return date_time_fields_state; |
-} |
- |
-} // namespace blink |