@progress/kendo-ui
Version:
This package is part of the [Kendo UI for jQuery](http://www.telerik.com/kendo-ui) suite.
1,414 lines (1,117 loc) • 65 kB
JavaScript
module.exports =
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ({
/***/ 0:
/***/ (function(module, exports, __webpack_require__) {
__webpack_require__(1498);
module.exports = __webpack_require__(1498);
/***/ }),
/***/ 3:
/***/ (function(module, exports) {
module.exports = function() { throw new Error("define cannot be used indirect"); };
/***/ }),
/***/ 19:
/***/ (function(module, exports) {
module.exports = require("../kendo.core");
/***/ }),
/***/ 923:
/***/ (function(module, exports) {
module.exports = require("../kendo.color");
/***/ }),
/***/ 1450:
/***/ (function(module, exports) {
module.exports = require("./runtime");
/***/ }),
/***/ 1481:
/***/ (function(module, exports) {
module.exports = require("./references");
/***/ }),
/***/ 1498:
/***/ (function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(19), __webpack_require__(923), __webpack_require__(1450), __webpack_require__(1499), __webpack_require__(1481) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
})(function(){
(function(kendo) {
if (kendo.support.browser.msie && kendo.support.browser.version < 9) {
return;
}
var RangeRef = kendo.spreadsheet.RangeRef;
var UnionRef = kendo.spreadsheet.UnionRef;
var CellRef = kendo.spreadsheet.CellRef;
var Range = kendo.spreadsheet.Range;
// This is a “dynamic variable” (see Greenspun's 10th rule). It's
// bound to an array via sheet._saveModifiedFormulas (which see)
// while the callback runs. The goal is to enable external code
// to get a list of formulas or validations that have been
// adjusted as an effect of an insert/delete row/column operation,
// to be able to undo it.
//
// The reason why simply saving the state via sheet.getState() or
// range.getState() won't suffice is that an insert or delete
// operation can have far-reaching effects, like adjusting
// formulas from another sheet.
var MODIFIED_FORMULAS;
var Selection = kendo.Class.extend({
init: function(sheet) {
this._sheet = sheet;
this.selection = kendo.spreadsheet.FIRSTREF.toRangeRef();
this.originalSelection = kendo.spreadsheet.FIRSTREF.toRangeRef();
this._activeCell = kendo.spreadsheet.FIRSTREF.toRangeRef();
this.originalActiveCell = kendo.spreadsheet.FIRSTREF;
},
currentSelectionRange: function() {
return this.selection.rangeAt(this.selectionRangeIndex).toRangeRef();
},
currentOriginalNavigationRange: function() {
return this.originalSelection.rangeAt(this.selectionRangeIndex).toRangeRef();
},
currentNavigationRange: function() {
if (this.singleCellSelection()) {
return this._sheet._sheetRef;
} else {
return this.selection.rangeAt(this.selectionRangeIndex).toRangeRef();
}
},
nextNavigationRange: function() {
if (!this.singleCellSelection()) {
this.selectionRangeIndex = this.selection.nextRangeIndex(this.selectionRangeIndex);
}
return this.currentNavigationRange();
},
previousNavigationRange: function() {
if (!this.singleCellSelection()) {
this.selectionRangeIndex = this.selection.previousRangeIndex(this.selectionRangeIndex);
}
return this.currentNavigationRange();
},
activeCell: function(ref) {
if (ref) {
this.originalActiveCell = ref.first();
this._activeCell = this._sheet.unionWithMerged(ref.toRangeRef());
this._sheet.focus(ref);
this._sheet.triggerChange({ activeCell: true, selection: true });
}
return this._activeCell;
},
select: function(ref, expanded, changeActiveCell) {
if (ref) {
if (ref.eq(this.originalSelection)) {
return;
}
this._sheet.triggerSelect(new Range(ref, this._sheet));
this.originalSelection = ref;
this.selection = expanded;
if (changeActiveCell !== false) {
if (ref.isCell()) {
// when selecting part of a merged cell, i.e. A1:B2 is merged and select(B2)
// is requested, mark A1 as the actually active cell.
// https://github.com/telerik/kendo/issues/7698
this._sheet.forEachMergedCell(ref, function(merged){
ref = merged.topLeft;
});
this.activeCell(ref);
} else {
this.activeCell(this.selection.lastRange().first());
}
this.selectionRangeIndex = this.selection.size() - 1;
} else {
this._sheet.triggerChange({ selection: true });
}
}
return this.selection;
},
singleCellSelection: function() {
return this._activeCell.eq(this.selection);
}
});
var Sheet = kendo.Observable.extend({
init: function() {
kendo.Observable.prototype.init.call(this);
this._reinit.apply(this, arguments);
},
events: [
"commandRequest",
"afterInsertRow",
"afterDeleteRow",
"insertRow",
"insertColumn",
"deleteRow",
"deleteColumn",
"hideRow",
"hideColumn",
"unhideRow",
"unhideColumn",
"select"
],
_reinit: function(rowCount, columnCount, rowHeight, columnWidth, headerHeight, headerWidth, defaultCellStyle) {
defaultCellStyle = defaultCellStyle || {};
this._defaultCellStyle = {
background: defaultCellStyle.background,
color: defaultCellStyle.color,
fontFamily: defaultCellStyle.fontFamily,
fontSize: defaultCellStyle.fontSize,
italic: defaultCellStyle.italic,
bold: defaultCellStyle.bold,
underline: defaultCellStyle.underline,
wrap: defaultCellStyle.wrap,
verticalAlign: defaultCellStyle.verticalAlign,
textAlign: defaultCellStyle.textAlign
};
this._rows = new kendo.spreadsheet.Axis(rowCount, rowHeight);
this._columns = new kendo.spreadsheet.Axis(columnCount, columnWidth);
this._mergedCells = [];
this._frozenRows = 0;
this._frozenColumns = 0;
this._suspendChanges = false;
this._filter = null;
this._showGridLines = true;
this._gridLinesColor = null;
this._grid = new kendo.spreadsheet.Grid(this._rows, this._columns, rowCount, columnCount, headerHeight, headerWidth);
this._sheetRef = this._grid.normalize(kendo.spreadsheet.SHEETREF);
this._properties = new kendo.spreadsheet.PropertyBag(rowCount, columnCount, this._defaultCellStyle);
this._sorter = new kendo.spreadsheet.Sorter(this._grid, this._properties.sortable());
this._viewSelection = new Selection(this);
this._editSelection = new Selection(this);
this._formulaSelections = [];
},
_selectionState: function() {
return this._inEdit ? this._editSelection : this._viewSelection;
},
navigator: function() {
if(!this._navigator) {
this._navigator = new kendo.spreadsheet.SheetNavigator(this);
}
return this._navigator;
},
axisManager: function() {
if(!this._axisManager) {
this._axisManager = new kendo.spreadsheet.AxisManager(this);
}
return this._axisManager;
},
_name: function(value) {
if (!value) {
return this._sheetName;
}
this._sheetName = value;
return this;
},
name: function() {
return this._name();
},
_property: function(accessor, value, reason) {
if (value === undefined) {
return accessor();
} else {
accessor(value);
return this.triggerChange(reason);
}
},
_field: function(name, value, reason) {
if (value === undefined) {
return this[name];
} else {
this[name] = value;
return this.triggerChange(reason);
}
},
suspendChanges: function(value) {
if (value === undefined) {
return this._suspendChanges;
}
this._suspendChanges = value;
return this;
},
triggerChange: function(reason) {
if (!this._suspendChanges) {
this.trigger("change", reason);
}
return this;
},
triggerSelect: function(range) {
this.trigger("select", { range: range });
},
setDataSource: function(dataSource, columns) {
if (this.dataSourceBinder) {
this.dataSourceBinder.destroy();
}
this.dataSourceBinder = new kendo.spreadsheet.SheetDataSourceBinder({
dataSource: dataSource,
sheet: this,
columns: columns
});
this.dataSource = this.dataSourceBinder.dataSource;
},
hideColumn: function(columnIndex) {
if (this.trigger("hideColumn", { index: columnIndex })) {
return;
}
return this._property(this._columns.hide.bind(this._columns), columnIndex, { layout: true });
},
unhideColumn: function(columnIndex) {
if (this.trigger("unhideColumn", { index: columnIndex })) {
return;
}
return this._property(this._columns.unhide.bind(this._columns), columnIndex, { layout: true });
},
isHiddenColumn: function(columnIndex) {
return this._grid._columns.hidden(columnIndex);
},
_copyRange: function(sourceRangeRef, targetRef) {
var grid = this._grid;
var rowCount = grid.rowCount;
var nextRefTopLeft = grid.normalize(sourceRangeRef.topLeft);
var nextRefBottomRight = grid.normalize(sourceRangeRef.bottomRight);
var nextIndex = nextRefTopLeft.col * rowCount + nextRefTopLeft.row;
var nextBottomIndex = nextRefBottomRight.col * rowCount + nextRefBottomRight.row;
var targetIndex = targetRef.col * rowCount + targetRef.row;
this._properties.copy(nextIndex, nextBottomIndex, targetIndex);
},
_saveModifiedFormulas: function(array, callback) {
var save = MODIFIED_FORMULAS;
MODIFIED_FORMULAS = array;
var ret = callback();
MODIFIED_FORMULAS = save;
return ret;
},
_restoreModifiedFormulas: function(array) {
var wb = this._workbook;
array.forEach(function(f){
var sheet = wb.sheetByName(f.sheet), index;
if (f instanceof kendo.spreadsheet.calc.runtime.Formula) {
index = sheet._grid.cellRefIndex(f); // f has row, col
sheet._properties.set("formula", index, index, f);
}
if (f instanceof kendo.spreadsheet.validation.Validation) {
index = sheet._grid.cellRefIndex(f); // f has row, col
sheet._properties.set("validation", index, index, f);
}
});
},
_adjustReferences: function(operation, start, delta, mergedCells) {
this._mergedCells = mergedCells.reduce(function(a, ref){
ref = ref.adjust(null, null, null, null, operation == "row", start, delta);
if (ref instanceof RangeRef) {
a.push(ref);
}
return a;
}, []);
if (this._workbook) {
var affectedSheet = this._name();
this._workbook._sheets.forEach(function(sheet){
sheet._forFormulas(function(formula){
var prev = formula.adjust(affectedSheet, operation, start, delta);
if (prev && MODIFIED_FORMULAS) {
// if formula.adjust returns non-null,
// that means the formula was indeed
// modified and the returned value is a
// copy of the previous Formula, which we
// can use for undoing the operation.
MODIFIED_FORMULAS.push(prev);
}
});
sheet._forValidations(function(validation){
var prev = validation.adjust(affectedSheet, operation, start, delta);
if (prev && MODIFIED_FORMULAS) {
MODIFIED_FORMULAS.push(prev);
}
});
});
this._workbook.adjustNames(affectedSheet, operation == "row", start, delta);
}
var selection = this.select();
selection = selection.adjust(null, null, null, null, operation == "row", start, delta);
if (selection !== kendo.spreadsheet.NULLREF) {
this.select(selection);
}
// adjust column widths or row heights and hidden attribute
var axis = operation == "col" ? this._columns : this._rows;
axis.adjust(start, delta);
},
_forFormulas: function(callback) {
var props = this._properties;
var formulas = props.get("formula").values();
var n = formulas.length;
formulas.forEach(function(f, i){
callback.call(this, f.value, i, n);
}, this);
},
_forValidations: function(callback) {
var props = this._properties;
props.get("validation").values().forEach(function(v){
callback.call(this, v.value);
}, this);
},
preventInsertRow: function(rowIndex, count) {
if (this.selectedHeaders().allRows) {
return { reason: "error", type: "insertRowWhenColumnIsSelected" };
}
count = count || 1;
var grid = this._grid;
var range = this.range(grid.rowCount - count, 0, count, grid.columnCount);
//TODO: Improve has value to return true only if real value is available?
if (range.hasValue()) {
return { reason: "error", type: "shiftingNonblankCells" };
}
return false;
},
preventInsertColumn: function(colIndex, count) {
if (this.selectedHeaders().allCols) {
return { reason: "error", type: "insertColumnWhenRowIsSelected" };
}
count = count || 1;
var grid = this._grid;
var range = this.range(0, grid.columnCount - count, grid.rowCount, count);
//TODO: Improve has value to return true only if real value is available?
if (range.hasValue()) {
return { reason: "error", type: "shiftingNonblankCells" };
}
return false;
},
insertRow: function(rowIndex) {
var result = this.preventInsertRow(rowIndex);
if (result) {
throw new Error("Shifting nonblank cells off the worksheet is not supported!");
}
if (this.trigger("insertRow", { index: rowIndex })) {
return;
}
this.batch(function() {
var grid = this._grid;
var columnCount = grid.columnCount;
var rowCount = grid.rowCount;
var frozenRows = this.frozenRows();
if (rowIndex < frozenRows) {
this.frozenRows(frozenRows + 1);
}
var mergedCells = this._mergedCells.slice();
for (var ci = 0; ci < columnCount; ci++) {
var ref = new RangeRef(new CellRef(rowIndex, ci), new CellRef(rowIndex, ci));
var topLeft = grid.normalize(ref.topLeft);
var bottomRight = grid.normalize(ref.bottomRight);
var nextRef = new RangeRef(
new CellRef(topLeft.row, topLeft.col),
new CellRef(rowCount - 2, bottomRight.col)
);
this._copyRange(nextRef, new CellRef(topLeft.row + 1, topLeft.col));
new Range(ref, this).clear({ clearAll: true, keepBorders: true });
}
this._adjustReferences("row", rowIndex, 1, mergedCells);
}, {
recalc: true,
layout: true,
insertRow: { index: rowIndex },
ref: new RangeRef(new CellRef(rowIndex, 0), new CellRef(Infinity, Infinity))
});
this.trigger("afterInsertRow", { index: rowIndex });
return this;
},
isEnabledRow: function(rowIndex) {
var ref = new RangeRef(new CellRef(rowIndex, 0), new CellRef(rowIndex, this._grid.columnCount));
return new Range(ref, this).enable();
},
deleteRow: function(rowIndex) {
if (!this.isEnabledRow(rowIndex)) {
return this;
}
if (this.trigger("deleteRow", { index: rowIndex })) {
return;
}
this.batch(function() {
var grid = this._grid;
var columnCount = grid.columnCount;
var frozenRows = this.frozenRows();
if (rowIndex < frozenRows) {
this.frozenRows(frozenRows - 1);
}
var mergedCells = this._mergedCells.slice();
for (var ci = 0; ci < columnCount; ci++) {
var ref = new RangeRef(new CellRef(rowIndex, ci), new CellRef(rowIndex, ci));
new Range(ref, this).clear({ clearAll: true, keepBorders: true });
var topLeft = grid.normalize(ref.topLeft);
var bottomRight = grid.normalize(ref.bottomRight);
var nextRef = new RangeRef(
new CellRef(topLeft.row + 1, topLeft.col),
new CellRef(Infinity, bottomRight.col)
);
this._copyRange(nextRef, topLeft);
var nextRefBottomRight = grid.normalize(nextRef.bottomRight);
new Range(new RangeRef(nextRefBottomRight, nextRefBottomRight), this).clear();
}
this._adjustReferences("row", rowIndex, -1, mergedCells);
}, {
recalc: true,
layout: true,
deleteRow: { index: rowIndex },
ref: new RangeRef(new CellRef(rowIndex, 0), new CellRef(Infinity, Infinity))
});
this.trigger("afterDeleteRow", { index: rowIndex });
return this;
},
insertColumn: function(columnIndex) {
if (this.trigger("insertColumn", { index: columnIndex })) {
return;
}
this.batch(function() {
var grid = this._grid;
var columnCount = grid.columnCount;
var frozenColumns = this.frozenColumns();
if (columnIndex < frozenColumns) {
this.frozenColumns(frozenColumns + 1);
}
var mergedCells = this._mergedCells.slice();
for (var ci = columnCount; ci >= columnIndex; ci--) {
var ref = new RangeRef(new CellRef(0, ci), new CellRef(Infinity, ci));
new Range(ref, this).clear({ clearAll: true, keepBorders: true });
if (ci == columnIndex) {
break;
}
var topLeft = grid.normalize(ref.topLeft);
var bottomRight = grid.normalize(ref.bottomRight);
var nextRef = new RangeRef(
new CellRef(topLeft.row, topLeft.col - 1),
new CellRef(bottomRight.row, bottomRight.col - 1)
);
this._copyRange(nextRef, topLeft);
}
this._adjustReferences("col", columnIndex, 1, mergedCells);
}, {
recalc: true,
layout: true,
insertColumn: { index: columnIndex },
ref: new RangeRef(new CellRef(0, columnIndex), new CellRef(Infinity, Infinity))
});
return this;
},
isEnabledColumn: function(columnIndex) {
var ref = new RangeRef(new CellRef(0, columnIndex), new CellRef(Infinity, columnIndex));
return new Range(ref, this).enable();
},
deleteColumn: function(columnIndex) {
if (!this.isEnabledColumn(columnIndex)) {
return this;
}
if (this.trigger("deleteColumn", { index: columnIndex })) {
return;
}
this.batch(function() {
var grid = this._grid;
var columnCount = grid.columnCount;
var frozenColumns = this.frozenColumns();
if (columnIndex < frozenColumns) {
this.frozenColumns(frozenColumns - 1);
}
var mergedCells = this._mergedCells.slice();
for (var ci = columnIndex; ci < columnCount; ci++) {
var ref = new RangeRef(new CellRef(0, ci), new CellRef(Infinity, ci));
new Range(ref, this).clear({ clearAll: true, keepBorders: true });
if (ci == columnCount - 1) {
break;
}
var topLeft = grid.normalize(ref.topLeft);
var bottomRight = grid.normalize(ref.bottomRight);
var nextRef = new RangeRef(
new CellRef(topLeft.row, topLeft.col + 1),
new CellRef(bottomRight.row, bottomRight.col + 1)
);
this._copyRange(nextRef, topLeft);
}
this._adjustReferences("col", columnIndex, -1, mergedCells);
}, {
recalc: true,
layout: true,
deleteColumn: { index: columnIndex },
ref: new RangeRef(new CellRef(0, columnIndex), new CellRef(Infinity, Infinity))
});
return this;
},
hideRow: function(rowIndex) {
if (this.trigger("hideRow", { index: rowIndex })) {
return;
}
return this._property(this._rows.hide.bind(this._rows), rowIndex, { layout: true });
},
unhideRow: function(rowIndex) {
if (this.trigger("unhideRow", { index: rowIndex })) {
return;
}
return this._property(this._rows.unhide.bind(this._rows), rowIndex, { layout: true });
},
isHiddenRow: function(rowIndex) {
return this._grid._rows.hidden(rowIndex);
},
columnWidth: function(columnIndex, width) {
return this._property(this._columns.value.bind(this._columns, columnIndex, columnIndex), width, { layout: true });
},
rowHeight: function(rowIndex, height) {
return this._property(this._rows.value.bind(this._rows, rowIndex, rowIndex), height, { layout: true });
},
frozenRows: function(value) {
return this._field("_frozenRows", value, { layout: true });
},
frozenColumns: function(value) {
return this._field("_frozenColumns", value, { layout: true });
},
showGridLines: function(value) {
return this._field("_showGridLines", value, { layout: true });
},
gridLinesColor: function(value) {
return this._field("_gridLinesColor", value, { layout: true });
},
_ref: function(row, column, numRows, numColumns) {
var ref = null;
if (row instanceof kendo.spreadsheet.Ref) {
return row;
}
if (row instanceof kendo.spreadsheet.Range) {
return row._ref.toRangeRef();
}
if (typeof row === "string") {
ref = kendo.spreadsheet.calc.parseReference(row);
} else {
if (!numRows) {
numRows = 1;
}
if (!numColumns) {
numColumns = 1;
}
ref = new RangeRef(new CellRef(row, column), new CellRef(row + numRows - 1, column + numColumns - 1));
}
return ref;
},
range: function(row, column, numRows, numColumns) {
return new Range(this._ref(row, column, numRows, numColumns), this);
},
_getMergedCells: function(range) {
var grid = this._grid;
var primary = {};
var secondary = {};
var hasMerged = false;
this.forEachMergedCell(range, function(ref) {
var topLeft = ref.topLeft;
grid.forEach(ref, function(cellRef) {
if (topLeft.eq(cellRef)) {
primary[cellRef.print()] = ref;
hasMerged = true;
} else if (range.contains(cellRef)) {
secondary[cellRef.print()] = topLeft;
hasMerged = true;
}
});
});
return { primary: primary, secondary: secondary, hasMerged: hasMerged };
},
forEachMergedCell: function(ref, callback) {
var selectAll = false;
if (typeof callback === "undefined") {
callback = ref;
selectAll = true;
}
this._mergedCells.forEach(function(merged) {
if (selectAll || merged.intersects(ref)) {
callback(merged);
}
});
},
forEachFilterHeader: function(ref, callback) {
var selectAll = false;
if (typeof callback === "undefined") {
callback = ref;
selectAll = true;
}
if (this._filter) {
var refs = [];
// get refs of all columns
this._filter.ref.forEachColumn(function(columnRef) {
if (selectAll || columnRef.intersects(ref)) {
refs.push(columnRef.topLeft);
}
});
// filter out merged references
this._mergedCells.forEach(function(merged) {
refs = refs.map(function(ref) {
if (merged.intersects(ref)) {
return merged;
}
return ref;
});
});
// use only unique refs
refs.reduce(function unique(result, element) {
if (result.indexOf(element) < 0) {
result.push(element);
}
return result;
}, []).forEach(callback);
}
},
forEach: function(ref, callback) {
function forEachRange(ref) {
if (!(ref instanceof RangeRef)) {
ref = ref.toRangeRef();
}
var topLeft = self._grid.normalize(ref.topLeft);
var bottomRight = self._grid.normalize(ref.bottomRight);
function doIt(value) {
callback(ri++, ci, value);
}
for (var ci = topLeft.col; ci <= bottomRight.col; ci++) {
var ri = topLeft.row;
var startCellIndex = self._grid.index(ri, ci);
var endCellIndex = self._grid.index(bottomRight.row, ci);
self._properties.forEach(startCellIndex, endCellIndex, doIt);
}
}
var self = this;
if (!(ref instanceof RangeRef)) {
ref = self._ref(ref);
}
if (ref instanceof UnionRef) {
// _ref() might still return a UnionRef, for instance, if
// `ref` happens to be one. Probably an oversight, but it
// turns out to be useful.
ref.forEach(forEachRange);
} else {
forEachRange(ref);
}
},
startResizing: function(initialPosition) {
this._initialPosition = initialPosition;
this._resizeInProgress = true;
},
startAutoFill: function() {
this._autoFillInProgress = true;
var selection = this.select();
this._autoFillOrigin = selection;
this._autoFillDest = selection;
this.triggerChange({ selection: true });
},
updateAutoFill: function(dest, punch, hint, direction) {
this._autoFillDest = dest;
this._autoFillPunch = punch;
this._autoFillHint = hint;
this._autoFillDirection = direction;
this.triggerChange({ selection: true });
},
autoFillRef: function() {
return this._autoFillDest;
},
autoFillPunch: function() {
return this._autoFillPunch;
},
autoFillInProgress: function() {
return this._autoFillInProgress;
},
resizingInProgress: function() {
return this._resizeInProgress;
},
completeResizing: function() {
if (this._resizeInProgress) {
this._resizeInProgress = false;
var hintPosition = this.resizeHintPosition();
if (this._initialPosition && hintPosition) {
var handlePosition = this.resizeHandlePosition();
if (handlePosition.col !== -Infinity) {
this.trigger("commandRequest", {
command: "ColumnWidthCommand",
options: {
target: handlePosition.col,
value: this.columnWidth(handlePosition.col) - (this._initialPosition.x - hintPosition.x)
}
});
} else {
this.trigger("commandRequest", {
command: "RowHeightCommand",
options: {
target: handlePosition.row,
value: this.rowHeight(handlePosition.row) - (this._initialPosition.y - hintPosition.y)
}
});
}
} else {
this.trigger("change", { resize: true });
}
}
},
resizeHandlePosition: function() {
return this._resizeHandlePosition;
},
resizeHintPosition: function(location) {
if (location !== undefined) {
this._resizeHintPosition = location;
this.trigger("change", { resize: true });
}
return this._resizeHintPosition;
},
removeResizeHandle: function() {
if (this._resizeHandlePosition) {
this._resizeHintPosition = undefined;
this._resizeHandlePosition = undefined;
this._initialPosition = undefined;
this.trigger("change", { resize: true });
}
},
positionResizeHandle: function(ref) {
this._resizeHandlePosition = ref;
this.trigger("change", { resize: true });
},
startSelection: function() {
this._selectionInProgress = true;
},
completeSelection: function() {
if (this._selectionInProgress) {
this._selectionInProgress = false;
this._resizeHintPosition = undefined;
this.trigger("change", { selection: true });
}
if (this._autoFillInProgress) {
this._autoFillInProgress = false;
var dest = this._autoFillDest;
var origin = this._autoFillOrigin;
if (this._autoFillPunch) { // we just clear data here
this.trigger("commandRequest", {
command: "ClearContentCommand", options: { operatingRange: this.range(this._autoFillPunch) }
});
} else {
if (!dest.eq(origin)) {
this.trigger("commandRequest", {
command: "AutoFillCommand", options: { operatingRange: this.range(dest), origin: this.range(origin) }
});
} else {
this.triggerChange({ selection: true });
}
}
this._autoFillDest = null;
this._autoFillPunch = null;
this._autoFillOrigin = null;
this.select(dest);
}
},
selectionInProgress: function() {
return this._selectionInProgress;
},
select: function(ref, changeActiveCell) {
var selectionState = this._selectionState();
var expandedRef;
if (ref) {
ref = this._ref(ref);
ref = this._grid.normalize(ref);
expandedRef = this._grid.isAxis(ref) ? ref : this.unionWithMerged(ref);
}
return selectionState.select(ref, expandedRef, changeActiveCell);
},
originalSelect: function() {
return this._selectionState().originalSelection;
},
currentSelectionRange: function() {
return this._selectionState().currentSelectionRange();
},
currentOriginalSelectionRange: function() {
return this._selectionState().currentOriginalNavigationRange();
},
currentNavigationRange: function() {
return this._selectionState().currentNavigationRange();
},
nextNavigationRange: function() {
return this._selectionState().nextNavigationRange();
},
previousNavigationRange: function() {
return this._selectionState().previousNavigationRange();
},
selectionRangeIndex: function() {
return this._selectionState().selectionRangeIndex;
},
activeCell: function(ref) {
return this._selectionState().activeCell(ref);
},
originalActiveCell: function() {
return this._selectionState().originalActiveCell;
},
singleCellSelection: function() {
return this._selectionState().singleCellSelection();
},
unionWithMerged: function(ref) {
var mergedCells = this._mergedCells;
return ref.map(function(ref) {
return ref.toRangeRef().union(mergedCells);
});
},
trim: function(ref) {
var trims = [];
var grid = this._grid;
this._properties.forEachProperty(function(property) {
trims.push(grid.trim(ref, property.list));
});
return this.unionWithMerged(ref.topLeft.toRangeRef().union(trims));
},
focus: function(ref) {
if (ref) {
this._focus = ref.toRangeRef();
} else {
var focus = this._focus;
this._focus = null;
return focus;
}
},
activeCellSelection: function() {
return new Range(this._grid.normalize(this.activeCell()), this);
},
selection: function() {
return new Range(this._grid.normalize(this._selectionState().selection), this);
},
selectedHeaders: function() {
var selection = this.select();
var rows = {};
var cols = {};
var allCols = false;
var allRows = false;
var maxRow = this._grid.rowCount - 1;
var maxCol = this._grid.columnCount - 1;
selection.forEach(function(ref) {
var i;
var rowState = "partial";
var colState = "partial";
ref = ref.toRangeRef();
var bottomRight = ref.bottomRight;
var topLeft = ref.topLeft;
var rowSelection = topLeft.col <= 0 && bottomRight.col >= maxCol;
var colSelection = topLeft.row <= 0 && bottomRight.row >= maxRow;
if (colSelection) { //column selection
allRows = true;
colState = "full";
}
if (rowSelection) { //row selection
allCols = true;
rowState = "full";
}
if (!colSelection) { //column selection
for (i = topLeft.row; i <= bottomRight.row; i++) {
if (rows[i] !== "full") {
rows[i] = rowState;
}
}
}
if (!rowSelection) {
for (i = topLeft.col; i <= bottomRight.col; i++) {
if (cols[i] !== "full") {
cols[i] = colState;
}
}
}
});
return {
rows: rows,
cols: cols,
allRows: allRows,
allCols: allCols,
all: allRows && allCols
};
},
isInEditMode: function(isInEdit) {
if (isInEdit === undefined) {
return this._inEdit;
}
this._inEdit = isInEdit;
if (isInEdit) {
this._editSelection.selection = this._viewSelection.selection.clone();
this._editSelection.originalSelection = this._viewSelection.originalSelection.clone();
this._editSelection._activeCell = this._viewSelection._activeCell.clone();
this._editSelection.originalActiveCell = this._viewSelection.originalActiveCell.clone();
}
},
_setFormulaSelections: function(selection) {
this._formulaSelections = (selection || []).slice();
this.triggerChange({ selection: true });
},
_viewActiveCell: function() {
return this._viewSelection._activeCell.toRangeRef();
},
toJSON: function() {
var positions = {};
var rows = this._rows.toJSON("height", positions);
var columns = this._columns.toJSON("width", {});
var viewSelection = this._viewSelection;
var hyperlinks = [];
var defaultCellStyle = this._defaultCellStyle || {};
function clearDefaultStyle(cell) {
Object.keys(defaultCellStyle).forEach(function(key){
if (cell[key] === defaultCellStyle[key]) {
delete cell[key];
}
});
}
this.forEach(kendo.spreadsheet.SHEETREF, function(row, col, cell) {
clearDefaultStyle(cell);
if (Object.keys(cell).length === 0) {
return;
}
if (cell.link) {
hyperlinks.push({
ref : kendo.spreadsheet.Ref.display(null, row, col),
target : cell.link
});
}
var position = positions[row];
if (position === undefined) {
position = rows.length;
rows.push({ index: row });
positions[row] = position;
}
row = rows[position];
cell.index = col;
if (row.cells === undefined) {
row.cells = [];
}
if (cell.formula) {
// stringify Formula object.
if (cell.formula.arrayFormulaRange) {
cell.formula = {
src: cell.formula.toString(),
ref: cell.formula.arrayFormulaRange.toString()
};
} else {
cell.formula = cell.formula.toString();
}
}
if (cell.validation) {
cell.validation = cell.validation.toJSON();
}
if (cell.color) {
cell.color = kendo.parseColor(cell.color).toCss();
}
if (cell.background) {
cell.background = kendo.parseColor(cell.background).toCss();
}
if (cell.borderTop && cell.borderTop.color) {
cell.borderTop.color = kendo.parseColor(cell.borderTop.color).toCss();
}
if (cell.borderBottom && cell.borderBottom.color) {
cell.borderBottom.color = kendo.parseColor(cell.borderBottom.color).toCss();
}
if (cell.borderRight && cell.borderRight.color) {
cell.borderRight.color = kendo.parseColor(cell.borderRight.color).toCss();
}
if (cell.borderLeft && cell.borderLeft.color) {
cell.borderLeft.color = kendo.parseColor(cell.borderLeft.color).toCss();
}
row.cells.push(cell);
});
var json = {
name: this._name(),
rows: rows,
columns: columns,
selection: viewSelection.selection.toString(),
activeCell: viewSelection.activeCell().toString(),
frozenRows: this.frozenRows(),
frozenColumns: this.frozenColumns(),
showGridLines: this.showGridLines(),
gridLinesColor: this.gridLinesColor(),
mergedCells: this._mergedCells.map(function(ref) {
return ref.toString();
}),
hyperlinks: hyperlinks,
defaultCellStyle: defaultCellStyle
};
if (this._sort) {
json.sort = {
ref: this._sort.ref.toString(),
columns: this._sort.columns.map(function(column) {
return {
index: column.index,
ascending: column.ascending
};
})
};
}
if (this._filter) {
json.filter = {
ref: this._filter.ref.toString(),
columns: this._filter.columns.map(function(column) {
var filter = column.filter.toJSON();
filter.index = column.index;
return filter;
})
};
}
return json;
},
fromJSON: function(json) {
this.batch(function() {
if (json.name !== undefined) {
this._name(json.name);
}
if (json.frozenColumns !== undefined) {
this.frozenColumns(json.frozenColumns);
}
if (json.frozenRows !== undefined) {
this.frozenRows(json.frozenRows);
}
if (json.columns !== undefined) {
this._columns.fromJSON("width", json.columns);
}
if (json.rows !== undefined) {
this._rows.fromJSON("height", json.rows);
for (var ri = 0; ri < json.rows.length; ri++) {
var row = json.rows[ri];
var rowIndex = row.index;
if (rowIndex === undefined) {
rowIndex = ri;
}
if (row.cells) {
for (var ci = 0; ci < row.cells.length; ci++) {
var cell = row.cells[ci];
var columnIndex = cell.index;
if (columnIndex === undefined) {
columnIndex = ci;
}
if (cell.formula) {
var isArray = typeof cell.formula != "string";
var src = isArray ? cell.formula.src : cell.formula;
var formula = this._compileFormula(rowIndex, columnIndex, src);
if (isArray) {
formula.setArrayFormulaRange(
kendo.spreadsheet.calc.parseReference(cell.formula.ref));
}
cell.formula = formula;
}
if (cell.validation) {
cell.validation = this._compileValidation(rowIndex, columnIndex, cell.validation);
}
this._properties.fromJSON(this._grid.index(rowIndex, columnIndex), cell);
}
}
}
}
if (json.selection) {
this._viewSelection.selection =
this.