summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/browser/android/date_time_chooser_android.cc53
-rw-r--r--content/browser/android/date_time_chooser_android.h28
-rw-r--r--content/browser/web_contents/web_contents_impl.cc9
-rw-r--r--content/common/view_messages.h13
-rw-r--r--content/content_renderer.gypi2
-rw-r--r--content/content_tests.gypi1
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java33
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/input/DateTimePickerDialog.java8
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/input/InputDialogContainer.java232
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/input/MonthPicker.java20
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/input/MonthPickerDialog.java13
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/input/TwoFieldDatePicker.java15
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/input/TwoFieldDatePickerDialog.java20
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/input/WeekPicker.java27
-rw-r--r--content/public/android/java/src/org/chromium/content/browser/input/WeekPickerDialog.java15
-rw-r--r--content/public/android/javatests/src/org/chromium/content/browser/input/InputDialogContainerTest.java404
-rw-r--r--content/renderer/date_time_formatter.cc300
-rw-r--r--content/renderer/date_time_formatter.h81
-rw-r--r--content/renderer/date_time_formatter_unittest.cc225
-rw-r--r--content/renderer/render_view_impl.cc11
-rw-r--r--content/renderer/render_view_impl.h5
-rw-r--r--content/renderer/renderer_date_time_picker.cc60
-rw-r--r--content/renderer/renderer_date_time_picker.h2
23 files changed, 653 insertions, 924 deletions
diff --git a/content/browser/android/date_time_chooser_android.cc b/content/browser/android/date_time_chooser_android.cc
index be87a93..87f02b9f 100644
--- a/content/browser/android/date_time_chooser_android.cc
+++ b/content/browser/android/date_time_chooser_android.cc
@@ -40,25 +40,7 @@ void DateTimeChooserAndroid::InitializeDateInputTypes(
void DateTimeChooserAndroid::ReplaceDateTime(JNIEnv* env,
jobject,
- int dialog_type,
- int year,
- int month,
- int day,
- int hour,
- int minute,
- int second,
- int milli,
- int week) {
- ViewHostMsg_DateTimeDialogValue_Params value;
- value.year = year;
- value.month = month;
- value.day = day;
- value.hour = hour;
- value.minute = minute;
- value.second = second;
- value.milli = milli;
- value.week = week;
- value.dialog_type = dialog_type;
+ jdouble value) {
host_->Send(new ViewMsg_ReplaceDateTime(host_->GetRoutingID(), value));
}
@@ -66,20 +48,14 @@ void DateTimeChooserAndroid::CancelDialog(JNIEnv* env, jobject) {
host_->Send(new ViewMsg_CancelDateTimeDialog(host_->GetRoutingID()));
}
-void DateTimeChooserAndroid::ShowDialog(ContentViewCore* content,
- RenderViewHost* host,
- int type,
- int year,
- int month,
- int day,
- int hour,
- int minute,
- int second,
- int milli,
- int week,
- double min,
- double max,
- double step) {
+void DateTimeChooserAndroid::ShowDialog(
+ ContentViewCore* content,
+ RenderViewHost* host,
+ ui::TextInputType dialog_type,
+ double dialog_value,
+ double min,
+ double max,
+ double step) {
host_ = host;
JNIEnv* env = AttachCurrentThread();
@@ -87,15 +63,8 @@ void DateTimeChooserAndroid::ShowDialog(ContentViewCore* content,
env,
content->GetJavaObject().obj(),
reinterpret_cast<intptr_t>(this),
- type,
- year,
- month,
- day,
- hour,
- minute,
- second,
- milli,
- week,
+ dialog_type,
+ dialog_value,
min,
max,
step));
diff --git a/content/browser/android/date_time_chooser_android.h b/content/browser/android/date_time_chooser_android.h
index a5578e0..a04850f 100644
--- a/content/browser/android/date_time_chooser_android.h
+++ b/content/browser/android/date_time_chooser_android.h
@@ -9,6 +9,7 @@
#include "base/android/jni_helper.h"
#include "base/memory/scoped_ptr.h"
+#include "ui/base/ime/text_input_type.h"
namespace content {
@@ -22,33 +23,18 @@ class DateTimeChooserAndroid {
~DateTimeChooserAndroid();
// DateTimeChooser implementation:
+ // Shows the dialog. |dialog_value| is the date/time value converted to a
+ // number as defined in HTML. (See blink::InputType::parseToNumber())
void ShowDialog(ContentViewCore* content,
RenderViewHost* host,
- int type,
- int year,
- int month,
- int day,
- int hour,
- int minute,
- int second,
- int milli,
- int week,
+ ui::TextInputType dialog_type,
+ double dialog_value,
double min,
double max,
double step);
- // Replaces the current value with the one passed the different fields
- void ReplaceDateTime(JNIEnv* env,
- jobject,
- jint dialog_type,
- jint year,
- jint month,
- jint day,
- jint hour,
- jint minute,
- jint second,
- jint milli,
- jint week);
+ // Replaces the current value
+ void ReplaceDateTime(JNIEnv* env, jobject, jdouble value);
// Closes the dialog without propagating any changes.
void CancelDialog(JNIEnv* env, jobject);
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index f5d9326..e363c32 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -2340,14 +2340,7 @@ void WebContentsImpl::OnOpenDateTimeDialog(
date_time_chooser_->ShowDialog(ContentViewCore::FromWebContents(this),
GetRenderViewHost(),
value.dialog_type,
- value.year,
- value.month,
- value.day,
- value.hour,
- value.minute,
- value.second,
- value.milli,
- value.week,
+ value.dialog_value,
value.minimum,
value.maximum,
value.step);
diff --git a/content/common/view_messages.h b/content/common/view_messages.h
index 3ff33ca..d7db038 100644
--- a/content/common/view_messages.h
+++ b/content/common/view_messages.h
@@ -399,15 +399,8 @@ IPC_STRUCT_BEGIN(ViewHostMsg_CreateWorker_Params)
IPC_STRUCT_END()
IPC_STRUCT_BEGIN(ViewHostMsg_DateTimeDialogValue_Params)
- IPC_STRUCT_MEMBER(int, dialog_type)
- IPC_STRUCT_MEMBER(int, year)
- IPC_STRUCT_MEMBER(int, month)
- IPC_STRUCT_MEMBER(int, day)
- IPC_STRUCT_MEMBER(int, hour)
- IPC_STRUCT_MEMBER(int, minute)
- IPC_STRUCT_MEMBER(int, second)
- IPC_STRUCT_MEMBER(int, milli)
- IPC_STRUCT_MEMBER(int, week)
+ IPC_STRUCT_MEMBER(ui::TextInputType, dialog_type)
+ IPC_STRUCT_MEMBER(double, dialog_value)
IPC_STRUCT_MEMBER(double, minimum)
IPC_STRUCT_MEMBER(double, maximum)
IPC_STRUCT_MEMBER(double, step)
@@ -976,7 +969,7 @@ IPC_MESSAGE_ROUTED1(ViewMsg_SetBrowserRenderingStats,
// Replaces a date time input field.
IPC_MESSAGE_ROUTED1(ViewMsg_ReplaceDateTime,
- ViewHostMsg_DateTimeDialogValue_Params /* value */)
+ double /* dialog_value */)
// Copies the image at location x, y to the clipboard (if there indeed is an
// image at that location).
diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi
index a5e8710..9c83c0e 100644
--- a/content/content_renderer.gypi
+++ b/content/content_renderer.gypi
@@ -102,8 +102,6 @@
'renderer/context_menu_params_builder.h',
'renderer/cursor_utils.cc',
'renderer/cursor_utils.h',
- 'renderer/date_time_formatter.cc',
- 'renderer/date_time_formatter.h',
'renderer/device_orientation/device_motion_event_pump.cc',
'renderer/device_orientation/device_motion_event_pump.h',
'renderer/device_orientation/device_orientation_event_pump.cc',
diff --git a/content/content_tests.gypi b/content/content_tests.gypi
index eed3507..e7a3846 100644
--- a/content/content_tests.gypi
+++ b/content/content_tests.gypi
@@ -512,7 +512,6 @@
'renderer/android/email_detector_unittest.cc',
'renderer/android/phone_number_detector_unittest.cc',
'renderer/bmp_image_decoder_unittest.cc',
- 'renderer/date_time_formatter_unittest.cc',
'renderer/device_orientation/device_motion_event_pump_unittest.cc',
'renderer/device_orientation/device_orientation_event_pump_unittest.cc',
'renderer/disambiguation_popup_helper_unittest.cc',
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java b/content/public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java
index c5b42ac..a45bc57 100644
--- a/content/public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java
@@ -26,13 +26,8 @@ class DateTimeChooserAndroid {
new InputDialogContainer.InputActionDelegate() {
@Override
- public void replaceDateTime(
- int dialogType,
- int year, int month, int day, int hour, int minute,
- int second, int milli, int week) {
- nativeReplaceDateTime(mNativeDateTimeChooserAndroid,
- dialogType,
- year, month, day, hour, minute, second, milli, week);
+ public void replaceDateTime(double value) {
+ nativeReplaceDateTime(mNativeDateTimeChooserAndroid, value);
}
@Override
@@ -42,28 +37,22 @@ class DateTimeChooserAndroid {
});
}
- private void showDialog(int dialogType, int year, int month, int monthDay,
- int hour, int minute, int second, int milli,
- int week, double min, double max, double step) {
- mInputDialogContainer.showDialog(
- dialogType, year, month, monthDay,
- hour, minute, second, milli, week, min, max, step);
+ private void showDialog(int dialogType, double dialogValue,
+ double min, double max, double step) {
+ mInputDialogContainer.showDialog(dialogType, dialogValue, min, max, step);
}
@CalledByNative
private static DateTimeChooserAndroid createDateTimeChooser(
ContentViewCore contentViewCore,
- long nativeDateTimeChooserAndroid, int dialogType,
- int year, int month, int day,
- int hour, int minute, int second, int milli, int week,
+ long nativeDateTimeChooserAndroid,
+ int dialogType, double dialogValue,
double min, double max, double step) {
DateTimeChooserAndroid chooser =
new DateTimeChooserAndroid(
contentViewCore.getContext(),
nativeDateTimeChooserAndroid);
- chooser.showDialog(
- dialogType, year, month, day, hour, minute, second, milli,
- week, min, max, step);
+ chooser.showDialog(dialogType, dialogValue, min, max, step);
return chooser;
}
@@ -77,10 +66,8 @@ class DateTimeChooserAndroid {
textInputTypeMonth, textInputTypeTime, textInputTypeWeek);
}
- private native void nativeReplaceDateTime(
- long nativeDateTimeChooserAndroid, int dialogType,
- int year, int month, int day, int hour, int minute,
- int second, int milli, int week);
+ private native void nativeReplaceDateTime(long nativeDateTimeChooserAndroid,
+ double dialogValue);
private native void nativeCancelDialog(long nativeDateTimeChooserAndroid);
}
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/DateTimePickerDialog.java b/content/public/android/java/src/org/chromium/content/browser/input/DateTimePickerDialog.java
index 07c1deb..8c3be1b 100644
--- a/content/public/android/java/src/org/chromium/content/browser/input/DateTimePickerDialog.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/DateTimePickerDialog.java
@@ -60,11 +60,11 @@ class DateTimePickerDialog extends AlertDialog implements OnClickListener,
int monthOfYear,
int dayOfMonth,
int hourOfDay, int minute, boolean is24HourView,
- long min, long max) {
+ double min, double max) {
super(context, 0);
- mMinTimeMillis = min;
- mMaxTimeMillis = max;
+ mMinTimeMillis = (long) min;
+ mMaxTimeMillis = (long) max;
mCallBack = callBack;
@@ -81,7 +81,7 @@ class DateTimePickerDialog extends AlertDialog implements OnClickListener,
setView(view);
mDatePicker = (DatePicker) view.findViewById(R.id.date_picker);
DateDialogNormalizer.normalize(mDatePicker, this,
- year, monthOfYear, dayOfMonth, hourOfDay, minute, min, max);
+ year, monthOfYear, dayOfMonth, hourOfDay, minute, mMinTimeMillis, mMaxTimeMillis);
mTimePicker = (TimePicker) view.findViewById(R.id.time_picker);
mTimePicker.setIs24HourView(is24HourView);
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/InputDialogContainer.java b/content/public/android/java/src/org/chromium/content/browser/input/InputDialogContainer.java
index ac61046..7ec81cb 100644
--- a/content/public/android/java/src/org/chromium/content/browser/input/InputDialogContainer.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/InputDialogContainer.java
@@ -21,34 +21,18 @@ import org.chromium.content.browser.input.DateTimePickerDialog.OnDateTimeSetList
import org.chromium.content.browser.input.MultiFieldTimePickerDialog.OnMultiFieldTimeSetListener;
import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.TimeZone;
+import java.util.concurrent.TimeUnit;
public class InputDialogContainer {
interface InputActionDelegate {
void cancelDateTimeDialog();
- void replaceDateTime(int dialogType,
- int year, int month, int day, int hour, int minute, int second, int milli, int week);
+ void replaceDateTime(double value);
}
- // Default values used in Time representations of selected date/time before formatting.
- // They are never displayed to the user.
- private static final int YEAR_DEFAULT = 1970;
- private static final int MONTH_DEFAULT = 0;
- private static final int MONTHDAY_DEFAULT = 1;
- private static final int HOUR_DEFAULT = 0;
- private static final int MINUTE_DEFAULT = 0;
- private static final int WEEK_DEFAULT = 0;
-
- // Date formats as accepted by Time.format.
- private static final String HTML_DATE_FORMAT = "%Y-%m-%d";
- private static final String HTML_TIME_FORMAT = "%H:%M";
- // For datetime we always send selected time as UTC, as we have no timezone selector.
- // This is consistent with other browsers.
- private static final String HTML_DATE_TIME_FORMAT = "%Y-%m-%dT%H:%MZ";
- private static final String HTML_DATE_TIME_LOCAL_FORMAT = "%Y-%m-%dT%H:%M";
- private static final String HTML_MONTH_FORMAT = "%Y-%m";
- private static final String HTML_WEEK_FORMAT = "%Y-%w";
-
private static int sTextInputTypeDate;
private static int sTextInputTypeDateTime;
private static int sTextInputTypeDateTimeLocal;
@@ -87,73 +71,103 @@ public class InputDialogContainer {
mInputActionDelegate = inputActionDelegate;
}
- private Time normalizeTime(int year, int month, int monthDay,
- int hour, int minute, int second) {
- Time result = new Time();
- if (year == 0 && month == 0 && monthDay == 0 && hour == 0 &&
- minute == 0 && second == 0) {
- Calendar cal = Calendar.getInstance();
- result.set(cal.get(Calendar.SECOND), cal.get(Calendar.MINUTE),
- cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.DATE),
- cal.get(Calendar.MONTH), cal.get(Calendar.YEAR));
+ void showDialog(final int dialogType, double dialogValue,
+ double min, double max, double step) {
+ Calendar cal;
+ // |dialogValue|, |min|, |max| mean different things depending on the |dialogType|.
+ // For input type=month is the number of months since 1970.
+ // For input type=time it is milliseconds since midnight.
+ // For other types they are just milliseconds since 1970.
+ // If |dialogValue| is NaN it means an empty value. We will show the current time.
+ if (Double.isNaN(dialogValue)) {
+ cal = Calendar.getInstance();
+ cal.set(Calendar.MILLISECOND, 0);
} else {
- result.set(second, minute, hour, monthDay, month, year);
+ if (dialogType == sTextInputTypeMonth) {
+ cal = MonthPicker.createDateFromValue(dialogValue);
+ } else if (dialogType == sTextInputTypeWeek) {
+ cal = WeekPicker.createDateFromValue(dialogValue);
+ } else {
+ GregorianCalendar gregorianCalendar =
+ new GregorianCalendar(TimeZone.getTimeZone("UTC"));
+ // According to the HTML spec we only use the Gregorian calendar
+ // so we ignore the Julian/Gregorian transition.
+ gregorianCalendar.setGregorianChange(new Date(Long.MIN_VALUE));
+ gregorianCalendar.setTimeInMillis((long) dialogValue);
+ cal = gregorianCalendar;
+ }
+ }
+ if (dialogType == sTextInputTypeDate) {
+ showDialog(dialogType,
+ cal.get(Calendar.YEAR),
+ cal.get(Calendar.MONTH),
+ cal.get(Calendar.DAY_OF_MONTH),
+ 0, 0, 0, 0, 0, min, max, step);
+ } else if (dialogType == sTextInputTypeTime) {
+ showDialog(dialogType, 0, 0, 0,
+ cal.get(Calendar.HOUR_OF_DAY),
+ cal.get(Calendar.MINUTE),
+ 0, 0, 0, min, max, step);
+ } else if (dialogType == sTextInputTypeDateTime ||
+ dialogType == sTextInputTypeDateTimeLocal) {
+ showDialog(dialogType,
+ cal.get(Calendar.YEAR),
+ cal.get(Calendar.MONTH),
+ cal.get(Calendar.DAY_OF_MONTH),
+ cal.get(Calendar.HOUR_OF_DAY),
+ cal.get(Calendar.MINUTE),
+ cal.get(Calendar.SECOND),
+ cal.get(Calendar.MILLISECOND),
+ 0, min, max, step);
+ } else if (dialogType == sTextInputTypeMonth) {
+ showDialog(dialogType, cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), 0,
+ 0, 0, 0, 0, 0, min, max, step);
+ } else if (dialogType == sTextInputTypeWeek) {
+ int year = WeekPicker.getISOWeekYearForDate(cal);
+ int week = WeekPicker.getWeekForDate(cal);
+ showDialog(dialogType, year, 0, 0, 0, 0, 0, 0, week, min, max, step);
}
- return result;
}
- void showDialog(final int dialogType, int year, int month, int monthDay,
- int hour, int minute, int second, int milli, int week,
- double min, double max, double step) {
+ void showDialog(final int dialogType,
+ int year, int month, int monthDay,
+ int hourOfDay, int minute, int second, int millis, int week,
+ double min, double max, double step) {
if (isDialogShowing()) mDialog.dismiss();
- // Java Date dialogs like longs but Blink prefers doubles..
- // Both parameters mean different things depending on the type
- // For input type=month min and max come as number on months since 1970
- // For other types (including type=time) they are just milliseconds since 1970
- // In any case the cast here is safe given the above restrictions.
- long minTime = (long) min;
- long maxTime = (long) max;
int stepTime = (int) step;
- if (milli > 1000) {
- second += milli / 1000;
- milli %= 1000;
- }
- Time time = normalizeTime(year, month, monthDay, hour, minute, second);
if (dialogType == sTextInputTypeDate) {
DatePickerDialog dialog = new DatePickerDialog(mContext,
- new DateListener(dialogType), time.year, time.month, time.monthDay);
+ new DateListener(dialogType),
+ year, month, monthDay);
DateDialogNormalizer.normalize(dialog.getDatePicker(), dialog,
- time.year, time.month, time.monthDay, 0, 0, minTime, maxTime);
+ year, month, monthDay,
+ 0, 0,
+ (long) min, (long) max);
dialog.setTitle(mContext.getText(R.string.date_picker_dialog_title));
mDialog = dialog;
} else if (dialogType == sTextInputTypeTime) {
mDialog = new MultiFieldTimePickerDialog(
mContext, 0 /* theme */ ,
- time.hour, time.minute, time.second, milli,
- (int) minTime, (int) maxTime, stepTime,
+ hourOfDay, minute, second, millis,
+ (int) min, (int) max, stepTime,
DateFormat.is24HourFormat(mContext),
new FullTimeListener(dialogType));
} else if (dialogType == sTextInputTypeDateTime ||
dialogType == sTextInputTypeDateTimeLocal) {
mDialog = new DateTimePickerDialog(mContext,
new DateTimeListener(dialogType),
- time.year, time.month, time.monthDay,
- time.hour, time.minute, DateFormat.is24HourFormat(mContext),
- minTime, maxTime);
+ year, month, monthDay,
+ hourOfDay, minute,
+ DateFormat.is24HourFormat(mContext), min, max);
} else if (dialogType == sTextInputTypeMonth) {
mDialog = new MonthPickerDialog(mContext, new MonthOrWeekListener(dialogType),
- time.year, time.month, minTime, maxTime);
+ year, month, min, max);
} else if (dialogType == sTextInputTypeWeek) {
- if (week == 0) {
- Calendar cal = Calendar.getInstance();
- year = WeekPicker.getISOWeekYearForDate(cal);
- week = WeekPicker.getWeekForDate(cal);
- }
mDialog = new WeekPickerDialog(mContext, new MonthOrWeekListener(dialogType),
- year, week, minTime, maxTime);
+ year, week, min, max);
}
mDialog.setButton(DialogInterface.BUTTON_POSITIVE,
@@ -170,7 +184,7 @@ public class InputDialogContainer {
@Override
public void onClick(DialogInterface dialog, int which) {
mDialogAlreadyDismissed = true;
- mInputActionDelegate.replaceDateTime(dialogType, 0, 0, 0, 0, 0, 0, 0, 0);
+ mInputActionDelegate.replaceDateTime(Double.NaN);
}
});
@@ -206,29 +220,7 @@ public class InputDialogContainer {
@Override
public void onDateSet(DatePicker view, int year, int month, int monthDay) {
- if (!mDialogAlreadyDismissed) {
- setFieldDateTimeValue(mDialogType,
- year, month, monthDay,
- HOUR_DEFAULT, MINUTE_DEFAULT, WEEK_DEFAULT,
- HTML_DATE_FORMAT);
- }
- }
- }
-
- private class TimeListener implements OnTimeSetListener {
- private final int mDialogType;
-
- TimeListener(int dialogType) {
- mDialogType = dialogType;
- }
-
- @Override
- public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
- if (!mDialogAlreadyDismissed) {
- setFieldDateTimeValue(mDialogType,
- YEAR_DEFAULT, MONTH_DEFAULT, MONTHDAY_DEFAULT,
- hourOfDay, minute, WEEK_DEFAULT, HTML_TIME_FORMAT);
- }
+ setFieldDateTimeValue(mDialogType, year, month, monthDay, 0, 0, 0, 0, 0);
}
}
@@ -240,11 +232,7 @@ public class InputDialogContainer {
@Override
public void onTimeSet(int hourOfDay, int minute, int second, int milli) {
- if (!mDialogAlreadyDismissed) {
- setFieldDateTimeValue(mDialogType,
- YEAR_DEFAULT, MONTH_DEFAULT, MONTHDAY_DEFAULT,
- hourOfDay, minute, second, milli, WEEK_DEFAULT, HTML_TIME_FORMAT);
- }
+ setFieldDateTimeValue(mDialogType, 0, 0, 0, hourOfDay, minute, second, milli, 0);
}
}
@@ -261,11 +249,7 @@ public class InputDialogContainer {
public void onDateTimeSet(DatePicker dateView, TimePicker timeView,
int year, int month, int monthDay,
int hourOfDay, int minute) {
- if (!mDialogAlreadyDismissed) {
- setFieldDateTimeValue(mDialogType, year, month, monthDay,
- hourOfDay, minute, WEEK_DEFAULT,
- mLocal ? HTML_DATE_TIME_LOCAL_FORMAT : HTML_DATE_TIME_FORMAT);
- }
+ setFieldDateTimeValue(mDialogType, year, month, monthDay, hourOfDay, minute, 0, 0, 0);
}
}
@@ -278,38 +262,46 @@ public class InputDialogContainer {
@Override
public void onValueSet(int year, int positionInYear) {
- if (!mDialogAlreadyDismissed) {
- if (mDialogType == sTextInputTypeMonth) {
- setFieldDateTimeValue(mDialogType, year, positionInYear, MONTHDAY_DEFAULT,
- HOUR_DEFAULT, MINUTE_DEFAULT, WEEK_DEFAULT,
- HTML_MONTH_FORMAT);
- } else {
- setFieldDateTimeValue(mDialogType, year, MONTH_DEFAULT, MONTHDAY_DEFAULT,
- HOUR_DEFAULT, MINUTE_DEFAULT, positionInYear, HTML_WEEK_FORMAT);
- }
+ if (mDialogType == sTextInputTypeMonth) {
+ setFieldDateTimeValue(mDialogType, year, positionInYear, 0, 0, 0, 0, 0, 0);
+ } else {
+ setFieldDateTimeValue(mDialogType, year, 0, 0, 0, 0, 0, 0, positionInYear);
}
}
}
- private void setFieldDateTimeValue(int dialogType,
- int year, int month, int monthDay, int hourOfDay,
- int minute, int week, String dateFormat) {
+ protected void setFieldDateTimeValue(int dialogType,
+ int year, int month, int monthDay,
+ int hourOfDay, int minute, int second, int millis,
+ int week) {
// Prevents more than one callback being sent to the native
// side when the dialog triggers multiple events.
+ if (mDialogAlreadyDismissed)
+ return;
mDialogAlreadyDismissed = true;
- mInputActionDelegate.replaceDateTime(dialogType,
- year, month, monthDay, hourOfDay, minute, 0 /* second */, 0 /* milli */, week);
- }
-
- private void setFieldDateTimeValue(int dialogType,
- int year, int month, int monthDay, int hourOfDay,
- int minute, int second, int milli, int week, String dateFormat) {
- // Prevents more than one callback being sent to the native
- // side when the dialog triggers multiple events.
- mDialogAlreadyDismissed = true;
-
- mInputActionDelegate.replaceDateTime(
- dialogType, year, month, monthDay, hourOfDay, minute, second, milli, week);
+ double value = 0;
+ if (dialogType == sTextInputTypeMonth) {
+ mInputActionDelegate.replaceDateTime((year - 1970) * 12 + month);
+ } else if (dialogType == sTextInputTypeWeek) {
+ mInputActionDelegate.replaceDateTime(
+ WeekPicker.createDateFromWeek(year, week).getTimeInMillis());
+ } else if (dialogType == sTextInputTypeTime) {
+ mInputActionDelegate.replaceDateTime(TimeUnit.HOURS.toMillis(hourOfDay) +
+ TimeUnit.MINUTES.toMillis(minute) +
+ TimeUnit.SECONDS.toMillis(second) +
+ millis);
+ } else {
+ Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
+ cal.clear();
+ cal.set(Calendar.YEAR, year);
+ cal.set(Calendar.MONTH, month);
+ cal.set(Calendar.DAY_OF_MONTH, monthDay);
+ cal.set(Calendar.HOUR_OF_DAY, hourOfDay);
+ cal.set(Calendar.MINUTE, minute);
+ cal.set(Calendar.SECOND, second);
+ cal.set(Calendar.MILLISECOND, millis);
+ mInputActionDelegate.replaceDateTime((double) cal.getTimeInMillis());
+ }
}
}
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/MonthPicker.java b/content/public/android/java/src/org/chromium/content/browser/input/MonthPicker.java
index ab1f31e..c7ebe8d 100644
--- a/content/public/android/java/src/org/chromium/content/browser/input/MonthPicker.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/MonthPicker.java
@@ -12,13 +12,14 @@ import java.text.DateFormatSymbols;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Locale;
+import java.util.TimeZone;
public class MonthPicker extends TwoFieldDatePicker {
private static final int MONTHS_NUMBER = 12;
private final String[] mShortMonths;
- public MonthPicker(Context context, long minValue, long maxValue) {
+ public MonthPicker(Context context, double minValue, double maxValue) {
super(context, minValue, maxValue);
getPositionInYearSpinner().setContentDescription(
@@ -29,23 +30,30 @@ public class MonthPicker extends TwoFieldDatePicker {
DateFormatSymbols.getInstance(Locale.getDefault()).getShortMonths();
// initialize to current date
- Calendar cal = Calendar.getInstance();
+ Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
init(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), null);
}
- @Override
- protected Calendar createDateFromValue(long value) {
+ /**
+ * Creates a date object from the |value| which is months since epoch.
+ */
+ public static Calendar createDateFromValue(double value) {
int year = (int) Math.min(value / 12 + 1970, Integer.MAX_VALUE);
int month = (int) (value % 12);
- Calendar cal = Calendar.getInstance();
+ Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
cal.clear();
cal.set(year, month, 1);
return cal;
}
@Override
+ protected Calendar getDateForValue(double value) {
+ return MonthPicker.createDateFromValue(value);
+ }
+
+ @Override
protected void setCurrentDate(int year, int month) {
- Calendar date = Calendar.getInstance();
+ Calendar date = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
date.set(year, month, 1);
if (date.before(getMinDate())) {
setCurrentDate(getMinDate());
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/MonthPickerDialog.java b/content/public/android/java/src/org/chromium/content/browser/input/MonthPickerDialog.java
index 24a4e8b..e995b62 100644
--- a/content/public/android/java/src/org/chromium/content/browser/input/MonthPickerDialog.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/MonthPickerDialog.java
@@ -17,25 +17,16 @@ public class MonthPickerDialog extends TwoFieldDatePickerDialog {
* @param monthOfYear The initial month of the dialog.
*/
public MonthPickerDialog(Context context, OnValueSetListener callBack,
- int year, int monthOfYear, long minMonth, long maxMonth) {
+ int year, int monthOfYear, double minMonth, double maxMonth) {
super(context, callBack, year, monthOfYear, minMonth, maxMonth);
setTitle(R.string.month_picker_dialog_title);
}
@Override
- protected TwoFieldDatePicker createPicker(Context context, long minValue, long maxValue) {
+ protected TwoFieldDatePicker createPicker(Context context, double minValue, double maxValue) {
return new MonthPicker(context, minValue, maxValue);
}
- @Override
- protected void tryNotifyDateSet() {
- if (mCallBack != null) {
- MonthPicker picker = getMonthPicker();
- picker.clearFocus();
- mCallBack.onValueSet(picker.getYear(), picker.getMonth());
- }
- }
-
/**
* Gets the {@link MonthPicker} contained in this dialog.
*
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/TwoFieldDatePicker.java b/content/public/android/java/src/org/chromium/content/browser/input/TwoFieldDatePicker.java
index 8b90c9c..0ff2bec 100644
--- a/content/public/android/java/src/org/chromium/content/browser/input/TwoFieldDatePicker.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/TwoFieldDatePicker.java
@@ -15,6 +15,7 @@ import android.widget.NumberPicker.OnValueChangeListener;
import org.chromium.content.R;
import java.util.Calendar;
+import java.util.TimeZone;
/**
* This class is heavily based on android.widget.DatePicker.
@@ -51,7 +52,7 @@ public abstract class TwoFieldDatePicker extends FrameLayout {
void onMonthOrWeekChanged(TwoFieldDatePicker view, int year, int positionInYear);
}
- public TwoFieldDatePicker(Context context, long minValue, long maxValue) {
+ public TwoFieldDatePicker(Context context, double minValue, double maxValue) {
super(context, null, android.R.attr.datePickerStyle);
LayoutInflater inflater = (LayoutInflater) context
@@ -86,15 +87,15 @@ public abstract class TwoFieldDatePicker extends FrameLayout {
}
};
- mCurrentDate = Calendar.getInstance();
+ mCurrentDate = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
if (minValue >= maxValue) {
- mMinDate = Calendar.getInstance();
+ mMinDate = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
mMinDate.set(0, 0, 1);
- mMaxDate = Calendar.getInstance();
+ mMaxDate = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
mMaxDate.set(9999, 0, 1);
} else {
- mMinDate = createDateFromValue(minValue);
- mMaxDate = createDateFromValue(maxValue);
+ mMinDate = getDateForValue(minValue);
+ mMaxDate = getDateForValue(maxValue);
}
// month
@@ -132,7 +133,7 @@ public abstract class TwoFieldDatePicker extends FrameLayout {
* Subclasses know the semantics of @value, and need to return
* a Calendar corresponding to it.
*/
- protected abstract Calendar createDateFromValue(long value);
+ protected abstract Calendar getDateForValue(double value);
/**
* Updates the current date.
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/TwoFieldDatePickerDialog.java b/content/public/android/java/src/org/chromium/content/browser/input/TwoFieldDatePickerDialog.java
index 7c36c36..d862e6e 100644
--- a/content/public/android/java/src/org/chromium/content/browser/input/TwoFieldDatePickerDialog.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/TwoFieldDatePickerDialog.java
@@ -29,8 +29,7 @@ public abstract class TwoFieldDatePickerDialog extends AlertDialog implements On
/**
* @param year The year that was set.
- * @param positionInYear The week in year.
- * with {@link java.util.Calendar}.
+ * @param positionInYear The position in the year that was set.
*/
void onValueSet(int year, int positionInYear);
}
@@ -45,8 +44,8 @@ public abstract class TwoFieldDatePickerDialog extends AlertDialog implements On
OnValueSetListener callBack,
int year,
int positionInYear,
- long minValue,
- long maxValue) {
+ double minValue,
+ double maxValue) {
this(context, 0, callBack, year, positionInYear, minValue, maxValue);
}
@@ -62,8 +61,8 @@ public abstract class TwoFieldDatePickerDialog extends AlertDialog implements On
OnValueSetListener callBack,
int year,
int positionInYear,
- long minValue,
- long maxValue) {
+ double minValue,
+ double maxValue) {
super(context, theme);
mCallBack = callBack;
@@ -79,7 +78,7 @@ public abstract class TwoFieldDatePickerDialog extends AlertDialog implements On
mPicker.init(year, positionInYear, this);
}
- protected TwoFieldDatePicker createPicker(Context context, long minValue, long maxValue) {
+ protected TwoFieldDatePicker createPicker(Context context, double minValue, double maxValue) {
return null;
}
@@ -91,7 +90,12 @@ public abstract class TwoFieldDatePickerDialog extends AlertDialog implements On
/**
* Notifies the listener, if such, that a date has been set.
*/
- protected abstract void tryNotifyDateSet();
+ protected void tryNotifyDateSet() {
+ if (mCallBack != null) {
+ mPicker.clearFocus();
+ mCallBack.onValueSet(mPicker.getYear(), mPicker.getPositionInYear());
+ }
+ }
@Override
protected void onStop() {
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/WeekPicker.java b/content/public/android/java/src/org/chromium/content/browser/input/WeekPicker.java
index b8924f4..a53460f 100644
--- a/content/public/android/java/src/org/chromium/content/browser/input/WeekPicker.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/WeekPicker.java
@@ -9,26 +9,30 @@ import android.content.Context;
import org.chromium.content.R;
import java.util.Calendar;
+import java.util.TimeZone;
// This class is heavily based on android.widget.DatePicker.
public class WeekPicker extends TwoFieldDatePicker {
- public WeekPicker(Context context, long minValue, long maxValue) {
+ public WeekPicker(Context context, double minValue, double maxValue) {
super(context, minValue, maxValue);
getPositionInYearSpinner().setContentDescription(
getResources().getString(R.string.accessibility_date_picker_week));
// initialize to current date
- Calendar cal = Calendar.getInstance();
+ Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
cal.setFirstDayOfWeek(Calendar.MONDAY);
cal.setMinimalDaysInFirstWeek(4);
cal.setTimeInMillis(System.currentTimeMillis());
init(getISOWeekYearForDate(cal), getWeekForDate(cal), null);
}
- private Calendar createDateFromWeek(int year, int week) {
- Calendar date = Calendar.getInstance();
+ /**
+ * Creates a date object from the |year| and |week|.
+ */
+ public static Calendar createDateFromWeek(int year, int week) {
+ Calendar date = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
date.clear();
date.setFirstDayOfWeek(Calendar.MONDAY);
date.setMinimalDaysInFirstWeek(4);
@@ -38,16 +42,23 @@ public class WeekPicker extends TwoFieldDatePicker {
return date;
}
- @Override
- protected Calendar createDateFromValue(long value) {
- Calendar date = Calendar.getInstance();
+ /**
+ * Creates a date object from the |value| which is milliseconds since epoch.
+ */
+ public static Calendar createDateFromValue(double value) {
+ Calendar date = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
date.clear();
date.setFirstDayOfWeek(Calendar.MONDAY);
date.setMinimalDaysInFirstWeek(4);
- date.setTimeInMillis(value);
+ date.setTimeInMillis((long) value);
return date;
}
+ @Override
+ protected Calendar getDateForValue(double value) {
+ return WeekPicker.createDateFromValue(value);
+ }
+
public static int getISOWeekYearForDate(Calendar date) {
int year = date.get(Calendar.YEAR);
int month = date.get(Calendar.MONTH);
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/WeekPickerDialog.java b/content/public/android/java/src/org/chromium/content/browser/input/WeekPickerDialog.java
index 83db991..0a7240e26 100644
--- a/content/public/android/java/src/org/chromium/content/browser/input/WeekPickerDialog.java
+++ b/content/public/android/java/src/org/chromium/content/browser/input/WeekPickerDialog.java
@@ -19,7 +19,7 @@ public class WeekPickerDialog extends TwoFieldDatePickerDialog {
public WeekPickerDialog(Context context,
OnValueSetListener callBack,
int year, int weekOfYear,
- long minValue, long maxValue) {
+ double minValue, double maxValue) {
this(context, 0, callBack, year, weekOfYear, minValue, maxValue);
}
@@ -35,25 +35,16 @@ public class WeekPickerDialog extends TwoFieldDatePickerDialog {
OnValueSetListener callBack,
int year,
int weekOfYear,
- long minValue, long maxValue) {
+ double minValue, double maxValue) {
super(context, theme, callBack, year, weekOfYear, minValue, maxValue);
setTitle(R.string.week_picker_dialog_title);
}
@Override
- protected TwoFieldDatePicker createPicker(Context context, long minValue, long maxValue) {
+ protected TwoFieldDatePicker createPicker(Context context, double minValue, double maxValue) {
return new WeekPicker(context, minValue, maxValue);
}
- @Override
- protected void tryNotifyDateSet() {
- if (mCallBack != null) {
- WeekPicker picker = getWeekPicker();
- picker.clearFocus();
- mCallBack.onValueSet(picker.getYear(), picker.getWeek());
- }
- }
-
/**
* Gets the {@link WeekPicker} contained in this dialog.
*
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/input/InputDialogContainerTest.java b/content/public/android/javatests/src/org/chromium/content/browser/input/InputDialogContainerTest.java
new file mode 100644
index 0000000..235a859
--- /dev/null
+++ b/content/public/android/javatests/src/org/chromium/content/browser/input/InputDialogContainerTest.java
@@ -0,0 +1,404 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content.browser.input;
+
+import android.content.Context;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.chromium.base.test.util.Feature;
+
+public class InputDialogContainerTest extends AndroidTestCase {
+ private static int TEXT_INPUT_TYPE_DATE = 0;
+ private static int TEXT_INPUT_TYPE_DATETIME = 1;
+ private static int TEXT_INPUT_TYPE_DATETIMELOCAL = 2;
+ private static int TEXT_INPUT_TYPE_MONTH = 3;
+ private static int TEXT_INPUT_TYPE_TIME = 4;
+ private static int TEXT_INPUT_TYPE_WEEK = 5;
+
+ // Defined in third_party/WebKit/Source/platform/DateComponents.h
+ private static double DATE_DIALOG_DEFAULT_MIN = -62135596800000.0;
+ private static double DATE_DIALOG_DEFAULT_MAX = 8640000000000000.0;
+ private static double DATETIMELOCAL_DIALOG_DEFAULT_MIN = -62135596800000.0;
+ private static double DATETIMELOCAL_DIALOG_DEFAULT_MAX = 8640000000000000.0;
+ private static double MONTH_DIALOG_DEFAULT_MIN = -23628.0;
+ private static double MONTH_DIALOG_DEFAULT_MAX = 3285488.0;
+ private static double TIME_DIALOG_DEFAULT_MIN = 0.0;
+ private static double TIME_DIALOG_DEFAULT_MAX = 86399999.0;
+ private static double WEEK_DIALOG_DEFAULT_MIN = -62135596800000.0;
+ private static double WEEK_DIALOG_DEFAULT_MAX = 8639999568000000.0;
+
+ InputActionDelegateForTests mInputActionDelegate;
+ InputDialogContainerForTests mInputDialogContainer;
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ InputDialogContainer.initializeInputTypes(TEXT_INPUT_TYPE_DATE,
+ TEXT_INPUT_TYPE_DATETIME,
+ TEXT_INPUT_TYPE_DATETIMELOCAL,
+ TEXT_INPUT_TYPE_MONTH,
+ TEXT_INPUT_TYPE_TIME,
+ TEXT_INPUT_TYPE_WEEK);
+ mInputActionDelegate = new InputActionDelegateForTests();
+ mInputDialogContainer = new InputDialogContainerForTests(getContext(),
+ mInputActionDelegate);
+ }
+
+ @SmallTest
+ @Feature({"DateTimeDialog"})
+ public void testDateValueParsing() {
+ mInputDialogContainer.setShowDialogExpectation(TEXT_INPUT_TYPE_DATE,
+ 1970, 0, 1,
+ 0, 0, 0, 0, 0,
+ DATE_DIALOG_DEFAULT_MIN, DATE_DIALOG_DEFAULT_MAX, 1.0);
+ mInputDialogContainer.showDialog(TEXT_INPUT_TYPE_DATE, 0.0,
+ DATE_DIALOG_DEFAULT_MIN, DATE_DIALOG_DEFAULT_MAX, 1.0);
+
+ mInputDialogContainer.setShowDialogExpectation(TEXT_INPUT_TYPE_DATE,
+ 1, 0, 1,
+ 0, 0, 0, 0, 0,
+ DATE_DIALOG_DEFAULT_MIN, DATE_DIALOG_DEFAULT_MAX, 1.0);
+ mInputDialogContainer.showDialog(TEXT_INPUT_TYPE_DATE, -62135596800000.0,
+ DATE_DIALOG_DEFAULT_MIN, DATE_DIALOG_DEFAULT_MAX, 1.0);
+
+ mInputDialogContainer.setShowDialogExpectation(TEXT_INPUT_TYPE_DATE,
+ 275760, 8, 13,
+ 0, 0, 0, 0, 0,
+ DATE_DIALOG_DEFAULT_MIN, DATE_DIALOG_DEFAULT_MAX, 1.0);
+ mInputDialogContainer.showDialog(TEXT_INPUT_TYPE_DATE, 8640000000000000.0,
+ DATE_DIALOG_DEFAULT_MIN, DATE_DIALOG_DEFAULT_MAX, 1.0);
+
+ mInputDialogContainer.setShowDialogExpectation(TEXT_INPUT_TYPE_DATE,
+ 2013, 10, 7,
+ 0, 0, 0, 0, 0,
+ DATE_DIALOG_DEFAULT_MIN, DATE_DIALOG_DEFAULT_MAX, 1.0);
+ mInputDialogContainer.showDialog(TEXT_INPUT_TYPE_DATE, 1383782400000.0,
+ DATE_DIALOG_DEFAULT_MIN, DATE_DIALOG_DEFAULT_MAX, 1.0);
+ }
+
+ @SmallTest
+ @Feature({"DateTimeDialog"})
+ public void testDatetimelocalValueParsing() {
+ mInputDialogContainer.setShowDialogExpectation(TEXT_INPUT_TYPE_DATETIMELOCAL,
+ 1970, 0, 1,
+ 0, 0, 0, 0, 0,
+ DATETIMELOCAL_DIALOG_DEFAULT_MIN, DATETIMELOCAL_DIALOG_DEFAULT_MAX, 1.0);
+ mInputDialogContainer.showDialog(TEXT_INPUT_TYPE_DATETIMELOCAL, 0,
+ DATETIMELOCAL_DIALOG_DEFAULT_MIN, DATETIMELOCAL_DIALOG_DEFAULT_MAX, 1.0);
+
+ mInputDialogContainer.setShowDialogExpectation(TEXT_INPUT_TYPE_DATETIMELOCAL,
+ 1, 0, 1,
+ 0, 0, 0, 0, 0,
+ DATETIMELOCAL_DIALOG_DEFAULT_MIN, DATETIMELOCAL_DIALOG_DEFAULT_MAX, 1.0);
+ mInputDialogContainer.showDialog(TEXT_INPUT_TYPE_DATETIMELOCAL, -62135596800000.0,
+ DATETIMELOCAL_DIALOG_DEFAULT_MIN, DATETIMELOCAL_DIALOG_DEFAULT_MAX, 1.0);
+
+ mInputDialogContainer.setShowDialogExpectation(TEXT_INPUT_TYPE_DATETIMELOCAL,
+ 275760, 8, 13,
+ 0, 0, 0, 0, 0,
+ DATETIMELOCAL_DIALOG_DEFAULT_MIN, DATETIMELOCAL_DIALOG_DEFAULT_MAX, 1.0);
+ mInputDialogContainer.showDialog(TEXT_INPUT_TYPE_DATETIMELOCAL, 8640000000000000.0,
+ DATETIMELOCAL_DIALOG_DEFAULT_MIN, DATETIMELOCAL_DIALOG_DEFAULT_MAX, 1.0);
+
+ mInputDialogContainer.setShowDialogExpectation(TEXT_INPUT_TYPE_DATETIMELOCAL,
+ 2013, 10, 8,
+ 1, 1, 2, 196, 0,
+ DATETIMELOCAL_DIALOG_DEFAULT_MIN, DATETIMELOCAL_DIALOG_DEFAULT_MAX, 0.001);
+ mInputDialogContainer.showDialog(TEXT_INPUT_TYPE_DATETIMELOCAL, 1383872462196.0,
+ DATETIMELOCAL_DIALOG_DEFAULT_MIN, DATETIMELOCAL_DIALOG_DEFAULT_MAX, 0.001);
+ }
+
+ @SmallTest
+ @Feature({"DateTimeDialog"})
+ public void testMonthValueParsing() {
+ mInputDialogContainer.setShowDialogExpectation(TEXT_INPUT_TYPE_MONTH,
+ 1970, 0, 0,
+ 0, 0, 0, 0, 0,
+ MONTH_DIALOG_DEFAULT_MIN, MONTH_DIALOG_DEFAULT_MAX, 1.0);
+ mInputDialogContainer.showDialog(TEXT_INPUT_TYPE_MONTH, 0.0,
+ MONTH_DIALOG_DEFAULT_MIN, MONTH_DIALOG_DEFAULT_MAX, 1.0);
+
+ mInputDialogContainer.setShowDialogExpectation(TEXT_INPUT_TYPE_MONTH,
+ 1, 0, 0,
+ 0, 0, 0, 0, 0,
+ MONTH_DIALOG_DEFAULT_MIN, MONTH_DIALOG_DEFAULT_MAX, 1.0);
+ mInputDialogContainer.showDialog(TEXT_INPUT_TYPE_MONTH, -23628.0,
+ MONTH_DIALOG_DEFAULT_MIN, MONTH_DIALOG_DEFAULT_MAX, 1.0);
+
+ mInputDialogContainer.setShowDialogExpectation(TEXT_INPUT_TYPE_MONTH,
+ 275760, 8, 0,
+ 0, 0, 0, 0, 0,
+ MONTH_DIALOG_DEFAULT_MIN, MONTH_DIALOG_DEFAULT_MAX, 1.0);
+ mInputDialogContainer.showDialog(TEXT_INPUT_TYPE_MONTH, 3285488.0,
+ MONTH_DIALOG_DEFAULT_MIN, MONTH_DIALOG_DEFAULT_MAX, 1.0);
+
+ mInputDialogContainer.setShowDialogExpectation(TEXT_INPUT_TYPE_MONTH,
+ 2013, 10, 0,
+ 0, 0, 0, 0, 0,
+ MONTH_DIALOG_DEFAULT_MIN, MONTH_DIALOG_DEFAULT_MAX, 1.0);
+ mInputDialogContainer.showDialog(TEXT_INPUT_TYPE_MONTH, 526.0,
+ MONTH_DIALOG_DEFAULT_MIN, MONTH_DIALOG_DEFAULT_MAX, 1.0);
+ }
+
+ @SmallTest
+ @Feature({"DateTimeDialog"})
+ public void testTimeValueParsing() {
+ mInputDialogContainer.setShowDialogExpectation(TEXT_INPUT_TYPE_TIME,
+ 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ TIME_DIALOG_DEFAULT_MIN, TIME_DIALOG_DEFAULT_MAX, 1.0);
+ mInputDialogContainer.showDialog(TEXT_INPUT_TYPE_TIME, 0.0,
+ TIME_DIALOG_DEFAULT_MIN, TIME_DIALOG_DEFAULT_MAX, 1.0);
+
+ // Time dialog only shows the hour and minute fields.
+ mInputDialogContainer.setShowDialogExpectation(TEXT_INPUT_TYPE_TIME,
+ 0, 0, 0,
+ 23, 59, 0, 0, 0,
+ TIME_DIALOG_DEFAULT_MIN, TIME_DIALOG_DEFAULT_MAX, 1.0);
+ mInputDialogContainer.showDialog(TEXT_INPUT_TYPE_TIME, 86399999.0,
+ TIME_DIALOG_DEFAULT_MIN, TIME_DIALOG_DEFAULT_MAX, 1.0);
+
+ mInputDialogContainer.setShowDialogExpectation(TEXT_INPUT_TYPE_TIME,
+ 0, 0, 0,
+ 15, 23, 0, 0, 0,
+ TIME_DIALOG_DEFAULT_MIN, TIME_DIALOG_DEFAULT_MAX, 1.0);
+ mInputDialogContainer.showDialog(TEXT_INPUT_TYPE_TIME, 55425678.0,
+ TIME_DIALOG_DEFAULT_MIN, TIME_DIALOG_DEFAULT_MAX, 1.0);
+ }
+
+ @SmallTest
+ @Feature({"DateTimeDialog"})
+ public void testWeekValueParsing() {
+ mInputDialogContainer.setShowDialogExpectation(TEXT_INPUT_TYPE_WEEK,
+ 1970, 0, 0,
+ 0, 0, 0, 0, 1,
+ WEEK_DIALOG_DEFAULT_MIN, WEEK_DIALOG_DEFAULT_MAX, 1.0);
+ mInputDialogContainer.showDialog(TEXT_INPUT_TYPE_WEEK, -259200000.0,
+ WEEK_DIALOG_DEFAULT_MIN, WEEK_DIALOG_DEFAULT_MAX, 1.0);
+
+ mInputDialogContainer.setShowDialogExpectation(TEXT_INPUT_TYPE_WEEK,
+ 1, 0, 0,
+ 0, 0, 0, 0, 1,
+ WEEK_DIALOG_DEFAULT_MIN, WEEK_DIALOG_DEFAULT_MAX, 1.0);
+ mInputDialogContainer.showDialog(TEXT_INPUT_TYPE_WEEK, -62135596800000.0,
+ WEEK_DIALOG_DEFAULT_MIN, WEEK_DIALOG_DEFAULT_MAX, 1.0);
+
+ mInputDialogContainer.setShowDialogExpectation(TEXT_INPUT_TYPE_WEEK,
+ 275760, 0, 0,
+ 0, 0, 0, 0, 37,
+ WEEK_DIALOG_DEFAULT_MIN, WEEK_DIALOG_DEFAULT_MAX, 1.0);
+ mInputDialogContainer.showDialog(TEXT_INPUT_TYPE_WEEK, 8639999568000000.0,
+ WEEK_DIALOG_DEFAULT_MIN, WEEK_DIALOG_DEFAULT_MAX, 1.0);
+
+ mInputDialogContainer.setShowDialogExpectation(TEXT_INPUT_TYPE_WEEK,
+ 2013, 0, 0,
+ 0, 0, 0, 0, 44,
+ WEEK_DIALOG_DEFAULT_MIN, WEEK_DIALOG_DEFAULT_MAX, 1.0);
+ mInputDialogContainer.showDialog(TEXT_INPUT_TYPE_WEEK, 1382918400000.0,
+ WEEK_DIALOG_DEFAULT_MIN, WEEK_DIALOG_DEFAULT_MAX, 1.0);
+ }
+
+ @SmallTest
+ @Feature({"DateTimeDialog"})
+ public void testDateValueGenerating() {
+ mInputActionDelegate.setReplaceDateTimeExpectation(0);
+ mInputDialogContainer.setFieldDateTimeValue(TEXT_INPUT_TYPE_DATE,
+ 1970, 0, 1,
+ 0, 0, 0, 0, 0);
+
+ mInputActionDelegate.setReplaceDateTimeExpectation(-62135596800000.0);
+ mInputDialogContainer.setFieldDateTimeValue(TEXT_INPUT_TYPE_DATE,
+ 1, 0, 1,
+ 0, 0, 0, 0, 0);
+
+ mInputActionDelegate.setReplaceDateTimeExpectation(8640000000000000.0);
+ mInputDialogContainer.setFieldDateTimeValue(TEXT_INPUT_TYPE_DATE,
+ 275760, 8, 13,
+ 0, 0, 0, 0, 0);
+
+ mInputActionDelegate.setReplaceDateTimeExpectation(1383782400000.0);
+ mInputDialogContainer.setFieldDateTimeValue(TEXT_INPUT_TYPE_DATE,
+ 2013, 10, 7,
+ 0, 0, 0, 0, 0);
+ }
+
+ @SmallTest
+ @Feature({"DateTimeDialog"})
+ public void testDatetimelocalValueGenerating() {
+ mInputActionDelegate.setReplaceDateTimeExpectation(0);
+ mInputDialogContainer.setFieldDateTimeValue(TEXT_INPUT_TYPE_DATETIMELOCAL,
+ 1970, 0, 1,
+ 0, 0, 0, 0, 0);
+
+ mInputActionDelegate.setReplaceDateTimeExpectation(-62135596800000.0);
+ mInputDialogContainer.setFieldDateTimeValue(TEXT_INPUT_TYPE_DATETIMELOCAL,
+ 1, 0, 1,
+ 0, 0, 0, 0, 0);
+
+ mInputActionDelegate.setReplaceDateTimeExpectation(8640000000000000.0);
+ mInputDialogContainer.setFieldDateTimeValue(TEXT_INPUT_TYPE_DATETIMELOCAL,
+ 275760, 8, 13,
+ 0, 0, 0, 0, 0);
+
+ mInputActionDelegate.setReplaceDateTimeExpectation(1383872462196.0);
+ mInputDialogContainer.setFieldDateTimeValue(TEXT_INPUT_TYPE_DATETIMELOCAL,
+ 2013, 10, 8,
+ 1, 1, 2, 196, 0);
+ }
+
+ @SmallTest
+ @Feature({"DateTimeDialog"})
+ public void testMonthValueGenerating() {
+ mInputActionDelegate.setReplaceDateTimeExpectation(0);
+ mInputDialogContainer.setFieldDateTimeValue(TEXT_INPUT_TYPE_MONTH,
+ 1970, 0, 0,
+ 0, 0, 0, 0, 0);
+
+ mInputActionDelegate.setReplaceDateTimeExpectation(-62135596800000.0);
+ mInputDialogContainer.setFieldDateTimeValue(TEXT_INPUT_TYPE_MONTH,
+ 1, 0, 1,
+ 0, 0, 0, 0, 0);
+
+ mInputActionDelegate.setReplaceDateTimeExpectation(8640000000000000.0);
+ mInputDialogContainer.setFieldDateTimeValue(TEXT_INPUT_TYPE_MONTH,
+ 275760, 8, 0,
+ 0, 0, 0, 0, 0);
+
+ mInputActionDelegate.setReplaceDateTimeExpectation(1383872462196.0);
+ mInputDialogContainer.setFieldDateTimeValue(TEXT_INPUT_TYPE_MONTH,
+ 2013, 10, 0,
+ 0, 0, 0, 0, 0);
+ }
+
+ @SmallTest
+ @Feature({"DateTimeDialog"})
+ public void testTimeValueGenerating() {
+ mInputActionDelegate.setReplaceDateTimeExpectation(0.0);
+ mInputDialogContainer.setFieldDateTimeValue(TEXT_INPUT_TYPE_TIME,
+ 0, 0, 0,
+ 0, 0, 0, 0, 0);
+
+ mInputActionDelegate.setReplaceDateTimeExpectation(86399999.0);
+ mInputDialogContainer.setFieldDateTimeValue(TEXT_INPUT_TYPE_TIME,
+ 0, 0, 0,
+ 23, 59, 59, 999, 0);
+
+ mInputActionDelegate.setReplaceDateTimeExpectation(55425678.0);
+ mInputDialogContainer.setFieldDateTimeValue(TEXT_INPUT_TYPE_TIME,
+ 2013, 10, 0,
+ 3, 23, 45, 678, 0);
+ }
+
+ @SmallTest
+ @Feature({"DateTimeDialog"})
+ public void testWeekValueGenerating() {
+ mInputActionDelegate.setReplaceDateTimeExpectation(-259200000.0);
+ mInputDialogContainer.setFieldDateTimeValue(TEXT_INPUT_TYPE_WEEK,
+ 1970, 0, 0,
+ 0, 0, 0, 0, 1);
+
+ mInputActionDelegate.setReplaceDateTimeExpectation(-62135596800000.0);
+ mInputDialogContainer.setFieldDateTimeValue(TEXT_INPUT_TYPE_WEEK,
+ 1, 0, 0,
+ 0, 0, 0, 0, 1);
+
+ mInputActionDelegate.setReplaceDateTimeExpectation(8639999568000000.0);
+ mInputDialogContainer.setFieldDateTimeValue(TEXT_INPUT_TYPE_WEEK,
+ 275760, 0, 0,
+ 0, 0, 0, 0, 37);
+
+ mInputActionDelegate.setReplaceDateTimeExpectation(1382918400000.0);
+ mInputDialogContainer.setFieldDateTimeValue(TEXT_INPUT_TYPE_WEEK,
+ 2013, 0, 0,
+ 0, 0, 0, 0, 44);
+ }
+
+ private static class InputActionDelegateForTests
+ implements InputDialogContainer.InputActionDelegate {
+ private double mExpectedDialogValue;
+
+ public void setReplaceDateTimeExpectation(double dialogValue) {
+ mExpectedDialogValue = dialogValue;
+ }
+
+ @Override
+ public void replaceDateTime(double dialogValue) {
+ assertEquals(mExpectedDialogValue, dialogValue);
+ }
+
+ @Override
+ public void cancelDateTimeDialog() {
+ }
+ };
+
+ private static class InputDialogContainerForTests extends InputDialogContainer {
+ private int mExpectedDialogType;
+ private int mExpectedYear;
+ private int mExpectedMonth;
+ private int mExpectedMonthDay;
+ private int mExpectedHourOfDay;
+ private int mExpectedMinute;
+ private int mExpectedSecond;
+ private int mExpectedMillis;
+ private int mExpectedWeek;
+ private double mExpectedMin;
+ private double mExpectedMax;
+ private double mExpectedStep;
+
+ public InputDialogContainerForTests(
+ Context context,
+ InputDialogContainer.InputActionDelegate inputActionDelegate) {
+ super(context, inputActionDelegate);
+ }
+
+ void setShowDialogExpectation(int dialogType,
+ int year, int month, int monthDay,
+ int hourOfDay, int minute, int second, int millis, int week,
+ double min, double max, double step) {
+ mExpectedDialogType = dialogType;
+ mExpectedYear = year;
+ mExpectedMonth = month;
+ mExpectedMonthDay = monthDay;
+ mExpectedHourOfDay = hourOfDay;
+ mExpectedMinute = minute;
+ mExpectedSecond = second;
+ mExpectedMillis = millis;
+ mExpectedWeek = week;
+ mExpectedMin = min;
+ mExpectedMax = max;
+ mExpectedStep = step;
+ }
+
+ @Override
+ void showDialog(final int dialogType,
+ int year, int month, int monthDay,
+ int hourOfDay, int minute, int second, int millis, int week,
+ double min, double max, double step) {
+ assertEquals(mExpectedDialogType, dialogType);
+ assertEquals(mExpectedYear, year);
+ assertEquals(mExpectedMonth, month);
+ assertEquals(mExpectedMonthDay, monthDay);
+ assertEquals(mExpectedHourOfDay, hourOfDay);
+ assertEquals(mExpectedMinute, minute);
+ assertEquals(mExpectedSecond, second);
+ assertEquals(mExpectedMillis, millis);
+ assertEquals(mExpectedWeek, week);
+ assertEquals(mExpectedMin, min);
+ assertEquals(mExpectedMax, max);
+ assertEquals(mExpectedStep, step);
+ }
+
+ public void setFieldDateTimeValue(int dialogType,
+ int year, int month, int monthDay,
+ int hourOfDay, int minute, int second, int millis,
+ int week) {
+ super.setFieldDateTimeValue(dialogType,
+ year, month, monthDay,
+ hourOfDay, minute, second, millis,
+ week);
+ }
+ }
+}
diff --git a/content/renderer/date_time_formatter.cc b/content/renderer/date_time_formatter.cc
deleted file mode 100644
index 1b94049..0000000
--- a/content/renderer/date_time_formatter.cc
+++ /dev/null
@@ -1,300 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/renderer/date_time_formatter.h"
-
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "third_party/WebKit/public/platform/WebCString.h"
-#include "third_party/WebKit/public/web/WebDateTimeChooserParams.h"
-#include "third_party/icu/source/i18n/unicode/smpdtfmt.h"
-
-
-namespace content {
-
-void DateTimeFormatter::CreatePatternMap() {
- // Initialize all the UI elements with empty patterns,
- // then fill in the ones that are actually date/time inputs and
- // are implemented.
- for (int i = 0 ; i <= ui::TEXT_INPUT_TYPE_MAX; ++i) {
- patterns_[i] = "";
- }
- patterns_[ui::TEXT_INPUT_TYPE_DATE] = "yyyy-MM-dd";
- patterns_[ui::TEXT_INPUT_TYPE_DATE_TIME] = "yyyy-MM-dd'T'HH:mm'Z'";
- patterns_[ui::TEXT_INPUT_TYPE_DATE_TIME_LOCAL] = "yyyy-MM-dd'T'HH:mm";
- patterns_[ui::TEXT_INPUT_TYPE_MONTH] = "yyyy-MM";
- patterns_[ui::TEXT_INPUT_TYPE_TIME] = "HH:mm";
- patterns_[ui::TEXT_INPUT_TYPE_WEEK] = "Y-'W'ww";
-}
-
-// Returns true if icu_value parses as a valid for the specified date/time
-// pattern. The date/time pattern given is for icu::SimpleDateFormat.
-static bool TryPattern(const char* pattern,
- const icu::UnicodeString& icu_value) {
- icu::UnicodeString time_pattern = pattern;
- UErrorCode success = U_ZERO_ERROR;
- icu::SimpleDateFormat formatter(time_pattern, success);
- formatter.parse(icu_value, success);
- return success == U_ZERO_ERROR;
-}
-
-// For a time value represented as a string find the longest time
-// pattern which matches it. A valid time can have hours and minutes
-// or hours, minutes and seconds or hour, minutes, seconds and upto 3
-// digits of fractional seconds. Specify step in milliseconds, it is 1000
-// times the value specified as "step" in the "<input type=time step=...>
-// HTML fragment. A value of 60000 or more indicates that seconds
-// are not expected and a value of 1000 or more indicates that fractional
-// seconds are not expected.
-static const char* FindLongestTimePatternWhichMatches(const std::string& value,
- double step) {
- const char* pattern = "HH:mm";
- if (step >= 60000)
- return pattern;
-
- icu::UnicodeString icu_value = icu::UnicodeString::fromUTF8(
- icu::StringPiece(value.data(), value.size()));
- const char* last_pattern = pattern;
- pattern = "HH:mm:ss";
- if (!TryPattern(pattern, icu_value))
- return last_pattern;
- if (step >= 1000)
- return pattern;
- last_pattern = pattern;
- pattern = "HH:mm:ss.S";
- if (!TryPattern(pattern, icu_value))
- return last_pattern;
- last_pattern = pattern;
- pattern = "HH:mm:ss.SS";
- if (!TryPattern(pattern, icu_value))
- return last_pattern;
- last_pattern = pattern;
- pattern = "HH:mm:ss.SSS";
- if (!TryPattern(pattern, icu_value))
- return last_pattern;
- return pattern;
-}
-
-DateTimeFormatter::DateTimeFormatter(
- const blink::WebDateTimeChooserParams& source)
- : formatted_string_(source.currentValue.utf8()) {
- CreatePatternMap();
- if (source.type == blink::WebDateTimeInputTypeTime)
- time_pattern_ =
- FindLongestTimePatternWhichMatches(formatted_string_, source.step);
- ExtractType(source);
- if (!ParseValues()) {
- type_ = ui::TEXT_INPUT_TYPE_NONE;
- ClearAll();
- LOG(WARNING) << "Problems parsing input <" << formatted_string_ << ">";
- }
-}
-
-DateTimeFormatter::DateTimeFormatter(ui::TextInputType type,
- int year,
- int month,
- int day,
- int hour,
- int minute,
- int second,
- int milli,
- int week_year,
- int week)
- : type_(type),
- year_(year),
- month_(month),
- day_(day),
- hour_(hour),
- minute_(minute),
- second_(second),
- milli_(milli),
- week_year_(week_year),
- week_(week) {
- CreatePatternMap();
- if (type_ == ui::TEXT_INPUT_TYPE_TIME && (second != 0 || milli != 0)) {
- if (milli == 0)
- time_pattern_ = "HH:mm:ss";
- else if (milli % 100 == 0)
- time_pattern_ = "HH:mm:ss.S";
- else if (milli % 10 == 0)
- time_pattern_ = "HH:mm:ss.SS";
- else
- time_pattern_ = "HH:mm:ss.SSS";
- pattern_ = &time_pattern_;
- } else {
- pattern_ = type_ > 0 && type_ <= ui::TEXT_INPUT_TYPE_MAX ?
- &patterns_[type_] : &patterns_[ui::TEXT_INPUT_TYPE_NONE];
- }
-
- formatted_string_ = FormatString();
-}
-
-DateTimeFormatter::~DateTimeFormatter() {
-}
-
-int DateTimeFormatter::GetYear() const {
- return year_;
-}
-
-int DateTimeFormatter::GetMonth() const {
- return month_;
-}
-
-int DateTimeFormatter::GetDay() const {
- return day_;
-}
-
-int DateTimeFormatter::GetHour() const {
- return hour_;
-}
-
-int DateTimeFormatter::GetMinute() const {
- return minute_;
-}
-
-int DateTimeFormatter::GetSecond() const {
- return second_;
-}
-
-int DateTimeFormatter::GetMilli() const { return milli_; }
-
-int DateTimeFormatter::GetWeekYear() const { return week_year_; }
-
-int DateTimeFormatter::GetWeek() const {
- return week_;
-}
-
-ui::TextInputType DateTimeFormatter::GetType() const {
- return type_;
-}
-
-const std::string& DateTimeFormatter::GetFormattedValue() const {
- return formatted_string_;
-}
-
-const std::string DateTimeFormatter::FormatString() const {
- UErrorCode success = U_ZERO_ERROR;
- if (year_ == 0 && month_ == 0 && day_ == 0 && hour_ == 0 && minute_ == 0 &&
- second_ == 0 && milli_ == 0 && week_year_ == 0 && week_ == 0) {
- return std::string();
- }
-
- std::string result;
- icu::GregorianCalendar calendar(success);
- if (success <= U_ZERO_ERROR) {
- if (type_ == ui::TEXT_INPUT_TYPE_WEEK) {
- // An ISO week starts with Monday.
- calendar.setFirstDayOfWeek(UCAL_MONDAY);
- // ISO 8601 defines that the week with the year's first Thursday is the
- // first week.
- calendar.setMinimalDaysInFirstWeek(4);
- calendar.set(UCAL_YEAR_WOY, week_year_);
- calendar.set(UCAL_WEEK_OF_YEAR, week_);
- } else {
- calendar.set(UCAL_YEAR, year_);
- calendar.set(UCAL_MONTH, month_);
- calendar.set(UCAL_DATE, day_);
- calendar.set(UCAL_HOUR_OF_DAY, hour_);
- calendar.set(UCAL_MINUTE, minute_);
- calendar.set(UCAL_SECOND, second_);
- calendar.set(UCAL_MILLISECOND, milli_);
- }
- icu::SimpleDateFormat formatter(*pattern_, success);
- icu::UnicodeString formatted_time;
- formatter.format(calendar, formatted_time, NULL, success);
- UTF16ToUTF8(formatted_time.getBuffer(),
- static_cast<size_t>(formatted_time.length()),
- &result);
- if (success <= U_ZERO_ERROR)
- return result;
- }
- LOG(WARNING) << "Calendar not created: error " << success;
- return std::string();
-}
-
-void DateTimeFormatter::ExtractType(
- const blink::WebDateTimeChooserParams& source) {
- switch (source.type) {
- case blink::WebDateTimeInputTypeDate:
- type_ = ui::TEXT_INPUT_TYPE_DATE;
- break;
- case blink::WebDateTimeInputTypeDateTime:
- type_ = ui::TEXT_INPUT_TYPE_DATE_TIME;
- break;
- case blink::WebDateTimeInputTypeDateTimeLocal:
- type_ = ui::TEXT_INPUT_TYPE_DATE_TIME_LOCAL;
- break;
- case blink::WebDateTimeInputTypeMonth:
- type_ = ui::TEXT_INPUT_TYPE_MONTH;
- break;
- case blink::WebDateTimeInputTypeTime:
- type_ = ui::TEXT_INPUT_TYPE_TIME;
- break;
- case blink::WebDateTimeInputTypeWeek:
- type_ = ui::TEXT_INPUT_TYPE_WEEK;
- break;
- case blink::WebDateTimeInputTypeNone:
- default:
- type_ = ui::TEXT_INPUT_TYPE_NONE;
- }
-}
-
-// Not all fields are defined in all configurations and ICU might store
-// garbage if success <= U_ZERO_ERROR so the output is sanitized here.
-int DateTimeFormatter::ExtractValue(
- const icu::Calendar* calendar, UCalendarDateFields value) const {
- UErrorCode success = U_ZERO_ERROR;
- int result = calendar->get(value, success);
- return (success <= U_ZERO_ERROR) ? result : 0;
-}
-
-bool DateTimeFormatter::ParseValues() {
- if (type_ == ui::TEXT_INPUT_TYPE_NONE) {
- ClearAll();
- return false;
- }
-
- if (formatted_string_.empty()) {
- ClearAll();
- return true;
- }
-
- UErrorCode success = U_ZERO_ERROR;
- icu::UnicodeString icu_value = icu::UnicodeString::fromUTF8(
- icu::StringPiece(formatted_string_.data(), formatted_string_.size()));
- if (type_ > 0 && type_ <= ui::TEXT_INPUT_TYPE_MAX) {
- const icu::UnicodeString pattern =
- type_ == ui::TEXT_INPUT_TYPE_TIME ? time_pattern_ : patterns_[type_];
- icu::SimpleDateFormat formatter(pattern, success);
- formatter.parse(icu_value, success);
- if (success <= U_ZERO_ERROR) {
- const icu::Calendar* cal = formatter.getCalendar();
- year_ = ExtractValue(cal, UCAL_YEAR);
- month_ = ExtractValue(cal, UCAL_MONTH);
- day_ = ExtractValue(cal, UCAL_DATE);
- hour_ = ExtractValue(cal, UCAL_HOUR_OF_DAY); // 24h format
- minute_ = ExtractValue(cal, UCAL_MINUTE);
- second_ = ExtractValue(cal, UCAL_SECOND);
- milli_ = ExtractValue(cal, UCAL_MILLISECOND);
- week_year_ = ExtractValue(cal, UCAL_YEAR_WOY);
- week_ = ExtractValue(cal, UCAL_WEEK_OF_YEAR);
- }
- }
-
- return (success <= U_ZERO_ERROR);
-}
-
-void DateTimeFormatter::ClearAll() {
- year_ = 0;
- month_ = 0;
- day_ = 0;
- hour_ = 0;
- minute_ = 0;
- second_ = 0;
- milli_ = 0;
- week_year_ = 0;
- week_ = 0;
-}
-
-} // namespace content
diff --git a/content/renderer/date_time_formatter.h b/content/renderer/date_time_formatter.h
deleted file mode 100644
index b91e117..0000000
--- a/content/renderer/date_time_formatter.h
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_RENDERER_DATE_TIME_FORMATTER_H_
-#define CONTENT_RENDERER_DATE_TIME_FORMATTER_H_
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "content/common/content_export.h"
-#include "third_party/icu/source/common/unicode/unistr.h"
-#include "third_party/icu/source/i18n/unicode/gregocal.h"
-#include "ui/base/ime/text_input_type.h"
-
-namespace blink {
-struct WebDateTimeChooserParams;
-} // namespace blink
-
-namespace content {
-
-// Converts between a text string representing a date/time and
-// a set of year/month/day/hour/minute/second/milli and vice versa.
-// It is timezone agnostic.
-class CONTENT_EXPORT DateTimeFormatter {
- public:
- explicit DateTimeFormatter(const blink::WebDateTimeChooserParams& source);
- DateTimeFormatter(ui::TextInputType type,
- int year,
- int month,
- int day,
- int hour,
- int minute,
- int second,
- int milli,
- int week_year,
- int week);
- ~DateTimeFormatter();
-
- int GetYear() const;
- int GetMonth() const;
- int GetDay() const;
- int GetHour() const;
- int GetMinute() const;
- int GetSecond() const;
- int GetMilli() const;
- int GetWeekYear() const;
- int GetWeek() const;
- ui::TextInputType GetType() const;
- const std::string& GetFormattedValue() const;
-
- private:
- void CreatePatternMap();
- bool ParseValues();
- const std::string FormatString() const;
- int ExtractValue(
- const icu::Calendar* calendar, UCalendarDateFields value) const;
- void ExtractType(const blink::WebDateTimeChooserParams& source);
- void ClearAll();
-
- ui::TextInputType type_;
- icu::UnicodeString patterns_[ui::TEXT_INPUT_TYPE_MAX + 1];
- icu::UnicodeString time_pattern_;
- int year_;
- int month_;
- int day_;
- int hour_;
- int minute_;
- int second_;
- int milli_;
- int week_year_;
- int week_;
- const icu::UnicodeString* pattern_;
- std::string formatted_string_;
-
- DISALLOW_COPY_AND_ASSIGN(DateTimeFormatter);
-};
-
-} // namespace content
-
-#endif // CONTENT_RENDERER_DATE_TIME_FORMATTER_H_
diff --git a/content/renderer/date_time_formatter_unittest.cc b/content/renderer/date_time_formatter_unittest.cc
deleted file mode 100644
index b521188..0000000
--- a/content/renderer/date_time_formatter_unittest.cc
+++ /dev/null
@@ -1,225 +0,0 @@
-// Copyright (c) 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <map>
-
-#include "content/renderer/date_time_formatter.h"
-#include "content/renderer/renderer_date_time_picker.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/public/web/WebDateTimeChooserParams.h"
-#include "third_party/icu/source/common/unicode/unistr.h"
-#include "ui/base/ime/text_input_type.h"
-
-namespace content {
-
-class RendererDateTimePickerTest {
-};
-
-TEST(RendererDateTimePickerTest, TestParserValidStringInputs) {
- blink::WebDateTimeChooserParams params;
- params.currentValue = "2010-07";
- params.type = blink::WebDateTimeInputTypeMonth;
- DateTimeFormatter sut(params);
- EXPECT_EQ(2010, sut.GetYear());
-
- // Month field is 0 based
- EXPECT_EQ(6, sut.GetMonth());
-
- // Month input defaults to the first day of the month (1 based)
- EXPECT_EQ(1, sut.GetDay());
- EXPECT_EQ(0, sut.GetHour());
- EXPECT_EQ(0, sut.GetMinute());
- EXPECT_EQ(0, sut.GetSecond());
- EXPECT_EQ(2010, sut.GetWeekYear());
- EXPECT_EQ(26, sut.GetWeek());
- EXPECT_EQ(ui::TEXT_INPUT_TYPE_MONTH, sut.GetType());
-
- params.currentValue = "2012-05-25";
- params.type = blink::WebDateTimeInputTypeDate;
- DateTimeFormatter sut2(params);
- EXPECT_EQ(2012, sut2.GetYear());
- EXPECT_EQ(4, sut2.GetMonth());
- EXPECT_EQ(25, sut2.GetDay());
- EXPECT_EQ(0, sut2.GetHour());
- EXPECT_EQ(0, sut2.GetMinute());
- EXPECT_EQ(0, sut2.GetSecond());
- EXPECT_EQ(2012, sut2.GetWeekYear());
- EXPECT_EQ(21, sut2.GetWeek());
- EXPECT_EQ(ui::TEXT_INPUT_TYPE_DATE, sut2.GetType());
-
- params.currentValue = "2013-05-21T12:15";
- params.type = blink::WebDateTimeInputTypeDateTimeLocal;
- DateTimeFormatter sut3(params);
- EXPECT_EQ(2013, sut3.GetYear());
- EXPECT_EQ(4, sut3.GetMonth());
- EXPECT_EQ(21, sut3.GetDay());
- EXPECT_EQ(12, sut3.GetHour());
- EXPECT_EQ(15, sut3.GetMinute());
- EXPECT_EQ(0, sut3.GetSecond());
- EXPECT_EQ(2013, sut3.GetWeekYear());
- EXPECT_EQ(21, sut3.GetWeek());
- EXPECT_EQ(ui::TEXT_INPUT_TYPE_DATE_TIME_LOCAL, sut3.GetType());
-
- params.currentValue = "2013-W15";
- params.type = blink::WebDateTimeInputTypeWeek;
- DateTimeFormatter sut4(params);
- EXPECT_EQ(2013, sut4.GetYear());
- EXPECT_EQ(3, sut4.GetMonth());
- EXPECT_EQ(7, sut4.GetDay());
- EXPECT_EQ(0, sut4.GetHour());
- EXPECT_EQ(0, sut4.GetMinute());
- EXPECT_EQ(0, sut4.GetSecond());
- EXPECT_EQ(2013, sut4.GetWeekYear());
- EXPECT_EQ(15, sut4.GetWeek());
- EXPECT_EQ(ui::TEXT_INPUT_TYPE_WEEK, sut4.GetType());
-
- params.currentValue = "12:15";
- params.type = blink::WebDateTimeInputTypeTime;
- DateTimeFormatter sut5(params);
- EXPECT_EQ(12, sut5.GetHour());
- EXPECT_EQ(15, sut5.GetMinute());
- EXPECT_EQ(0, sut5.GetSecond());
- EXPECT_EQ(0, sut5.GetMilli());
- EXPECT_EQ(ui::TEXT_INPUT_TYPE_TIME, sut5.GetType());
-
- params.currentValue = "12:15:02";
- params.type = blink::WebDateTimeInputTypeTime;
- DateTimeFormatter sut6(params);
- EXPECT_EQ(12, sut6.GetHour());
- EXPECT_EQ(15, sut6.GetMinute());
- EXPECT_EQ(02, sut6.GetSecond());
- EXPECT_EQ(0, sut6.GetMilli());
- EXPECT_EQ(ui::TEXT_INPUT_TYPE_TIME, sut6.GetType());
-
- params.currentValue = "12:15:02.1";
- params.type = blink::WebDateTimeInputTypeTime;
- DateTimeFormatter sut7(params);
- EXPECT_EQ(12, sut7.GetHour());
- EXPECT_EQ(15, sut7.GetMinute());
- EXPECT_EQ(02, sut7.GetSecond());
- EXPECT_EQ(100, sut7.GetMilli());
- EXPECT_EQ(ui::TEXT_INPUT_TYPE_TIME, sut7.GetType());
-
- params.currentValue = "12:15:02.123";
- params.type = blink::WebDateTimeInputTypeTime;
- DateTimeFormatter sut8(params);
- EXPECT_EQ(12, sut8.GetHour());
- EXPECT_EQ(15, sut8.GetMinute());
- EXPECT_EQ(02, sut8.GetSecond());
- EXPECT_EQ(123, sut8.GetMilli());
- EXPECT_EQ(ui::TEXT_INPUT_TYPE_TIME, sut8.GetType());
-}
-
-
-TEST(RendererDateTimePickerTest, TestParserInvalidStringInputs) {
-
- // Random non parsable text
- blink::WebDateTimeChooserParams params;
- params.currentValue = "<script injection";
- params.type = blink::WebDateTimeInputTypeMonth;
- DateTimeFormatter sut(params);
- EXPECT_EQ(0, sut.GetYear());
- EXPECT_EQ(0, sut.GetMonth());
- EXPECT_EQ(0, sut.GetDay());
- EXPECT_EQ(0, sut.GetHour());
- EXPECT_EQ(0, sut.GetMinute());
- EXPECT_EQ(0, sut.GetSecond());
- EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, sut.GetType());
-
- // unimplemented type
- params.currentValue = "week 23";
- params.type = blink::WebDateTimeInputTypeWeek; // Not implemented
- DateTimeFormatter sut2(params);
- EXPECT_EQ(0, sut2.GetYear());
- EXPECT_EQ(0, sut2.GetMonth());
- EXPECT_EQ(0, sut2.GetDay());
- EXPECT_EQ(0, sut2.GetHour());
- EXPECT_EQ(0, sut2.GetMinute());
- EXPECT_EQ(0, sut2.GetSecond());
- EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, sut2.GetType());
-
- // type is a subset of pattern
- params.currentValue = "2012-05-25";
- params.type = blink::WebDateTimeInputTypeDateTimeLocal;
- DateTimeFormatter sut3(params);
- EXPECT_EQ(0, sut3.GetYear());
- EXPECT_EQ(0, sut3.GetMonth());
- EXPECT_EQ(0, sut3.GetDay());
- EXPECT_EQ(0, sut3.GetHour());
- EXPECT_EQ(0, sut3.GetMinute());
- EXPECT_EQ(0, sut3.GetSecond());
- EXPECT_EQ(ui::TEXT_INPUT_TYPE_NONE, sut3.GetType());
-
- // type is a superset of pattern
- params.currentValue = "2013-05-21T12:15";
- params.type = blink::WebDateTimeInputTypeMonth;
- DateTimeFormatter sut4(params);
- EXPECT_EQ(2013, sut4.GetYear());
- EXPECT_EQ(4, sut4.GetMonth());
- EXPECT_EQ(1, sut4.GetDay());
- EXPECT_EQ(0, sut4.GetHour());
- EXPECT_EQ(0, sut4.GetMinute());
- EXPECT_EQ(0, sut4.GetSecond());
- EXPECT_EQ(ui::TEXT_INPUT_TYPE_MONTH, sut4.GetType());
-}
-
-
-TEST(RendererDateTimePickerTest, TestParserValidDateInputs) {
- DateTimeFormatter sut(
- ui::TEXT_INPUT_TYPE_MONTH, 2012, 11, 1, 0, 0, 0, 0, 0, 0);
- EXPECT_EQ("2012-12", sut.GetFormattedValue());
-
- DateTimeFormatter sut2(
- ui::TEXT_INPUT_TYPE_DATE_TIME_LOCAL, 2013, 3, 23, 15, 47, 0, 0, 0, 0);
- EXPECT_EQ("2013-04-23T15:47", sut2.GetFormattedValue());
-
- DateTimeFormatter sut3(
- ui::TEXT_INPUT_TYPE_WEEK, 0, 0, 0, 0, 0, 0, 0, 2012, 2);
- EXPECT_EQ("2012-W02", sut3.GetFormattedValue());
-}
-
-TEST(RendererDateTimePickerTest, TestParserValidTimeInputs) {
- DateTimeFormatter sut(
- ui::TEXT_INPUT_TYPE_TIME, 0, 0, 0, 12, 15, 0, 0, 0, 0);
- EXPECT_EQ("12:15", sut.GetFormattedValue());
-
- DateTimeFormatter sut2(
- ui::TEXT_INPUT_TYPE_TIME, 0, 0, 0, 12, 15, 02, 0, 0, 0);
- EXPECT_EQ("12:15:02", sut2.GetFormattedValue());
-
- DateTimeFormatter sut3(
- ui::TEXT_INPUT_TYPE_TIME, 0, 0, 0, 12, 15, 02, 123, 0, 0);
- EXPECT_EQ("12:15:02.123", sut3.GetFormattedValue());
-}
-
-TEST(RendererDateTimePickerTest, TestParserInvalidDateInputs) {
- DateTimeFormatter sut(ui::TEXT_INPUT_TYPE_WEEK, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- EXPECT_EQ("", sut.GetFormattedValue());
-
- DateTimeFormatter sut2(
- ui::TEXT_INPUT_TYPE_NONE, 2013, 3, 23, 0, 0, 0, 0, 0, 0);
- EXPECT_EQ("", sut2.GetFormattedValue());
-
- DateTimeFormatter sut3(
- ui::TEXT_INPUT_TYPE_NONE, 2013, 14, 32, 0, 0, 0, 0, 0, 0);
- EXPECT_EQ("", sut3.GetFormattedValue());
-
- DateTimeFormatter sut4(ui::TEXT_INPUT_TYPE_DATE, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- EXPECT_EQ("", sut4.GetFormattedValue());
-
- DateTimeFormatter sut5(ui::TEXT_INPUT_TYPE_TIME, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- EXPECT_EQ("", sut5.GetFormattedValue());
-
- DateTimeFormatter sut6(
- ui::TEXT_INPUT_TYPE_PASSWORD, 23, 0, 0, 0, 5, 0, 0, 0, 0);
- EXPECT_EQ("", sut6.GetFormattedValue());
-
- DateTimeFormatter sut7(ui::TEXT_INPUT_TYPE_MAX, 23, 0, 0, 0, 5, 0, 0, 0, 0);
- EXPECT_EQ("", sut7.GetFormattedValue());
-
- DateTimeFormatter sut8(
- static_cast<ui::TextInputType>(10000), 23, 0, 0, 0, 5, 0, 0, 0, 0);
- EXPECT_EQ("", sut8.GetFormattedValue());
-}
-} // namespace content
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc
index 2648186..fe704b2 100644
--- a/content/renderer/render_view_impl.cc
+++ b/content/renderer/render_view_impl.cc
@@ -112,7 +112,6 @@
#include "content/renderer/render_view_impl_params.h"
#include "content/renderer/render_view_mouse_lock_dispatcher.h"
#include "content/renderer/render_widget_fullscreen_pepper.h"
-#include "content/renderer/renderer_date_time_picker.h"
#include "content/renderer/renderer_webapplicationcachehost_impl.h"
#include "content/renderer/renderer_webcolorchooser_impl.h"
#include "content/renderer/resizing_mode_selector.h"
@@ -6150,11 +6149,21 @@ void RenderViewImpl::LaunchAndroidContentIntent(const GURL& intent,
bool RenderViewImpl::openDateTimeChooser(
const blink::WebDateTimeChooserParams& params,
blink::WebDateTimeChooserCompletion* completion) {
+ // JavaScript may try to open a date time chooser while one is already open.
+ if (date_time_picker_client_)
+ return false;
date_time_picker_client_.reset(
new RendererDateTimePicker(this, params, completion));
return date_time_picker_client_->Open();
}
+#if defined(OS_ANDROID)
+void RenderViewImpl::DismissDateTimeDialog() {
+ DCHECK(date_time_picker_client_);
+ date_time_picker_client_.reset(NULL);
+}
+#endif
+
WebMediaPlayer* RenderViewImpl::CreateAndroidWebMediaPlayer(
WebFrame* frame,
const blink::WebURL& url,
diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h
index 6a7ce2f..8ad186f 100644
--- a/content/renderer/render_view_impl.h
+++ b/content/renderer/render_view_impl.h
@@ -39,6 +39,7 @@
#include "content/renderer/mouse_lock_dispatcher.h"
#include "content/renderer/render_frame_impl.h"
#include "content/renderer/render_widget.h"
+#include "content/renderer/renderer_date_time_picker.h"
#include "content/renderer/renderer_webcookiejar_impl.h"
#include "content/renderer/stats_collection_observer.h"
#include "ipc/ipc_platform_file.h"
@@ -272,6 +273,10 @@ class CONTENT_EXPORT RenderViewImpl
const std::string& html,
bool replace);
+#if defined(OS_ANDROID)
+ void DismissDateTimeDialog();
+#endif
+
// Plugin-related functions --------------------------------------------------
#if defined(ENABLE_PLUGINS)
diff --git a/content/renderer/renderer_date_time_picker.cc b/content/renderer/renderer_date_time_picker.cc
index 074ebe5..46f0c38 100644
--- a/content/renderer/renderer_date_time_picker.cc
+++ b/content/renderer/renderer_date_time_picker.cc
@@ -6,45 +6,47 @@
#include "base/strings/string_util.h"
#include "content/common/view_messages.h"
-#include "content/renderer/date_time_formatter.h"
#include "content/renderer/render_view_impl.h"
-
#include "third_party/WebKit/public/web/WebDateTimeChooserCompletion.h"
#include "third_party/WebKit/public/web/WebDateTimeChooserParams.h"
#include "third_party/WebKit/public/web/WebDateTimeInputType.h"
+#include "ui/base/ime/text_input_type.h"
using blink::WebString;
namespace content {
+COMPILE_ASSERT(int(blink::WebTextInputTypeDate) == \
+ int(ui::TEXT_INPUT_TYPE_DATE), mismatching_enum);
+COMPILE_ASSERT(int(blink::WebTextInputTypeDateTime) == \
+ int(ui::TEXT_INPUT_TYPE_DATE_TIME), mismatching_enum);
+COMPILE_ASSERT(int(blink::WebTextInputTypeDateTimeLocal) == \
+ int(ui::TEXT_INPUT_TYPE_DATE_TIME_LOCAL), mismatching_enum);
+COMPILE_ASSERT(int(blink::WebTextInputTypeMonth) == \
+ int(ui::TEXT_INPUT_TYPE_MONTH), mismatching_enum);
+COMPILE_ASSERT(int(blink::WebTextInputTypeTime) == \
+ int(ui::TEXT_INPUT_TYPE_TIME), mismatching_enum);
+COMPILE_ASSERT(int(blink::WebTextInputTypeWeek) == \
+ int(ui::TEXT_INPUT_TYPE_WEEK), mismatching_enum);
+COMPILE_ASSERT(int(blink::WebTextInputTypeDateTimeField) == \
+ int(ui::TEXT_INPUT_TYPE_DATE_TIME_FIELD), mismatching_enums);
+
RendererDateTimePicker::RendererDateTimePicker(
RenderViewImpl* sender,
const blink::WebDateTimeChooserParams& params,
blink::WebDateTimeChooserCompletion* completion)
: RenderViewObserver(sender),
chooser_params_(params),
- chooser_completion_(completion){
+ chooser_completion_(completion) {
}
RendererDateTimePicker::~RendererDateTimePicker() {
}
bool RendererDateTimePicker::Open() {
- DateTimeFormatter parser(chooser_params_);
ViewHostMsg_DateTimeDialogValue_Params message;
- message.dialog_type = parser.GetType();
- if (message.dialog_type == ui::TEXT_INPUT_TYPE_WEEK) {
- message.year = parser.GetWeekYear();
- message.week = parser.GetWeek();
- } else {
- message.year = parser.GetYear();
- message.month = parser.GetMonth();
- message.day = parser.GetDay();
- message.hour = parser.GetHour();
- message.minute = parser.GetMinute();
- message.second = parser.GetSecond();
- message.milli = parser.GetMilli();
- }
+ message.dialog_type = static_cast<ui::TextInputType>(chooser_params_.type);
+ message.dialog_value = chooser_params_.doubleValue;
message.minimum = chooser_params_.minimum;
message.maximum = chooser_params_.maximum;
message.step = chooser_params_.step;
@@ -63,28 +65,20 @@ bool RendererDateTimePicker::OnMessageReceived(
return handled;
}
-void RendererDateTimePicker::OnReplaceDateTime(
- const ViewHostMsg_DateTimeDialogValue_Params& value) {
-
- DateTimeFormatter formatter(static_cast<ui::TextInputType>(value.dialog_type),
- value.year,
- value.month,
- value.day,
- value.hour,
- value.minute,
- value.second,
- value.milli,
- value.year,
- value.week);
-
+void RendererDateTimePicker::OnReplaceDateTime(double value) {
if (chooser_completion_)
- chooser_completion_->didChooseValue(WebString::fromUTF8(
- formatter.GetFormattedValue().c_str()));
+ chooser_completion_->didChooseValue(value);
+#if defined(OS_ANDROID)
+ static_cast<RenderViewImpl*>(render_view())->DismissDateTimeDialog();
+#endif
}
void RendererDateTimePicker::OnCancel() {
if (chooser_completion_)
chooser_completion_->didCancelChooser();
+#if defined(OS_ANDROID)
+ static_cast<RenderViewImpl*>(render_view())->DismissDateTimeDialog();
+#endif
}
} // namespace content
diff --git a/content/renderer/renderer_date_time_picker.h b/content/renderer/renderer_date_time_picker.h
index 2dc6386..7a780c7 100644
--- a/content/renderer/renderer_date_time_picker.h
+++ b/content/renderer/renderer_date_time_picker.h
@@ -29,7 +29,7 @@ class RendererDateTimePicker : public RenderViewObserver {
bool Open();
private:
- void OnReplaceDateTime(const ViewHostMsg_DateTimeDialogValue_Params& value);
+ void OnReplaceDateTime(double value);
void OnCancel();
// RenderViewObserver