Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(23)

Side by Side Diff: third_party/WebKit/Source/core/html/shadow/DateTimeNumericFieldElement.cpp

Issue 2815263002: Move form-related files in core/html/shadow to core/html/forms. (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2012 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
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
20 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 */
25
26 #include "core/html/shadow/DateTimeNumericFieldElement.h"
27
28 #include "core/CSSPropertyNames.h"
29 #include "core/CSSValueKeywords.h"
30 #include "core/events/KeyboardEvent.h"
31 #include "platform/fonts/Font.h"
32 #include "platform/text/PlatformLocale.h"
33 #include "platform/text/TextRun.h"
34
35 namespace blink {
36
37 int DateTimeNumericFieldElement::Range::ClampValue(int value) const {
38 return std::min(std::max(value, minimum), maximum);
39 }
40
41 bool DateTimeNumericFieldElement::Range::IsInRange(int value) const {
42 return value >= minimum && value <= maximum;
43 }
44
45 // ----------------------------
46
47 DateTimeNumericFieldElement::DateTimeNumericFieldElement(
48 Document& document,
49 FieldOwner& field_owner,
50 const Range& range,
51 const Range& hard_limits,
52 const String& placeholder,
53 const DateTimeNumericFieldElement::Step& step)
54 : DateTimeFieldElement(document, field_owner),
55 placeholder_(placeholder),
56 range_(range),
57 hard_limits_(hard_limits),
58 step_(step),
59 value_(0),
60 has_value_(false) {
61 DCHECK_NE(step_.step, 0);
62 DCHECK_LE(range_.minimum, range_.maximum);
63 DCHECK_LE(hard_limits_.minimum, hard_limits_.maximum);
64
65 // We show a direction-neutral string such as "--" as a placeholder. It
66 // should follow the direction of numeric values.
67 if (LocaleForOwner().IsRTL()) {
68 WTF::Unicode::CharDirection dir =
69 WTF::Unicode::Direction(FormatValue(this->Maximum())[0]);
70 if (dir == WTF::Unicode::kLeftToRight ||
71 dir == WTF::Unicode::kEuropeanNumber ||
72 dir == WTF::Unicode::kArabicNumber) {
73 SetInlineStyleProperty(CSSPropertyUnicodeBidi, CSSValueBidiOverride);
74 SetInlineStyleProperty(CSSPropertyDirection, CSSValueLtr);
75 }
76 }
77 }
78
79 float DateTimeNumericFieldElement::MaximumWidth(const ComputedStyle& style) {
80 float maximum_width = ComputeTextWidth(style, placeholder_);
81 maximum_width =
82 std::max(maximum_width, ComputeTextWidth(style, FormatValue(Maximum())));
83 maximum_width = std::max(maximum_width, ComputeTextWidth(style, Value()));
84 return maximum_width + DateTimeFieldElement::MaximumWidth(style);
85 }
86
87 int DateTimeNumericFieldElement::DefaultValueForStepDown() const {
88 return range_.maximum;
89 }
90
91 int DateTimeNumericFieldElement::DefaultValueForStepUp() const {
92 return range_.minimum;
93 }
94
95 void DateTimeNumericFieldElement::SetFocused(bool value,
96 WebFocusType focus_type) {
97 if (!value) {
98 int value = TypeAheadValue();
99 type_ahead_buffer_.Clear();
100 if (value >= 0)
101 SetValueAsInteger(value, kDispatchEvent);
102 }
103 DateTimeFieldElement::SetFocused(value, focus_type);
104 }
105
106 String DateTimeNumericFieldElement::FormatValue(int value) const {
107 Locale& locale = LocaleForOwner();
108 if (hard_limits_.maximum > 999)
109 return locale.ConvertToLocalizedNumber(String::Format("%04d", value));
110 if (hard_limits_.maximum > 99)
111 return locale.ConvertToLocalizedNumber(String::Format("%03d", value));
112 return locale.ConvertToLocalizedNumber(String::Format("%02d", value));
113 }
114
115 void DateTimeNumericFieldElement::HandleKeyboardEvent(
116 KeyboardEvent* keyboard_event) {
117 DCHECK(!IsDisabled());
118 if (keyboard_event->type() != EventTypeNames::keypress)
119 return;
120
121 UChar char_code = static_cast<UChar>(keyboard_event->charCode());
122 String number =
123 LocaleForOwner().ConvertFromLocalizedNumber(String(&char_code, 1));
124 const int digit = number[0] - '0';
125 if (digit < 0 || digit > 9)
126 return;
127
128 unsigned maximum_length =
129 DateTimeNumericFieldElement::FormatValue(range_.maximum).length();
130 if (type_ahead_buffer_.length() >= maximum_length) {
131 String current = type_ahead_buffer_.ToString();
132 type_ahead_buffer_.Clear();
133 unsigned desired_length = maximum_length - 1;
134 type_ahead_buffer_.Append(current, current.length() - desired_length,
135 desired_length);
136 }
137 type_ahead_buffer_.Append(number);
138 int new_value = TypeAheadValue();
139 if (new_value >= hard_limits_.minimum) {
140 SetValueAsInteger(new_value, kDispatchEvent);
141 } else {
142 has_value_ = false;
143 UpdateVisibleValue(kDispatchEvent);
144 }
145
146 if (type_ahead_buffer_.length() >= maximum_length ||
147 new_value * 10 > range_.maximum)
148 FocusOnNextField();
149
150 keyboard_event->SetDefaultHandled();
151 }
152
153 bool DateTimeNumericFieldElement::HasValue() const {
154 return has_value_;
155 }
156
157 void DateTimeNumericFieldElement::Initialize(const AtomicString& pseudo,
158 const String& ax_help_text) {
159 DateTimeFieldElement::Initialize(pseudo, ax_help_text, range_.minimum,
160 range_.maximum);
161 }
162
163 int DateTimeNumericFieldElement::Maximum() const {
164 return range_.maximum;
165 }
166
167 void DateTimeNumericFieldElement::SetEmptyValue(EventBehavior event_behavior) {
168 if (IsDisabled())
169 return;
170
171 has_value_ = false;
172 value_ = 0;
173 type_ahead_buffer_.Clear();
174 UpdateVisibleValue(event_behavior);
175 }
176
177 void DateTimeNumericFieldElement::SetValueAsInteger(
178 int value,
179 EventBehavior event_behavior) {
180 value_ = hard_limits_.ClampValue(value);
181 has_value_ = true;
182 UpdateVisibleValue(event_behavior);
183 }
184
185 void DateTimeNumericFieldElement::StepDown() {
186 int new_value =
187 RoundDown(has_value_ ? value_ - 1 : DefaultValueForStepDown());
188 if (!range_.IsInRange(new_value))
189 new_value = RoundDown(range_.maximum);
190 type_ahead_buffer_.Clear();
191 SetValueAsInteger(new_value, kDispatchEvent);
192 }
193
194 void DateTimeNumericFieldElement::StepUp() {
195 int new_value = RoundUp(has_value_ ? value_ + 1 : DefaultValueForStepUp());
196 if (!range_.IsInRange(new_value))
197 new_value = RoundUp(range_.minimum);
198 type_ahead_buffer_.Clear();
199 SetValueAsInteger(new_value, kDispatchEvent);
200 }
201
202 String DateTimeNumericFieldElement::Value() const {
203 return has_value_ ? FormatValue(value_) : g_empty_string;
204 }
205
206 int DateTimeNumericFieldElement::ValueAsInteger() const {
207 return has_value_ ? value_ : -1;
208 }
209
210 int DateTimeNumericFieldElement::TypeAheadValue() const {
211 if (type_ahead_buffer_.length())
212 return type_ahead_buffer_.ToString().ToInt();
213 return -1;
214 }
215
216 String DateTimeNumericFieldElement::VisibleValue() const {
217 if (type_ahead_buffer_.length())
218 return FormatValue(TypeAheadValue());
219 return has_value_ ? Value() : placeholder_;
220 }
221
222 int DateTimeNumericFieldElement::RoundDown(int n) const {
223 n -= step_.step_base;
224 if (n >= 0)
225 n = n / step_.step * step_.step;
226 else
227 n = -((-n + step_.step - 1) / step_.step * step_.step);
228 return n + step_.step_base;
229 }
230
231 int DateTimeNumericFieldElement::RoundUp(int n) const {
232 n -= step_.step_base;
233 if (n >= 0)
234 n = (n + step_.step - 1) / step_.step * step_.step;
235 else
236 n = -(-n / step_.step * step_.step);
237 return n + step_.step_base;
238 }
239
240 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698