@progress/kendo-ui
Version:
This package is part of the [Kendo UI for jQuery](http://www.telerik.com/kendo-ui) suite.
1,352 lines (1,133 loc) • 50.5 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__(1496);
module.exports = __webpack_require__(1496);
/***/ }),
/***/ 3:
/***/ (function(module, exports) {
module.exports = function() { throw new Error("define cannot be used indirect"); };
/***/ }),
/***/ 19:
/***/ (function(module, exports) {
module.exports = require("../kendo.core");
/***/ }),
/***/ 1496:
/***/ (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_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) {
'use strict';
if (kendo.support.browser.msie && kendo.support.browser.version < 9) {
return;
}
var $ = kendo.jQuery;
var alphaNumRegExp = /:alphanum$/;
var ACTIONS = {
"up": "up",
"down": "down",
"left": "left",
"right": "right",
"home": "first-col",
"ctrl+left": "first-col",
"end": "last-col",
"ctrl+right": "last-col",
"ctrl+up": "first-row",
"ctrl+down": "last-row",
"ctrl+home": "first",
"ctrl+end": "last",
"pageup": "prev-page",
"pagedown": "next-page"
};
var ENTRY_ACTIONS = {
"tab": "next",
"shift+tab": "previous",
"enter": "lower",
"shift+enter": "upper",
"delete": "clearContents",
"backspace": "clearContents",
"shift+:alphanum": "edit",
"alt+:alphanum": "edit",
":alphanum": "edit",
"ctrl+:alphanum": "ctrl",
"alt+ctrl+:alphanum": "edit",
":edit": "edit"
};
var CONTAINER_EVENTS = {
"wheel": "onWheel",
"*+mousedown": "onMouseDown",
"contextmenu": "onContextMenu",
"*+mousedrag": "onMouseDrag",
"*+mouseup": "onMouseUp",
"*+dblclick": "onDblClick",
"mousemove": "onMouseMove",
"touchmove": "onTouchMove",
"touchend": "onTouchEnd"
};
var CLIPBOARD_EVENTS = {
"pageup": "onPageUp",
"pagedown": "onPageDown",
"mouseup": "onMouseUp",
"*+cut": "onCut",
"*+paste": "onPaste",
"*+copy": "onCopy"
};
var EDITOR_EVENTS = {
"esc": "onEditorEsc",
"enter": "onEditorBlur",
"alt+enter": "insertNewline",
"shift+enter": "onEditorBlur",
"tab": "onEditorBlur",
"shift+tab": "onEditorBlur",
"shift+ctrl+enter": "onEditorArrayFormula"
};
var FORMULABAR_EVENTS = $.extend({ focus: "onEditorBarFocus" }, EDITOR_EVENTS);
var FORMULAINPUT_EVENTS = $.extend({ focus: "onEditorCellFocus" }, EDITOR_EVENTS);
var SELECTION_MODES = {
cell: "range",
rowheader: "row",
columnheader: "column",
topcorner: "sheet",
autofill: "autofill"
};
function toActionSelector(selectors) {
return selectors.map(function(action) {
return '[data-action="' + action + '"]';
}).join(",");
}
var COMPOSITE_UNAVAILABLE_ACTION_SELECTORS = toActionSelector([ 'cut', 'copy', 'paste', 'insert-left', 'insert-right', 'insert-above', 'insert-below' ]);
var UNHIDE_ACTION_SELECTORS = toActionSelector([ 'unhide-row', 'unhide-column' ]);
var ACTION_KEYS = [];
var SHIFT_ACTION_KEYS = [];
var ENTRY_ACTION_KEYS = [];
for (var key in ACTIONS) {
ACTION_KEYS.push(key);
SHIFT_ACTION_KEYS.push("shift+" + key);
}
for (key in ENTRY_ACTIONS) {
ENTRY_ACTION_KEYS.push(key);
}
CLIPBOARD_EVENTS[ACTION_KEYS] = "onAction";
CLIPBOARD_EVENTS[SHIFT_ACTION_KEYS] = "onShiftAction";
CLIPBOARD_EVENTS[ENTRY_ACTION_KEYS] = "onEntryAction";
FORMULAINPUT_EVENTS[ACTION_KEYS] = "onEditorAction";
FORMULAINPUT_EVENTS[SHIFT_ACTION_KEYS] = "onEditorShiftAction";
var Controller = kendo.Class.extend({
init: function(view, workbook) {
this.view = view;
this.workbook(workbook);
this.container = $(view.container);
this.clipboardElement = $(view.clipboard);
this.cellContextMenu = view.cellContextMenu;
this.rowHeaderContextMenu = view.rowHeaderContextMenu;
this.colHeaderContextMenu = view.colHeaderContextMenu;
this.drawingContextMenu = view.drawingContextMenu;
this.scroller = view.scroller;
this.tabstrip = view.tabstrip;
this.sheetsbar = view.sheetsbar;
view.nameEditor.bind("enter", this.onNameEditorEnter.bind(this));
view.nameEditor.bind("cancel", this.onNameEditorCancel.bind(this));
view.nameEditor.bind("select", this.onNameEditorSelect.bind(this));
view.nameEditor.bind("delete", this.onNameEditorDelete.bind(this));
this.editor = view.editor;
this.editor.bind("change", this.onEditorChange.bind(this));
this.editor.bind("activate", this.onEditorActivate.bind(this));
this.editor.bind("deactivate", this.onEditorDeactivate.bind(this));
this.editor.bind("update", this.onEditorUpdate.bind(this));
$(view.scroller).on("scroll", this.onScroll.bind(this));
this.listener = new kendo.spreadsheet.EventListener(this.container, this, CONTAINER_EVENTS);
this._enableEditorEvents();
if (this.sheetsbar) {
this.sheetsbar.bind("select", this.onSheetBarSelect.bind(this));
this.sheetsbar.bind("reorder", this.onSheetBarReorder.bind(this));
this.sheetsbar.bind("rename", this.onSheetBarRename.bind(this));
this.sheetsbar.bind("remove", this.onSheetBarRemove.bind(this));
}
this.cellContextMenu.bind("select", this.onContextMenuSelect.bind(this));
this.rowHeaderContextMenu.bind("select", this.onContextMenuSelect.bind(this));
this.colHeaderContextMenu.bind("select", this.onContextMenuSelect.bind(this));
this.drawingContextMenu.bind("select", this.onContextMenuSelect.bind(this));
// this is necessary for Windows to catch prevent context menu correctly
this.cellContextMenu.element
.add(this.rowHeaderContextMenu.element)
.add(this.colHeaderContextMenu.element)
.add(this.drawingContextMenu.element)
.on("contextmenu", false);
if (this.tabstrip) {
this.tabstrip.bind("action", this.onCommandRequest.bind(this));
this.tabstrip.bind("dialog", this.onDialogRequest.bind(this));
}
},
_enableEditorEvents: function (enable) {
if (enable === undefined || enable) {
this.keyListener = new kendo.spreadsheet.EventListener(this.clipboardElement, this, CLIPBOARD_EVENTS);
this.barKeyListener = new kendo.spreadsheet.EventListener(this.editor.barElement(), this, FORMULABAR_EVENTS);
this.inputKeyListener = new kendo.spreadsheet.EventListener(this.editor.cellElement(), this, FORMULAINPUT_EVENTS);
} else {
this.keyListener.destroy();
this.barKeyListener.destroy();
this.inputKeyListener.destroy();
}
},
_execute: function(options) {
var result = this._workbook.execute(options);
if (options.command === "EditCommand" && !result) {
this._workbook.trigger("change", { editorClose: true });
}
if (result) {
this._preventNavigation = true;
if (result.reason === "error") {
this.editor.deactivate(true); // make sure we don't call any change hooks
this.view.showError(result, function(){
// we only get here in case of a validation error when the user decided to retry.
this.activateEditor(false);
// reset to last input from user
this.editor.value(this._lastEditorValue);
// however, set _value manually such that it'll detect change properly. ugly :-\
this.editor._value = this._workbook._inputForRef(this._workbook.activeSheet()._viewActiveCell());
// seems like a nice UX to have the whole input selected
this.editor.select();
}.bind(this));
} else {
this.view.openDialog(result.reason);
}
}
return result;
},
_activeTooltip: function() {
return this._workbook.activeSheet().activeCell().simplify().toString();
},
onContextMenuSelect: function(e) {
var action = $(e.item).data("action");
var command;
switch(action) {
case "cut":
command = { command: "ToolbarCutCommand", options: { workbook: this._workbook } };
break;
case "copy":
command = { command: "ToolbarCopyCommand", options: { workbook: this._workbook } };
break;
case "paste":
command = { command: "ToolbarPasteCommand", options: { workbook: this._workbook } };
break;
case "delete-drawing":
command = { command: "DeleteDrawingCommand", options: { drawing: this.navigator._sheet._activeDrawing } };
break;
case "bring-to-front":
command = { command: "BringToFrontCommand", options: { drawing: this.navigator._sheet._activeDrawing } };
break;
case "send-to-back":
command = { command: "SendToBackCommand", options: { drawing: this.navigator._sheet._activeDrawing } };
break;
case "unmerge":
command = { command: "MergeCellCommand", options: { value: "unmerge" } };
break;
case "merge":
this.view.openDialog("merge");
break;
case "hide-row":
command = { command: "HideLineCommand", options: { axis: "row" } };
break;
case "hide-column":
command = { command: "HideLineCommand", options: { axis: "column" } };
break;
case "unhide-row":
command = { command: "UnHideLineCommand", options: { axis: "row" } };
break;
case "unhide-column":
command = { command: "UnHideLineCommand", options: { axis: "column" } };
break;
case "delete-row":
command = { command: "DeleteRowCommand" };
break;
case "delete-column":
command = { command: "DeleteColumnCommand" };
break;
}
if (command) {
this._execute(command);
}
},
onSheetBarRemove: function(e) {
var sheet = this._workbook.sheetByName(e.name);
//TODO: move to model!
if (!sheet) {
return;
}
this._workbook.removeSheet(sheet);
},
destroy: function() {
this.listener.destroy();
this._enableEditorEvents(false);
this.keyListener.destroy();
this.inputKeyListener.destroy();
},
onSheetBarSelect: function(e) {
var sheet;
var workbook = this._workbook;
if (e.isAddButton) {
if (this._workbook.trigger("insertSheet")) {
return;
}
sheet = workbook.insertSheet();
} else {
sheet = workbook.sheetByName(e.name);
}
//TODO: move to model
if (workbook.activeSheet().name() !== sheet.name()) {
if (this._workbook.trigger("selectSheet", { sheet: sheet })) {
return;
}
if (!this.editor.canInsertRef(false)) {
this.editor.deactivate();
}
workbook.activeSheet(sheet);
}
},
onSheetBarReorder: function(e) {
var sheet = this._workbook.sheetByIndex(e.oldIndex);
this._workbook.moveSheetToIndex(sheet, e.newIndex);
this._workbook.activeSheet(sheet);
},
onSheetBarRename: function(e) {
var sheet = this._workbook.sheetByIndex(e.sheetIndex);
if (this._workbook.sheetByName(e.name)) {
this.view.showError({ reason: "error", type: "duplicateSheetName" });
return;
}
this._workbook.renameSheet(sheet, e.name);
this.clipboardElement.focus();
},
sheet: function(sheet) {
this.navigator = sheet.navigator();
this.axisManager = sheet.axisManager();
},
workbook: function(workbook) {
this._workbook = workbook;
this.clipboard = workbook.clipboard();
workbook.bind("commandRequest", this.onCommandRequest.bind(this));
},
refresh: function() {
var editor = this.editor;
var workbook = this._workbook;
var sheet = workbook.activeSheet();
this._viewPortHeight = this.view.scroller.clientHeight;
this.navigator.height(this._viewPortHeight);
if (!editor.isActive() && !this.isEditorDisabled) {
editor.enable(sheet.selection().enable() !== false);
this.resetEditorValue();
}
var ref = sheet.selection()._ref.simplify();
var def = this._workbook.nameForRef(ref, sheet.name());
this.view.nameEditor.value(def.name);
},
onScroll: function() {
this.view.render({ scroll: true });
},
onWheel: function(event) {
var deltaX = event.originalEvent.deltaX;
var deltaY = event.originalEvent.deltaY;
if (event.originalEvent.deltaMode === 1) {
deltaX *= 10;
deltaY *= 10;
}
this.scrollWith(deltaX, deltaY);
event.preventDefault();
},
onTouchMove: function() {
this.view.forceScrollerStackingOrder(2);
},
onTouchEnd: function() {
this.view.forceScrollerStackingOrder(1);
},
onAction: function(event, action) {
var sheet = this._workbook.activeSheet();
sheet._activeDrawing = null;
this.navigator.moveActiveCell(ACTIONS[action]);
event.preventDefault();
},
onPageUp: function() {
this.scrollDown(-this._viewPortHeight);
},
onPageDown: function() {
this.scrollDown(this._viewPortHeight);
},
onEntryAction: function(event, action) {
var sheet = this._workbook.activeSheet();
if (event.mod) {
var shouldPrevent = true;
var key = String.fromCharCode(event.keyCode);
switch(key) {
case "A":
sheet._activeDrawing = null;
this.navigator.selectAll();
break;
case "Y":
this._workbook.undoRedoStack.redo();
break;
case "Z":
this._workbook.undoRedoStack.undo();
break;
default:
shouldPrevent = false;
break;
}
if (shouldPrevent) {
event.preventDefault();
}
} else {
var disabled = sheet.selection().enable() === false;
var casual = action !== ":edit";
if (action == "delete" || action == "backspace") {
if (sheet._activeDrawing) {
this._execute({
command: "DeleteDrawingCommand",
options: { drawing: sheet._activeDrawing }
});
} else if (!disabled) {
this._execute({ command: "ClearContentCommand" });
}
event.preventDefault();
} else if (alphaNumRegExp.test(action) || !casual) {
sheet._activeDrawing = null;
if (disabled) {
event.preventDefault();
return;
}
if (casual) {
this.editor.value("");
}
this.activateEditor(casual);
} else {
this.navigator.navigateInSelection(ENTRY_ACTIONS[action]);
event.preventDefault();
}
}
},
onShiftAction: function(event, action) {
this.navigator.modifySelection(ACTIONS[action.replace("shift+", "")], this.appendSelection);
event.preventDefault();
},
onMouseMove: function(event) {
var sheet = this._workbook.activeSheet();
if (sheet.resizingInProgress() || sheet.selectionInProgress()) {
return;
}
var object = this.objectAt(event);
if (object.type === "columnresizehandle" || object.type === "rowresizehandle") {
sheet.positionResizeHandle(object.ref);
} else {
sheet.removeResizeHandle();
}
sheet._renderComment(object.type == "cell" ? object.ref : null);
},
onMouseDown: function(event) {
var object = this.objectAt(event);
if (object.pane) {
this.originFrame = object.pane;
}
if (this._startResizingDrawing(event, object)) {
event.stopPropagation();
return;
}
var sheet = this._workbook.activeSheet();
var win = this.container.closest('[data-role="window"]');
if (win.length) {
win = kendo.widgetInstance(win);
if (win && win.options.modal) {
event.stopPropagation();
}
}
sheet._activeDrawing = null;
if (object.type === "drawing") {
sheet._activeDrawing = object.drawing;
object.copy = object.drawing.clone();
object.startBox = sheet.drawingBoundingBox(object.copy);
sheet.startDragging(object);
sheet.triggerChange({ dragging: true });
event.preventDefault();
return;
}
if (object.type === "editor") {
// XXX: canceling the edits, because they might not
// validate. Not sure it's the Right Thing.
this.onEditorEsc();
this.openCustomEditor();
event.preventDefault();
return;
}
if (this.editor.canInsertRef(false) && object.ref) {
this._workbook.activeSheet()._setFormulaSelections(this.editor.highlightedRefs());
this.navigator.startSelection(object.ref, this._selectionMode, this.appendSelection, event.shiftKey);
event.preventDefault();
return;
} else {
this._preventNavigation = false;
this.editor.deactivate();
if (this._preventNavigation) {
return; // validation error
}
}
if (object.type === "columnresizehandle" || object.type === "rowresizehandle") {
sheet.startResizing({ x: object.x, y: object.y });
event.preventDefault();
return;
}
if (object.type === "filtericon") {
this.openFilterMenu(event);
event.preventDefault();
return;
}
this._selectionMode = SELECTION_MODES[object.type];
this.appendSelection = event.mod;
this.navigator.startSelection(object.ref, this._selectionMode, this.appendSelection, event.shiftKey);
},
_startResizingDrawing: function(event) {
var handle = $(event.target).closest(".k-spreadsheet-drawing-handle");
if (handle.length) {
var location = this.translateCoords(event);
var direction = handle.data("direction");
var sheet = this._workbook.activeSheet();
var drawing = sheet._activeDrawing;
sheet.startDragging({
pane : this.originFrame,
drawing : drawing,
copy : drawing.clone(),
startBox : sheet.drawingBoundingBox(drawing),
resize : direction,
//aspect : drawing.width / drawing.height,
startX : location.x,
startY : location.y
});
return true;
}
},
onContextMenu: function(event) {
var sheet = this._workbook.activeSheet();
event.preventDefault();
if (sheet.resizingInProgress() || sheet.draggingInProgress()) {
return;
}
this.cellContextMenu.close();
this.colHeaderContextMenu.close();
this.rowHeaderContextMenu.close();
this.drawingContextMenu.close();
var menu;
var object = this.objectAt(event);
if (object.type === "columnresizehandle" || object.type === "rowresizehandle") {
return;
}
if (object.ref) {
this.navigator.selectForContextMenu(object.ref, SELECTION_MODES[object.type]);
} else if (object.type == "drawing") {
this.navigator.selectDrawingForContextMenu(object.drawing);
}
var isComposite = this.navigator._sheet.select() instanceof kendo.spreadsheet.UnionRef;
var showUnhide = false;
var showUnmerge = false;
if (object.type == "columnheader") {
menu = this.colHeaderContextMenu;
showUnhide = !isComposite && this.axisManager.selectionIncludesHiddenColumns();
} else if (object.type == "rowheader") {
menu = this.rowHeaderContextMenu;
showUnhide = !isComposite && this.axisManager.selectionIncludesHiddenRows();
} else if (object.type == "drawing") {
menu = this.drawingContextMenu;
} else {
menu = this.cellContextMenu;
showUnmerge = this.navigator.selectionIncludesMergedCells();
}
menu.element.find(COMPOSITE_UNAVAILABLE_ACTION_SELECTORS).toggle(!isComposite);
menu.element.find(UNHIDE_ACTION_SELECTORS).toggle(showUnhide);
menu.element.find('[data-action=unmerge]').toggle(showUnmerge);
// avoid the immediate close
setTimeout(function() {
menu.open(event.pageX, event.pageY);
});
},
prevent: function(event) {
event.preventDefault();
},
constrainResize: function(type, ref) {
var sheet = this._workbook.activeSheet();
var resizeHandle = sheet.resizeHandlePosition();
return !resizeHandle || type === "outside" || type === "topcorner" || ref.col < resizeHandle.col || ref.row < resizeHandle.row;
},
_dragDrawing: function(event) {
var sheet = this._workbook.activeSheet();
var drag = sheet.draggingInProgress();
if (!drag) {
return false;
}
var location = this.translateCoords(event);
var drawing = drag.drawing;
var deltaX = location.x - drag.startX;
var deltaY = location.y - drag.startY;
if (drag.resize == "SE") {
if (drag.aspect) {
if (Math.abs(deltaX) > Math.abs(deltaY)) {
drawing.width = Math.max(drag.copy.width + deltaX, 20);
drawing.height = drawing.width / drag.aspect;
} else {
drawing.height = Math.max(drag.copy.height + deltaY, 20);
drawing.width = drawing.height * drag.aspect;
}
} else {
drawing.width = Math.max(drag.copy.width + deltaX, 20);
drawing.height = Math.max(drag.copy.height + deltaY, 20);
}
}
else if (drag.resize == "E") {
drawing.width = Math.max(drag.copy.width + deltaX, 20);
}
else if (drag.resize == "S") {
drawing.height = Math.max(drag.copy.height + deltaY, 20);
}
else if (drag.resize == "N") {
if (drag.copy.height - deltaY > 20) {
drawing.height = drag.copy.height - deltaY;
drawing.offsetY = drag.copy.offsetY + deltaY;
}
}
else if (drag.resize == "W") {
if (drag.copy.width - deltaX > 20) {
drawing.width = drag.copy.width - deltaX;
drawing.offsetX = drag.copy.offsetX + deltaX;
}
}
else if (drag.resize == "NE") {
drawing.width = Math.max(drag.copy.width + deltaX, 20);
if (drag.copy.height - deltaY > 20) {
drawing.height = drag.copy.height - deltaY;
drawing.offsetY = drag.copy.offsetY + deltaY;
}
}
else if (drag.resize == "SW") {
drawing.height = Math.max(drag.copy.height + deltaY, 20);
if (drag.copy.width - deltaX > 20) {
drawing.width = drag.copy.width - deltaX;
drawing.offsetX = drag.copy.offsetX + deltaX;
}
}
else if (drag.resize == "NW") {
if (drag.copy.height - deltaY > 20) {
drawing.height = drag.copy.height - deltaY;
drawing.offsetY = drag.copy.offsetY + deltaY;
}
if (drag.copy.width - deltaX > 20) {
drawing.width = drag.copy.width - deltaX;
drawing.offsetX = drag.copy.offsetX + deltaX;
}
}
// just moving (no resize)
else {
drawing.offsetX = drag.copy.offsetX + deltaX;
drawing.offsetY = drag.copy.offsetY + deltaY;
}
sheet.triggerChange({ dragging: true });
return true;
},
onMouseDrag: function(event) {
if (this._selectionMode === "sheet") {
return;
}
var location = { clientX: event.clientX, clientY: event.clientY };
var sheet = this._workbook.activeSheet();
if (this._dragDrawing(event)) {
return;
}
var object = this.objectAt(location);
if (sheet.resizingInProgress()) {
if (!this.constrainResize(object.type, object.ref)) {
sheet.resizeHintPosition({ x: object.x, y: object.y });
}
return;
}
if (object.type === "outside") {
this.startAutoScroll(object);
return;
}
if (this.originFrame === object.pane) {
this.selectToLocation(location);
} else { // cross frame selection
var frame = this.originFrame._grid;
if (object.x > frame.right) {
this.scrollLeft();
}
if (object.y > frame.bottom) {
this.scrollTop();
}
if (object.y < frame.top || object.x < frame.left) {
this.startAutoScroll(object, location);
} else {
this.selectToLocation(location);
}
}
event.preventDefault();
},
onMouseUp: function(event) {
var sheet = this._workbook.activeSheet();
sheet.completeResizing();
sheet.completeDragging();
this.navigator.completeSelection();
this.stopAutoScroll();
var editor = this.editor.activeEditor();
if (!editor) {
return;
}
var el = event.target;
while (el) {
if (el === editor.element[0]) {
return;
}
el = el.parentNode;
}
var object = this.objectAt(event);
if (object && object.ref && editor.canInsertRef(false)) {
editor.refAtPoint(sheet);
sheet._setFormulaSelections(editor.highlightedRefs());
}
},
onDblClick: function(event) {
var object = this.objectAt(event);
var disabled = this._workbook.activeSheet().selection().enable() === false;
if (object.type !== "cell" || disabled) {
return;
}
var sel = this._workbook.activeSheet().selection();
this.activateEditor(!sel.value() && !sel.formula());
this.onEditorUpdate();
},
onCut: function(e) {
if(e){
var table = this.clipboardElement.find("table.kendo-clipboard-"+ this.clipboard._uid).detach();
this.clipboardElement.append(table.clone(false));
setTimeout(function() {
this.clipboardElement.empty().append(table);
}.bind(this));
}
this._execute({
command: "CutCommand",
options: { workbook: this.view._workbook, event: e.originalEvent || e }
});
},
clipBoardValue: function() {
return this.clipboardElement.html();
},
_pasteImage: function(dataTransferItem) {
var self = this;
var blob = dataTransferItem.getAsFile();
var img = new window.Image();
img.src = window.URL.createObjectURL(blob);
img.onload = function() {
self._execute({
command: "InsertImageCommand",
options: {
blob: blob,
width: img.width,
height: img.height
}
});
};
setTimeout(function(){
window.URL.revokeObjectURL(img.src);
}, 10);
},
onPaste: function(e) {
var self = this;
var html = "";
var plain = "";
self.clipboard.menuInvoked = (e === undefined);
if(e) {
var clipboardData = e.originalEvent.clipboardData;
if (clipboardData && clipboardData.getData) {
e.preventDefault();
var hasHTML = false;
var hasPlainText = false;
//Firefox uses DOMStringList, needs special handling
if(window.DOMStringList && clipboardData.types instanceof window.DOMStringList) {
hasHTML = clipboardData.types.contains("text/html");
hasPlainText = clipboardData.types.contains("text/plain");
} else {
hasHTML = (/text\/html/.test(clipboardData.types));
hasPlainText = (/text\/plain/.test(clipboardData.types));
}
if (hasHTML) {
html = clipboardData.getData('text/html');
}
if (hasPlainText) {
plain = clipboardData.getData('text/plain').trim();
}
if (!hasHTML && !hasPlainText && clipboardData.items && clipboardData.items.length) {
for (var i = 0; i < clipboardData.items.length; ++i) {
var item = clipboardData.items[i];
if (item.kind == "file" && /^image\/(?:png|jpe?g|gif)$/i.test(item.type)) {
return self._pasteImage(item);
}
}
}
} else {
//workaround for IE's lack of access to the HTML clipboard data
var table = self.clipboardElement.find("table.kendo-clipboard-"+ self.clipboard._uid).detach();
self.clipboardElement.empty();
setTimeout(function() {
var html = self.clipboardElement.html();
var plain = window.clipboardData.getData("Text").trim();
if(!html && !plain) {
return;
}
self.clipboard.external({html: html, plain: plain});
self.clipboardElement.empty().append(table);
self._execute({
command: "PasteCommand",
options: { workbook: self.view._workbook, event: e.originalEvent || e }
});
self.clipboard.menuInvoked = true;
});
return;
}
} else {
if (kendo.support.browser.msie) {
self.clipboardElement.focus().select();
document.execCommand('paste');
return;
} else {
self.clipboard.menuInvoked = true;
}
}
if (!html && !plain) {
return;
}
self.clipboard.external({html: html, plain:plain});
self._execute({
command: "PasteCommand",
options: { workbook: self.view._workbook, event: e.originalEvent || e }
});
},
onCopy: function(e) {
this.clipboard.menuInvoked = (e === undefined);
this._execute({
command: "CopyCommand",
options: { workbook: this.view._workbook, event: e.originalEvent || e }
});
},
////////////////////////////////////////////////////////////////////
scrollTop: function() {
this.scroller.scrollTop = 0;
},
scrollLeft: function() {
this.scroller.scrollLeft = 0;
},
scrollDown: function(value) {
this.scroller.scrollTop += value;
},
scrollRight: function(value) {
this.scroller.scrollLeft += value;
},
scrollWith: function(right, down) {
this.scroller.scrollTop += down;
this.scroller.scrollLeft += right;
},
translateCoords: function(location) {
var box = this.container[0].getBoundingClientRect();
return {
x: location.clientX - box.left,
y: location.clientY - box.top
};
},
objectAt: function(location, noDrawing) {
if (!location) {
return;
}
location = this.translateCoords(location);
return this.view.objectAt(location.x, location.y, noDrawing);
},
selectToLocation: function(cellLocation) {
var object = this.objectAt(cellLocation, true);
if (object.pane && object.ref) { // cell, rowheader or columnheader
this.extendSelection(object);
this.lastKnownCellLocation = cellLocation;
this.originFrame = object.pane;
}
this.stopAutoScroll();
},
extendSelection: function(object) {
this.navigator.extendSelection(object.ref, this._selectionMode, this.appendSelection);
},
autoScroll: function() {
var x = this._autoScrollTarget.x;
var y = this._autoScrollTarget.y;
var boundaries = this.originFrame._grid;
var scroller = this.view.scroller;
var scrollStep = 8;
var scrollLeft = scroller.scrollLeft;
var scrollTop = scroller.scrollTop;
if (x < boundaries.left) {
this.scrollRight(-scrollStep);
}
if (x > boundaries.right) {
this.scrollRight(scrollStep);
}
if (y < boundaries.top) {
this.scrollDown(-scrollStep);
}
if (y > boundaries.bottom) {
this.scrollDown(scrollStep);
}
if (scrollTop === scroller.scrollTop && scrollLeft === scroller.scrollLeft) {
this.selectToLocation(this.finalLocation);
} else {
this.extendSelection(this.objectAt(this.lastKnownCellLocation));
}
},
startAutoScroll: function(viewObject, location) {
if (!this._scrollInterval) {
this._scrollInterval = setInterval(this.autoScroll.bind(this), 50);
}
this.finalLocation = location || this.lastKnownCellLocation;
this._autoScrollTarget = viewObject;
},
stopAutoScroll: function() {
clearInterval(this._scrollInterval);
this._scrollInterval = null;
},
openCustomEditor: function() {
this.view.openCustomEditor();
},
openFilterMenu: function(event) {
var object = this.objectAt(event);
var sheet = this._workbook.activeSheet();
var column = sheet.filterColumn(object.ref);
var filterMenu = this.view.createFilterMenu(column);
filterMenu.bind("action", this.onCommandRequest.bind(this));
filterMenu.bind("action", filterMenu.close.bind(filterMenu));
filterMenu.openFor(event.target);
},
////////////////////////////////////////////////////////////////////
_saveEditorValue: function(arrayFormula) {
var sheet = this.editor._range.sheet();
var value = this.editor.value();
if (this._workbook.activeSheet() !== sheet) {
// remove highlighted refs (XXX: which are mostly wrong, BTW)
this._workbook.activeSheet()._setFormulaSelections();
// go back to the original sheet
this._workbook.activeSheet(sheet);
}
sheet.isInEditMode(false);
this._lastEditorValue = value;
this._execute({
command: "EditCommand",
options: {
value: value,
arrayFormula: arrayFormula
}
});
},
onEditorChange: function() {
this._saveEditorValue(false);
},
onEditorArrayFormula: function() {
this._saveEditorValue(true);
this.editor.deactivate(true);
},
onEditorActivate: function() {
var workbook = this._workbook;
var sheet = workbook.activeSheet();
sheet._setFormulaSelections(this.editor.highlightedRefs());
sheet.isInEditMode(true);
},
onEditorDeactivate: function() {
var sheet = this._workbook.activeSheet();
sheet.isInEditMode(false);
sheet._setFormulaSelections([]);
},
onEditorUpdate: function() {
this._workbook.activeSheet()._setFormulaSelections(this.editor.highlightedRefs());
},
onEditorBarFocus: function() {
var disabled = this._workbook.activeSheet().selection().enable() === false;
if (disabled) {
return;
}
this.editor
.activate({
range: this._workbook.activeSheet().selection(),
rect: this.view.activeCellRectangle(),
tooltip: this._activeTooltip()
});
},
onEditorCellFocus: function() {
this.editor.scale();
},
onEditorEsc: function() {
this.resetEditorValue();
this.editor.deactivate();
this.clipboardElement.focus();
},
insertNewline: function(e) {
e.preventDefault();
this.editor.insertNewline();
},
onEditorBlur: function(_, action) {
if (this.editor.isFiltered()) {
return;
}
this._preventNavigation = false;
this.editor.deactivate();
if (!this._preventNavigation) {
this.clipboardElement.focus();
this.navigator.navigateInSelection(ENTRY_ACTIONS[action]);
}
},
onEditorAction: function(event, action) {
var editor = this.editor;
var sheet = this._workbook.activeSheet();
if (this._casualEditing && /^(?:up|right|down|left)$/.test(action)) {
this.deactivateEditor();
this.navigator.moveActiveCell(ACTIONS[action]);
event.preventDefault();
}
else if (editor.canInsertRef(true)) {
this.navigator.moveActiveCell(ACTIONS[action]);
editor.activeEditor().refAtPoint(sheet);
sheet._setFormulaSelections(editor.highlightedRefs());
event.preventDefault();
}
},
onEditorShiftAction: function(event, action) {
var editor = this.editor;
var sheet = this._workbook.activeSheet();
if (editor.canInsertRef(true)) {
this.navigator.modifySelection(ACTIONS[action.replace("shift+", "")], this.appendSelection);
editor.activeEditor().refAtPoint(sheet);
sheet._setFormulaSelections(editor.highlightedRefs());
event.preventDefault();
}
},
////////////////////////////////////////////////////////////////////
resetEditorValue: function() {
var sheet = this._workbook.activeSheet();
var ref = sheet.activeCell();
var input = this._workbook._inputForRef(ref);
var x = sheet.range(ref).intersectingArrayFormula();
if (x) {
input = "=" + x.formula;
}
this.editor.value(input, !!x);
},
activateEditor: function(casual) {
// This flag will be false when F2 has been pressed, and
// true when editing is "casual", i.e., user just started
// typing. In this case we want arrow keys to do cell
// navigation rather than move the cursor.
// https://github.com/telerik/kendo-ui-core/issues/3644
this._casualEditing = casual;
this.editor.activate({
range: this._workbook.activeSheet().selection(),
rect: this.view.activeCellRectangle(),
tooltip: this._activeTooltip()
}).focus();
},
deactivateEditor: function() {
this.view.editor.deactivate();
},
onCommandRequest: function(e) {
if (e.command) {
this._execute(e);
} else {
this._workbook.undoRedoStack[e.action]();
}
},
onDialogRequest: function(e) {
var additionalOptions = {
pdfExport: this._workbook.options.pdf,
excelExport: this._workbook.options.excel
};
if (e.options) {
$.extend(true, e.options, additionalOptions);
} else {
e.options = additionalOptions;
}
this.view.openDialog(e.name, e.options);
},
onNameEditorEnter: function() {
var ref;
var workbook = this._workbook;
var sheet = workbook.activeSheet();
var name = this.view.nameEditor.value();
// 1. does it look like a reference, or already defined
// name? If so, just select it (don't define/modify any
// names)
ref = kendo.spreadsheet.calc.parseReference(name, true) || workbook.nameValue(name);
if (ref instanceof kendo.spreadsheet.Ref) {
if (ref.sheet && ref.sheet.toLowerCase() != sheet.name().toLowerCase()) {
// reference points to another sheet, select it if found
var tmp = workbook.sheetByName(ref.sheet);
if (tmp) {
workbook.activeSheet(tmp);
sheet = tmp;
}
}
sheet.range(ref).select();
return;
}
ref = sheet.selection()._ref.clone().simplify().setSheet(sheet.name(), true);
// XXX: should we check if a name is already defined for this range, and update it instead?
// Excel just adds a new one, and provides a more complete Name Manager dialog.
//var def = workbook.nameForRef(ref, sheet.name());
// just define new name
this._execute({
command: "DefineNameCommand",
options: { name: name, value: ref }
});
this.clipboardElement.focus();
},
onNameEditorCancel: function() {
this.clipboardElement.focus();
},
onNameEditorSelect: function(ev) {
var name = ev.name;
var workbook = this._workbook;
var sheet = workbook.activeSheet();
var ref = workbook.nameValue(name);
if (ref instanceof kendo.spreadsheet.Ref) {
if (ref.sheet && ref.sheet.toLowerCase() != sheet.name().toLowerCase()) {
// reference points to another sheet, select it if found
var tmp = workbook.sheetByName(ref.sheet);
if (tmp) {
workbook.activeSheet(tmp);
sheet = tmp;
}