📄 sync.grid.js
字号:
break; } ++x; } if (identical) { yRemoves[y] = true; } ++y; } // If no reductions are necessary on the y-axis, do nothing. if (yRemoves.length === 0) { return; } for (var removedY = this.gridYSize - 1; removedY >= 0; --removedY) { if (!yRemoves[removedY]) { continue; } // Shorten the y-spans of the cell array that will be retained to // reflect the fact that a cell array is being removed. var retainedCellArray = this.cellArrays[removedY - 1]; for (x = 0; x < this.gridXSize; ++x) { if (x === 0 || retainedCellArray[x] != retainedCellArray[x - 1]) { // Reduce y-span, taking care not to reduce it multiple times if cell has an x-span. if (retainedCellArray[x] != null) { --retainedCellArray[x].ySpan; } } } // Remove the duplicate cell array. this.cellArrays.splice(removedY, 1); // Remove size data for removed row, add value to previous if necessary. var removedYExtent = this.yExtents.splice(removedY, 1)[0]; if (removedYExtent) { this.yExtents[removedY - 1] = this.addExtents(this.yExtents[removedY - 1], removedYExtent, this.horizontalOrientation ? false : true); } // Decrement the grid size to reflect cell array removal. --this.gridYSize; } }, /** * Iterates over cells to create the cell matrix, adjusting column and row spans as of cells to ensure * that no overlap occurs between column and row spans. * Additionally determines actual y-size of grid. * * @param {Array} cells array of <code>Echo.Sync.Grid.Processor.Cell</code> instances */ renderCellMatrix: function(cells) { this.gridXSize = parseInt(this.grid.render("size", 2), 10); var x = 0, y = 0, xIndex, yIndex, yCells = this._getCellArray(y); for (var componentIndex = 0; componentIndex < cells.length; ++componentIndex) { // Set x-span to fill remaining size in the event SPAN_FILL has been specified or if the cell would // otherwise extend past the specified size. if (cells[componentIndex].xSpan == Echo.Grid.SPAN_FILL || cells[componentIndex].xSpan > this.gridXSize - x) { cells[componentIndex].xSpan = this.gridXSize - x; } // Set x-span of any cell INCORRECTLY set to negative value to 1 (note that SPAN_FILL has already been handled). if (cells[componentIndex].xSpan < 1) { cells[componentIndex].xSpan = 1; } // Set y-span of any cell INCORRECTLY set to negative value (or more likely SPAN_FILL) to 1. if (cells[componentIndex].ySpan < 1) { cells[componentIndex].ySpan = 1; } if (cells[componentIndex].xSpan != 1 || cells[componentIndex].ySpan != 1) { // Scan to ensure no y-spans are blocking this x-span. // If a y-span is blocking, shorten the x-span to not // interfere. for (xIndex = 1; xIndex < cells[componentIndex].xSpan; ++xIndex) { if (yCells[x + xIndex] != null) { // Blocking component found. cells[componentIndex].xSpan = xIndex; break; } } for (yIndex = 0; yIndex < cells[componentIndex].ySpan; ++yIndex) { var yIndexCells = this._getCellArray(y + yIndex); for (xIndex = 0; xIndex < cells[componentIndex].xSpan; ++xIndex) { yIndexCells[x + xIndex] = cells[componentIndex]; } } } yCells[x] = cells[componentIndex]; if (componentIndex < cells.length - 1) { // Move rendering cursor. var nextRenderPointFound = false; while (!nextRenderPointFound) { if (x < this.gridXSize - 1) { ++x; } else { // Move cursor to next line. x = 0; ++y; yCells = this._getCellArray(y); } nextRenderPointFound = yCells[x] == null; } } } // Store actual 'y' dimension. this.gridYSize = this.cellArrays.length; } }) }, $load: function() { this._prototypeTable = this._createPrototypeTable(); Echo.Render.registerPeer("Grid", this); }, /** * The number of columns. * @type Number */ _columnCount: null, /** * The number of rows. * @type Number */ _rowCount: null, /** * Processes a key press event (for focus navigation amongst child cells. */ _processKeyPress: function(e) { if (!this.client) { return; } var focusPrevious, focusedComponent, focusFlags, focusChild; switch (e.keyCode) { case 37: case 39: focusPrevious = this.component.getRenderLayoutDirection().isLeftToRight() ? e.keyCode == 37 : e.keyCode == 39; focusedComponent = this.client.application.getFocusedComponent(); if (focusedComponent && focusedComponent.peer && focusedComponent.peer.getFocusFlags) { focusFlags = focusedComponent.peer.getFocusFlags(); if ((focusPrevious && focusFlags & Echo.Render.ComponentSync.FOCUS_PERMIT_ARROW_LEFT) || (!focusPrevious && focusFlags & Echo.Render.ComponentSync.FOCUS_PERMIT_ARROW_RIGHT)) { focusChild = this.client.application.focusManager.findInParent(this.component, focusPrevious); if (focusChild) { this.client.application.setFocusedComponent(focusChild); Core.Web.DOM.preventEventDefault(e); return false; } } } break; case 38: case 40: focusPrevious = e.keyCode == 38; focusedComponent = this.client.application.getFocusedComponent(); if (focusedComponent && focusedComponent.peer && focusedComponent.peer.getFocusFlags) { focusFlags = focusedComponent.peer.getFocusFlags(); if ((focusPrevious && focusFlags & Echo.Render.ComponentSync.FOCUS_PERMIT_ARROW_UP) || (!focusPrevious && focusFlags & Echo.Render.ComponentSync.FOCUS_PERMIT_ARROW_DOWN)) { focusChild = this.client.application.focusManager.findInParent(this.component, focusPrevious, this._columnCount); if (focusChild) { this.client.application.setFocusedComponent(focusChild); Core.Web.DOM.preventEventDefault(e); return false; } } } break; } return true; }, /** @see Echo.Render.ComponentSync#renderAdd */ renderAdd: function(update, parentElement) { var gridProcessor = new Echo.Sync.Grid.Processor(this.component), defaultInsets = Echo.Sync.Insets.toCssValue(this.component.render("insets", 0)), defaultBorder = this.component.render("border", ""), width = this.component.render("width"), height = this.component.render("height"), td, columnIndex; this._columnCount = gridProcessor.getColumnCount(); this._rowCount = gridProcessor.getRowCount(); this._table = Echo.Sync.Grid._prototypeTable.cloneNode(true); this._table.id = this.component.renderId; Echo.Sync.renderComponentDefaults(this.component, this._table); Echo.Sync.Border.render(defaultBorder, this._table); this._table.style.padding = defaultInsets; // Render percent widths using measuring for IE to avoid potential horizontal scrollbars. if (width && Core.Web.Env.QUIRK_IE_TABLE_PERCENT_WIDTH_SCROLLBAR_ERROR && Echo.Sync.Extent.isPercent(width)) { this._renderPercentWidthByMeasure = parseInt(width, 10); width = null; } // Set overall width/height. if (width) { if (Echo.Sync.Extent.isPercent(width)) { this._table.style.width = width; } else { this._table.style.width = Echo.Sync.Extent.toCssValue(width, true); } } if (height) { if (Echo.Sync.Extent.isPercent(height)) { this._table.style.height = height; } else { this._table.style.height = Echo.Sync.Extent.toCssValue(height, false); } } // Render column widths into colgroup element. var colGroup = this._table.firstChild; for (columnIndex = 0; columnIndex < this._columnCount; ++columnIndex) { var col = document.createElement("col"); width = gridProcessor.xExtents[columnIndex]; if (width != null) { if (Echo.Sync.Extent.isPercent(width)) { col.width = width.toString(); } else { col.width = Echo.Sync.Extent.toCssValue(width, true); } } colGroup.appendChild(col); } var tbody = colGroup.nextSibling; var size = parseInt(this.component.render("size", 2), 10); var tr; var renderedComponentIds = {}; var xSpan, ySpan; if (gridProcessor.horizontalOrientation) { xSpan = "colSpan"; ySpan = "rowSpan"; } else { xSpan = "rowSpan"; ySpan = "colSpan"; } var tdPrototype = document.createElement("td"); Echo.Sync.Border.render(defaultBorder, tdPrototype); tdPrototype.style.padding = defaultInsets; tdPrototype.style.overflow = "hidden"; // Render grid layout. for (var rowIndex = 0; rowIndex < this._rowCount; ++rowIndex) { tr = document.createElement("tr"); height = gridProcessor.yExtents[rowIndex]; if (height) { tr.style.height = Echo.Sync.Extent.toCssValue(height, false); } tbody.appendChild(tr); for (columnIndex = 0; columnIndex < this._columnCount; ++columnIndex) { var cell = gridProcessor.getCell(columnIndex, rowIndex); if (cell == null) { td = document.createElement("td"); tr.appendChild(td); continue; } if (renderedComponentIds[cell.component.renderId]) { // Cell already rendered. continue; } renderedComponentIds[cell.component.renderId] = true; td = tdPrototype.cloneNode(false); if (cell.xSpan > 1) { td.setAttribute(xSpan, cell.xSpan); } if (cell.ySpan > 1) { td.setAttribute(ySpan, cell.ySpan); } var layoutData = cell.component.render("layoutData"); if (layoutData) { Echo.Sync.Insets.render(layoutData.insets, td, "padding"); Echo.Sync.Alignment.render(layoutData.alignment, td, true, this.component); Echo.Sync.FillImage.render(layoutData.backgroundImage, td); Echo.Sync.Color.render(layoutData.background, td, "backgroundColor"); } Echo.Render.renderComponentAdd(update, cell.component, td); tr.appendChild(td); } } Core.Web.Event.add(this._table, Core.Web.Env.QUIRK_IE_KEY_DOWN_EVENT_REPEAT ? "keydown" : "keypress", Core.method(this, this._processKeyPress), false); parentElement.appendChild(this._table); }, /** @see Echo.Render.ComponentSync#renderDisplay */ renderDisplay: function() { if (this._renderPercentWidthByMeasure) { this._table.style.width = ""; var tableParent = this._table.parentNode; var availableWidth = tableParent.offsetWidth; if (tableParent.style.paddingLeft) { availableWidth -= parseInt(tableParent.style.paddingLeft, 10); } if (tableParent.style.paddingRight) { availableWidth -= parseInt(tableParent.style.paddingRight, 10); } var width = ((availableWidth * this._renderPercentWidthByMeasure) / 100) - Core.Web.Measure.SCROLL_WIDTH; if (width > 0) { this._table.style.width = width + "px"; } } }, /** @see Echo.Render.ComponentSync#renderDispose */ renderDispose: function(update) { Core.Web.Event.removeAll(this._table); this._table = null; this._renderPercentWidthByMeasure = null; }, /** @see Echo.Render.ComponentSync#renderUpdate */ renderUpdate: function(update) { var element = this._table; var containerElement = element.parentNode; Echo.Render.renderComponentDispose(update, update.parent); containerElement.removeChild(element); this.renderAdd(update, containerElement); return true; }});
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -