Changeset 133434 in webkit


Ignore:
Timestamp:
Nov 4, 2012 11:13:27 PM (11 years ago)
Author:
keishi@webkit.org
Message:

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

Reviewed by Kent Tamura.

Source/WebCore:

Month class needs to be introduced to implement a month picker. This
patch just introduces the Month class into the calendar picker without
changing the current behavior.

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

  • Resources/pagepopups/calendarPicker.js:

(Month.prototype.toLocaleString): Returns a localized month string.
(Month): Takes a Month object, number representing the month, or year and month numbers.
(Month.parse): Returns a new Month from an ISO month string.
(Month.createFromDate): Returns a new Month containing the given datetime.
(Month.prototype.equals): Returns true if the given month is the same.
(Month.prototype.previous): Returns the previous month.
(Month.prototype.next): Returns the next month.
(Month.prototype.startDate): Returns a datetime that is the start of this month. The value is inclusive.
(Month.prototype.endDate): Returns a datetime that is the end of this month. The value is exclusive.
(Month.prototype.valueOf): Returns a number representing the month.
(Month.prototype.toString): Returns an ISO month string.
(YearMonthController): Use Month object.
(YearMonthController.prototype.attachTo): Year 275760 ends in September so use the year before to measure the label width.
(YearMonthController.prototype.setMonth): Take a month object.
(YearMonthController.prototype._redraw): Use ISO month string for element.dataset.value.
(YearMonthController.prototype._handleYearMonthChange):
(YearMonthController.prototype.moveRelatively):
(DaysTable): Use Month object.
(DaysTable.prototype._renderMonth): Take a month object. Testing for isNaN is moved up to fix a bug when showing September, 275760.
(DaysTable.prototype._navigateToMonth): Take a month object.
(DaysTable.prototype._navigateToMonthWithAnimation): Take a month object.
(DaysTable.prototype.navigateToMonthAndKeepSelectionPosition): Take a month object.
(DaysTable.prototype.selectDate):
(DaysTable.prototype._maybeSetPreviousMonth): Use Month object to calculate the previous month.
(DaysTable.prototype._maybeSetNextMonth): Use Month object to calculate the next month.

LayoutTests:

  • platform/chromium-win/platform/chromium/fast/forms/calendar-picker/calendar-picker-key-operations-expected.txt:
  • platform/chromium/fast/forms/calendar-picker/calendar-picker-key-operations-expected.txt:
  • platform/chromium/fast/forms/calendar-picker/calendar-picker-key-operations.html: Adjust the expectation because we changed the month string format.
  • platform/chromium/fast/forms/calendar-picker/calendar-picker-mouse-operations-expected.txt:
  • platform/chromium/fast/forms/calendar-picker/calendar-picker-mouse-operations.html: Ditto.
Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r133433 r133434  
     12012-11-04  Keishi Hattori  <keishi@webkit.org>
     2
     3        Introduce Month class to calendar picker
     4        https://bugs.webkit.org/show_bug.cgi?id=101024
     5
     6        Reviewed by Kent Tamura.
     7
     8        * platform/chromium-win/platform/chromium/fast/forms/calendar-picker/calendar-picker-key-operations-expected.txt:
     9        * platform/chromium/fast/forms/calendar-picker/calendar-picker-key-operations-expected.txt:
     10        * platform/chromium/fast/forms/calendar-picker/calendar-picker-key-operations.html: Adjust the expectation because we changed the month string format.
     11        * platform/chromium/fast/forms/calendar-picker/calendar-picker-mouse-operations-expected.txt:
     12        * platform/chromium/fast/forms/calendar-picker/calendar-picker-mouse-operations.html: Ditto.
     13
    1142012-11-04  Kent Tamura  <tkent@chromium.org>
    215
  • trunk/LayoutTests/platform/chromium-win/platform/chromium/fast/forms/calendar-picker/calendar-picker-key-operations-expected.txt

    r133293 r133434  
    99PASS popupWindow.pagePopupController.toString() is "[object PagePopupController]"
    1010PASS selectedDate() is "2000-01-02"
    11 PASS currentMonth() is "2000-0"
     11PASS currentMonth() is "2000-01"
    1212Check that arrow keys work properly even when going between weeks and months.
    1313PASS selectedDate() is "1999-12-26"
    14 PASS currentMonth() is "2000-0"
     14PASS currentMonth() is "2000-01"
    1515PASS selectedDate() is "2000-01-02"
    16 PASS currentMonth() is "1999-11"
     16PASS currentMonth() is "1999-12"
    1717PASS selectedDate() is "1999-12-26"
    18 PASS currentMonth() is "2000-0"
     18PASS currentMonth() is "2000-01"
    1919PASS selectedDate() is "2000-01-02"
    20 PASS currentMonth() is "2000-0"
     20PASS currentMonth() is "2000-01"
    2121PASS selectedDate() is "1999-12-26"
    22 PASS currentMonth() is "2000-0"
     22PASS currentMonth() is "2000-01"
    2323PASS selectedDate() is "2000-01-08"
    24 PASS currentMonth() is "1999-11"
     24PASS currentMonth() is "1999-12"
    2525PASS selectedDate() is "1999-12-26"
    26 PASS currentMonth() is "2000-0"
     26PASS currentMonth() is "2000-01"
    2727press m
    2828PASS selectedDate() is "2000-01-30"
    29 PASS currentMonth() is "2000-1"
     29PASS currentMonth() is "2000-02"
    3030press shift + m
    3131PASS selectedDate() is "1999-12-26"
    32 PASS currentMonth() is "2000-0"
     32PASS currentMonth() is "2000-01"
    3333press y
    3434PASS selectedDate() is "2000-12-31"
    35 PASS currentMonth() is "2001-0"
     35PASS currentMonth() is "2001-01"
    3636press shift + y
    3737PASS selectedDate() is "1999-12-26"
    38 PASS currentMonth() is "2000-0"
     38PASS currentMonth() is "2000-01"
    3939press d
    4040PASS selectedDate() is "2009-12-27"
    41 PASS currentMonth() is "2010-0"
     41PASS currentMonth() is "2010-01"
    4242press shift + d
    4343PASS selectedDate() is "1999-12-26"
    44 PASS currentMonth() is "2000-0"
     44PASS currentMonth() is "2000-01"
    4545PASS document.getElementById("mock-page-popup") is null
    4646PASS document.getElementById("date").value is "1999-12-26"
  • trunk/LayoutTests/platform/chromium/fast/forms/calendar-picker/calendar-picker-key-operations-expected.txt

    r133293 r133434  
    99PASS popupWindow.pagePopupController.toString() is "[object PagePopupController]"
    1010PASS selectedDate() is "2000-01-02"
    11 PASS currentMonth() is "2000-0"
     11PASS currentMonth() is "2000-01"
    1212Check that arrow keys work properly even when going between weeks and months.
    1313PASS selectedDate() is "1999-12-26"
    14 PASS currentMonth() is "2000-0"
     14PASS currentMonth() is "2000-01"
    1515PASS selectedDate() is "2000-01-02"
    16 PASS currentMonth() is "1999-11"
     16PASS currentMonth() is "1999-12"
    1717PASS selectedDate() is "1999-12-26"
    18 PASS currentMonth() is "2000-0"
     18PASS currentMonth() is "2000-01"
    1919PASS selectedDate() is "2000-01-02"
    20 PASS currentMonth() is "2000-0"
     20PASS currentMonth() is "2000-01"
    2121PASS selectedDate() is "1999-12-26"
    22 PASS currentMonth() is "2000-0"
     22PASS currentMonth() is "2000-01"
    2323PASS selectedDate() is "2000-01-08"
    24 PASS currentMonth() is "1999-11"
     24PASS currentMonth() is "1999-12"
    2525PASS selectedDate() is "1999-12-26"
    26 PASS currentMonth() is "2000-0"
     26PASS currentMonth() is "2000-01"
    2727press m
    2828PASS selectedDate() is "2000-01-30"
    29 PASS currentMonth() is "2000-1"
     29PASS currentMonth() is "2000-02"
    3030press shift + m
    3131PASS selectedDate() is "1999-12-26"
    32 PASS currentMonth() is "2000-0"
     32PASS currentMonth() is "2000-01"
    3333press y
    3434PASS selectedDate() is "2000-12-31"
    35 PASS currentMonth() is "2001-0"
     35PASS currentMonth() is "2001-01"
    3636press shift + y
    3737PASS selectedDate() is "1999-12-26"
    38 PASS currentMonth() is "2000-0"
     38PASS currentMonth() is "2000-01"
    3939press d
    4040PASS selectedDate() is "2009-12-27"
    41 PASS currentMonth() is "2010-0"
     41PASS currentMonth() is "2010-01"
    4242press shift + d
    4343PASS selectedDate() is "1999-12-26"
    44 PASS currentMonth() is "2000-0"
     44PASS currentMonth() is "2000-01"
    4545PASS document.getElementById("mock-page-popup") is null
    4646PASS document.getElementById("date").value is "1999-12-26"
  • trunk/LayoutTests/platform/chromium/fast/forms/calendar-picker/calendar-picker-key-operations.html

    r133293 r133434  
    2323
    2424    shouldBe('selectedDate()', '"2000-01-02"');
    25     shouldBe('currentMonth()', '"2000-0"');
     25    shouldBe('currentMonth()', '"2000-01"');
    2626
    2727    debug('Check that arrow keys work properly even when going between weeks and months.');
     
    2929    eventSender.keyDown('upArrow');
    3030    shouldBe('selectedDate()', '"1999-12-26"');
    31     shouldBe('currentMonth()', '"2000-0"');
     31    shouldBe('currentMonth()', '"2000-01"');
    3232    // Move from first row of January 2000 to last row of December 1999.
    3333    eventSender.keyDown('upArrow');
    3434    shouldBe('selectedDate()', '"2000-01-02"');
    35     shouldBe('currentMonth()', '"1999-11"');
     35    shouldBe('currentMonth()', '"1999-12"');
    3636   
    3737    eventSender.keyDown('downArrow');
    3838    shouldBe('selectedDate()', '"1999-12-26"');
    39     shouldBe('currentMonth()', '"2000-0"');
     39    shouldBe('currentMonth()', '"2000-01"');
    4040    eventSender.keyDown('downArrow');
    4141    shouldBe('selectedDate()', '"2000-01-02"');
    42     shouldBe('currentMonth()', '"2000-0"');
     42    shouldBe('currentMonth()', '"2000-01"');
    4343
    4444    eventSender.keyDown('upArrow');
    4545    shouldBe('selectedDate()', '"1999-12-26"');
    46     shouldBe('currentMonth()', '"2000-0"');
     46    shouldBe('currentMonth()', '"2000-01"');
    4747
    4848    // Move from top left of January 2000 to bottom right of December 1999.
    4949    eventSender.keyDown('leftArrow');
    5050    shouldBe('selectedDate()', '"2000-01-08"');
    51     shouldBe('currentMonth()', '"1999-11"');
     51    shouldBe('currentMonth()', '"1999-12"');
    5252
    5353    eventSender.keyDown('rightArrow');
    5454    shouldBe('selectedDate()', '"1999-12-26"');
    55     shouldBe('currentMonth()', '"2000-0"');
     55    shouldBe('currentMonth()', '"2000-01"');
    5656
    5757    debug("press m");
    5858    eventSender.keyDown('m');
    5959    shouldBe('selectedDate()', '"2000-01-30"');
    60     shouldBe('currentMonth()', '"2000-1"');
     60    shouldBe('currentMonth()', '"2000-02"');
    6161
    6262    debug("press shift + m");
    6363    eventSender.keyDown('M');
    6464    shouldBe('selectedDate()', '"1999-12-26"');
    65     shouldBe('currentMonth()', '"2000-0"');
     65    shouldBe('currentMonth()', '"2000-01"');
    6666
    6767    debug("press y");
    6868    eventSender.keyDown('y');
    6969    shouldBe('selectedDate()', '"2000-12-31"');
    70     shouldBe('currentMonth()', '"2001-0"');
     70    shouldBe('currentMonth()', '"2001-01"');
    7171
    7272    debug("press shift + y");
    7373    eventSender.keyDown('Y');
    7474    shouldBe('selectedDate()', '"1999-12-26"');
    75     shouldBe('currentMonth()', '"2000-0"');
     75    shouldBe('currentMonth()', '"2000-01"');
    7676
    7777    debug("press d");
    7878    eventSender.keyDown('d');
    7979    shouldBe('selectedDate()', '"2009-12-27"');
    80     shouldBe('currentMonth()', '"2010-0"');
     80    shouldBe('currentMonth()', '"2010-01"');
    8181
    8282    debug("press shift + d");
    8383    eventSender.keyDown('D');
    8484    shouldBe('selectedDate()', '"1999-12-26"');
    85     shouldBe('currentMonth()', '"2000-0"');
     85    shouldBe('currentMonth()', '"2000-01"');
    8686
    8787    eventSender.keyDown('\n');
     
    122122    var now = new Date();
    123123    var expectedDate = serializeDate(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate());
    124     var expectedMonth = now.getUTCFullYear() + "-" + now.getMonth();
     124    var expectedMonth = popupWindow.Month.createFromDate(now).toString();
    125125    return selectedDate() === expectedDate && currentMonth() === expectedMonth;
    126126}
  • trunk/LayoutTests/platform/chromium/fast/forms/calendar-picker/calendar-picker-mouse-operations-expected.txt

    r131538 r133434  
    77PASS document.getElementById("mock-page-popup") is null
    88PASS selectedDate() is "2000-01-02"
    9 PASS currentMonth() is "2000-0"
     9PASS currentMonth() is "2000-01"
    1010Check that hovering over an entry highlights it.
    1111PASS selectedDate() is "1999-12-31"
    12 PASS currentMonth() is "2000-0"
     12PASS currentMonth() is "2000-01"
    1313PASS selectedDate() is "2000-01-04"
    14 PASS currentMonth() is "2000-0"
     14PASS currentMonth() is "2000-01"
    1515Check that navigating between months maintains selection position.
    1616PASS selectedDate() is "2000-02-08"
    17 PASS currentMonth() is "2000-1"
     17PASS currentMonth() is "2000-02"
    1818Check that moving the mouse outside the popup de-highlights entries.
    1919PASS selectedDate() is undefined.
  • trunk/LayoutTests/platform/chromium/fast/forms/calendar-picker/calendar-picker-mouse-operations.html

    r132028 r133434  
    2121function test() {
    2222    shouldBe('selectedDate()', '"2000-01-02"');
    23     shouldBe('currentMonth()', '"2000-0"');
     23    shouldBe('currentMonth()', '"2000-01"');
    2424
    2525    debug('Check that hovering over an entry highlights it.');
    2626    hoverOverElement(popupWindow.document.getElementsByClassName("day")[5]);
    2727    shouldBe('selectedDate()', '"1999-12-31"');
    28     shouldBe('currentMonth()', '"2000-0"');
     28    shouldBe('currentMonth()', '"2000-01"');
    2929
    3030    hoverOverElement(popupWindow.document.getElementsByClassName("day")[9]);
    3131    shouldBe('selectedDate()', '"2000-01-04"');
    32     shouldBe('currentMonth()', '"2000-0"');
     32    shouldBe('currentMonth()', '"2000-01"');
    3333
    3434    debug('Check that navigating between months maintains selection position.');
    3535    eventSender.keyDown('m');
    3636    shouldBe('selectedDate()', '"2000-02-08"');
    37     shouldBe('currentMonth()', '"2000-1"');
     37    shouldBe('currentMonth()', '"2000-02"');
    3838
    3939    debug('Check that moving the mouse outside the popup de-highlights entries.');
  • trunk/Source/WebCore/ChangeLog

    r133432 r133434  
     12012-11-04  Keishi Hattori  <keishi@webkit.org>
     2
     3        Introduce Month class to calendar picker
     4        https://bugs.webkit.org/show_bug.cgi?id=101024
     5
     6        Reviewed by Kent Tamura.
     7
     8        Month class needs to be introduced to implement a month picker. This
     9        patch just introduces the Month class into the calendar picker without
     10        changing the current behavior.
     11
     12        No new tests. Covered by existing calendar-picker-*.html tests.
     13
     14        * Resources/pagepopups/calendarPicker.js:
     15        (Month.prototype.toLocaleString): Returns a localized month string.
     16        (Month): Takes a Month object, number representing the month, or year and month numbers.
     17        (Month.parse): Returns a new Month from an ISO month string.
     18        (Month.createFromDate): Returns a new Month containing the given datetime.
     19        (Month.prototype.equals): Returns true if the given month is the same.
     20        (Month.prototype.previous): Returns the previous month.
     21        (Month.prototype.next): Returns the next month.
     22        (Month.prototype.startDate): Returns a datetime that is the start of this month. The value is inclusive.
     23        (Month.prototype.endDate): Returns a datetime that is the end of this month. The value is exclusive.
     24        (Month.prototype.valueOf): Returns a number representing the month.
     25        (Month.prototype.toString): Returns an ISO month string.
     26        (YearMonthController): Use Month object.
     27        (YearMonthController.prototype.attachTo): Year 275760 ends in September so use the year before to measure the label width.
     28        (YearMonthController.prototype.setMonth): Take a month object.
     29        (YearMonthController.prototype._redraw): Use ISO month string for element.dataset.value.
     30        (YearMonthController.prototype._handleYearMonthChange):
     31        (YearMonthController.prototype.moveRelatively):
     32        (DaysTable): Use Month object.
     33        (DaysTable.prototype._renderMonth): Take a month object. Testing for isNaN is moved up to fix a bug when showing September, 275760.
     34        (DaysTable.prototype._navigateToMonth): Take a month object.
     35        (DaysTable.prototype._navigateToMonthWithAnimation): Take a month object.
     36        (DaysTable.prototype.navigateToMonthAndKeepSelectionPosition): Take a month object.
     37        (DaysTable.prototype.selectDate):
     38        (DaysTable.prototype._maybeSetPreviousMonth): Use Month object to calculate the previous month.
     39        (DaysTable.prototype._maybeSetNextMonth): Use Month object to calculate the next month.
     40
    1412012-11-04  Halton Huo  <halton.huo@intel.com>
    242
  • trunk/Source/WebCore/Resources/pagepopups/calendarPicker.js

    r132596 r133434  
    140140
    141141/**
    142  * @param {!number} year
    143  * @param {!number} month
    144142 * @return {!string}
    145143 */
    146 function formatYearMonth(year, month) {
    147     var yearString = localizeNumber(year);
    148     var monthString = global.params.monthLabels[month];
     144Month.prototype.toLocaleString = function() {
     145    if (isNaN(this.year) || isNaN(this.year))
     146        return "Invalid Month";
     147    var yearString = localizeNumber(this.year);
     148    var monthString = global.params.monthLabels[this.month];
    149149    switch (getLanguage()) {
    150150    case "eu":
     
    159159        return yearString + ". " + monthString;
    160160    case "ja":
    161         return yearString + "年" + formatJapaneseImperialEra(year, month) + " " + monthString;
     161        return yearString + "年" + formatJapaneseImperialEra(this.year, this.month) + " " + monthString;
    162162    case "zh":
    163163        return yearString + "年" + monthString;
     
    173173        return monthString + " " + yearString;
    174174    }
    175 }
     175};
    176176
    177177function createUTCDate(year, month, date) {
     
    209209    return yearString + "-" + ("0" + (month + 1)).substr(-2, 2) + "-" + ("0" + day).substr(-2, 2);
    210210}
     211
     212/**
     213 * @param {!number|Month} valueOrMonthOrYear
     214 * @param {!number=} month
     215 */
     216function Month(valueOrMonthOrYear, month) {
     217    if (arguments.length == 2) {
     218        this.year = valueOrMonthOrYear;
     219        this.month = month;
     220    } else if (valueOrMonthOrYear instanceof Month) {
     221        this.year = valueOrMonthOrYear.year;
     222        this.month = valueOrMonthOrYear.month;
     223    } else {
     224        this.year = Math.floor(valueOrMonthOrYear / 12) + 1970;
     225        this.month = valueOrMonthOrYear % 12;
     226    }
     227    this.year = this.year + Math.floor(this.month / 12);
     228    this.month = this.month < 0 ? this.month % 12 + 12 : this.month % 12;
     229    if (this.year < 0 || Month.Maximum < this) {
     230        this.year = NaN;
     231        this.month = NaN;
     232    }
     233};
     234
     235Month.ISOStringRegExp = /^(\d+)-(\d+)$/;
     236
     237// See WebCore/platform/DateComponents.h.
     238Month.Maximum = new Month(275760, 8);
     239
     240/**
     241 * @param {!string} str
     242 * @return {?Month}
     243 */
     244Month.parse = function(str) {
     245    var match = Month.ISOStringRegExp.exec(str);
     246    if (!match)
     247        return null;
     248    var year = parseInt(match[1], 10);
     249    var month = parseInt(match[2], 10) - 1;
     250    return new Month(year, month);
     251};
     252
     253/**
     254 * @param {!Date} date
     255 * @return {!Month}
     256 */
     257Month.createFromDate = function(date) {
     258    return new Month(date.getUTCFullYear(), date.getUTCMonth());
     259};
     260
     261/**
     262 * @param {!Month} other
     263 * @return {!bool}
     264 */
     265Month.prototype.equals = function(other) {
     266    return this.year === other.year && this.month === other.month;
     267};
     268
     269/**
     270 * @return {!Month}
     271 */
     272Month.prototype.previous = function() {
     273    return new Month(this.year, this.month - 1);
     274};
     275
     276/**
     277 * @return {!Month}
     278 */
     279Month.prototype.next = function() {
     280    return new Month(this.year, this.month + 1);
     281};
     282
     283/**
     284 * @return {!Date}
     285 */
     286Month.prototype.startDate = function() {
     287    return createUTCDate(this.year, this.month, 1);
     288};
     289
     290/**
     291 * @return {!Date}
     292 */
     293Month.prototype.endDate = function() {
     294    if (this.equals(Month.Maximum))
     295        return CalendarPicker.MaximumPossibleDate;
     296    return this.next().startDate();
     297};
     298
     299/**
     300 * @return {!number}
     301 */
     302Month.prototype.valueOf = function() {
     303    return (this.year - 1970) * 12 + this.month;
     304};
     305
     306/**
     307 * @return {!string}
     308 */
     309Month.prototype.toString = function() {
     310    var yearString = String(this.year);
     311    if (yearString.length < 4)
     312        yearString = ("000" + yearString).substr(-4, 4);
     313    return yearString + "-" + ("0" + (this.month + 1)).substr(-2, 2);
     314};
    211315
    212316// ----------------------------------------------------------------
     
    434538    this.picker = picker;
    435539    /**
    436      * @type {!number}
     540     * @type {?Month}
    437541     */
    438     this._currentYear = -1;
    439     /**
    440      * @type {!number}
    441      */
    442     this._currentMonth = -1;
     542    this._currentMonth = null;
    443543}
    444544
     
    478578
    479579    var maximumYear = this.picker.maximumDate.getUTCFullYear();
     580    // Because the maximum possible year is September we should use the year before it.
     581    if (maximumYear === Month.Maximum.year)
     582        maximumYear--;
    480583    var maxWidth = 0;
    481584    for (var m = 0; m < 12; ++m) {
    482         this._month.textContent = formatYearMonth(maximumYear, m);
     585        this._month.textContent = new Month(maximumYear, m).toLocaleString();
    483586        maxWidth = Math.max(maxWidth, this._month.offsetWidth);
    484587    }
    485588    if (getLanguage() == "ja" && ImperialEraLimit < maximumYear) {
    486589        for (var m = 0; m < 12; ++m) {
    487             this._month.textContent = formatYearMonth(ImperialEraLimit, m);
     590            this._month.textContent = new Month(ImperialEraLimit, m).toLocaleString();
    488591            maxWidth = Math.max(maxWidth, this._month.offsetWidth);
    489592        }
     
    552655
    553656/**
    554  * @return {!number}
    555  */
    556 YearMonthController.prototype.year = function() {
    557     return this._currentYear;
    558 };
    559 
    560 /**
    561  * @return {!number}
     657 * @return {?Month}
    562658 */
    563659YearMonthController.prototype.month = function() {
     
    566662
    567663/**
    568  * @param {!number} year
    569  * @param {!number} month
    570  */
    571 YearMonthController.prototype.setYearMonth = function(year, month) {
    572     this._currentYear = year;
    573     this._currentMonth = month;
     664 * @param {!Month} month
     665 */
     666YearMonthController.prototype.setMonth = function(month) {
     667    this._currentMonth = new Month(month);
    574668    this._redraw();
    575669};
    576670
    577671YearMonthController.prototype._redraw = function() {
    578     var min = this.picker.minimumDate.getUTCFullYear() * 12 + this.picker.minimumDate.getUTCMonth();
    579     var max = this.picker.maximumDate.getUTCFullYear() * 12 + this.picker.maximumDate.getUTCMonth();
    580     var current = this._currentYear * 12 + this._currentMonth;
     672    var min = Month.createFromDate(this.picker.minimumDate).valueOf();
     673    var max = Month.createFromDate(this.picker.maximumDate).valueOf();
     674    var current = this._currentMonth.valueOf();
    581675    if (this._left3)
    582676        this._left3.disabled = current - 13 < min;
     
    587681    if (this._right3)
    588682        this._right3.disabled = current + 13 > max;
    589     this._month.innerText = formatYearMonth(this._currentYear, this._currentMonth);
     683    this._month.innerText = this._currentMonth.toLocaleString();
    590684    while (this._monthPopupContents.hasChildNodes())
    591685        this._monthPopupContents.removeChild(this._monthPopupContents.firstChild);
     
    594688        if (m < min || m > max)
    595689            continue;
    596         var option = createElement("div", ClassNames.MonthSelectorPopupEntry, formatYearMonth(Math.floor(m / 12), m % 12));
    597         option.dataset.value = String(Math.floor(m / 12)) + "-" + String(m % 12);
     690        var month = new Month(m);
     691        var option = createElement("div", ClassNames.MonthSelectorPopupEntry, month.toLocaleString());
     692        option.dataset.value = month.toString();
    598693        this._monthPopupContents.appendChild(option);
    599694        if (m == current)
     
    716811    if (!selection)
    717812        return;
    718     var value = selection.dataset.value;
    719     var result  = value.match(/(\d+)-(\d+)/);
    720     if (!result)
    721         return;
    722     var newYear = Number(result[1]);
    723     var newMonth = Number(result[2]);
    724     this.picker.daysTable.navigateToMonthAndKeepSelectionPosition(newYear, newMonth);
     813    this.picker.daysTable.navigateToMonthAndKeepSelectionPosition(Month.parse(selection.dataset.value));
    725814};
    726815
     
    780869 */
    781870YearMonthController.prototype.moveRelatively = function(amount) {
    782     var min = this.picker.minimumDate.getUTCFullYear() * 12 + this.picker.minimumDate.getUTCMonth();
    783     var max = this.picker.maximumDate.getUTCFullYear() * 12 + this.picker.maximumDate.getUTCMonth();
    784     var current = this._currentYear * 12 + this._currentMonth;
     871    var min = Month.createFromDate(this.picker.minimumDate).valueOf();
     872    var max = Month.createFromDate(this.picker.maximumDate).valueOf();
     873    var current = this._currentMonth.valueOf();
    785874    var updated = current;
    786875    if (amount < 0)
     
    790879    if (updated == current)
    791880        return;
    792     this.picker.daysTable.navigateToMonthAndKeepSelectionPosition(Math.floor(updated / 12), updated % 12);
     881    this.picker.daysTable.navigateToMonthAndKeepSelectionPosition(new Month(updated));
    793882};
    794883
     
    802891    this.picker = picker;
    803892    /**
    804      * @type {!number}
     893     * @type {?Month}
    805894     */
    806     this._currentYear = -1;
    807     /**
    808      * @type {!number}
    809      */
    810     this._currentMonth = -1;
     895    this._currentMonth = null;
    811896}
    812897
     
    890975 * @param {!number} month
    891976 */
    892 DaysTable.prototype._renderMonth = function(year, month) {
    893     this._currentYear = year;
    894     this._currentMonth = month;
    895     var dayIterator = createUTCDate(year, month, 1);
     977DaysTable.prototype._renderMonth = function(month) {
     978    this._currentMonth = new Month(month);
     979    var dayIterator = this._currentMonth.startDate();
    896980    var monthStartDay = dayIterator.getUTCDay();
    897981    var weekStartDay = global.params.weekStartDay || 0;
     
    902986    for (var w = 0; w < DaysTable._Weeks; w++) {
    903987        for (var d = 0; d < 7; d++) {
    904             var iterYear = dayIterator.getUTCFullYear();
    905             var iterMonth = dayIterator.getUTCMonth();
     988            var iterMonth = Month.createFromDate(dayIterator);
    906989            var time = dayIterator.getTime();
    907990            var element = this._days[w][d];
    908991            element.innerText = localizeNumber(dayIterator.getUTCDate());
    909992            element.className = ClassNames.Day;
    910             element.dataset.submitValue = serializeDate(iterYear, iterMonth, dayIterator.getUTCDate());
    911             if (this.picker.outOfRange(time))
     993            element.dataset.submitValue = serializeDate(iterMonth.year, iterMonth.month, dayIterator.getUTCDate());
     994            if (isNaN(time)) {
     995                element.innerText = "-";
     996                element.classList.add(ClassNames.Unavailable);
     997            } else if (this.picker.outOfRange(time))
    912998                element.classList.add(ClassNames.Unavailable);
    913999            else if (this.picker.stepMismatch(time))
    9141000                element.classList.add(ClassNames.Unavailable);
    915             else if ((iterYear == year && dayIterator.getUTCMonth() < month) || (month == 0 && iterMonth == 11)) {
     1001            else if (!iterMonth.equals(this._currentMonth)) {
    9161002                element.classList.add(ClassNames.Available);
    9171003                element.classList.add(ClassNames.NotThisMonth);
    918             } else if ((iterYear == year && dayIterator.getUTCMonth() > month) || (month == 11 && iterMonth == 0)) {
    919                 element.classList.add(ClassNames.Available);
    920                 element.classList.add(ClassNames.NotThisMonth);
    921             } else if (isNaN(time)) {
    922                 element.innerText = "-";
    923                 element.classList.add(ClassNames.Unavailable);
    9241004            } else
    9251005                element.classList.add(ClassNames.Available);
     
    9321012
    9331013/**
    934  * @param {!number} year
    935  * @param {!number} month
    936  */
    937 DaysTable.prototype._navigateToMonth = function(year, month) {
    938     this.picker.yearMonthController.setYearMonth(year, month);
    939     this._renderMonth(year, month);
    940 };
    941 
    942 /**
    943  * @param {!number} year
    944  * @param {!number} month
    945  */
    946 DaysTable.prototype._navigateToMonthWithAnimation = function(year, month) {
    947     if (this._currentYear >= 0 && this._currentMonth >= 0) {
    948         if (year == this._currentYear && month == this._currentMonth)
     1014 * @param {!Month} month
     1015 */
     1016DaysTable.prototype._navigateToMonth = function(month) {
     1017    this.picker.yearMonthController.setMonth(month);
     1018    this._renderMonth(month);
     1019};
     1020
     1021/**
     1022 * @param {!Month} month
     1023 */
     1024DaysTable.prototype._navigateToMonthWithAnimation = function(month) {
     1025    if (this._currentMonth) {
     1026        var delta = this._currentMonth.valueOf() - month.valueOf();
     1027        if (delta === 0)
    9491028            return;
    950         var decreasing = false;
    951         if (year < this._currentYear)
    952             decreasing = true;
    953         else if (year > this._currentYear)
    954             decreasing = false;
    955         else
    956             decreasing = month < this._currentMonth;
    9571029        var daysStyle = this._daysContainer.style;
    9581030        daysStyle.position = "relative";
    9591031        daysStyle.webkitTransition = "left 0.1s ease";
    960         daysStyle.left = (decreasing ? "" : "-") + this._daysContainer.offsetWidth + "px";
    961     }
    962     this._navigateToMonth(year, month);
     1032        daysStyle.left = (delta > 0 ? "" : "-") + this._daysContainer.offsetWidth + "px";
     1033    }
     1034    this._navigateToMonth(month);
    9631035};
    9641036
     
    9751047
    9761048/**
    977  * @param {!number} year
    978  * @param {!number} month
    979  */
    980 DaysTable.prototype.navigateToMonthAndKeepSelectionPosition = function(year, month) {
    981     if (year == this._currentYear && month == this._currentMonth)
     1049 * @param {!Month} month
     1050 */
     1051DaysTable.prototype.navigateToMonthAndKeepSelectionPosition = function(month) {
     1052    if (this._currentMonth.equals(month))
    9821053        return;
    9831054    var firstNodeInSelectedRange = this._firstNodeInSelectedRange();
    984     this._navigateToMonthWithAnimation(year, month);
     1055    this._navigateToMonthWithAnimation(month);
    9851056    if (firstNodeInSelectedRange) {
    9861057        var x = parseInt(firstNodeInSelectedRange.dataset.positionX, 10);
     
    9951066DaysTable.prototype.selectDate = function(date) {
    9961067    this._deselect();
    997     this._navigateToMonthWithAnimation(date.getUTCFullYear(), date.getUTCMonth());
     1068    this._navigateToMonthWithAnimation(Month.createFromDate(date));
    9981069    var dateString = serializeDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate());
    9991070    for (var w = 0; w < DaysTable._Weeks; w++) {
     
    10431114 */
    10441115DaysTable.prototype._maybeSetPreviousMonth = function() {
    1045     var year = this.picker.yearMonthController.year();
    1046     var month = this.picker.yearMonthController.month();
    1047     var thisMonthStartTime = createUTCDate(year, month, 1).getTime();
    1048     if (this.picker.minimumDate.getTime() >= thisMonthStartTime)
     1116    var currentMonth = this.picker.yearMonthController.month();
     1117    if (this.picker.minimumDate >= currentMonth.startDate())
    10491118        return false;
    1050     if (month == 0) {
    1051         year--;
    1052         month = 11;
    1053     } else
    1054         month--;
    1055     this._navigateToMonthWithAnimation(year, month);
     1119    this._navigateToMonthWithAnimation(currentMonth.previous());
    10561120    return true;
    10571121};
     
    10611125 */
    10621126DaysTable.prototype._maybeSetNextMonth = function() {
    1063     var year = this.picker.yearMonthController.year();
    1064     var month = this.picker.yearMonthController.month();
    1065     if (month == 11) {
    1066         year++;
    1067         month = 0;
    1068     } else
    1069         month++;
    1070     var nextMonthStartTime = createUTCDate(year, month, 1).getTime();
    1071     if (this.picker.maximumDate.getTime() < nextMonthStartTime)
     1127    var currentMonth = this.picker.yearMonthController.month();
     1128    if (this.picker.maximumDate < currentMonth.endDate())
    10721129        return false;
    1073     this._navigateToMonthWithAnimation(year, month);
     1130    this._navigateToMonthWithAnimation(currentMonth.next());
    10741131    return true;
    10751132};
Note: See TracChangeset for help on using the changeset viewer.