UNPKG

sbis3-node-ws

Version:

Модуль позволяет использовать ядро интерфейсного фреймворка sbis3-ws(`core.js`) и модуль работы с данными (`Source.js`) в приложении на nodejs.

1,406 lines (1,158 loc) 44.9 kB
/** * DivTable layout engine. * @author smirnovdm */ define('Core/dt_layout', function() { (function ($){ 'use strict'; $.dtLayoutEngine = true; $.dtPostFilter = function (options){ if (!options) options = {}; var filters = $.dtPostFilter.filters, i, ln; if (filters === undefined){ dt_JS_VAlignFilter(options); dt_JS_HAlignFilter(options); } else { for (i = 0, ln = filters.length; i < ln; i++) { filters[i].apply(options); } } }; var getClasses_rclass = /[\n\t\r]/g, isHidden_rclass = /\bws-hidden\b/g; function getClasses(element) { return (" " + element.className + " ").replace(getClasses_rclass, " "); } function memoize0(obj, func, cachedFuncName) { return function() { var res = func.call(obj); obj[cachedFuncName] = function() { return res; }; return res; }; } // вызывать только для auto-sized элементов $.fn.getNativeWidth = function fn_getNativeWidth (){ var element = this[0], classes = getClasses(element); if (classes.indexOf(' ws-art-rectangle ') !== -1 || classes.indexOf(' ws-art-border ') !== -1) { return 0; } var nativeWidth = 0; if (classes.indexOf(' ws-labeled-control ') !== -1) {// отдельная обработка контрола с меткой var ctrl = this.find('[wscontrol="true"]'); if (ctrl.length === 1) { ctrl = ctrl.wsControl(); nativeWidth = ctrl._isContainerInsideParent() ? ctrl.getMinWidth() : 0; } } else if (element.getAttribute('HorizontalAlignment') !== 'Stretch') { // TODO можно ли это сделать классами? Сперва накатить класс, потом снять var oldStyles = { 'position': this.css('position'), 'float': 'none', 'white-space': this.css('white-space'), 'width': '' }; var style = { 'float':'left', 'position':'static', 'width':'auto', 'white-space':'nowrap' }; this.css(style); nativeWidth = this.width(); this.css(oldStyles); } var margins = element.getAttribute('alignmargin'); if (margins !== null) { margins = margins.split(','); nativeWidth += ((parseInt(margins[3], 10) + parseInt(margins[1], 10)) || 0); } return nativeWidth; }; // вызывать только для auto-sized элементов $.fn.getNativeHeight = function fn_getNativeHeight (){ var element = this[0], classes = getClasses(element); if (classes.indexOf(' ws-art-rectangle ') !== -1 || classes.indexOf(' ws-art-border ') !== -1) { return 0; } var nativeHeight = 0; if (classes.indexOf(' ws-labeled-control ') !== -1) {// отдельная обработка контрола с меткой var ctrl = this.find('[wscontrol="true"]'); if (ctrl.length === 1) { ctrl = ctrl.wsControl(); nativeHeight = ctrl._isContainerInsideParent() ? ctrl.getMinHeight() : 0; } } else if (element.getAttribute('VerticalAlignment') !== 'Stretch') { var oldStyles = { 'position': this.css('position'), 'float': 'none', 'white-space': this.css('white-space'), 'width': '' }; var style = { 'float':'left', 'position':'static', 'width':'auto', 'white-space':'nowrap' }; this.css(style); nativeHeight = this.height(); this.css(oldStyles); } var margins = element.getAttribute('alignmargin'); if (margins !== null) { margins = margins.split(','); nativeHeight += ((parseInt(margins[0], 10) + parseInt(margins[2], 10)) || 0); } return nativeHeight; }; function dt_JS_VAlignFilter(options) { var selector = '.dt_verticalCenter,.dt_grid[verticalalignment="Stretch"],.dt_layout[verticalalignment="Stretch"]', elements = options.dom !== undefined ? $(options.dom).find(selector) : $(selector), i, ln = elements.length; for (i = 0; i < ln; i++ ) { var element = elements[i], jqElement, classes = getClasses(element), margin, isAbsolute; if (element.getAttribute('wscontrol') !== 'true' && (classes.indexOf(' dt_grid ') !== -1 || classes.indexOf(' dt_layout ') !== -1)) { jqElement = $(element); var maxSize = parseInt(jqElement.css('max-height'), 10); if (!isNaN(maxSize)) { isAbsolute = jqElement.css('position') === 'absolute'; var parentHeight = jqElement.parent().outerHeight(), tPos = '', tbMargin, cssParam = isAbsolute ? 'margin-top' : 'padding-top'; margin = element.getAttribute('alignMargin'); if (margin !== null) { margin = margin.split(','); tbMargin = (parseInt(margin[0], 10) + parseInt(margin[2], 10)) || 0; } else tbMargin = 0; if ((parentHeight - tbMargin) > maxSize) tPos = Math.round((parentHeight - tbMargin - jqElement.outerHeight()) / 2); jqElement.css(cssParam, tPos); } } else if (classes.indexOf(' dt_verticalCenter ') !== -1) { jqElement = $(element); jqElement.css('bottom', 'auto'); isAbsolute = jqElement.css('position') === 'absolute'; var cssData = { 'top': '50%'}, cssProperty = isAbsolute ? 'margin-top' : 'padding-top', containerHeight = jqElement.outerHeight(); margin = element.getAttribute('alignMargin'); if (margin !== null) { margin = margin.split(','); containerHeight -= Math.round(parseInt(margin[0], 10) || 0); // top containerHeight += Math.round(parseInt(margin[2], 10) || 0); // bottom } cssData[cssProperty] = -Math.round((containerHeight) / 2); jqElement.css(cssData); } } } function dt_JS_HAlignFilter(options){ var selector = '.dt_horizontalCenter,.dt_grid[horizontalalignment="Stretch"],.dt_layout[horizontalalignment="Stretch"]', elements = options.dom !== undefined ? $(options.dom).find(selector) : $(selector), i, ln = elements.length; for (i = 0; i < ln; i++ ) { var element = elements[i], jqElement, classes = getClasses(element), margin, isAbsolute; if (element.getAttribute('wscontrol') !== 'true' && (classes.indexOf(' dt_grid ') !== -1 || classes.indexOf(' dt_layout ') !== -1)) { jqElement = $(element); var maxSize = parseInt(jqElement.css('max-width'), 10); if (!isNaN(maxSize)) { isAbsolute = jqElement.css('position') === 'absolute'; var parentWidth = jqElement.parent().outerWidth(), tPos = '', cssParam = isAbsolute ? 'margin-left' : 'padding-left', lrMargin; margin = element.getAttribute('alignMargin'); if (margin !== null) { margin = margin.split(','); lrMargin = (parseInt(margin[1], 10) + parseInt(margin[3], 10)) || 0; } else lrMargin = 0; if ((parentWidth - lrMargin) > maxSize) tPos = Math.round((parentWidth - lrMargin - jqElement.outerWidth()) / 2); jqElement.css(cssParam, tPos); } } else if (classes.indexOf(' dt_horizontalCenter ') !== -1) { jqElement = $(element); isAbsolute = jqElement.css('position') === 'absolute'; if (isAbsolute) { jqElement.css('right', 'auto'); var nativeWidth = jqElement.outerWidth(); margin = element.getAttribute('alignMargin'); if (margin !== null) { margin = margin.split(','); nativeWidth -= (parseInt(margin[3], 10) || 0); // left nativeWidth += (parseInt(margin[1], 10) || 0); // right } var marginLeft = - Math.round((nativeWidth) / 2); jqElement.css('margin-left', marginLeft); jqElement.css('left', '50%'); } } } } /** * @constructor */ function dt_Container(owner, config){ var dom, domEl, domElClassList, domStyle; dom = owner.getContainer(); domEl = dom[0]; domElClassList = domEl.classList, domStyle = domEl.style; var isElHidden = domElClassList !== void(0) ? function () { return domElClassList.contains('ws-hidden'); } : function () { return isHidden_rclass.test(domEl.className); } ; function getDomWidth() { var offsetWidth = domEl.offsetWidth; if (offsetWidth === 0) { //Хак: иногда пересчёт глючит даже на видимом элементе, надо его заставить сработать... if (!isElHidden()) { var oldVis = domStyle.visibility; domStyle.visibility = 'hidden'; offsetWidth = domEl.offsetWidth; domStyle.visibility = oldVis; } } return offsetWidth - this.getPaddingBorderWidth(); } function getDomHeight() { return domEl.offsetHeight; } //offsetHeight - потому что там раньше был outerHeight() - а он такой же (кроме случая с невидимостью) var result = { getPaddingBorderWidth: null, getMargin: function(name) { var margins, wsMargin = dom.attr('alignMargin'); if (wsMargin) { wsMargin = wsMargin.split(','); margins = {top: parseInt(wsMargin[0], 10) || 0, right: parseInt(wsMargin[1], 10) || 0, bottom: parseInt(wsMargin[2], 10) || 0, left: parseInt(wsMargin[3], 10) || 0}; } else margins = {top: 0, right: 0, bottom: 0, left: 0}; this.getMargin = function(name) { return margins[name]; }; return margins[name]; }, reset: function() { this.getFixedWidth = memoize0(this, this._getFixedWidth, 'getFixedWidth'); this.getFixedHeight = memoize0(this, this._getFixedHeight, 'getFixedHeight'); this.getWidth = memoize0(this, this._getWidth, 'getWidth'); this.getHeight = memoize0(this, this._getHeight, 'getHeight'); this._getDomWidth = memoize0(this, getDomWidth, '_getDomWidth'); this._getDomHeight = memoize0(this, getDomHeight, '_getDomHeight'); this.isFixedWidth = memoize0(this, this._isFixedWidth, 'isFixedWidth'); this.isFixedHeight = memoize0(this, this._isFixedHeight, 'isFixedHeight'); }, resetResizer: function() { this.getResizerHeight = memoize0(this, this._getResizerHeight, 'getResizerHeight'); }, _getDomWidth: null, _getDomHeight: null, getFixedWidth: null, _getFixedWidth: function() { var fixedWidth = null; if (dom.hasClass('dt_fixedWidth')) { if (owner) { fixedWidth = owner._getFixedWidth(); } else { fixedWidth = this._getDomWidth(); } } return fixedWidth; }, getFixedHeight: null, _getFixedHeight: function() { var fixedHeight = null; if (dom.hasClass('dt_fixedHeight')) { if (owner) { fixedHeight = owner._getFixedHeight(); } else { fixedHeight = this._getDomHeight(); } } return fixedHeight; }, Dom: dom, getWidth: null, _getWidth: function() { var width = this.getFixedWidth(); if (width) { return width; } if(!owner || owner.getAlignment().horizontalAlignment === "Stretch"){ // Ширина на полную // При stretch по родителю можно сразу брать размер контейнера return this._getDomWidth(); } // Автоширина // Возвращается 0, чтобы посчитать авторазмеры: // fixedsize ячейки останутся fixed // autosize - встанут по контенту // starsize - схлопнется до 0 return 0; }, getResizerHeight: null, _getResizerHeight: function() { var resizer = owner && owner.getResizer(); return resizer && $ws.helpers.getElementCachedDim(resizer, 'height'); }, getHeight: null, _getHeight: function() { var height = this.getFixedHeight(); if (height) { return height; } if(!owner || owner.getAlignment().verticalAlignment === "Stretch"){ // Высота на полную return this._getDomHeight(); } return 0; }, _isFixedHeight: function() { return !!this.getFixedHeight(); }, isFixedHeight: null, _isFixedWidth: function() { return !!this.getFixedWidth(); }, isFixedWidth: null }; result.getPaddingBorderWidth = memoize0(result, function() { return (parseFloat( dom.css("paddingLeft") ) || 0) + (parseFloat( dom.css("paddingRight") ) || 0) + (parseFloat( dom.css("borderLeftWidth" ) ) || 0) + (parseFloat( dom.css("borderRightWidth" ) ) || 0); }, 'getPaddingBorderWidth'); return result; } /** * @constructor */ function dt_Layout(config){ var _rows, _cellsNameHash, layoutApi, rowCache = {}, colCache = {}, rowCount = config.getRowCount(), colCount = config.getColCount(), container = config.getContainer(), strategy = config.getStrategy(), columnControlWidths = new Array(colCount), rowControlHeights = new Array(rowCount); var getCells = function() { var configs = config.getCellsConfigs(), i, ln, c, cfg, _cells; _cells = []; _rows = {}; _cellsNameHash = {}; for (i = 0, ln = configs.length; i < ln; i++) { cfg = configs[i]; c = new dt_Cell(cfg, layoutApi); _cells.push(c); if (_rows[cfg.top] === undefined) _rows[cfg.top] = []; _rows[cfg.top].push(c); _cellsNameHash[cfg.name] = c; } getCells = function() { return _cells; }; return _cells; }; var getRows = function() { if (_rows === undefined) getCells(); var i, cln, j, row, cell, found; for (i in _rows) { if (!_rows.hasOwnProperty(i)) continue; row = _rows[i]; found = false; for (j = 0, cln = row.length; j < cln; j++) { cell = row[j]; row.haveControlsWithHeightDependsOnWidth = found = cell.haveControlsWithHeightDependsOnWidth(); if (found) break; } } getRows = function() { return _rows; }; return _rows; }; function settingWidth(){ var rows = getRows(), containerWidth = container.getWidth(), realWidths = strategy.getWidthValues(layoutApi, columnControlWidths); for (var rowNum = 0; rowNum < rowCount; rowNum++) { var thisRow = rows[rowNum]; for (var i = 0, l = thisRow.length; i < l; i++) { var cell = thisRow[i]; var cellConfig = cell.Config; var realWidth = 0; for (var left = cellConfig.left, l2 = cellConfig.right; left <= l2; left++) { realWidth += realWidths[left]; } cell.setWidth(realWidth); var leftPosition = (cellConfig.left > 0 ) ? cell.getLeftSibling().RightPosition : 0; cell.setLeftPosition(leftPosition); } } return containerWidth; } function settingHeight(){ // Массив минимальных высот из конфига var realHeights = strategy.getHeightValues(layoutApi, rowControlHeights), cells = getCells(); var i, l; for (i = 0, l = cells.length; i < l; i++) { var cell = cells[i], cellHeight = 0, cellConfig = cell.Config, t, l2; for (t = cellConfig.top, l2 = cellConfig.bottom; t <= l2; t++){ cellHeight += realHeights[t]; } cell.setHeight(cellHeight); } } function settingTop() { var rows = getRows(); // Пройдем по каждой строке for (var rowNum = 0; rowNum < rowCount; rowNum++) { var thisRow = rows[rowNum]; // Для каждой строки возьмем ее ячейки for (var i = 0, l = thisRow.length; i < l; i++){ var aCell = thisRow[i]; // Получим ближайших соседей по вертикали вниз var downSiblings = aCell.getDownSiblings(); if (downSiblings) { var y = aCell.YCoordinate, // top текущей ячейки cellHeight = aCell.Height; // высота текущей ячейки // пройдем по всем соседям снизу for (var j = 0, len = downSiblings.length; j < len; j++){ // отодвинем ее нужное расстояние downSiblings[j].setYCoordinate(y + cellHeight); } } if (aCell.YCoordinate === 0) aCell.Dom.removeClass('dt_notopborder'); else aCell.Dom.addClass('dt_notopborder'); if (aCell.LeftPosition === 0) aCell.Dom.removeClass('dt_noleftborder'); else aCell.Dom.addClass('dt_noleftborder'); } } } function reset(options) { layoutApi.getMaxHeight = memoize0(layoutApi, layoutApi._getMaxHeight, 'getMaxHeight'); if (!options || !options.resetDependentHeightsOnly) layoutApi.getMaxWidth = memoize0(layoutApi, layoutApi._getMaxWidth, 'getMaxWidth'); } function resetControls(options) { var i, ln, rows, result; if (options.resetDependentHeightsOnly) { result = false; rows = getRows(); for (i = 0, ln = rowCount; i < ln; i++) { if (rows[i].haveControlsWithHeightDependsOnWidth) { result = true; rowControlHeights[i] = void(0); } } } else { for (i = 0, ln = colCount; i < ln; i++) columnControlWidths[i] = void(0); for (i = 0, ln = rowCount; i < ln; i++) rowControlHeights[i] = void(0); result = true; } return result; } function _reset(options) { var res, result = false; if (options === undefined) options = {resetControls: true, resetContainer: true, resetResizer: true}; if (options.resetControls || options.resetContainer || options.resetResizer) { reset(options); if (options.resetContainer) { result = true; container.reset(); } if (options.resetResizer) { result = true; container.resetResizer(); } if (options.resetControls) { res = resetControls(options); result = res || result; } } return result; } function _refresh(options) { var cells, i, ln, changed = false; _reset(options); cells = getCells(); settingWidth(); for (i = 0, ln = cells.length; i < ln; i++) { if (cells[i].draw({width: true, left: true})) changed = true; } settingHeight(); settingTop(); for (i = 0, ln = cells.length; i < ln; i++) { if (cells[i].draw({top: true, height: true})) changed = true; } return changed; } layoutApi = { getRowCells: function(rowNum) { if (rowCache[rowNum] === undefined) { var cells = getCells(), i, ln, res = [], cfg; for (i = 0, ln = cells.length; i < ln; i++) { cfg = cells[i].Config; if (cfg.top === rowNum && cfg.rowspan === 1) res.push(cells[i]); } rowCache[rowNum] = res; } return rowCache[rowNum]; }, getColCells: function(colNum) { if (colCache[colNum] === undefined) { var cells = getCells(), i, ln, res = [], cfg; for (i = 0, ln = cells.length; i < ln; i++) { cfg = cells[i].Config; if (cfg.left === colNum && cfg.colspan === 1) res.push(cells[i]); } colCache[colNum] = res; } return colCache[colNum]; }, getConfig: function() { return config; }, getCellByName: function(name) { if (_cellsNameHash === undefined) getCells(); this.getCellByName = function(name) { return _cellsNameHash[name]; }; return _cellsNameHash[name]; }, refresh: _refresh, reset: _reset, getContainer: function() { return container; }, applyFilters: function() { }, getMaxWidth: null, _getMaxWidth: function() { var width; // fixed Width if((width = container.getFixedWidth()) !== null){ return width; } // auto Width var realWidths = strategy.getWidthValues(layoutApi, columnControlWidths, true), i, ln; width = 0; for(i = 0, ln = realWidths.length; i < ln; i++){ width += realWidths[i]; } return width; }, getMaxHeight: null, _getMaxHeight: function () { var height; // fixed Height if((height = container.getFixedHeight()) !== null){ return height; } // auto Height var realHeights = strategy.getHeightValues(layoutApi, rowControlHeights, true); height = 0; for (var i = 0, ln = realHeights.length; i < ln; i++) { height += realHeights[i]; } return height; } }; container.Dom.data('divTable', layoutApi); return layoutApi; } /** * Получить высоту для ячеек * @param {Array} elements массив объектов dt_cell * @returns {Array} массив с вычисленными высотами ячеек */ dt_Layout.getElementsHeight = function (elements){ var maxSize = 0; for(var i = 0, l = elements.length; i < l; i++){ var height = elements[i].getNativeHeight(); if(height > maxSize){ maxSize = height; } } return maxSize; }; /** * Получить ширину для ячеек * @param {Array} elements массив объектов dt_cell * @returns array массив с вычисленными ширинами ячеек */ dt_Layout.getElementsWidth = function (elements){ var maxSize = 0; for(var i = 0, l = elements.length; i < l; i++) { var width = elements[i].getNativeWidth(); if(width > maxSize){ maxSize = width; } } return maxSize; }; /** * @constructor */ function dt_Cell(config, parent) { var _width = 0, _height = 0, _leftPx = 0, _topPx = 0, empty = config.empty, controls = [], parentConfig = parent.getConfig(), parentRowCount = parentConfig.getRowCount(), parentDisplay = parentConfig.getDisplay(), currentDimen = { top: false, left: false, width: false, height: false }, nonControlsInCell = [], borderDeltaX = 0, borderDeltaY = 0, dom, id; if (!empty) { dom = config.dom; id = dom[0].id; nonControlsInCell = dom.children($ws.helpers.NON_CTRL); controls = parentConfig.getControls()[id] || controls; } if (config['addClass']) { dom.addClass(config['addClass']); } return { haveControlsWithHeightDependsOnWidth: function() { return !!$ws.helpers.find(controls, function(control) { return (control._horizontalAlignment === 'Stretch') && control._isHeightDependentOnWidth(); }); }, draw: function dt_Cell_Draw(params){ if (empty) { this.draw = function() { return false; }; return false; } var val, changes = false, updateCss = {}; if (params['width'] === true) { val = _width - borderDeltaX; if (val < 0) val = 0; if (currentDimen['width'] !== val) { currentDimen['width'] = val; updateCss['width'] = val; changes = true; } } if (params['height'] === true) { val = _height - borderDeltaY; if (val < 0) val = 0; if (currentDimen['height'] !== val) { currentDimen['height'] = val; updateCss['height'] = val; changes = true; } } if (params['left'] === true) { if (currentDimen['left'] !== _leftPx) { currentDimen['left'] = _leftPx; updateCss['left'] = _leftPx; changes = true; } } if (params['top'] === true) { if (currentDimen['top'] !== _topPx) { currentDimen['top'] = _topPx; updateCss['top'] = _topPx; changes = true; } } if (changes) { dom.css(updateCss); } return changes; }, getNativeHeight: function (){ if (empty) { this.getNativeHeight = function() { return undefined; }; return undefined; } // getting controls in the cell var minHeight = 0, i, ln, h; for (i = 0, ln = controls.length; i < ln; i++) { h = controls[i]._isContainerInsideParent() ? controls[i].getMinHeight() : 0; if (h > minHeight) { minHeight = h; } } h = $ws.helpers.getNonControlSize(nonControlsInCell, 'Height'); if (h > minHeight){ minHeight = h; } return minHeight; }, getNativeWidth: function () { if (empty) { this.getNativeWidth = function() { return undefined; }; return undefined; } // getting controls in the cell var minWidth = 0, i, ln, w; for (i = 0, ln = controls.length; i < ln; i++) { w = controls[i]._isContainerInsideParent() ? controls[i].getMinWidth() : 0; if (w > minWidth) { minWidth = w; } } w = $ws.helpers.getNonControlSize(nonControlsInCell, 'Width'); if (w > minWidth) { minWidth = w; } return minWidth; }, Config: config, setWidth: function (width){ _width = width; this.RightPosition = _leftPx + _width; }, Height: _height, setHeight: function (height){ _height = height; this.Height = height; }, setLeftPosition: function (left){ _leftPx = left; this.LeftPosition = left; this.RightPosition = _leftPx + _width; }, RightPosition: _leftPx, getLeftSibling: function () { if(config['left'] === 0){ this.getLeftSibling = function() { return null; }; return null; } var leftSiblingName = parent.getConfig().getDisplay()[config.top][config.left - 1], myLeftSibling = parent.getCellByName(leftSiblingName); this.getLeftSibling = function() { return myLeftSibling; }; return myLeftSibling; }, getDownSiblings: function (){ var siblings = [], cfgBottom = config.bottom; for(var l = config.left, len = config.right; l <= len; l++) { if(cfgBottom != parentRowCount - 1){ var offset = 1; do { var downSiblingName = parentDisplay[config.top + offset][l]; offset++; } while(downSiblingName === config.name); siblings.push(parent.getCellByName(downSiblingName)); } } this.getDownSiblings = function() { return siblings; }; return siblings; }, setYCoordinate: function (y){ _topPx = y; this.YCoordinate = y; }, YCoordinate: _topPx, Dom: dom }; } /** * Обертка для конфига * @constructor * @param config */ function dt_Config(owner, config){ var display = config.display, rowCount = display.length, colCount = display[0].length, innerConfig = config.config; if (innerConfig === undefined) innerConfig = config.config = {columns: [], minSizes: {}, strategy: 'general'}; else { if (innerConfig.columns === undefined) innerConfig.columns = []; if (innerConfig.minSizes === undefined) innerConfig.minSizes = {}; if (innerConfig.strategy === undefined) innerConfig.strategy = 'general'; } if (config.rows === undefined){ config.rows = []; } if (config.columns === undefined){ config.columns = []; } if (config.minSizes === undefined) config.minSizes = {}; if (config.minSizes['rows'] === undefined){ config.minSizes['rows'] = []; } if (config.minSizes['columns'] === 'undefined'){ config.minSizes['columns'] = []; } var rows = config.rows, columns = config.columns, minSizes = config.minSizes, minSizesRows = minSizes.rows, minSizesCols = minSizes.columns, strategy, i; // Преобразуем строки в массив for (i = 0; i < rowCount; i++){ if (rows[i] === undefined) rows[i] = '1*'; if (minSizesRows[i] === undefined) minSizesRows[i] = 0; } for (i = 0; i < colCount; i++){ if (columns[i] === undefined) columns[i] = '1*'; if (minSizesCols[i] === undefined) minSizesCols[i] = 0; } if (innerConfig.strategy === 'general') { strategy = new GeneralStrategy(); } else { throw "Strategy " + innerConfig.strategy + " is not supported now"; } var container = new dt_Container(owner, config); return { getDisplay:function (){ return display; }, getCellsConfigs: function dt_Config_getCellsConfigs(){ var parentDom = container.Dom, cells = [], alreadyThere = [], cellConfig, emptiesNum = -1, rowNum, colNum, name; for (rowNum = 0; rowNum < rowCount; rowNum++) { for (colNum = 0; colNum < colCount; colNum++) { name = display[rowNum][colNum]; if (name !== 0) { if (alreadyThere[name] === undefined) { alreadyThere[name] = true; cellConfig = { name: name, left: colNum, top: rowNum, id: config.cells[name]['id'], dom: $(config.cells[name]['id'], parentDom) }; var right = colNum; var bottom = rowNum; var bLine = display[bottom]; while (bLine[right] !== undefined && bLine[right] === name) { right++; } cellConfig.right = --right; right = colNum; while (display[bottom] !== undefined && display[bottom][right] === name) { bottom++; } cellConfig.bottom = --bottom; cellConfig.colspan = cellConfig.right - cellConfig.left + 1; cellConfig.rowspan = cellConfig.bottom - cellConfig.top + 1; var addClass = ''; if(cellConfig.left !== 0){ addClass += 'dt_noleftborder'; } if(cellConfig.top !== 0){ addClass += ' dt_notopborder'; } cellConfig.addClass = addClass; cells.push(cellConfig); } } else{ cellConfig = { empty: true, name: emptiesNum + '', left: colNum, top: rowNum, right: colNum, bottom: rowNum, colspan: 1, rowspan: 1 }; display[rowNum][colNum] = cellConfig.name; emptiesNum--; cells.push(cellConfig); } } } this.getCellsConfigs = function() { return cells }; return cells; }, getStrategy: function (){ return strategy; }, getContainer: function (){ return container; }, getRowsConfig: function (){ return rows; }, getColumnsConfig: function (){ return columns; }, getRowCount: function (){ return rowCount; }, getColCount: function (){ return colCount; }, getControls: function dt_Config_getControls(){ var cellControls = {}; if(owner && owner.getImmediateChildControls){ var allControls = owner.getImmediateChildControls(), controlsCount = allControls.length; for(i = 0; i < controlsCount; i++){ var cell = allControls[i].getContainer().parent().closest('.dt_cell, .dt_layout'); if(cell.hasClass('dt_cell')) { var cell_id = cell[0].id; if(!cellControls[cell_id]){ cellControls[cell_id] = []; } cellControls[cell_id].push(allControls[i]); } } } this.getControls = function() { return cellControls; }; return cellControls; }, getOwner: function (){ return owner; }, getMinSizesConfig: function() { return minSizes; } } } /** * Класс GeneralNumber. Формат result = param * R + delta; * @param param * @param delta */ function GeneralNumber(param, delta){ var isFixed = param === 0; return { delta: delta, param: param, isLiquid: !isFixed, isAuto: (isFixed && delta === 0), toSimple: (isFixed ? delta : param * 100 + '%') }; } /** * * @param ar массив. пример: * '50', * '40%', * '60%', * '100' */ GeneralNumber.arrayToGenerals = function (ar){ var params = [], generalParams = [], totalFixed = 0, totalPercent = 0, i, l1, param, val, isPercent, genPercent, delta; for (i = 0, l1 = ar.length; i < l1; i++) { params[i] = {}; param = params[i]; val = ar[i]; if (typeof(val) === 'string') { isPercent = (val.charAt(val.length - 1) === '%'); } else { isPercent = false; } param.isPercent = isPercent; if (isPercent) { totalPercent += (param['value'] = parseFloat(val)); } else { totalFixed += (param['value'] = val); } } for (i = 0, l1 = params.length; i < l1; i++) { param = params[i]; if (param.isPercent) { // 100% totalPercent // x // percentValue param['value'] genPercent = param['value'] / totalPercent; delta = -(totalFixed * genPercent); generalParams.push(new GeneralNumber(genPercent, delta)); } else { generalParams.push(new GeneralNumber(0, param['value'])); } } return generalParams; }; GeneralNumber.parseGeneral = function (ar){ if(ar instanceof Array){ return new GeneralNumber(ar[0], ar[1]); } else { throw "GeneralNumber.parseGeneral: cannot parse!"; } }; function GeneralStrategy() { } GeneralStrategy.prototype.getHeightValues = function GeneralStrategy_getHeightValues (dt_layout, rowControlHeights, calcMinSize){ var dtlConfig = dt_layout.getConfig(), configArray = dtlConfig.getRowsConfig(), values = [], simples = [], fixedSimples = [], container = dt_layout.getContainer(), totalSize = container.getHeight(), minHeights = dtlConfig.getMinSizesConfig().rows, dtlOwner = dtlConfig.getOwner(), liquidAsElements = calcMinSize || (!container.isFixedHeight() && dtlOwner.getAlignment().verticalAlignment !== "Stretch"), doJob, step, i, l1, gen, resizerHeight; if (!container.isFixedHeight()) { resizerHeight = container.getResizerHeight(); if (resizerHeight) totalSize = Math.max(totalSize, resizerHeight); } var minHeight = dtlOwner._options.minHeight; if (totalSize < minHeight) { totalSize = minHeight; } function getRowHeight(i) { var res = rowControlHeights[i]; if (res === void(0)) res = rowControlHeights[i] = dt_Layout.getElementsHeight(dt_layout.getRowCells(i)); return res; } doJob = true; step = 0; while (doJob && step++ < 10) { doJob = false; // auto for (i = 0, l1 = configArray.length; i < l1; i++) { if (fixedSimples[i] !== undefined) { simples[i] = fixedSimples[i]; } else { gen = GeneralNumber.parseGeneral(configArray[i]); if (gen.isAuto) { // находим высоту строки с auto simples[i] = getRowHeight(i); } else { // Fixed or StarSize if (gen.isLiquid && liquidAsElements) { simples[i] = getRowHeight(i); } else{ simples[i] = gen.toSimple; } } } } var newGenerals = GeneralNumber.arrayToGenerals(simples); for (i = 0, l1 = newGenerals.length; i < l1; i++) { gen = newGenerals[i]; values[i] = gen.isLiquid ? Math.floor(totalSize * gen.param + gen.delta) : gen.delta; var minHeight2 = minHeights[i]; if(values[i] < minHeight2){ fixedSimples[i] = minHeight2; doJob = true; } } } return values; }; GeneralStrategy.prototype.getWidthValues = function GeneralStrategy_getWidthValues (dt_layout, colControlWidths, calcMinSize){ var dtlConfig = dt_layout.getConfig(), configArray = dtlConfig.getColumnsConfig(), values = [], simples = [], fixedSimples = [], container = dt_layout.getContainer(), totalSize = container.getWidth(), minWidths = dtlConfig.getMinSizesConfig()['columns'], dtlOwner = dtlConfig.getOwner(), minWidth = dtlOwner._options.minWidth, liquidAsElements = calcMinSize || (!container.isFixedWidth() && dtlOwner.getAlignment().horizontalAlignment !== "Stretch"), doJob, step, i, l1, gen, newGenerals; // получить минимальную ширину if (totalSize < minWidth) { totalSize = minWidth; } function getColWidth(i) { var res = colControlWidths[i]; if (res === void(0)) res = colControlWidths[i] = dt_Layout.getElementsWidth(dt_layout.getColCells(i)); return res; } doJob = true; step = 0; while (doJob && step++ < 10) { doJob = false; // auto for (i = 0, l1 = configArray.length; i < l1; i++) { if (fixedSimples[i] !== undefined){ simples[i] = fixedSimples[i]; } else { gen = GeneralNumber.parseGeneral(configArray[i]); if (gen.isAuto) {// AutoSize simples[i] = getColWidth(i); } else { // Fixed or StarSize if (gen.isLiquid && liquidAsElements) { simples[i] = getColWidth(i); } else{ simples[i] = gen.toSimple; } } } } newGenerals = GeneralNumber.arrayToGenerals(simples); for (i = 0, l1 = newGenerals.length; i < l1; i++) { gen = newGenerals[i]; values[i] = gen.isLiquid ? Math.floor(totalSize * gen.param + gen.delta) : gen.delta; if (values[i] < minWidths[i]) { fixedSimples[i] = minWidths[i]; doJob = true; } } } return values; }; $.doTable = function DT_doTable (owner, config){ if (config.firstRender === undefined) config.firstRender = true; var dtConfig = new dt_Config(owner, config); var dtLayout = new dt_Layout(dtConfig); if (config.firstRender) dtLayout.refresh(); else dtLayout.reset(); }; })(jQuery); });