📄 sync.grid.js
字号:
/** * Component rendering peer: Grid */Echo.Sync.Grid = Core.extend(Echo.Render.ComponentSync, { $static: { /** * Creates a prototype rendering of the basic DOM structure of a Grid which may be cloned * for enhanced rendering performance. * * @return the prototype DOM hierarchy * @type Element */ _createPrototypeTable: function() { var table = document.createElement("table"); table.style.outlineStyle = "none"; table.tabIndex = "-1"; table.style.borderCollapse = "collapse"; var colGroup = document.createElement("colgroup"); table.appendChild(colGroup); table.appendChild(document.createElement("tbody")); return table; }, /** * Performs processing on layout of grid, determining rendered cell sizes, and * eliminating conflicting row/column spans. * * This object describes coordinates in terms of x and y, rather than column/row. * The translation between x/y and column/row varies based on the grid's orientation. * For horizontally oriented grids, the x-axis represents columns and the y-axis rows. * For vertically oriented grids, the x-axis represents rows and the y-axis columns. */ Processor: Core.extend({ $static: { /** * Representation of a single cell of the grid. */ Cell: Core.extend({ /** * The number of cells spanned in the x direction * @type Number */ xSpan: null, /** * The number of cells spanned in the y direction. * @type Number */ ySpan: null, /** * The index of the child component within the Grid parent. * @type Number */ index: null, /** * The child component. * @type Echo.Component */ component: null, /** * Creates a new cell. * * @param {Echo.Component} component the component * @param {Number} index the index of the component within the Grid parent * @param {Number} xSpan the number of cells spanned in the x direction * @param {Number} ySpan the number of cells spanned in the y direction */ $construct: function(component, index, xSpan, ySpan) { this.component = component; this.index = index; this.xSpan = xSpan; this.ySpan = ySpan; } }) }, /** * Two dimensional array which contains <code>Cell</code>s. * Each index of this array contains an array which represents a y-index of the grid. * Each index in a contained arrays represents a cell of the grid. * @type Array */ cellArrays: null, /** * The Grid being rendered. * @type Echo.Grid */ grid: null, /** * The size of the grid's x-axis. * @type Number */ gridXSize: null, /** * The size of the grid's x-axis. * @type Number */ gridYSize: null, /** * Array of extents representing cell sizes on x-axis. * @type Array */ xExtents: null, /** * Array of extents representing cell sizes on y-axis. * @type Array */ yExtents: null, /** * Flag indicating whether the grid is horizontally oriented. * @type Boolean */ horizontalOrientation: null, /** * Creates a new Processor instance. * * @param {Echo.Grid} grid the supported grid */ $construct: function(grid) { this.grid = grid; this.cellArrays = []; this.horizontalOrientation = grid.render("orientation") != Echo.Grid.ORIENTATION_VERTICAL; var cells = this.createCells(); if (cells == null) { // Special case: empty Grid. this.gridXSize = 0; this.gridYSize = 0; return; } this.renderCellMatrix(cells); this.calculateExtents(); this.reduceY(); this.reduceX(); }, /** * Adds two extents. * * @param {#Extent} a the first extent * @param {#Extent} b the second extent * @param {Boolean} flag indicating whether extents are horizontal * @return the sum of the extents * @type #Extent */ addExtents: function(a, b, horizontal) { var ap = Echo.Sync.Extent.isPercent(a), bp = Echo.Sync.Extent.isPercent(b); if (ap || bp) { if (ap && bp) { // Both are percents, add them. return (parseFloat(ap) + parseFloat(bp)) + "%"; } else { // One extent is percent, the other is not: return the percent extent. return ap ? a : b; } } else { return Echo.Sync.Extent.toPixels(a) + Echo.Sync.Extent.toPixels(b); } }, /** * Calculates sizes of columns and rows. */ calculateExtents: function() { var i, xProperty = this.horizontalOrientation ? "columnWidth" : "rowHeight", yProperty = this.horizontalOrientation ? "rowHeight" : "columnWidth"; this.xExtents = []; for (i = 0; i < this.gridXSize; ++i) { this.xExtents.push(this.grid.renderIndex(xProperty, i)); } this.yExtents = []; for (i = 0; i < this.gridYSize; ++i) { this.yExtents.push(this.grid.renderIndex(yProperty, i)); } }, /** * Creates array of <code>Cell</code> instances representing child components of the grid. * * @return the array of <code>Cell</code> instances * @type Array */ createCells: function() { var childCount = this.grid.getComponentCount(); if (childCount === 0) { // Abort if Grid is empty. return null; } var cells = []; for (var i = 0; i < childCount; ++i) { var child = this.grid.getComponent(i); var layoutData = child.render("layoutData"); if (layoutData) { var xSpan = this.horizontalOrientation ? layoutData.columnSpan : layoutData.rowSpan; var ySpan = this.horizontalOrientation ? layoutData.rowSpan : layoutData.columnSpan; cells.push(new Echo.Sync.Grid.Processor.Cell(child, i, xSpan ? xSpan : 1, ySpan ? ySpan : 1)); } else { cells.push(new Echo.Sync.Grid.Processor.Cell(child, i, 1, 1)); } } return cells; }, /** * Returns an array representing the cells at the specified y-index. * If no array currently exists, one is created. * * @param {Integer} y the y-index * @return the array of cells. * @type Array */ _getCellArray: function(y) { while (y >= this.cellArrays.length) { this.cellArrays.push([]); } return this.cellArrays[y]; }, /** * Returns the number of columns that should be rendered. * * @return the number of rendered columns * @type Integer */ getColumnCount: function() { return this.horizontalOrientation ? this.gridXSize : this.gridYSize; }, /** * Returns the cell that should be rendered at the * specified position. * * @param {Integer} column the column index * @param {Integer} row the row index * @return the cell * @type Echo.Sync.Grid.Processor.Cell */ getCell: function(column, row) { if (this.horizontalOrientation) { return this.cellArrays[row][column]; } else { return this.cellArrays[column][row]; } }, /** * Returns the number of rows that should be rendered. * * @return the number of rendered rows * @type Integer */ getRowCount: function() { return this.horizontalOrientation ? this.gridYSize : this.gridXSize; }, /** * Remove duplicates from the x-axis where all cells simply * "span over" a given x-axis coordinate. */ reduceX: function() { // Determine duplicate cell sets on x-axis. var xRemoves = [], x = 1, y, length = this.cellArrays[0].length; while (x < length) { y = 0; var identical = true; while (y < this.cellArrays.length) { if (this.cellArrays[y][x] != this.cellArrays[y][x - 1]) { identical = false; break; } ++y; } if (identical) { xRemoves[x] = true; } ++x; } // If no reductions are necessary on the x-axis, do nothing. if (xRemoves.length === 0) { return; } for (var removedX = this.gridXSize - 1; removedX >= 1; --removedX) { if (!xRemoves[removedX]) { continue; } for (y = 0; y < this.gridYSize; ++y) { if (y === 0 || this.cellArrays[y][removedX - 1] != this.cellArrays[y - 1][removedX - 1]) { // Reduce x-span, taking care not to reduce it multiple times if cell has a y-span. if (this.cellArrays[y][removedX - 1] != null) { --this.cellArrays[y][removedX - 1].xSpan; } } this.cellArrays[y].splice(removedX, 1); } var removedXExtent = this.xExtents.splice(removedX, 1)[0]; if (removedXExtent) { this.xExtents[removedX - 1] = this.addExtents(this.xExtents[removedX - 1], removedXExtent, this.horizontalOrientation ? true : false); } --this.gridXSize; } }, /** * Remove duplicates from the y-axis where all cells simply * "span over" a given y-axis coordinate. */ reduceY: function() { var yRemoves = [], y = 1, x, size = this.cellArrays.length, previousCellArray, currentCellArray = this.cellArrays[0]; while (y < size) { previousCellArray = currentCellArray; currentCellArray = this.cellArrays[y]; x = 0; var identical = true; while (x < currentCellArray.length) { if (currentCellArray[x] != previousCellArray[x]) { identical = false;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -