Title: [144254] trunk/Source/WebCore
Revision
144254
Author
[email protected]
Date
2013-02-27 18:24:16 -0800 (Wed, 27 Feb 2013)

Log Message

Add month popup for new calendar picker
https://bugs.webkit.org/show_bug.cgi?id=110830

Reviewed by Kent Tamura.

Adding month popup view for use in the new calendar picker (Bug 109439).
YearListCell will grow in height when selected to reveal the buttons for
selecting the month.

No new tests. Code is not used yet.

* Resources/pagepopups/calendarPicker.js:
(YearListCell): A row inside the month popup. Contains buttons for choosing a month.
(YearListCell.prototype._recycleBin):
(YearListCell.prototype.reset): Resets a thrown away cell for reuse at the given row.
(YearListCell.prototype.height):
(YearListCell.prototype.setHeight):
(YearListView): List view showing YearListCells.
(YearListView.prototype.onMouseOver): If the mouse is over a month button, highlights it.
(YearListView.prototype.onMouseOut): De-highlights the month button.
(YearListView.prototype.setWidth): Set scroll view width to leave space for the scroll bar.
(YearListView.prototype.setHeight): Sets the scroll bar height as well.
(YearListView.prototype._animateRow): Animates the row height to open/close the YearListCell.
(YearListView.prototype.onCellHeightAnimatorDidStop): Keep this._runningAnimators and this._animatingRows up to date.
(YearListView.prototype.onCellHeightAnimatorStep): Update the cell height and position.
(YearListView.prototype.onClick): If this is a click on a month button, select the month.
(YearListView.prototype.rowAtScrollOffset): Calculates the row currently at the given offset.
(YearListView.prototype.scrollOffsetForRow): Calculates the current scroll offset of the given row.
(YearListView.prototype.prepareNewCell): Prepares a new or recycled YearListCell.
(YearListView.prototype.updateCells): Updates the position of the visible cells.
(YearListView.prototype.deselect): Deselects a row.
(YearListView.prototype.deselectWithoutAnimating): Deselects a row without the closing animation.
(YearListView.prototype.select): Selects a row.
(YearListView.prototype.selectWithoutAnimating): Deselects a row without the opening animation.
(YearListView.prototype.buttonForMonth): Returns the month button for a given month. Returns null if the cell is not visible.
(YearListView.prototype.dehighlightMonth): Dehighlights the month button.
(YearListView.prototype.highlightMonth): Highlights the month button.
(YearListView.prototype.show): Call when showing the year list view. Shows the given month as highlighted.
(YearListView.prototype.hide): Dispatches a did hide event which will be picked up by the CalendarPicker and the MonthPopupView will close.
(YearListView.prototype._moveHighlightTo): Used to move the month highlight in response to a key event.
(YearListView.prototype.onKeyDown): Arrow keys and PageUp/PageDown keys work.
(MonthPopupView): The popup view to be overlayed over the calendar picker.
(MonthPopupView.prototype.show): Takes the initialMonth to show and the calendarTableRect so we can overlay the year list view right on top of it.
(MonthPopupView.prototype.hide):
(MonthPopupView.prototype.onClick): Hides itself if the use clicks outside the year list view.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (144253 => 144254)


--- trunk/Source/WebCore/ChangeLog	2013-02-28 01:33:44 UTC (rev 144253)
+++ trunk/Source/WebCore/ChangeLog	2013-02-28 02:24:16 UTC (rev 144254)
@@ -1,3 +1,51 @@
+2013-02-27  Keishi Hattori  <[email protected]>
+
+        Add month popup for new calendar picker
+        https://bugs.webkit.org/show_bug.cgi?id=110830
+
+        Reviewed by Kent Tamura.
+
+        Adding month popup view for use in the new calendar picker (Bug 109439).
+        YearListCell will grow in height when selected to reveal the buttons for
+        selecting the month.
+
+        No new tests. Code is not used yet.
+
+        * Resources/pagepopups/calendarPicker.js:
+        (YearListCell): A row inside the month popup. Contains buttons for choosing a month.
+        (YearListCell.prototype._recycleBin):
+        (YearListCell.prototype.reset): Resets a thrown away cell for reuse at the given row.
+        (YearListCell.prototype.height):
+        (YearListCell.prototype.setHeight):
+        (YearListView): List view showing YearListCells.
+        (YearListView.prototype.onMouseOver): If the mouse is over a month button, highlights it.
+        (YearListView.prototype.onMouseOut): De-highlights the month button.
+        (YearListView.prototype.setWidth): Set scroll view width to leave space for the scroll bar.
+        (YearListView.prototype.setHeight): Sets the scroll bar height as well.
+        (YearListView.prototype._animateRow): Animates the row height to open/close the YearListCell.
+        (YearListView.prototype.onCellHeightAnimatorDidStop): Keep this._runningAnimators and this._animatingRows up to date.
+        (YearListView.prototype.onCellHeightAnimatorStep): Update the cell height and position.
+        (YearListView.prototype.onClick): If this is a click on a month button, select the month.
+        (YearListView.prototype.rowAtScrollOffset): Calculates the row currently at the given offset.
+        (YearListView.prototype.scrollOffsetForRow): Calculates the current scroll offset of the given row.
+        (YearListView.prototype.prepareNewCell): Prepares a new or recycled YearListCell.
+        (YearListView.prototype.updateCells): Updates the position of the visible cells.
+        (YearListView.prototype.deselect): Deselects a row.
+        (YearListView.prototype.deselectWithoutAnimating): Deselects a row without the closing animation.
+        (YearListView.prototype.select): Selects a row.
+        (YearListView.prototype.selectWithoutAnimating): Deselects a row without the opening animation.
+        (YearListView.prototype.buttonForMonth): Returns the month button for a given month. Returns null if the cell is not visible.
+        (YearListView.prototype.dehighlightMonth): Dehighlights the month button.
+        (YearListView.prototype.highlightMonth): Highlights the month button.
+        (YearListView.prototype.show): Call when showing the year list view. Shows the given month as highlighted.
+        (YearListView.prototype.hide): Dispatches a did hide event which will be picked up by the CalendarPicker and the MonthPopupView will close.
+        (YearListView.prototype._moveHighlightTo): Used to move the month highlight in response to a key event.
+        (YearListView.prototype.onKeyDown): Arrow keys and PageUp/PageDown keys work.
+        (MonthPopupView): The popup view to be overlayed over the calendar picker.
+        (MonthPopupView.prototype.show): Takes the initialMonth to show and the calendarTableRect so we can overlay the year list view right on top of it.
+        (MonthPopupView.prototype.hide):
+        (MonthPopupView.prototype.onClick): Hides itself if the use clicks outside the year list view.
+
 2013-02-27  Adam Barth  <[email protected]>
 
         Use FeatureObserver to see how often web sites use multipart main documents

Modified: trunk/Source/WebCore/Resources/pagepopups/calendarPicker.js (144253 => 144254)


--- trunk/Source/WebCore/Resources/pagepopups/calendarPicker.js	2013-02-28 01:33:44 UTC (rev 144253)
+++ trunk/Source/WebCore/Resources/pagepopups/calendarPicker.js	2013-02-28 02:24:16 UTC (rev 144254)
@@ -1881,6 +1881,628 @@
 
 /**
  * @constructor
+ * @extends ListCell
+ * @param {!Array} shortMonthLabels
+ */
+function YearListCell(shortMonthLabels) {
+    ListCell.call(this);
+    this.element.classList.add(YearListCell.ClassNameYearListCell);
+    this.element.style.height = YearListCell.Height + "px";
+
+    /**
+     * @type {!Element}
+     * @const
+     */
+    this.label = createElement("div", YearListCell.ClassNameLabel, "----");
+    this.element.appendChild(this.label);
+
+    /**
+     * @type {!Array} Array of the 12 month button elements.
+     * @const
+     */
+    this.monthButtons = [];
+    var monthChooserElement = createElement("div", YearListCell.ClassNameMonthChooser);
+    for (var r = 0; r < YearListCell.ButtonRows; ++r) {
+        var buttonsRow = createElement("div", YearListCell.ClassNameMonthButtonsRow);
+        for (var c = 0; c < YearListCell.ButtonColumns; ++c) {
+            var month = c + r * YearListCell.ButtonColumns;
+            var button = createElement("button", YearListCell.ClassNameMonthButton, shortMonthLabels[month]);
+            button.dataset.month = month;
+            buttonsRow.appendChild(button);
+            this.monthButtons.push(button);
+        }
+        monthChooserElement.appendChild(buttonsRow);
+    }
+    this.element.appendChild(monthChooserElement);
+
+    /**
+     * @type {!boolean}
+     * @private
+     */
+    this._selected = false;
+    /**
+     * @type {!number}
+     * @private
+     */
+    this._height = 0;
+}
+
+YearListCell.prototype = Object.create(ListCell.prototype);
+
+YearListCell.Height = 25;
+YearListCell.ButtonRows = 3;
+YearListCell.ButtonColumns = 4;
+YearListCell.SelectedHeight = 121;
+YearListCell.ClassNameYearListCell = "year-list-cell";
+YearListCell.ClassNameLabel = "label";
+YearListCell.ClassNameMonthChooser = "month-chooser";
+YearListCell.ClassNameMonthButtonsRow = "month-buttons-row";
+YearListCell.ClassNameMonthButton = "month-button";
+YearListCell.ClassNameHighlighted = "highlighted";
+
+YearListCell._recycleBin = [];
+
+/**
+ * @return {!Array}
+ * @override
+ */
+YearListCell.prototype._recycleBin = function() {
+    return YearListCell._recycleBin;
+};
+
+/**
+ * @param {!number} row
+ */
+YearListCell.prototype.reset = function(row) {
+    this.row = row;
+    this.label.textContent = row + 1;
+    for (var i = 0; i < this.monthButtons.length; ++i) {
+        this.monthButtons[i].classList.remove(YearListCell.ClassNameHighlighted);
+    }
+    this.show();
+};
+
+/**
+ * @return {!number} The height in pixels.
+ */
+YearListCell.prototype.height = function() {
+    return this._height;
+};
+
+/**
+ * @param {!number} height Height in pixels.
+ */
+YearListCell.prototype.setHeight = function(height) {
+    if (this._height === height)
+        return;
+    this._height = height;
+    this.element.style.height = this._height + "px";
+};
+
+/**
+ * @constructor
+ * @extends ListView
+ * @param {!Month} minimumMonth
+ * @param {!Month} maximumMonth
+ */
+function YearListView(minimumMonth, maximumMonth) {
+    ListView.call(this);
+    this.element.classList.add("year-list-view");
+
+    /**
+     * @type {?Month}
+     */
+    this.highlightedMonth = null;
+    /**
+     * @type {!Month}
+     * @const
+     * @protected
+     */
+    this._minimumMonth = minimumMonth;
+    /**
+     * @type {!Month}
+     * @const
+     * @protected
+     */
+    this._maximumMonth = maximumMonth;
+
+    this.scrollView.minimumContentOffset = (this._minimumMonth.year - 1) * YearListCell.Height;
+    this.scrollView.maximumContentOffset = (this._maximumMonth.year - 1) * YearListCell.Height + YearListCell.SelectedHeight;
+    
+    /**
+     * @type {!Object}
+     * @const
+     * @protected
+     */
+    this._runningAnimators = {};
+    /**
+     * @type {!Array}
+     * @const
+     * @protected
+     */
+    this._animatingRows = [];
+    /**
+     * @type {!boolean}
+     * @protected
+     */
+    this._ignoreMouseOutUntillNextMouseOver = false;
+    
+    /**
+     * @type {!ScrubbyScrollBar}
+     * @const
+     */
+    this.scrubbyScrollBar = new ScrubbyScrollBar(this.scrollView);
+    this.scrubbyScrollBar.attachTo(this);
+    
+    this.element.addEventListener("mouseover", this.onMouseOver, false);
+    this.element.addEventListener("mouseout", this.onMouseOut, false);
+    this.element.addEventListener("keydown", this.onKeyDown, false);
+}
+
+YearListView.prototype = Object.create(ListView.prototype);
+
+YearListView.Height = YearListCell.SelectedHeight - 1;
+YearListView.EventTypeYearListViewDidHide = "yearListViewDidHide";
+YearListView.EventTypeYearListViewDidSelectMonth = "yearListViewDidSelectMonth";
+
+/**
+ * @param {?Event} event
+ */
+YearListView.prototype._onMouseOver_ = function(event) {
+    var monthButtonElement = enclosingNodeOrSelfWithClass(event.target, YearListCell.ClassNameMonthButton);
+    if (!monthButtonElement)
+        return;
+    var cellElement = enclosingNodeOrSelfWithClass(monthButtonElement, YearListCell.ClassNameYearListCell);
+    var cell = cellElement.$view;
+    this.highlightMonth(new Month(cell.row + 1, parseInt(monthButtonElement.dataset.month, 10)));
+    this._ignoreMouseOutUntillNextMouseOver = false;
+};
+
+/**
+ * @param {?Event} event
+ */
+YearListView.prototype._onMouseOut_ = function(event) {
+    if (this._ignoreMouseOutUntillNextMouseOver)
+        return;
+    var monthButtonElement = enclosingNodeOrSelfWithClass(event.target, YearListCell.ClassNameMonthButton);
+    if (!monthButtonElement) {
+        this.dehighlightMonth();
+    }
+};
+
+/**
+ * @param {!number} width Width in pixels.
+ * @override
+ */
+YearListView.prototype.setWidth = function(width) {
+    ListView.prototype.setWidth.call(this, width - this.scrubbyScrollBar.element.offsetWidth);
+    this.element.style.width = width + "px";
+};
+
+/**
+ * @param {!number} height Height in pixels.
+ * @override
+ */
+YearListView.prototype.setHeight = function(height) {
+    ListView.prototype.setHeight.call(this, height);
+    this.scrubbyScrollBar.setHeight(height);
+};
+
+/**
+ * @enum {number}
+ */
+YearListView.RowAnimationDirection = {
+    Opening: 0,
+    Closing: 1
+};
+
+/**
+ * @param {!number} row
+ * @param {!YearListView.RowAnimationDirection} direction
+ */
+YearListView.prototype._animateRow = function(row, direction) {
+    var fromValue = direction === YearListView.RowAnimationDirection.Closing ? YearListCell.SelectedHeight : YearListCell.Height;
+    var oldAnimator = this._runningAnimators[row];
+    if (oldAnimator) {
+        oldAnimator.stop();
+        fromValue = oldAnimator.currentValue;
+    }
+    var cell = this.cellAtRow(row);
+    var animator = new Animator();
+    animator.step = this.onCellHeightAnimatorStep;
+    animator.setFrom(fromValue);
+    animator.setTo(direction === YearListView.RowAnimationDirection.Opening ? YearListCell.SelectedHeight : YearListCell.Height);
+    animator.timingFunction = AnimationTimingFunction.EaseInOut;
+    animator.duration = 300;
+    animator.row = row;
+    animator.on(Animator.EventTypeDidAnimationStop, this.onCellHeightAnimatorDidStop);
+    this._runningAnimators[row] = animator;
+    this._animatingRows.push(row);
+    this._animatingRows.sort();
+    animator.start();
+};
+
+/**
+ * @param {?Animator} animator
+ */
+YearListView.prototype._onCellHeightAnimatorDidStop_ = function(animator) {
+    delete this._runningAnimators[animator.row];
+    var index = this._animatingRows.indexOf(animator.row);
+    this._animatingRows.splice(index, 1);
+};
+
+/**
+ * @param {!Animator} animator
+ */
+YearListView.prototype._onCellHeightAnimatorStep_ = function(animator) {
+    var cell = this.cellAtRow(animator.row);
+    if (cell)
+        cell.setHeight(animator.currentValue);
+    this.updateCells();
+};
+
+/**
+ * @param {?Event} event
+ */
+YearListView.prototype._onClick_ = function(event) {
+    var oldSelectedRow = this.selectedRow;
+    ListView.prototype.onClick.call(this, event);
+    var year = this.selectedRow + 1;
+    if (this.selectedRow !== oldSelectedRow) {
+        var month = this.highlightedMonth ? this.highlightedMonth.month : 0;
+        this.dispatchEvent(YearListView.EventTypeYearListViewDidSelectMonth, this, new Month(year, month));
+        this.scrollView.scrollTo(this.selectedRow * YearListCell.Height, true);
+    } else {
+        var monthButton = enclosingNodeOrSelfWithClass(event.target, YearListCell.ClassNameMonthButton);
+        if (!monthButton)
+            return;
+        var month = parseInt(monthButton.dataset.month, 10);
+        this.dispatchEvent(YearListView.EventTypeYearListViewDidSelectMonth, this, new Month(year, month));
+        this.hide();
+    }
+};
+
+/**
+ * @param {!number} scrollOffset
+ * @return {!number}
+ * @override
+ */
+YearListView.prototype.rowAtScrollOffset = function(scrollOffset) {
+    var remainingOffset = scrollOffset;
+    var lastAnimatingRow = 0;
+    var rowsWithIrregularHeight = this._animatingRows.slice();
+    if (this.selectedRow > -1 && !this._runningAnimators[this.selectedRow]) {
+        rowsWithIrregularHeight.push(this.selectedRow);
+        rowsWithIrregularHeight.sort();
+    }
+    for (var i = 0; i < rowsWithIrregularHeight.length; ++i) {
+        var row = rowsWithIrregularHeight[i];
+        var animator = this._runningAnimators[row];
+        var rowHeight = animator ? animator.currentValue : YearListCell.SelectedHeight;
+        if (remainingOffset <= (row - lastAnimatingRow) * YearListCell.Height) {
+            return lastAnimatingRow + Math.floor(remainingOffset / YearListCell.Height);
+        }
+        remainingOffset -= (row - lastAnimatingRow) * YearListCell.Height;
+        if (remainingOffset <= (rowHeight - YearListCell.Height))
+            return row;
+        remainingOffset -= rowHeight - YearListCell.Height;
+        lastAnimatingRow = row;
+    }
+    return lastAnimatingRow + Math.floor(remainingOffset / YearListCell.Height);
+};
+
+/**
+ * @param {!number} row
+ * @return {!number}
+ * @override
+ */
+YearListView.prototype.scrollOffsetForRow = function(row) {
+    var scrollOffset = row * YearListCell.Height;
+    for (var i = 0; i < this._animatingRows.length; ++i) {
+        var animatingRow = this._animatingRows[i];
+        if (animatingRow >= row)
+            break;
+        var animator = this._runningAnimators[animatingRow];
+        scrollOffset += animator.currentValue - YearListCell.Height;
+    }
+    if (this.selectedRow > -1 && this.selectedRow < row && !this._runningAnimators[this.selectedRow]) {
+        scrollOffset += YearListCell.SelectedHeight - YearListCell.Height;
+    }
+    return scrollOffset;
+};
+
+/**
+ * @param {!number} row
+ * @return {!YearListCell}
+ * @override
+ */
+YearListView.prototype.prepareNewCell = function(row) {
+    var cell = YearListCell._recycleBin.pop() || new YearListCell(global.params.shortMonthLabels);
+    cell.reset(row);
+    cell.setSelected(this.selectedRow === row);
+    if (this.highlightedMonth && row === this.highlightedMonth.year - 1) {
+        cell.monthButtons[this.highlightedMonth.month].classList.add(YearListCell.ClassNameHighlighted);
+    }
+    for (var i = 0; i < cell.monthButtons.length; ++i) {
+        var month = new Month(row + 1, i);
+        cell.monthButtons[i].disabled = this._minimumMonth > month || this._maximumMonth < month;
+    }
+    var animator = this._runningAnimators[row];
+    if (animator)
+        cell.setHeight(animator.currentValue);
+    else if (row === this.selectedRow)
+        cell.setHeight(YearListCell.SelectedHeight);
+    else
+        cell.setHeight(YearListCell.Height);
+    return cell;
+};
+
+/**
+ * @override
+ */
+YearListView.prototype.updateCells = function() {
+    var firstVisibleRow = this.firstVisibleRow();
+    var lastVisibleRow = this.lastVisibleRow();
+    console.assert(firstVisibleRow <= lastVisibleRow);
+    for (var c in this._cells) {
+        var cell = this._cells[c];
+        if (cell.row < firstVisibleRow || cell.row > lastVisibleRow)
+            this.throwAwayCell(cell);
+    }
+    for (var i = firstVisibleRow; i <= lastVisibleRow; ++i) {
+        var cell = this._cells[i];
+        if (cell)
+            cell.setPosition(this.scrollView.contentPositionForContentOffset(this.scrollOffsetForRow(cell.row)));
+        else
+            this.addCellIfNecessary(i);
+    }
+    this.setNeedsUpdateCells(false);
+};
+
+/**
+ * @override
+ */
+YearListView.prototype.deselect = function() {
+    if (this.selectedRow === ListView.NoSelection)
+        return;
+    var selectedCell = this._cells[this.selectedRow];
+    if (selectedCell)
+        selectedCell.setSelected(false);
+    this._animateRow(this.selectedRow, YearListView.RowAnimationDirection.Closing);
+    this.selectedRow = ListView.NoSelection;
+    this.setNeedsUpdateCells(true);
+};
+
+YearListView.prototype.deselectWithoutAnimating = function() {
+    if (this.selectedRow === ListView.NoSelection)
+        return;
+    var selectedCell = this._cells[this.selectedRow];
+    if (selectedCell) {
+        selectedCell.setSelected(false);
+        selectedCell.setHeight(YearListCell.Height);
+    }
+    this.selectedRow = ListView.NoSelection;
+    this.setNeedsUpdateCells(true);
+};
+
+/**
+ * @param {!number} row
+ * @override
+ */
+YearListView.prototype.select = function(row) {
+    if (this.selectedRow === row)
+        return;
+    this.deselect();
+    if (row === ListView.NoSelection)
+        return;
+    this.selectedRow = row;
+    if (this.selectedRow !== ListView.NoSelection) {
+        var selectedCell = this._cells[this.selectedRow];
+        this._animateRow(this.selectedRow, YearListView.RowAnimationDirection.Opening);
+        if (selectedCell)
+            selectedCell.setSelected(true);
+        var month = this.highlightedMonth ? this.highlightedMonth.month : 0;
+        this.highlightMonth(new Month(this.selectedRow + 1, month));
+    }
+    this.setNeedsUpdateCells(true);
+};
+
+/**
+ * @param {!number} row
+ */
+YearListView.prototype.selectWithoutAnimating = function(row) {
+    if (this.selectedRow === row)
+        return;
+    this.deselectWithoutAnimating();
+    if (row === ListView.NoSelection)
+        return;
+    this.selectedRow = row;
+    if (this.selectedRow !== ListView.NoSelection) {
+        var selectedCell = this._cells[this.selectedRow];
+        if (selectedCell) {
+            selectedCell.setSelected(true);
+            selectedCell.setHeight(YearListCell.SelectedHeight);
+        }
+        var month = this.highlightedMonth ? this.highlightedMonth.month : 0;
+        this.highlightMonth(new Month(this.selectedRow + 1, month));
+    }
+    this.setNeedsUpdateCells(true);
+};
+
+/**
+ * @param {!Month} month
+ * @return {?HTMLButtonElement}
+ */
+YearListView.prototype.buttonForMonth = function(month) {
+    if (!month)
+        return null;
+    var row = month.year - 1;
+    var cell = this.cellAtRow(row);
+    if (!cell)
+        return null;
+    return cell.monthButtons[month.month];
+};
+
+YearListView.prototype.dehighlightMonth = function() {
+    if (!this.highlightedMonth)
+        return;
+    var monthButton = this.buttonForMonth(this.highlightedMonth);
+    if (monthButton) {
+        monthButton.classList.remove(YearListCell.ClassNameHighlighted);
+    }
+    this.highlightedMonth = null;
+};
+
+/**
+ * @param {!Month} month
+ */
+YearListView.prototype.highlightMonth = function(month) {
+    if (this.highlightedMonth && this.highlightedMonth.equals(month))
+        return;
+    this.dehighlightMonth();
+    this.highlightedMonth = month;
+    if (!this.highlightedMonth)
+        return;
+    var monthButton = this.buttonForMonth(this.highlightedMonth);
+    if (monthButton) {
+        monthButton.classList.add(YearListCell.ClassNameHighlighted);
+    }
+};
+
+/**
+ * @param {!Month} month
+ */
+YearListView.prototype.show = function(month) {
+    this._ignoreMouseOutUntillNextMouseOver = true;
+    
+    this.scrollToRow(month.year - 1, false);
+    this.selectWithoutAnimating(month.year - 1);
+    this.highlightMonth(month);
+};
+
+YearListView.prototype.hide = function() {
+    this.dispatchEvent(YearListView.EventTypeYearListViewDidHide, this);
+};
+
+/**
+ * @param {!Month} month
+ */
+YearListView.prototype._moveHighlightTo = function(month) {
+    this.highlightMonth(month);
+    this.select(this.highlightedMonth.year - 1);
+
+    this.dispatchEvent(YearListView.EventTypeYearListViewDidSelectMonth, this, month);
+    this.scrollView.scrollTo(this.selectedRow * YearListCell.Height, true);
+    return true;
+};
+
+/**
+ * @param {?Event} event
+ */
+YearListView.prototype._onKeyDown_ = function(event) {
+    var key = event.keyIdentifier;
+    var eventHandled = false;
+    if (key == "U+0054") // 't' key.
+        eventHandled = this._moveHighlightTo(Month.createFromToday());
+    else if (this.highlightedMonth) {
+        if (global.params.isLocaleRTL ? key == "Right" : key == "Left")
+            eventHandled = this._moveHighlightTo(this.highlightedMonth.previous());
+        else if (key == "Up")
+            eventHandled = this._moveHighlightTo(this.highlightedMonth.previous(YearListCell.ButtonColumns));
+        else if (global.params.isLocaleRTL ? key == "Left" : key == "Right")
+            eventHandled = this._moveHighlightTo(this.highlightedMonth.next());
+        else if (key == "Down")
+            eventHandled = this._moveHighlightTo(this.highlightedMonth.next(YearListCell.ButtonColumns));
+        else if (key == "PageUp")
+            eventHandled = this._moveHighlightTo(this.highlightedMonth.previous(MonthsPerYear));
+        else if (key == "PageDown")
+            eventHandled = this._moveHighlightTo(this.highlightedMonth.next(MonthsPerYear));
+        else if (key == "Enter") {
+            this.dispatchEvent(YearListView.EventTypeYearListViewDidSelectMonth, this, this.highlightedMonth);
+            this.hide();
+            eventHandled = true;
+        }
+    } else if (key == "Up") {
+        this.scrollView.scrollBy(-YearListCell.Height, true);
+        eventHandled = true;
+    } else if (key == "Down") {
+        this.scrollView.scrollBy(YearListCell.Height, true);
+        eventHandled = true;
+    } else if (key == "PageUp") {
+        this.scrollView.scrollBy(-this.scrollView.height(), true);
+        eventHandled = true;
+    } else if (key == "PageDown") {
+        this.scrollView.scrollBy(this.scrollView.height(), true);
+        eventHandled = true;
+    }
+
+    if (eventHandled) {
+        event.stopPropagation();
+        event.preventDefault();
+    }
+};
+
+/**
+ * @constructor
+ * @extends View
+ * @param {!Month} minimumMonth
+ * @param {!Month} maximumMonth
+ */
+function MonthPopupView(minimumMonth, maximumMonth) {
+    View.call(this, createElement("div", MonthPopupView.ClassNameMonthPopupView));
+
+    /**
+     * @type {!YearListView}
+     * @const
+     */
+    this.yearListView = new YearListView(minimumMonth, maximumMonth);
+    this.yearListView.attachTo(this);
+
+    /**
+     * @type {!boolean}
+     */
+    this.isVisible = false;
+
+    this.element.addEventListener("click", this.onClick, false);
+}
+
+MonthPopupView.prototype = Object.create(View.prototype);
+
+MonthPopupView.ClassNameMonthPopupView = "month-popup-view";
+
+MonthPopupView.prototype.show = function(initialMonth, calendarTableRect) {
+    this.isVisible = true;
+    document.body.appendChild(this.element);
+    this.yearListView.setWidth(calendarTableRect.width - 2);
+    this.yearListView.setHeight(YearListView.Height);
+    if (global.params.isLocaleRTL)
+        this.yearListView.element.style.right = calendarTableRect.x + "px";
+    else
+        this.yearListView.element.style.left = calendarTableRect.x + "px";
+    this.yearListView.element.style.top = calendarTableRect.y + "px";
+    this.yearListView.show(initialMonth);
+    this.yearListView.element.focus();
+};
+
+MonthPopupView.prototype.hide = function() {
+    if (!this.isVisible)
+        return;
+    this.isVisible = false;
+    this.element.parentNode.removeChild(this.element);
+    this.yearListView.hide();
+};
+
+/**
+ * @param {?Event} event
+ */
+MonthPopupView.prototype._onClick_ = function(event) {
+    if (event.target !== this.element)
+        return;
+    this.hide();
+};
+
+/**
+ * @constructor
  * @param {!Element} element
  * @param {!Object} config
  */
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to