Changeset 143901 in webkit
- Timestamp:
- Feb 25, 2013 3:31:09 AM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r143900 r143901 1 2013-02-25 Keishi Hattori <keishi@webkit.org> 2 3 Add list view for new calendar picker 4 https://bugs.webkit.org/show_bug.cgi?id=110140 5 6 Reviewed by Kent Tamura. 7 8 Adding list view class to be used in the new calendar picker (Bug 109439). 9 10 No new tests. Code is not yet used. 11 12 * Resources/pagepopups/calendarPicker.js: 13 (ListCell): One row inside the list view. We reuse 14 list cells to avoid animation hiccups caused by memory allocation. 15 (ListCell.prototype._recycleBin): Returns array to 16 store thrown away list cells so we can reuse them. 17 (ListCell.prototype.throwAway): Hides the cell and puts it in the recycle bin. 18 (ListCell.prototype.show): 19 (ListCell.prototype.hide): Hide the cell when we don't need the cell any more. 20 (ListCell.prototype.width): 21 (ListCell.prototype.setWidth): 22 (ListCell.prototype.position): 23 (ListCell.prototype.setPosition): Sets the CSS transform to position the cell. 24 (ListCell.prototype.setSelected): Adds selected CSS class. 25 (ListView): Shows a scrolling list. 26 (ListView.prototype.onAnimationFrameWillFinish): Calls updateCells if the cells need to be updated. 27 (ListView.prototype.setNeedsUpdateCells): Mark the cells as need to be updated. 28 (ListView.prototype.cellAtRow): Returns the cell at a given row. If the cell is not visible and doesn't exist, returns undefined. 29 (ListView.prototype.rowAtScrollOffset): The row that is displayed at the given scroll offset. 30 (ListView.prototype.scrollOffsetForRow): The scroll offset for the top of a given row. 31 (ListView.prototype.addCellIfNecessary): Adds the cell for a given row. 32 (ListView.prototype.prepareNewCell): Prepares a new or recycled cell for a given row. 33 (ListView.prototype.throwAwayCell): Throws a way a cell. 34 (ListView.prototype.firstVisibleRow): The first visible row at the top of the view. 35 (ListView.prototype.lastVisibleRow): The last visible row at the bottom of the view. 36 (ListView.prototype.scrollViewDidChangeContentOffset): 37 (ListView.prototype.scrollViewDidChangeHeight): 38 (ListView.prototype.scrollViewDidChangePartition): 39 (ListView.prototype.updateCells): Updates all the cells that are visible. 40 (ListView.prototype.width): 41 (ListView.prototype.setWidth): 42 (ListView.prototype.height): 43 (ListView.prototype.setHeight): 44 (ListView.prototype.onClick): Clicking on a row selects it. 45 (ListView.prototype.select): 46 (ListView.prototype.deselect): 47 (ListView.prototype.scrollToRow): Scrolls to a given row. 48 1 49 2013-02-25 Alexei Filippov <alph@chromium.org> 2 50 -
trunk/Source/WebCore/Resources/pagepopups/calendarPicker.js
r143867 r143901 1362 1362 ScrollView.prototype.contentPositionForContentOffset = function(offset) { 1363 1363 return offset - this._partitionNumber * ScrollView.PartitionHeight; 1364 }; 1365 1366 /** 1367 * @constructor 1368 * @extends View 1369 */ 1370 function ListCell() { 1371 View.call(this, createElement("div", ListCell.ClassNameListCell)); 1372 1373 /** 1374 * @type {!number} 1375 */ 1376 this.row = NaN; 1377 /** 1378 * @type {!number} 1379 */ 1380 this._width = 0; 1381 /** 1382 * @type {!number} 1383 */ 1384 this._position = 0; 1385 } 1386 1387 ListCell.prototype = Object.create(View.prototype); 1388 1389 ListCell.DefaultRecycleBinLimit = 64; 1390 ListCell.ClassNameListCell = "list-cell"; 1391 ListCell.ClassNameHidden = "hidden"; 1392 1393 /** 1394 * @return {!Array} An array to keep thrown away cells. 1395 */ 1396 ListCell.prototype._recycleBin = function() { 1397 console.assert(false, "NOT REACHED: ListCell.prototype._recycleBin needs to be overridden."); 1398 return []; 1399 }; 1400 1401 ListCell.prototype.throwAway = function() { 1402 this.hide(); 1403 var limit = typeof this.constructor.RecycleBinLimit === "undefined" ? ListCell.DefaultRecycleBinLimit : this.constructor.RecycleBinLimit; 1404 var recycleBin = this._recycleBin(); 1405 if (recycleBin.length < limit) 1406 recycleBin.push(this); 1407 }; 1408 1409 ListCell.prototype.show = function() { 1410 this.element.classList.remove(ListCell.ClassNameHidden); 1411 }; 1412 1413 ListCell.prototype.hide = function() { 1414 this.element.classList.add(ListCell.ClassNameHidden); 1415 }; 1416 1417 /** 1418 * @return {!number} Width in pixels. 1419 */ 1420 ListCell.prototype.width = function(){ 1421 return this._width; 1422 }; 1423 1424 /** 1425 * @param {!number} width Width in pixels. 1426 */ 1427 ListCell.prototype.setWidth = function(width){ 1428 if (this._width === width) 1429 return; 1430 this._width = width; 1431 this.element.style.width = this._width + "px"; 1432 }; 1433 1434 /** 1435 * @return {!number} Position in pixels. 1436 */ 1437 ListCell.prototype.position = function(){ 1438 return this._position; 1439 }; 1440 1441 /** 1442 * @param {!number} y Position in pixels. 1443 */ 1444 ListCell.prototype.setPosition = function(y) { 1445 if (this._position === y) 1446 return; 1447 this._position = y; 1448 this.element.style.webkitTransform = "translate(0, " + this._position + "px)"; 1449 }; 1450 1451 /** 1452 * @param {!boolean} selected 1453 */ 1454 ListCell.prototype.setSelected = function(selected) { 1455 if (this._selected === selected) 1456 return; 1457 this._selected = selected; 1458 if (this._selected) 1459 this.element.classList.add("selected"); 1460 else 1461 this.element.classList.remove("selected"); 1462 }; 1463 1464 /** 1465 * @constructor 1466 * @extends View 1467 */ 1468 function ListView() { 1469 View.call(this, createElement("div", ListView.ClassNameListView)); 1470 this.element.tabIndex = 0; 1471 1472 /** 1473 * @type {!number} 1474 * @private 1475 */ 1476 this._width = 0; 1477 /** 1478 * @type {!Object} 1479 * @private 1480 */ 1481 this._cells = {}; 1482 1483 /** 1484 * @type {!number} 1485 */ 1486 this.selectedRow = ListView.NoSelection; 1487 1488 /** 1489 * @type {!ScrollView} 1490 */ 1491 this.scrollView = new ScrollView(); 1492 this.scrollView.delegate = this; 1493 this.scrollView.minimumContentOffset = 0; 1494 this.scrollView.setWidth(0); 1495 this.scrollView.setHeight(0); 1496 this.scrollView.attachTo(this); 1497 1498 this.element.addEventListener("click", this.onClick, false); 1499 1500 /** 1501 * @type {!boolean} 1502 * @private 1503 */ 1504 this._needsUpdateCells = false; 1505 } 1506 1507 ListView.prototype = Object.create(View.prototype); 1508 1509 ListView.NoSelection = -1; 1510 ListView.ClassNameListView = "list-view"; 1511 1512 ListView.prototype.onAnimationFrameWillFinish = function() { 1513 if (this._needsUpdateCells) 1514 this.updateCells(); 1515 }; 1516 1517 /** 1518 * @param {!boolean} needsUpdateCells 1519 */ 1520 ListView.prototype.setNeedsUpdateCells = function(needsUpdateCells) { 1521 if (this._needsUpdateCells === needsUpdateCells) 1522 return; 1523 this._needsUpdateCells = needsUpdateCells; 1524 if (this._needsUpdateCells) 1525 AnimationManager.shared.on(AnimationManager.EventTypeAnimationFrameWillFinish, this.onAnimationFrameWillFinish); 1526 else 1527 AnimationManager.shared.removeListener(AnimationManager.EventTypeAnimationFrameWillFinish, this.onAnimationFrameWillFinish); 1528 }; 1529 1530 /** 1531 * @param {!number} row 1532 * @return {?ListCell} 1533 */ 1534 ListView.prototype.cellAtRow = function(row) { 1535 return this._cells[row]; 1536 }; 1537 1538 /** 1539 * @param {!number} offset Scroll offset in pixels. 1540 * @return {!number} 1541 */ 1542 ListView.prototype.rowAtScrollOffset = function(offset) { 1543 console.assert(false, "NOT REACHED: ListView.prototype.rowAtScrollOffset needs to be overridden."); 1544 return 0; 1545 }; 1546 1547 /** 1548 * @param {!number} row 1549 * @return {!number} Scroll offset in pixels. 1550 */ 1551 ListView.prototype.scrollOffsetForRow = function(row) { 1552 console.assert(false, "NOT REACHED: ListView.prototype.scrollOffsetForRow needs to be overridden."); 1553 return 0; 1554 }; 1555 1556 /** 1557 * @param {!number} row 1558 * @return {!ListCell} 1559 */ 1560 ListView.prototype.addCellIfNecessary = function(row) { 1561 var cell = this._cells[row]; 1562 if (cell) 1563 return cell; 1564 cell = this.prepareNewCell(row); 1565 cell.attachTo(this.scrollView.contentElement); 1566 cell.setWidth(this._width); 1567 cell.setPosition(this.scrollView.contentPositionForContentOffset(this.scrollOffsetForRow(row))); 1568 this._cells[row] = cell; 1569 return cell; 1570 }; 1571 1572 /** 1573 * @param {!number} row 1574 * @return {!ListCell} 1575 */ 1576 ListView.prototype.prepareNewCell = function(row) { 1577 console.assert(false, "NOT REACHED: ListView.prototype.prepareNewCell should be overridden."); 1578 return new ListCell(); 1579 }; 1580 1581 /** 1582 * @param {!ListCell} cell 1583 */ 1584 ListView.prototype.throwAwayCell = function(cell) { 1585 delete this._cells[cell.row]; 1586 cell.throwAway(); 1587 }; 1588 1589 /** 1590 * @return {!number} 1591 */ 1592 ListView.prototype.firstVisibleRow = function() { 1593 return this.rowAtScrollOffset(this.scrollView.contentOffset()); 1594 }; 1595 1596 /** 1597 * @return {!number} 1598 */ 1599 ListView.prototype.lastVisibleRow = function() { 1600 return this.rowAtScrollOffset(this.scrollView.contentOffset() + this.scrollView.height() - 1); 1601 }; 1602 1603 /** 1604 * @param {!ScrollView} scrollView 1605 */ 1606 ListView.prototype.scrollViewDidChangeContentOffset = function(scrollView) { 1607 this.setNeedsUpdateCells(true); 1608 }; 1609 1610 /** 1611 * @param {!ScrollView} scrollView 1612 */ 1613 ListView.prototype.scrollViewDidChangeHeight = function(scrollView) { 1614 this.setNeedsUpdateCells(true); 1615 }; 1616 1617 /** 1618 * @param {!ScrollView} scrollView 1619 */ 1620 ListView.prototype.scrollViewDidChangePartition = function(scrollView) { 1621 this.setNeedsUpdateCells(true); 1622 }; 1623 1624 ListView.prototype.updateCells = function() { 1625 var firstVisibleRow = this.firstVisibleRow(); 1626 var lastVisibleRow = this.lastVisibleRow(); 1627 console.assert(firstVisibleRow <= lastVisibleRow); 1628 for (var c in this._cells) { 1629 var cell = this._cells[c]; 1630 if (cell.row < firstVisibleRow || cell.row > lastVisibleRow) 1631 this.throwAwayCell(cell); 1632 } 1633 for (var i = firstVisibleRow; i <= lastVisibleRow; ++i) { 1634 var cell = this._cells[i]; 1635 if (cell) 1636 cell.setPosition(this.scrollView.contentPositionForContentOffset(this.scrollOffsetForRow(cell.row))); 1637 else 1638 this.addCellIfNecessary(i); 1639 } 1640 this.setNeedsUpdateCells(false); 1641 }; 1642 1643 /** 1644 * @return {!number} Width in pixels. 1645 */ 1646 ListView.prototype.width = function() { 1647 return this._width; 1648 }; 1649 1650 /** 1651 * @param {!number} width Width in pixels. 1652 */ 1653 ListView.prototype.setWidth = function(width) { 1654 if (this._width === width) 1655 return; 1656 this._width = width; 1657 this.scrollView.setWidth(this._width); 1658 for (var c in this._cells) { 1659 this._cells[c].setWidth(this._width); 1660 } 1661 this.element.style.width = this._width + "px"; 1662 this.setNeedsUpdateCells(true); 1663 }; 1664 1665 /** 1666 * @return {!number} Height in pixels. 1667 */ 1668 ListView.prototype.height = function() { 1669 return this.scrollView.height(); 1670 }; 1671 1672 /** 1673 * @param {!number} height Height in pixels. 1674 */ 1675 ListView.prototype.setHeight = function(height) { 1676 this.scrollView.setHeight(height); 1677 }; 1678 1679 /** 1680 * @param {?Event} event 1681 */ 1682 ListView.prototype.onClick = function(event) { 1683 var clickedCellElement = enclosingNodeOrSelfWithClass(event.target, ListCell.ClassNameListCell); 1684 if (!clickedCellElement) 1685 return; 1686 var clickedCell = clickedCellElement.$view; 1687 if (clickedCell.row !== this.selectedRow) 1688 this.select(clickedCell.row); 1689 }; 1690 1691 /** 1692 * @param {!number} row 1693 */ 1694 ListView.prototype.select = function(row) { 1695 if (this.selectedRow === row) 1696 return; 1697 this.deselect(); 1698 if (row === ListView.NoSelection) 1699 return; 1700 this.selectedRow = row; 1701 var selectedCell = this._cells[this.selectedRow]; 1702 if (selectedCell) 1703 selectedCell.setSelected(true); 1704 }; 1705 1706 ListView.prototype.deselect = function() { 1707 if (this.selectedRow === ListView.NoSelection) 1708 return; 1709 var selectedCell = this._cells[this.selectedRow]; 1710 if (selectedCell) 1711 selectedCell.setSelected(false); 1712 this.selectedRow = ListView.NoSelection; 1713 }; 1714 1715 /** 1716 * @param {!number} row 1717 * @param {!boolean} animate 1718 */ 1719 ListView.prototype.scrollToRow = function(row, animate) { 1720 this.scrollView.scrollTo(this.scrollOffsetForRow(row), animate); 1364 1721 }; 1365 1722
Note: See TracChangeset
for help on using the changeset viewer.