Title: [133565] trunk/Source/WebCore
Revision
133565
Author
[email protected]
Date
2012-11-05 23:18:12 -0800 (Mon, 05 Nov 2012)

Log Message

Introduce Day class to calendar picker
https://bugs.webkit.org/show_bug.cgi?id=101194

Reviewed by Kent Tamura.

Introducing Day class so day, week, and month can all be abstracted. To
solve some of the complexity around which months to show, I made
CalendarPicker in charge of it. This also made YearMonthController and
DaysTable independent of each other.

No new tests. Covered by existing calendar-picker-*.html tests.

* Resources/pagepopups/calendarPicker.js:
(createUTCDate): Allow negative month or date.
(parseDateString): Will return Day or Month depending on string format.
(Day): Represents a day.
(Day.parse): Parse yyyy-mm-dd.
(Day.createFromDate): Creates a Day that contains a datetime.
(Day.createFromToday): Creates Day for today. A method with the same name will be added to Week and Month in the future.
(Day.prototype.equals): Returns true if they are the same.
(Day.prototype.previous): Returns the previous day.
(Day.prototype.next): Returns the next day.
(Day.prototype.startDate): Returns the datetime that is the start of this day.
(Day.prototype.endDate): Returns the datetime that is the start of this day.
(Day.prototype.valueOf): Returns the milliseconds since epoch.
(Day.prototype.toString): Returns an ISO date string.
(Month): Fix bug in calculating month from value.
(Month.prototype.endDate): Use Day.Maximum.
(CalendarPicker): Added _currentMonth. yearMonthController and daysTable can be private members now.
(CalendarPicker.prototype._layout):
(CalendarPicker.prototype.handleToday): Use Day.createFromToday.
(CalendarPicker.prototype.shouldShowMonth): Returns true if the month should be shown.
(CalendarPicker.prototype.showMonth): Shows the given month. If the month is out of the range of months that should be shown, we clamp the month and show that.
(CalendarPicker.prototype.currentMonth): Returns the current month that is shown.
(YearMonthController): Removed _currentMonth.
(YearMonthController.prototype.attachTo):
(YearMonthController.prototype.setMonth):
(YearMonthController.prototype._handleYearMonthChange): Use CalendarPicker.showMonth
(YearMonthController.prototype.moveRelatively):
(DaysTable):
(CalendarPicker.prototype._stepMismatch): Made private.
(CalendarPicker.prototype._outOfRange): Made private.
(CalendarPicker.prototype.isValidDate): Take Day or Month instead of milliseconds since epoch.
(DaysTable.prototype._renderMonth):
(DaysTable.prototype.navigateToMonth): Shows a given month. Can use animation and leave the selection position as is.
(DaysTable.prototype.selectRange): Select a range.
(DaysTable.prototype._maybeSetPreviousMonth):
(DaysTable.prototype._maybeSetNextMonth):
(DaysTable.prototype._handleKey):
(CalendarPicker.prototype._handleBodyKeyDown):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (133564 => 133565)


--- trunk/Source/WebCore/ChangeLog	2012-11-06 07:16:27 UTC (rev 133564)
+++ trunk/Source/WebCore/ChangeLog	2012-11-06 07:18:12 UTC (rev 133565)
@@ -1,3 +1,56 @@
+2012-11-05  Keishi Hattori  <[email protected]>
+
+        Introduce Day class to calendar picker
+        https://bugs.webkit.org/show_bug.cgi?id=101194
+
+        Reviewed by Kent Tamura.
+
+        Introducing Day class so day, week, and month can all be abstracted. To
+        solve some of the complexity around which months to show, I made
+        CalendarPicker in charge of it. This also made YearMonthController and
+        DaysTable independent of each other.
+
+        No new tests. Covered by existing calendar-picker-*.html tests.
+
+        * Resources/pagepopups/calendarPicker.js:
+        (createUTCDate): Allow negative month or date.
+        (parseDateString): Will return Day or Month depending on string format.
+        (Day): Represents a day.
+        (Day.parse): Parse yyyy-mm-dd.
+        (Day.createFromDate): Creates a Day that contains a datetime.
+        (Day.createFromToday): Creates Day for today. A method with the same name will be added to Week and Month in the future.
+        (Day.prototype.equals): Returns true if they are the same.
+        (Day.prototype.previous): Returns the previous day.
+        (Day.prototype.next): Returns the next day.
+        (Day.prototype.startDate): Returns the datetime that is the start of this day.
+        (Day.prototype.endDate): Returns the datetime that is the start of this day.
+        (Day.prototype.valueOf): Returns the milliseconds since epoch.
+        (Day.prototype.toString): Returns an ISO date string.
+        (Month): Fix bug in calculating month from value.
+        (Month.prototype.endDate): Use Day.Maximum.
+        (CalendarPicker): Added _currentMonth. yearMonthController and daysTable can be private members now.
+        (CalendarPicker.prototype._layout):
+        (CalendarPicker.prototype.handleToday): Use Day.createFromToday.
+        (CalendarPicker.prototype.shouldShowMonth): Returns true if the month should be shown.
+        (CalendarPicker.prototype.showMonth): Shows the given month. If the month is out of the range of months that should be shown, we clamp the month and show that.
+        (CalendarPicker.prototype.currentMonth): Returns the current month that is shown.
+        (YearMonthController): Removed _currentMonth.
+        (YearMonthController.prototype.attachTo):
+        (YearMonthController.prototype.setMonth):
+        (YearMonthController.prototype._handleYearMonthChange): Use CalendarPicker.showMonth
+        (YearMonthController.prototype.moveRelatively):
+        (DaysTable):
+        (CalendarPicker.prototype._stepMismatch): Made private.
+        (CalendarPicker.prototype._outOfRange): Made private.
+        (CalendarPicker.prototype.isValidDate): Take Day or Month instead of milliseconds since epoch.
+        (DaysTable.prototype._renderMonth):
+        (DaysTable.prototype.navigateToMonth): Shows a given month. Can use animation and leave the selection position as is.
+        (DaysTable.prototype.selectRange): Select a range.
+        (DaysTable.prototype._maybeSetPreviousMonth):
+        (DaysTable.prototype._maybeSetNextMonth):
+        (DaysTable.prototype._handleKey):
+        (CalendarPicker.prototype._handleBodyKeyDown):
+
 2012-11-05  Kenichi Ishibashi  <[email protected]>
 
         Unreviewed, Adding #if PLATFORM(CHROMIUM) for the fix of

Modified: trunk/Source/WebCore/Resources/pagepopups/calendarPicker.js (133564 => 133565)


--- trunk/Source/WebCore/Resources/pagepopups/calendarPicker.js	2012-11-06 07:16:27 UTC (rev 133564)
+++ trunk/Source/WebCore/Resources/pagepopups/calendarPicker.js	2012-11-06 07:18:12 UTC (rev 133565)
@@ -175,39 +175,126 @@
 };
 
 function createUTCDate(year, month, date) {
-    var newDate = new Date(Date.UTC(year, month, date));
-    if (year < 100)
-        newDate.setUTCFullYear(year);
+    var newDate = new Date(0);
+    newDate.setUTCFullYear(year);
+    newDate.setUTCMonth(month);
+    newDate.setUTCDate(date);
     return newDate;
 };
 
 /**
- * @param {string=} opt_current
- * @return {!Date}
+ * @param {string} dateString
+ * @return {?Day|Month}
  */
-function parseDateString(opt_current) {
-    if (opt_current) {
-        var result = opt_current.match(/(\d+)-(\d+)-(\d+)/);
-        if (result)
-            return createUTCDate(Number(result[1]), Number(result[2]) - 1, Number(result[3]));
-    }
+function parseDateString(dateString) {
+    var month = Month.parse(dateString);
+    if (month)
+        return month;
+    return Day.parse(dateString);
+}
+
+/**
+ * @param {!number|Day} valueOrDayOrYear
+ * @param {!number=} month
+ * @param {!number=} date
+ */
+function Day(valueOrDayOrYear, month, date) {
+    var dateObject;
+    if (arguments.length == 3)
+        dateObject = createUTCDate(valueOrDayOrYear, month, date);
+    else if (valueOrDayOrYear instanceof Day)
+        dateObject = createUTCDate(valueOrDayOrYear.year, valueOrDayOrYear.month, valueOrDayOrYear.date);
+    else
+        dateObject = new Date(valueOrDayOrYear);
+    this.year = dateObject.getUTCFullYear();    
+    this.month = dateObject.getUTCMonth();
+    this.date = dateObject.getUTCDate();
+};
+
+Day.ISOStringRegExp = /^(\d+)-(\d+)-(\d+)$/;
+
+// See WebCore/platform/DateComponents.h.
+Day.Minimum = new Date(-62135596800000.0);
+Day.Maximum = new Date(8640000000000000.0);
+
+/**
+ * @param {!string} str
+ * @return {?Month}
+ */
+Day.parse = function(str) {
+    var match = Day.ISOStringRegExp.exec(str);
+    if (!match)
+        return null;
+    var year = parseInt(match[1], 10);
+    var month = parseInt(match[2], 10) - 1;
+    var date = parseInt(match[3], 10);
+    return new Day(year, month, date);
+};
+/**
+ * @param {!Date} date
+ * @return {!Month}
+ */
+Day.createFromDate = function(date) {
+    return new Day(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
+};
+
+Day.createFromToday = function() {
     var now = new Date();
-    // Create UTC date with same numbers as local date.
-    return createUTCDate(now.getFullYear(), now.getMonth(), now.getDate());
+    return new Day(now.getFullYear(), now.getMonth(), now.getDate());
 }
 
 /**
- * @param {!number} year
- * @param {!number} month
- * @param {!number} day
+ * @param {!Day} other
+ * @return {!bool}
+ */
+Day.prototype.equals = function(other) {
+    return this.year === other.year && this.month === other.month && this.date === other.date;
+};
+
+/**
+ * @return {!Day}
+ */
+Day.prototype.previous = function() {
+    return new Day(this.year, this.month, this.date - 1);
+};
+
+/**
+ * @return {!Day}
+ */
+Day.prototype.next = function() {
+    return new Day(this.year, this.month, this.date + 1);
+};
+
+/**
+ * @return {!Date}
+ */
+Day.prototype.startDate = function() {
+    return createUTCDate(this.year, this.month, this.date);
+};
+
+/**
+ * @return {!Date}
+ */
+Day.prototype.endDate = function() {
+    return createUTCDate(this.year, this.month, this.date + 1);
+};
+
+/**
+ * @return {!number}
+ */
+Day.prototype.valueOf = function() {
+    return this.startDate().getTime();
+};
+
+/**
  * @return {!string}
  */
-function serializeDate(year, month, day) {
-    var yearString = String(year);
+Day.prototype.toString = function() {
+    var yearString = String(this.year);
     if (yearString.length < 4)
         yearString = ("000" + yearString).substr(-4, 4);
-    return yearString + "-" + ("0" + (month + 1)).substr(-2, 2) + "-" + ("0" + day).substr(-2, 2);
-}
+    return yearString + "-" + ("0" + (this.month + 1)).substr(-2, 2) + "-" + ("0" + this.date).substr(-2, 2);
+};
 
 /**
  * @param {!number|Month} valueOrMonthOrYear
@@ -221,12 +308,12 @@
         this.year = valueOrMonthOrYear.year;
         this.month = valueOrMonthOrYear.month;
     } else {
-        this.year = Math.floor(valueOrMonthOrYear / 12) + 1970;
-        this.month = valueOrMonthOrYear % 12;
+        this.year = 1970;
+        this.month = valueOrMonthOrYear;
     }
     this.year = this.year + Math.floor(this.month / 12);
     this.month = this.month < 0 ? this.month % 12 + 12 : this.month % 12;
-    if (this.year < 0 || Month.Maximum < this) {
+    if (this.year <= 0 || Month.Maximum < this) {
         this.year = NaN;
         this.month = NaN;
     }
@@ -292,7 +379,7 @@
  */
 Month.prototype.endDate = function() {
     if (this.equals(Month.Maximum))
-        return CalendarPicker.MaximumPossibleDate;
+        return Day.Maximum.startDate();
     return this.next().startDate();
 };
 
@@ -418,30 +505,33 @@
     this._handleWindowResizeBound = this._handleWindowResize.bind(this);
     window.addEventListener("resize", this._handleWindowResizeBound, false);
     // We assume this._config.min is a valid date.
-    this.minimumDate = (typeof this._config.min !== "undefined") ? parseDateString(this._config.min) : CalendarPicker.MinimumPossibleDate;
+    this._minimumValue = (typeof this._config.min !== "undefined") ? parseDateString(this._config.min).valueOf() : Day.Minimum.valueOf();
     // We assume this._config.max is a valid date.
-    this.maximumDate = (typeof this._config.max !== "undefined") ? parseDateString(this._config.max) : CalendarPicker.MaximumPossibleDate;
+    this._maximumValue = (typeof this._config.max !== "undefined") ? parseDateString(this._config.max).valueOf() : Day.Maximum.valueOf();
     this.step = (typeof this._config.step !== undefined) ? Number(this._config.step) : CalendarPicker.DefaultStepScaleFactor;
     this.stepBase = (typeof this._config.stepBase !== "undefined") ? Number(this._config.stepBase) : CalendarPicker.DefaultStepBase;
-    this.yearMonthController = new YearMonthController(this);
-    this.daysTable = new DaysTable(this);
+    this._minimumMonth = Month.createFromDate(new Date(this._minimumValue));
+    this.maximumMonth = Month.createFromDate(new Date(this._maximumValue));
+    this._currentMonth = new Month(NaN, NaN);
+    this._yearMonthController = new YearMonthController(this);
+    this._daysTable = new DaysTable(this);
     this._hadKeyEvent = false;
     this._layout();
-    var initialDate = parseDateString(this._config.currentValue);
-    if (initialDate < this.minimumDate)
-        initialDate = this.minimumDate;
-    else if (initialDate > this.maximumDate)
-        initialDate = this.maximumDate;
-    this.daysTable.selectDate(initialDate);
+    var initialSelection = parseDateString(this._config.currentValue);
+    if (!initialSelection)
+        initialSelection = Day.createFromToday();
+    if (initialSelection.valueOf() < this._minimumValue)
+        initialSelection = new Day(this._minimumValue);
+    else if (initialSelection.valueOf() > this._maximumValue)
+        initialSelection = new Day(this._maximumValue);
+    this.showMonth(Month.createFromDate(initialSelection.startDate()), false);
+    this._daysTable.selectRange(initialSelection);
     this.fixWindowSize();
     this._handleBodyKeyDownBound = this._handleBodyKeyDown.bind(this);
     document.body.addEventListener("keydown", this._handleBodyKeyDownBound, false);
 }
 CalendarPicker.prototype = Object.create(Picker.prototype);
 
-// Hard limits of type=date. See WebCore/platform/DateComponents.h.
-CalendarPicker.MinimumPossibleDate = new Date(-62135596800000.0);
-CalendarPicker.MaximumPossibleDate = new Date(8640000000000000.0);
 // See WebCore/html/DateInputType.cpp.
 CalendarPicker.DefaultStepScaleFactor = 86400000;
 CalendarPicker.DefaultStepBase = 0.0;
@@ -457,17 +547,17 @@
 CalendarPicker.prototype._layout = function() {
     if (this._config.isCalendarRTL)
         this._element.classList.add("rtl");
-    this.yearMonthController.attachTo(this._element);
-    this.daysTable.attachTo(this._element);
+    this._yearMonthController.attachTo(this._element);
+    this._daysTable.attachTo(this._element);
     this._layoutButtons();
     // DaysTable will have focus but we don't want to show its focus ring until the first key event.
     this._element.classList.add(ClassNames.NoFocusRing);
 };
 
 CalendarPicker.prototype.handleToday = function() {
-    var date = new Date();
-    this.daysTable.selectDate(date);
-    this.submitValue(serializeDate(date.getFullYear(), date.getMonth(), date.getDate()));
+    var today = Day.createFromToday();
+    this._daysTable.selectRange(today);
+    this.submitValue(today.toString());
 };
 
 CalendarPicker.prototype.handleClear = function() {
@@ -528,6 +618,38 @@
     this.lastFocusableControl = this.clear || this.today;
 };
 
+/**
+ * @param {!Month} month
+ * @return {!bool}
+ */
+CalendarPicker.prototype.shouldShowMonth = function(month) {
+    return this._minimumMonth.valueOf() <= month.valueOf() && this.maximumMonth.valueOf() >= month.valueOf();
+};
+
+/**
+ * @param {!Month} month
+ * @param {!bool=} animate
+ * @param {!bool=} keepSelectionPosition
+ */
+CalendarPicker.prototype.showMonth = function(month, animate, keepSelectionPosition) {
+    if (this._currentMonth.equals(month))
+        return;
+    else if (month.valueOf() < this._minimumMonth.valueOf())
+        month = this._minimumMonth;
+    else if (month.valueOf() > this.maximumMonth.valueOf())
+        month = this.maximumMonth;
+    this._yearMonthController.setMonth(month);
+    this._daysTable.navigateToMonth(month, animate, keepSelectionPosition);
+    this._currentMonth = month;
+};
+
+/**
+ * @return {!Month}
+ */
+CalendarPicker.prototype.currentMonth = function() {
+    return this._currentMonth;
+};
+
 // ----------------------------------------------------------------
 
 /**
@@ -536,10 +658,6 @@
  */
 function YearMonthController(picker) {
     this.picker = picker;
-    /**
-     * @type {?Month}
-     */
-    this._currentMonth = null;
 }
 
 /**
@@ -576,14 +694,12 @@
     this._wall.addEventListener("click", this._closePopup.bind(this), false);
     element.appendChild(this._wall);
 
-    var maximumYear = this.picker.maximumDate.getUTCFullYear();
-    // Because the maximum possible year is September we should use the year before it.
-    if (maximumYear === Month.Maximum.year)
-        maximumYear--;
+    var month = this.picker.maximumMonth;
     var maxWidth = 0;
     for (var m = 0; m < 12; ++m) {
-        this._month.textContent = new Month(maximumYear, m).toLocaleString();
+        this._month.textContent = month.toLocaleString();
         maxWidth = Math.max(maxWidth, this._month.offsetWidth);
+        month = month.previous();
     }
     if (getLanguage() == "ja" && ImperialEraLimit < maximumYear) {
         for (var m = 0; m < 12; ++m) {
@@ -654,44 +770,30 @@
 };
 
 /**
- * @return {?Month}
- */
-YearMonthController.prototype.month = function() {
-    return this._currentMonth;
-};
-
-/**
  * @param {!Month} month
  */
 YearMonthController.prototype.setMonth = function(month) {
-    this._currentMonth = new Month(month);
-    this._redraw();
-};
-
-YearMonthController.prototype._redraw = function() {
-    var min = Month.createFromDate(this.picker.minimumDate).valueOf();
-    var max = Month.createFromDate(this.picker.maximumDate).valueOf();
-    var current = this._currentMonth.valueOf();
+    var monthValue = month.valueOf();
     if (this._left3)
-        this._left3.disabled = current - 13 < min;
-    this._left2.disabled = current - 2 < min;
-    this._left1.disabled = current - 1 < min;
-    this._right1.disabled = current + 1 > max;
-    this._right2.disabled = current + 2 > max;
+        this._left3.disabled = !this.picker.shouldShowMonth(new Month(monthValue - 13));
+    this._left2.disabled = !this.picker.shouldShowMonth(new Month(monthValue - 2));
+    this._left1.disabled = !this.picker.shouldShowMonth(new Month(monthValue - 1));
+    this._right1.disabled = !this.picker.shouldShowMonth(new Month(monthValue + 1));
+    this._right2.disabled = !this.picker.shouldShowMonth(new Month(monthValue + 2));
     if (this._right3)
-        this._right3.disabled = current + 13 > max;
-    this._month.innerText = this._currentMonth.toLocaleString();
+        this._left3.disabled = !this.picker.shouldShowMonth(new Month(monthValue + 13));
+    this._month.innerText = month.toLocaleString();
     while (this._monthPopupContents.hasChildNodes())
         this._monthPopupContents.removeChild(this._monthPopupContents.firstChild);
 
-    for (var m = current - 6; m <= current + 6; m++) {
-        if (m < min || m > max)
+    for (var m = monthValue - 6; m <= monthValue + 6; m++) {
+        var month = new Month(m);
+        if (!this.picker.shouldShowMonth(month))
             continue;
-        var month = new Month(m);
         var option = createElement("div", ClassNames.MonthSelectorPopupEntry, month.toLocaleString());
         option.dataset.value = month.toString();
         this._monthPopupContents.appendChild(option);
-        if (m == current)
+        if (m == monthValue)
             option.classList.add(ClassNames.SelectedMonthYear);
     }
 };
@@ -810,7 +912,7 @@
     var selection = this._getSelection();
     if (!selection)
         return;
-    this.picker.daysTable.navigateToMonthAndKeepSelectionPosition(Month.parse(selection.dataset.value));
+    this.picker.showMonth(Month.parse(selection.dataset.value));
 };
 
 /*
@@ -868,17 +970,9 @@
  * @param {!number} amount
  */
 YearMonthController.prototype.moveRelatively = function(amount) {
-    var min = Month.createFromDate(this.picker.minimumDate).valueOf();
-    var max = Month.createFromDate(this.picker.maximumDate).valueOf();
-    var current = this._currentMonth.valueOf();
-    var updated = current;
-    if (amount < 0)
-        updated = current + amount >= min ? current + amount : min;
-    else
-        updated = current + amount <= max ? current + amount : max;
-    if (updated == current)
-        return;
-    this.picker.daysTable.navigateToMonthAndKeepSelectionPosition(new Month(updated));
+    var current = this.picker.currentMonth().valueOf();
+    var updated = new Month(current + amount);
+    this.picker.showMonth(updated, true, true);
 };
 
 // ----------------------------------------------------------------
@@ -889,10 +983,6 @@
  */
 function DaysTable(picker) {
     this.picker = picker;
-    /**
-     * @type {?Month}
-     */
-    this._currentMonth = null;
 }
 
 /**
@@ -947,36 +1037,35 @@
 };
 
 /**
- * @param {!number} time date in millisecond.
+ * @param {!number} value
  * @return {!boolean}
  */
-CalendarPicker.prototype.stepMismatch = function(time) {
-    return (time - this.stepBase) % this.step != 0;
+CalendarPicker.prototype._stepMismatch = function(value) {
+    return (value - this.stepBase) % this.step != 0;
 }
 
 /**
- * @param {!number} time date in millisecond.
+ * @param {!number} value
  * @return {!boolean}
  */
-CalendarPicker.prototype.outOfRange = function(time) {
-    return time < this.minimumDate.getTime() || time > this.maximumDate.getTime();
+CalendarPicker.prototype._outOfRange = function(value) {
+    return value < this._minimumValue || value > this._maximumValue;
 }
 
 /**
- * @param {!number} time date in millisecond.
+ * @param {!Month|Day} range
  * @return {!boolean}
  */
-CalendarPicker.prototype.isValidDate = function(time) {
-    return !this.outOfRange(time) && !this.stepMismatch(time);
+CalendarPicker.prototype.isValidDate = function(range) {
+    var value = range.valueOf();
+    return !this._outOfRange(value) && !this._stepMismatch(value);
 }
 
 /**
- * @param {!number} year
- * @param {!number} month
+ * @param {!Month} month
  */
 DaysTable.prototype._renderMonth = function(month) {
-    this._currentMonth = new Month(month);
-    var dayIterator = this._currentMonth.startDate();
+    var dayIterator = month.startDate();
     var monthStartDay = dayIterator.getUTCDay();
     var weekStartDay = global.params.weekStartDay || 0;
     var startOffset = weekStartDay - monthStartDay;
@@ -990,15 +1079,13 @@
             var element = this._days[w][d];
             element.innerText = localizeNumber(dayIterator.getUTCDate());
             element.className = ClassNames.Day;
-            element.dataset.submitValue = serializeDate(iterMonth.year, iterMonth.month, dayIterator.getUTCDate());
+            element.dataset.submitValue = Day.createFromDate(dayIterator).toString();
             if (isNaN(time)) {
                 element.innerText = "-";
                 element.classList.add(ClassNames.Unavailable);
-            } else if (this.picker.outOfRange(time))
+            } else if (!this.picker.isValidDate(Day.createFromDate(dayIterator)))
                 element.classList.add(ClassNames.Unavailable);
-            else if (this.picker.stepMismatch(time))
-                element.classList.add(ClassNames.Unavailable);
-            else if (!iterMonth.equals(this._currentMonth)) {
+            else if (!iterMonth.equals(month)) {
                 element.classList.add(ClassNames.Available);
                 element.classList.add(ClassNames.NotThisMonth);
             } else
@@ -1007,31 +1094,28 @@
         }
     }
 
-    this.picker.today.disabled = !this.picker.isValidDate(parseDateString().getTime());
+    this.picker.today.disabled = !this.picker.isValidDate(Day.createFromToday().valueOf());
 };
 
 /**
  * @param {!Month} month
+ * @param {!bool} animate
+ * @param {!bool} keepSelectionPosition
  */
-DaysTable.prototype._navigateToMonth = function(month) {
-    this.picker.yearMonthController.setMonth(month);
-    this._renderMonth(month);
-};
-
-/**
- * @param {!Month} month
- */
-DaysTable.prototype._navigateToMonthWithAnimation = function(month) {
-    if (this._currentMonth) {
-        var delta = this._currentMonth.valueOf() - month.valueOf();
-        if (delta === 0)
-            return;
+DaysTable.prototype.navigateToMonth = function(month, animate, keepSelectionPosition) {
+    var firstNodeInSelectedRange = this._firstNodeInSelectedRange();
+    if (animate) {
         var daysStyle = this._daysContainer.style;
         daysStyle.position = "relative";
         daysStyle.webkitTransition = "left 0.1s ease";
-        daysStyle.left = (delta > 0 ? "" : "-") + this._daysContainer.offsetWidth + "px";
+        daysStyle.left = (this.picker.currentMonth().valueOf() > month.valueOf() ? "" : "-") + this._daysContainer.offsetWidth + "px";
     }
-    this._navigateToMonth(month);
+    this._renderMonth(month);
+    if (keepSelectionPosition && firstNodeInSelectedRange) {
+        var x = parseInt(firstNodeInSelectedRange.dataset.positionX, 10);
+        var y = parseInt(firstNodeInSelectedRange.dataset.positionY, 10);
+        this._selectRangeAtPosition(x, y);
+    }
 };
 
 DaysTable.prototype._moveInDays = function() {
@@ -1046,27 +1130,12 @@
 };
 
 /**
- * @param {!Month} month
- */
-DaysTable.prototype.navigateToMonthAndKeepSelectionPosition = function(month) {
-    if (this._currentMonth.equals(month))
-        return;
-    var firstNodeInSelectedRange = this._firstNodeInSelectedRange();
-    this._navigateToMonthWithAnimation(month);
-    if (firstNodeInSelectedRange) {
-        var x = parseInt(firstNodeInSelectedRange.dataset.positionX, 10);
-        var y = parseInt(firstNodeInSelectedRange.dataset.positionY, 10);
-        this._selectRangeAtPosition(x, y);
-    }
-};
-
-/**
  * @param {!Date} date
  */
-DaysTable.prototype.selectDate = function(date) {
+DaysTable.prototype.selectRange = function(day) {
     this._deselect();
-    this._navigateToMonthWithAnimation(Month.createFromDate(date));
-    var dateString = serializeDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
+    this.picker.showMonth(Month.createFromDate(day.startDate()), true);
+    var dateString = day.toString();
     for (var w = 0; w < DaysTable._Weeks; w++) {
         for (var d = 0; d < 7; d++) {
             if (this._days[w][d].dataset.submitValue == dateString) {
@@ -1113,10 +1182,10 @@
  * @return {!boolean}
  */
 DaysTable.prototype._maybeSetPreviousMonth = function() {
-    var currentMonth = this.picker.yearMonthController.month();
-    if (this.picker.minimumDate >= currentMonth.startDate())
+    var previousMonth = this.picker.currentMonth().previous();
+    if (!this.picker.shouldShowMonth(previousMonth))
         return false;
-    this._navigateToMonthWithAnimation(currentMonth.previous());
+    this.picker.showMonth(previousMonth, true);
     return true;
 };
 
@@ -1124,10 +1193,10 @@
  * @return {!boolean}
  */
 DaysTable.prototype._maybeSetNextMonth = function() {
-    var currentMonth = this.picker.yearMonthController.month();
-    if (this.picker.maximumDate < currentMonth.endDate())
+    var nextMonth = this.picker.currentMonth().next();
+    if (!this.picker.shouldShowMonth(nextMonth))
         return false;
-    this._navigateToMonthWithAnimation(currentMonth.next());
+    this.picker.showMonth(nextMonth, true);
     return true;
 };
 
@@ -1237,7 +1306,7 @@
         }
 
     } else if (key == "U+0054") { // 't'
-        this.selectDate(new Date());
+        this.selectRange(Day.createFromToday());
         event.stopPropagation();
         event.preventDefault();
     }
@@ -1271,11 +1340,11 @@
             this.lastFocusableControl.focus();
         }
     } else if (key == "U+004D") { // 'm'
-        this.yearMonthController.moveRelatively(event.shiftKey ? YearMonthController.PreviousMonth : YearMonthController.NextMonth);
+        this._yearMonthController.moveRelatively(event.shiftKey ? YearMonthController.PreviousMonth : YearMonthController.NextMonth);
     } else if (key == "U+0059") { // 'y'
-        this.yearMonthController.moveRelatively(event.shiftKey ? YearMonthController.PreviousYear : YearMonthController.NextYear);
+        this._yearMonthController.moveRelatively(event.shiftKey ? YearMonthController.PreviousYear : YearMonthController.NextYear);
     } else if (key == "U+0044") { // 'd'
-        this.yearMonthController.moveRelatively(event.shiftKey ? YearMonthController.PreviousTenYears : YearMonthController.NextTenYears);
+        this._yearMonthController.moveRelatively(event.shiftKey ? YearMonthController.PreviousTenYears : YearMonthController.NextTenYears);
     } else if (key == "U+001B") // ESC
         this.handleCancel();
 }
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to