Title: [143901] trunk/Source/WebCore
- Revision
- 143901
- Author
- [email protected]
- Date
- 2013-02-25 03:31:09 -0800 (Mon, 25 Feb 2013)
Log Message
Add list view for new calendar picker
https://bugs.webkit.org/show_bug.cgi?id=110140
Reviewed by Kent Tamura.
Adding list view class to be used in the new calendar picker (Bug 109439).
No new tests. Code is not yet used.
* Resources/pagepopups/calendarPicker.js:
(ListCell): One row inside the list view. We reuse
list cells to avoid animation hiccups caused by memory allocation.
(ListCell.prototype._recycleBin): Returns array to
store thrown away list cells so we can reuse them.
(ListCell.prototype.throwAway): Hides the cell and puts it in the recycle bin.
(ListCell.prototype.show):
(ListCell.prototype.hide): Hide the cell when we don't need the cell any more.
(ListCell.prototype.width):
(ListCell.prototype.setWidth):
(ListCell.prototype.position):
(ListCell.prototype.setPosition): Sets the CSS transform to position the cell.
(ListCell.prototype.setSelected): Adds selected CSS class.
(ListView): Shows a scrolling list.
(ListView.prototype.onAnimationFrameWillFinish): Calls updateCells if the cells need to be updated.
(ListView.prototype.setNeedsUpdateCells): Mark the cells as need to be updated.
(ListView.prototype.cellAtRow): Returns the cell at a given row. If the cell is not visible and doesn't exist, returns undefined.
(ListView.prototype.rowAtScrollOffset): The row that is displayed at the given scroll offset.
(ListView.prototype.scrollOffsetForRow): The scroll offset for the top of a given row.
(ListView.prototype.addCellIfNecessary): Adds the cell for a given row.
(ListView.prototype.prepareNewCell): Prepares a new or recycled cell for a given row.
(ListView.prototype.throwAwayCell): Throws a way a cell.
(ListView.prototype.firstVisibleRow): The first visible row at the top of the view.
(ListView.prototype.lastVisibleRow): The last visible row at the bottom of the view.
(ListView.prototype.scrollViewDidChangeContentOffset):
(ListView.prototype.scrollViewDidChangeHeight):
(ListView.prototype.scrollViewDidChangePartition):
(ListView.prototype.updateCells): Updates all the cells that are visible.
(ListView.prototype.width):
(ListView.prototype.setWidth):
(ListView.prototype.height):
(ListView.prototype.setHeight):
(ListView.prototype.onClick): Clicking on a row selects it.
(ListView.prototype.select):
(ListView.prototype.deselect):
(ListView.prototype.scrollToRow): Scrolls to a given row.
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (143900 => 143901)
--- trunk/Source/WebCore/ChangeLog 2013-02-25 10:53:00 UTC (rev 143900)
+++ trunk/Source/WebCore/ChangeLog 2013-02-25 11:31:09 UTC (rev 143901)
@@ -1,3 +1,51 @@
+2013-02-25 Keishi Hattori <[email protected]>
+
+ Add list view for new calendar picker
+ https://bugs.webkit.org/show_bug.cgi?id=110140
+
+ Reviewed by Kent Tamura.
+
+ Adding list view class to be used in the new calendar picker (Bug 109439).
+
+ No new tests. Code is not yet used.
+
+ * Resources/pagepopups/calendarPicker.js:
+ (ListCell): One row inside the list view. We reuse
+ list cells to avoid animation hiccups caused by memory allocation.
+ (ListCell.prototype._recycleBin): Returns array to
+ store thrown away list cells so we can reuse them.
+ (ListCell.prototype.throwAway): Hides the cell and puts it in the recycle bin.
+ (ListCell.prototype.show):
+ (ListCell.prototype.hide): Hide the cell when we don't need the cell any more.
+ (ListCell.prototype.width):
+ (ListCell.prototype.setWidth):
+ (ListCell.prototype.position):
+ (ListCell.prototype.setPosition): Sets the CSS transform to position the cell.
+ (ListCell.prototype.setSelected): Adds selected CSS class.
+ (ListView): Shows a scrolling list.
+ (ListView.prototype.onAnimationFrameWillFinish): Calls updateCells if the cells need to be updated.
+ (ListView.prototype.setNeedsUpdateCells): Mark the cells as need to be updated.
+ (ListView.prototype.cellAtRow): Returns the cell at a given row. If the cell is not visible and doesn't exist, returns undefined.
+ (ListView.prototype.rowAtScrollOffset): The row that is displayed at the given scroll offset.
+ (ListView.prototype.scrollOffsetForRow): The scroll offset for the top of a given row.
+ (ListView.prototype.addCellIfNecessary): Adds the cell for a given row.
+ (ListView.prototype.prepareNewCell): Prepares a new or recycled cell for a given row.
+ (ListView.prototype.throwAwayCell): Throws a way a cell.
+ (ListView.prototype.firstVisibleRow): The first visible row at the top of the view.
+ (ListView.prototype.lastVisibleRow): The last visible row at the bottom of the view.
+ (ListView.prototype.scrollViewDidChangeContentOffset):
+ (ListView.prototype.scrollViewDidChangeHeight):
+ (ListView.prototype.scrollViewDidChangePartition):
+ (ListView.prototype.updateCells): Updates all the cells that are visible.
+ (ListView.prototype.width):
+ (ListView.prototype.setWidth):
+ (ListView.prototype.height):
+ (ListView.prototype.setHeight):
+ (ListView.prototype.onClick): Clicking on a row selects it.
+ (ListView.prototype.select):
+ (ListView.prototype.deselect):
+ (ListView.prototype.scrollToRow): Scrolls to a given row.
+
2013-02-25 Alexei Filippov <[email protected]>
Web Inspector: move profile type specific code out of ProfilesPanel (refactor)
Modified: trunk/Source/WebCore/Resources/pagepopups/calendarPicker.js (143900 => 143901)
--- trunk/Source/WebCore/Resources/pagepopups/calendarPicker.js 2013-02-25 10:53:00 UTC (rev 143900)
+++ trunk/Source/WebCore/Resources/pagepopups/calendarPicker.js 2013-02-25 11:31:09 UTC (rev 143901)
@@ -1365,6 +1365,363 @@
/**
* @constructor
+ * @extends View
+ */
+function ListCell() {
+ View.call(this, createElement("div", ListCell.ClassNameListCell));
+
+ /**
+ * @type {!number}
+ */
+ this.row = NaN;
+ /**
+ * @type {!number}
+ */
+ this._width = 0;
+ /**
+ * @type {!number}
+ */
+ this._position = 0;
+}
+
+ListCell.prototype = Object.create(View.prototype);
+
+ListCell.DefaultRecycleBinLimit = 64;
+ListCell.ClassNameListCell = "list-cell";
+ListCell.ClassNameHidden = "hidden";
+
+/**
+ * @return {!Array} An array to keep thrown away cells.
+ */
+ListCell.prototype._recycleBin = function() {
+ console.assert(false, "NOT REACHED: ListCell.prototype._recycleBin needs to be overridden.");
+ return [];
+};
+
+ListCell.prototype.throwAway = function() {
+ this.hide();
+ var limit = typeof this.constructor.RecycleBinLimit === "undefined" ? ListCell.DefaultRecycleBinLimit : this.constructor.RecycleBinLimit;
+ var recycleBin = this._recycleBin();
+ if (recycleBin.length < limit)
+ recycleBin.push(this);
+};
+
+ListCell.prototype.show = function() {
+ this.element.classList.remove(ListCell.ClassNameHidden);
+};
+
+ListCell.prototype.hide = function() {
+ this.element.classList.add(ListCell.ClassNameHidden);
+};
+
+/**
+ * @return {!number} Width in pixels.
+ */
+ListCell.prototype.width = function(){
+ return this._width;
+};
+
+/**
+ * @param {!number} width Width in pixels.
+ */
+ListCell.prototype.setWidth = function(width){
+ if (this._width === width)
+ return;
+ this._width = width;
+ this.element.style.width = this._width + "px";
+};
+
+/**
+ * @return {!number} Position in pixels.
+ */
+ListCell.prototype.position = function(){
+ return this._position;
+};
+
+/**
+ * @param {!number} y Position in pixels.
+ */
+ListCell.prototype.setPosition = function(y) {
+ if (this._position === y)
+ return;
+ this._position = y;
+ this.element.style.webkitTransform = "translate(0, " + this._position + "px)";
+};
+
+/**
+ * @param {!boolean} selected
+ */
+ListCell.prototype.setSelected = function(selected) {
+ if (this._selected === selected)
+ return;
+ this._selected = selected;
+ if (this._selected)
+ this.element.classList.add("selected");
+ else
+ this.element.classList.remove("selected");
+};
+
+/**
+ * @constructor
+ * @extends View
+ */
+function ListView() {
+ View.call(this, createElement("div", ListView.ClassNameListView));
+ this.element.tabIndex = 0;
+
+ /**
+ * @type {!number}
+ * @private
+ */
+ this._width = 0;
+ /**
+ * @type {!Object}
+ * @private
+ */
+ this._cells = {};
+
+ /**
+ * @type {!number}
+ */
+ this.selectedRow = ListView.NoSelection;
+
+ /**
+ * @type {!ScrollView}
+ */
+ this.scrollView = new ScrollView();
+ this.scrollView.delegate = this;
+ this.scrollView.minimumContentOffset = 0;
+ this.scrollView.setWidth(0);
+ this.scrollView.setHeight(0);
+ this.scrollView.attachTo(this);
+
+ this.element.addEventListener("click", this.onClick, false);
+
+ /**
+ * @type {!boolean}
+ * @private
+ */
+ this._needsUpdateCells = false;
+}
+
+ListView.prototype = Object.create(View.prototype);
+
+ListView.NoSelection = -1;
+ListView.ClassNameListView = "list-view";
+
+ListView.prototype._onAnimationFrameWillFinish_ = function() {
+ if (this._needsUpdateCells)
+ this.updateCells();
+};
+
+/**
+ * @param {!boolean} needsUpdateCells
+ */
+ListView.prototype.setNeedsUpdateCells = function(needsUpdateCells) {
+ if (this._needsUpdateCells === needsUpdateCells)
+ return;
+ this._needsUpdateCells = needsUpdateCells;
+ if (this._needsUpdateCells)
+ AnimationManager.shared.on(AnimationManager.EventTypeAnimationFrameWillFinish, this.onAnimationFrameWillFinish);
+ else
+ AnimationManager.shared.removeListener(AnimationManager.EventTypeAnimationFrameWillFinish, this.onAnimationFrameWillFinish);
+};
+
+/**
+ * @param {!number} row
+ * @return {?ListCell}
+ */
+ListView.prototype.cellAtRow = function(row) {
+ return this._cells[row];
+};
+
+/**
+ * @param {!number} offset Scroll offset in pixels.
+ * @return {!number}
+ */
+ListView.prototype.rowAtScrollOffset = function(offset) {
+ console.assert(false, "NOT REACHED: ListView.prototype.rowAtScrollOffset needs to be overridden.");
+ return 0;
+};
+
+/**
+ * @param {!number} row
+ * @return {!number} Scroll offset in pixels.
+ */
+ListView.prototype.scrollOffsetForRow = function(row) {
+ console.assert(false, "NOT REACHED: ListView.prototype.scrollOffsetForRow needs to be overridden.");
+ return 0;
+};
+
+/**
+ * @param {!number} row
+ * @return {!ListCell}
+ */
+ListView.prototype.addCellIfNecessary = function(row) {
+ var cell = this._cells[row];
+ if (cell)
+ return cell;
+ cell = this.prepareNewCell(row);
+ cell.attachTo(this.scrollView.contentElement);
+ cell.setWidth(this._width);
+ cell.setPosition(this.scrollView.contentPositionForContentOffset(this.scrollOffsetForRow(row)));
+ this._cells[row] = cell;
+ return cell;
+};
+
+/**
+ * @param {!number} row
+ * @return {!ListCell}
+ */
+ListView.prototype.prepareNewCell = function(row) {
+ console.assert(false, "NOT REACHED: ListView.prototype.prepareNewCell should be overridden.");
+ return new ListCell();
+};
+
+/**
+ * @param {!ListCell} cell
+ */
+ListView.prototype.throwAwayCell = function(cell) {
+ delete this._cells[cell.row];
+ cell.throwAway();
+};
+
+/**
+ * @return {!number}
+ */
+ListView.prototype.firstVisibleRow = function() {
+ return this.rowAtScrollOffset(this.scrollView.contentOffset());
+};
+
+/**
+ * @return {!number}
+ */
+ListView.prototype.lastVisibleRow = function() {
+ return this.rowAtScrollOffset(this.scrollView.contentOffset() + this.scrollView.height() - 1);
+};
+
+/**
+ * @param {!ScrollView} scrollView
+ */
+ListView.prototype.scrollViewDidChangeContentOffset = function(scrollView) {
+ this.setNeedsUpdateCells(true);
+};
+
+/**
+ * @param {!ScrollView} scrollView
+ */
+ListView.prototype.scrollViewDidChangeHeight = function(scrollView) {
+ this.setNeedsUpdateCells(true);
+};
+
+/**
+ * @param {!ScrollView} scrollView
+ */
+ListView.prototype.scrollViewDidChangePartition = function(scrollView) {
+ this.setNeedsUpdateCells(true);
+};
+
+ListView.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);
+};
+
+/**
+ * @return {!number} Width in pixels.
+ */
+ListView.prototype.width = function() {
+ return this._width;
+};
+
+/**
+ * @param {!number} width Width in pixels.
+ */
+ListView.prototype.setWidth = function(width) {
+ if (this._width === width)
+ return;
+ this._width = width;
+ this.scrollView.setWidth(this._width);
+ for (var c in this._cells) {
+ this._cells[c].setWidth(this._width);
+ }
+ this.element.style.width = this._width + "px";
+ this.setNeedsUpdateCells(true);
+};
+
+/**
+ * @return {!number} Height in pixels.
+ */
+ListView.prototype.height = function() {
+ return this.scrollView.height();
+};
+
+/**
+ * @param {!number} height Height in pixels.
+ */
+ListView.prototype.setHeight = function(height) {
+ this.scrollView.setHeight(height);
+};
+
+/**
+ * @param {?Event} event
+ */
+ListView.prototype._onClick_ = function(event) {
+ var clickedCellElement = enclosingNodeOrSelfWithClass(event.target, ListCell.ClassNameListCell);
+ if (!clickedCellElement)
+ return;
+ var clickedCell = clickedCellElement.$view;
+ if (clickedCell.row !== this.selectedRow)
+ this.select(clickedCell.row);
+};
+
+/**
+ * @param {!number} row
+ */
+ListView.prototype.select = function(row) {
+ if (this.selectedRow === row)
+ return;
+ this.deselect();
+ if (row === ListView.NoSelection)
+ return;
+ this.selectedRow = row;
+ var selectedCell = this._cells[this.selectedRow];
+ if (selectedCell)
+ selectedCell.setSelected(true);
+};
+
+ListView.prototype.deselect = function() {
+ if (this.selectedRow === ListView.NoSelection)
+ return;
+ var selectedCell = this._cells[this.selectedRow];
+ if (selectedCell)
+ selectedCell.setSelected(false);
+ this.selectedRow = ListView.NoSelection;
+};
+
+/**
+ * @param {!number} row
+ * @param {!boolean} animate
+ */
+ListView.prototype.scrollToRow = function(row, animate) {
+ this.scrollView.scrollTo(this.scrollOffsetForRow(row), animate);
+};
+
+/**
+ * @constructor
* @param {!Element} element
* @param {!Object} config
*/
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes