');
loading.prepend(this.wrapper.clone().css({
position: 'absolute',
top: 0,
left: 0
}));
this.wrapper.append(loading);
var pb = $('
').appendTo(loading).kendoProgressBar({
type: 'chunk',
chunkCount: 10,
min: 0,
max: 1,
value: 0
}).data('kendoProgressBar');
deferred.progress(function (e) {
pb.value(e.progress);
}).always(function () {
kendo.destroy(loading);
loading.remove();
});
};
}
function syncTableHeight(table1, table2) {
table1 = table1[0];
table2 = table2[0];
if (table1.rows.length !== table2.rows.length) {
var lockedHeigth = table1.offsetHeight;
var tableHeigth = table2.offsetHeight;
var row;
var diff;
if (lockedHeigth > tableHeigth) {
row = table2.rows[table2.rows.length - 1];
if (filterRowRegExp.test(row.className)) {
row = table2.rows[table2.rows.length - 2];
}
diff = lockedHeigth - tableHeigth;
} else {
row = table1.rows[table1.rows.length - 1];
if (filterRowRegExp.test(row.className)) {
row = table1.rows[table1.rows.length - 2];
}
diff = tableHeigth - lockedHeigth;
}
row.style.height = row.offsetHeight + diff + 'px';
}
}
function adjustRowHeight(row1, row2) {
var height;
var offsetHeight1 = row1.offsetHeight;
var offsetHeight2 = row2.offsetHeight;
if (offsetHeight1 > offsetHeight2) {
height = offsetHeight1 + 'px';
} else if (offsetHeight1 < offsetHeight2) {
height = offsetHeight2 + 'px';
}
if (height) {
row1.style.height = row2.style.height = height;
}
}
function getCommand(commands, name) {
var idx, length, command;
if (typeof commands === STRING && commands === name) {
return commands;
}
if (isPlainObject(commands) && commands.name === name) {
return commands;
}
if (isArray(commands)) {
for (idx = 0, length = commands.length; idx < length; idx++) {
command = commands[idx];
if (typeof command === STRING && command === name || command.name === name) {
return command;
}
}
}
return null;
}
function focusTable(table, direct) {
var msie = browser.msie || browser.edge;
if (direct === true) {
table = $(table);
var scrollTop, scrollLeft;
scrollTop = table.parent().scrollTop();
scrollLeft = table.parent().scrollLeft();
if (msie) {
try {
table[0].setActive();
} catch (e) {
table[0].focus();
}
} else {
table[0].focus();
}
table.parent().scrollTop(scrollTop).scrollLeft(scrollLeft);
} else {
$(table).one('focusin', function (e) {
e.preventDefault();
}).focus();
}
}
function isInputElement(element) {
return $(element).is(':button,a,:input,a>.k-icon,textarea,span.k-select,span.k-icon,span.k-link,.k-input,.k-multiselect-wrap,.k-tool-icon');
}
function tableClick(e) {
var currentTarget = $(e.currentTarget), isHeader = currentTarget.is('th'), table = this.table.add(this.lockedTable), headerTable = this.thead.parent().add($('>table', this.lockedHeader)), isInput = isInputElement(e.target), currentTable = currentTarget.closest('table')[0];
if (kendo.support.touch) {
return;
}
if (isInput && currentTarget.find(kendo.roleSelector('filtercell')).length) {
this._setCurrent(currentTarget);
return;
}
if (currentTable !== table[0] && currentTable !== table[1] && currentTable !== headerTable[0] && currentTable !== headerTable[1]) {
return;
}
if ($(e.target).is('a.k-i-collapse, a.k-i-expand')) {
return;
}
if (this.options.navigatable) {
this._setCurrent(currentTarget);
}
if (isHeader || !isInput) {
setTimeout(function () {
if (!(isIE8 && $(kendo._activeElement()).hasClass('k-widget'))) {
if (!isInputElement(kendo._activeElement())) {
focusTable(currentTable, true);
}
}
});
}
if (isHeader) {
e.preventDefault();
}
}
function isInEdit(cell) {
return cell && (cell.hasClass('k-edit-cell') || cell.parent().hasClass('k-grid-edit-row'));
}
function groupRowBuilder(colspan, level, text) {
return '
' + groupCells(level) + '| ' + ' ' + '' + text + ' |
';
}
function groupRowLockedContentBuilder(colspan) {
return '
' + '| ' + ' |
';
}
ui.plugin(Grid);
ui.plugin(VirtualScrollable);
}(window.kendo.jQuery));
return window.kendo;
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('kendo.listview', [
'kendo.data',
'kendo.editable',
'kendo.selectable'
], f);
}(function () {
var __meta__ = {
id: 'listview',
name: 'ListView',
category: 'web',
description: 'The ListView widget offers rich support for interacting with data.',
depends: ['data'],
features: [
{
id: 'listview-editing',
name: 'Editing',
description: 'Support for record editing',
depends: ['editable']
},
{
id: 'listview-selection',
name: 'Selection',
description: 'Support for selection',
depends: ['selectable']
}
]
};
(function ($, undefined) {
var kendo = window.kendo, CHANGE = 'change', CANCEL = 'cancel', DATABOUND = 'dataBound', DATABINDING = 'dataBinding', Widget = kendo.ui.Widget, keys = kendo.keys, FOCUSSELECTOR = '>*:not(.k-loading-mask)', PROGRESS = 'progress', ERROR = 'error', FOCUSED = 'k-state-focused', SELECTED = 'k-state-selected', KEDITITEM = 'k-edit-item', EDIT = 'edit', REMOVE = 'remove', SAVE = 'save', CLICK = 'click', NS = '.kendoListView', proxy = $.proxy, activeElement = kendo._activeElement, progress = kendo.ui.progress, DataSource = kendo.data.DataSource;
var ListView = kendo.ui.DataBoundWidget.extend({
init: function (element, options) {
var that = this;
options = $.isArray(options) ? { dataSource: options } : options;
Widget.fn.init.call(that, element, options);
options = that.options;
that.wrapper = element = that.element;
if (element[0].id) {
that._itemId = element[0].id + '_lv_active';
}
that._element();
that._dataSource();
that._templates();
that._navigatable();
that._selectable();
that._pageable();
that._crudHandlers();
if (that.options.autoBind) {
that.dataSource.fetch();
}
kendo.notify(that);
},
events: [
CHANGE,
CANCEL,
DATABINDING,
DATABOUND,
EDIT,
REMOVE,
SAVE
],
options: {
name: 'ListView',
autoBind: true,
selectable: false,
navigatable: false,
template: '',
altTemplate: '',
editTemplate: ''
},
setOptions: function (options) {
Widget.fn.setOptions.call(this, options);
this._templates();
if (this.selectable) {
this.selectable.destroy();
this.selectable = null;
}
this._selectable();
},
_templates: function () {
var options = this.options;
this.template = kendo.template(options.template || '');
this.altTemplate = kendo.template(options.altTemplate || options.template);
this.editTemplate = kendo.template(options.editTemplate || '');
},
_item: function (action) {
return this.element.children()[action]();
},
items: function () {
return this.element.children();
},
dataItem: function (element) {
var attr = kendo.attr('uid');
var uid = $(element).closest('[' + attr + ']').attr(attr);
return this.dataSource.getByUid(uid);
},
setDataSource: function (dataSource) {
this.options.dataSource = dataSource;
this._dataSource();
if (this.options.autoBind) {
dataSource.fetch();
}
},
_unbindDataSource: function () {
var that = this;
that.dataSource.unbind(CHANGE, that._refreshHandler).unbind(PROGRESS, that._progressHandler).unbind(ERROR, that._errorHandler);
},
_dataSource: function () {
var that = this;
if (that.dataSource && that._refreshHandler) {
that._unbindDataSource();
} else {
that._refreshHandler = proxy(that.refresh, that);
that._progressHandler = proxy(that._progress, that);
that._errorHandler = proxy(that._error, that);
}
that.dataSource = DataSource.create(that.options.dataSource).bind(CHANGE, that._refreshHandler).bind(PROGRESS, that._progressHandler).bind(ERROR, that._errorHandler);
},
_progress: function () {
progress(this.element, true);
},
_error: function () {
progress(this.element, false);
},
_element: function () {
this.element.addClass('k-widget k-listview').attr('role', 'listbox');
},
refresh: function (e) {
var that = this, view = that.dataSource.view(), data, items, item, html = '', idx, length, template = that.template, altTemplate = that.altTemplate, active = activeElement();
e = e || {};
if (e.action === 'itemchange') {
if (!that._hasBindingTarget() && !that.editable) {
data = e.items[0];
item = that.items().filter('[' + kendo.attr('uid') + '=' + data.uid + ']');
if (item.length > 0) {
idx = item.index();
that.angular('cleanup', function () {
return { elements: [item] };
});
item.replaceWith(template(data));
item = that.items().eq(idx);
item.attr(kendo.attr('uid'), data.uid);
that.angular('compile', function () {
return {
elements: [item],
data: [{ dataItem: data }]
};
});
that.trigger('itemChange', {
item: item,
data: data
});
}
}
return;
}
if (that.trigger(DATABINDING, {
action: e.action || 'rebind',
items: e.items,
index: e.index
})) {
return;
}
that._angularItems('cleanup');
that._destroyEditable();
for (idx = 0, length = view.length; idx < length; idx++) {
if (idx % 2) {
html += altTemplate(view[idx]);
} else {
html += template(view[idx]);
}
}
that.element.html(html);
items = that.items();
for (idx = 0, length = view.length; idx < length; idx++) {
items.eq(idx).attr(kendo.attr('uid'), view[idx].uid).attr('role', 'option').attr('aria-selected', 'false');
}
if (that.element[0] === active && that.options.navigatable) {
that.current(items.eq(0));
}
that._angularItems('compile');
that.trigger(DATABOUND);
},
_pageable: function () {
var that = this, pageable = that.options.pageable, settings, pagerId;
if ($.isPlainObject(pageable)) {
pagerId = pageable.pagerId;
settings = $.extend({}, pageable, {
dataSource: that.dataSource,
pagerId: null
});
that.pager = new kendo.ui.Pager($('#' + pagerId), settings);
}
},
_selectable: function () {
var that = this, multi, current, selectable = that.options.selectable, navigatable = that.options.navigatable;
if (selectable) {
multi = kendo.ui.Selectable.parseOptions(selectable).multiple;
that.selectable = new kendo.ui.Selectable(that.element, {
aria: true,
multiple: multi,
filter: FOCUSSELECTOR,
change: function () {
that.trigger(CHANGE);
}
});
if (navigatable) {
that.element.on('keydown' + NS, function (e) {
if (e.keyCode === keys.SPACEBAR) {
current = that.current();
if (e.target == e.currentTarget) {
e.preventDefault();
}
if (multi) {
if (!e.ctrlKey) {
that.selectable.clear();
} else {
if (current && current.hasClass(SELECTED)) {
current.removeClass(SELECTED);
return;
}
}
} else {
that.selectable.clear();
}
that.selectable.value(current);
}
});
}
}
},
current: function (candidate) {
var that = this, element = that.element, current = that._current, id = that._itemId;
if (candidate === undefined) {
return current;
}
if (current && current[0]) {
if (current[0].id === id) {
current.removeAttr('id');
}
current.removeClass(FOCUSED);
element.removeAttr('aria-activedescendant');
}
if (candidate && candidate[0]) {
id = candidate[0].id || id;
that._scrollTo(candidate[0]);
element.attr('aria-activedescendant', id);
candidate.addClass(FOCUSED).attr('id', id);
}
that._current = candidate;
},
_scrollTo: function (element) {
var that = this, container, UseJQueryoffset = false, SCROLL = 'scroll';
if (that.wrapper.css('overflow') == 'auto' || that.wrapper.css('overflow') == SCROLL) {
container = that.wrapper[0];
} else {
container = window;
UseJQueryoffset = true;
}
var scrollDirectionFunc = function (direction, dimension) {
var elementOffset = UseJQueryoffset ? $(element).offset()[direction.toLowerCase()] : element['offset' + direction], elementDimension = element['client' + dimension], containerScrollAmount = $(container)[SCROLL + direction](), containerDimension = $(container)[dimension.toLowerCase()]();
if (elementOffset + elementDimension > containerScrollAmount + containerDimension) {
$(container)[SCROLL + direction](elementOffset + elementDimension - containerDimension);
} else if (elementOffset < containerScrollAmount) {
$(container)[SCROLL + direction](elementOffset);
}
};
scrollDirectionFunc('Top', 'Height');
scrollDirectionFunc('Left', 'Width');
},
_navigatable: function () {
var that = this, navigatable = that.options.navigatable, element = that.element, clickCallback = function (e) {
that.current($(e.currentTarget));
if (!$(e.target).is(':button,a,:input,a>.k-icon,textarea')) {
element.focus();
}
};
if (navigatable) {
that._tabindex();
element.on('focus' + NS, function () {
var current = that._current;
if (!current || !current.is(':visible')) {
current = that._item('first');
}
that.current(current);
}).on('focusout' + NS, function () {
if (that._current) {
that._current.removeClass(FOCUSED);
}
}).on('keydown' + NS, function (e) {
var key = e.keyCode, current = that.current(), target = $(e.target), canHandle = !target.is(':button,textarea,a,a>.t-icon,input'), isTextBox = target.is(':text,:password'), preventDefault = kendo.preventDefault, editItem = element.find('.' + KEDITITEM), active = activeElement(), idx;
if (!canHandle && !isTextBox && keys.ESC != key || isTextBox && keys.ESC != key && keys.ENTER != key) {
return;
}
if (keys.UP === key || keys.LEFT === key) {
if (current) {
current = current.prev();
}
that.current(!current || !current[0] ? that._item('last') : current);
preventDefault(e);
} else if (keys.DOWN === key || keys.RIGHT === key) {
if (current) {
current = current.next();
}
that.current(!current || !current[0] ? that._item('first') : current);
preventDefault(e);
} else if (keys.PAGEUP === key) {
that.current(null);
that.dataSource.page(that.dataSource.page() - 1);
preventDefault(e);
} else if (keys.PAGEDOWN === key) {
that.current(null);
that.dataSource.page(that.dataSource.page() + 1);
preventDefault(e);
} else if (keys.HOME === key) {
that.current(that._item('first'));
preventDefault(e);
} else if (keys.END === key) {
that.current(that._item('last'));
preventDefault(e);
} else if (keys.ENTER === key) {
if (editItem.length !== 0 && (canHandle || isTextBox)) {
idx = that.items().index(editItem);
if (active) {
active.blur();
}
that.save();
var focusAgain = function () {
that.element.trigger('focus');
that.current(that.items().eq(idx));
};
that.one('dataBound', focusAgain);
} else if (that.options.editTemplate !== '') {
that.edit(current);
}
} else if (keys.ESC === key) {
editItem = element.find('.' + KEDITITEM);
if (editItem.length === 0) {
return;
}
idx = that.items().index(editItem);
that.cancel();
that.element.trigger('focus');
that.current(that.items().eq(idx));
}
});
element.on('mousedown' + NS + ' touchstart' + NS, FOCUSSELECTOR, proxy(clickCallback, that));
}
},
clearSelection: function () {
var that = this;
that.selectable.clear();
that.trigger(CHANGE);
},
select: function (items) {
var that = this, selectable = that.selectable;
items = $(items);
if (items.length) {
if (!selectable.options.multiple) {
selectable.clear();
items = items.first();
}
selectable.value(items);
return;
}
return selectable.value();
},
_destroyEditable: function () {
var that = this;
if (that.editable) {
that.editable.destroy();
delete that.editable;
}
},
_modelFromElement: function (element) {
var uid = element.attr(kendo.attr('uid'));
return this.dataSource.getByUid(uid);
},
_closeEditable: function () {
var that = this, editable = that.editable, data, item, index, template = that.template;
if (editable) {
if (editable.element.index() % 2) {
template = that.altTemplate;
}
that.angular('cleanup', function () {
return { elements: [editable.element] };
});
data = that._modelFromElement(editable.element);
that._destroyEditable();
index = editable.element.index();
editable.element.replaceWith(template(data));
item = that.items().eq(index);
item.attr(kendo.attr('uid'), data.uid);
if (that._hasBindingTarget()) {
kendo.bind(item, data);
}
that.angular('compile', function () {
return {
elements: [item],
data: [{ dataItem: data }]
};
});
}
return true;
},
edit: function (item) {
var that = this, data = that._modelFromElement(item), container, uid = data.uid, index;
that.cancel();
item = that.items().filter('[' + kendo.attr('uid') + '=' + uid + ']');
index = item.index();
item.replaceWith(that.editTemplate(data));
container = that.items().eq(index).addClass(KEDITITEM).attr(kendo.attr('uid'), data.uid);
that.editable = container.kendoEditable({
model: data,
clearContainer: false,
errorTemplate: false,
target: that
}).data('kendoEditable');
that.trigger(EDIT, {
model: data,
item: container
});
},
save: function () {
var that = this, editable = that.editable, model;
if (!editable) {
return;
}
var container = editable.element;
model = that._modelFromElement(container);
if (editable.end() && !that.trigger(SAVE, {
model: model,
item: container
})) {
that._closeEditable();
that.dataSource.sync();
}
},
remove: function (item) {
var that = this, dataSource = that.dataSource, data = that._modelFromElement(item);
if (that.editable) {
dataSource.cancelChanges(that._modelFromElement(that.editable.element));
that._closeEditable();
}
if (!that.trigger(REMOVE, {
model: data,
item: item
})) {
item.hide();
dataSource.remove(data);
dataSource.sync();
}
},
add: function () {
var that = this, dataItem, dataSource = that.dataSource, index = dataSource.indexOf((dataSource.view() || [])[0]);
if (index < 0) {
index = 0;
}
that.cancel();
dataItem = dataSource.insert(index, {});
that.edit(that.element.find('[data-uid=\'' + dataItem.uid + '\']'));
},
cancel: function () {
var that = this, dataSource = that.dataSource;
if (that.editable) {
var container = that.editable.element;
var model = that._modelFromElement(container);
if (!that.trigger(CANCEL, {
model: model,
container: container
})) {
dataSource.cancelChanges(model);
that._closeEditable();
}
}
},
_crudHandlers: function () {
var that = this, clickNS = CLICK + NS;
that.element.on(clickNS, '.k-edit-button', function (e) {
var item = $(this).closest('[' + kendo.attr('uid') + ']');
that.edit(item);
e.preventDefault();
});
that.element.on(clickNS, '.k-delete-button', function (e) {
var item = $(this).closest('[' + kendo.attr('uid') + ']');
that.remove(item);
e.preventDefault();
});
that.element.on(clickNS, '.k-update-button', function (e) {
that.save();
e.preventDefault();
});
that.element.on(clickNS, '.k-cancel-button', function (e) {
that.cancel();
e.preventDefault();
});
},
destroy: function () {
var that = this;
Widget.fn.destroy.call(that);
that._unbindDataSource();
that._destroyEditable();
that.element.off(NS);
if (that.pager) {
that.pager.destroy();
}
kendo.destroy(that.element);
}
});
kendo.ui.plugin(ListView);
}(window.kendo.jQuery));
return window.kendo;
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('kendo.upload', ['kendo.core'], f);
}(function () {
var __meta__ = {
id: 'upload',
name: 'Upload',
category: 'web',
description: 'The Upload widget uses progressive enhancement to deliver the best possible uploading experience to users.',
depends: ['core']
};
(function ($, undefined) {
var kendo = window.kendo, Widget = kendo.ui.Widget, antiForgeryTokens = kendo.antiForgeryTokens, logToConsole = kendo.logToConsole, rFileExtension = /\.([^\.]+)$/, NS = '.kendoUpload', SELECT = 'select', UPLOAD = 'upload', SUCCESS = 'success', ERROR = 'error', COMPLETE = 'complete', CANCEL = 'cancel', PROGRESS = 'progress', REMOVE = 'remove';
var Upload = Widget.extend({
init: function (element, options) {
var that = this;
Widget.fn.init.call(that, element, options);
that.name = element.name;
that.multiple = that.options.multiple;
that.localization = that.options.localization;
var activeInput = that.element;
that.wrapper = activeInput.closest('.k-upload');
if (that.wrapper.length === 0) {
that.wrapper = that._wrapInput(activeInput);
}
that._activeInput(activeInput);
that.toggle(that.options.enabled);
var ns = that._ns = NS + '-' + kendo.guid();
activeInput.closest('form').on('submit' + ns, $.proxy(that._onParentFormSubmit, that)).on('reset' + ns, $.proxy(that._onParentFormReset, that));
if (that.options.async.saveUrl) {
that._module = that._supportsFormData() ? new formDataUploadModule(that) : new iframeUploadModule(that);
that._async = true;
var initialFiles = that.options.files;
if (initialFiles.length > 0) {
that._renderInitialFiles(initialFiles);
}
} else {
that._module = new syncUploadModule(that);
}
if (that._supportsDrop()) {
that._setupDropZone();
}
that.wrapper.on('click', '.k-upload-action', $.proxy(that._onFileAction, that)).on('click', '.k-upload-selected', $.proxy(that._onUploadSelected, that));
if (that.element.val()) {
that._onInputChange({ target: that.element });
}
},
events: [
SELECT,
UPLOAD,
SUCCESS,
ERROR,
COMPLETE,
CANCEL,
PROGRESS,
REMOVE
],
options: {
name: 'Upload',
enabled: true,
multiple: true,
showFileList: true,
template: '',
files: [],
async: {
removeVerb: 'POST',
autoUpload: true,
withCredentials: true
},
localization: {
'select': 'Select files...',
'cancel': 'Cancel',
'retry': 'Retry',
'remove': 'Remove',
'uploadSelectedFiles': 'Upload files',
'dropFilesHere': 'drop files here to upload',
'statusUploading': 'uploading',
'statusUploaded': 'uploaded',
'statusWarning': 'warning',
'statusFailed': 'failed',
'headerStatusUploading': 'Uploading...',
'headerStatusUploaded': 'Done'
}
},
setOptions: function (options) {
var that = this, activeInput = that.element;
Widget.fn.setOptions.call(that, options);
that.multiple = that.options.multiple;
activeInput.attr('multiple', that._supportsMultiple() ? that.multiple : false);
that.toggle(that.options.enabled);
},
enable: function (enable) {
enable = typeof enable === 'undefined' ? true : enable;
this.toggle(enable);
},
disable: function () {
this.toggle(false);
},
toggle: function (enable) {
enable = typeof enable === 'undefined' ? enable : !enable;
this.wrapper.toggleClass('k-state-disabled', enable);
this.element.prop('disabled', enable);
},
destroy: function () {
var that = this;
$(document).add($('.k-dropzone', that.wrapper)).add(that.wrapper.closest('form')).off(that._ns);
$(that.element).off(NS);
Widget.fn.destroy.call(that);
},
_addInput: function (sourceInput) {
if (!sourceInput[0].nodeType) {
return;
}
var that = this, input = sourceInput.clone().val('');
input.insertAfter(that.element).data('kendoUpload', that);
$(that.element).hide().attr('tabindex', '-1').removeAttr('id').off(NS);
that._activeInput(input);
that.element.focus();
},
_activeInput: function (input) {
var that = this, wrapper = that.wrapper;
that.element = input;
input.attr('multiple', that._supportsMultiple() ? that.multiple : false).attr('autocomplete', 'off').on('click' + NS, function (e) {
if (wrapper.hasClass('k-state-disabled')) {
e.preventDefault();
}
}).on('focus' + NS, function () {
$(this).parent().addClass('k-state-focused');
}).on('blur' + NS, function () {
$(this).parent().removeClass('k-state-focused');
}).on('change' + NS, $.proxy(that._onInputChange, that)).on('keydown' + NS, $.proxy(that._onInputKeyDown, that));
},
_onInputKeyDown: function (e) {
var that = this;
var firstButton = that.wrapper.find('.k-upload-action:first');
if (e.keyCode === kendo.keys.TAB && firstButton.length > 0) {
e.preventDefault();
firstButton.focus();
}
},
_onInputChange: function (e) {
var that = this;
var input = $(e.target);
var files = assignGuidToFiles(that._inputFiles(input), that._isAsyncNonBatch());
var prevented = that.trigger(SELECT, { files: files });
if (prevented) {
that._addInput(input);
input.remove();
} else {
that._module.onSelect({ target: input }, files);
}
},
_onDrop: function (e) {
var dt = e.originalEvent.dataTransfer;
var that = this;
var droppedFiles = dt.files;
var files = assignGuidToFiles(getAllFileInfo(droppedFiles), that._isAsyncNonBatch());
stopEvent(e);
if (droppedFiles.length > 0 && !that.wrapper.hasClass('k-state-disabled')) {
if (!that.multiple && files.length > 1) {
files.splice(1, files.length - 1);
}
var prevented = that.trigger(SELECT, { files: files });
if (!prevented) {
that._module.onSelect({ target: $('.k-dropzone', that.wrapper) }, files);
}
}
},
_isAsyncNonBatch: function () {
return this._async && !this.options.async.batch || false;
},
_renderInitialFiles: function (files) {
var that = this;
var idx = 0;
files = assignGuidToFiles(files, true);
for (idx = 0; idx < files.length; idx++) {
var currentFile = files[idx];
var fileEntry = that._enqueueFile(currentFile.name, { fileNames: [currentFile] });
fileEntry.addClass('k-file-success').data('files', [files[idx]]);
$('.k-progress', fileEntry).width('100%');
if (!that.options.template) {
$('.k-upload-status', fileEntry).prepend('
100%');
}
if (that._supportsRemove()) {
that._fileAction(fileEntry, REMOVE);
}
}
},
_prepareTemplateData: function (name, data) {
var filesData = data.fileNames, templateData = {}, totalSize = 0, idx = 0;
for (idx = 0; idx < filesData.length; idx++) {
totalSize += filesData[idx].size;
}
templateData.name = name;
templateData.size = totalSize;
templateData.files = data.fileNames;
return templateData;
},
_prepareDefaultFileEntryTemplate: function (name, data) {
var extension = '';
var defaultTemplate = $('
' + '' + '' + '' + name + '' + '' + '');
if (data.fileNames.length == 1 && !!data.fileNames[0].extension) {
extension = data.fileNames[0].extension.substring(1);
$('.k-icon', defaultTemplate).addClass('k-i-' + extension);
}
return defaultTemplate;
},
_enqueueFile: function (name, data) {
var that = this;
var existingFileEntries;
var fileEntry;
var fileUid = data.fileNames[0].uid;
var fileList = $('.k-upload-files', that.wrapper);
var options = that.options;
var template = options.template;
var templateData;
var removeEventArgs;
if (fileList.length === 0) {
fileList = $('
').appendTo(that.wrapper);
if (!that.options.showFileList) {
fileList.hide();
}
that.wrapper.removeClass('k-upload-empty');
}
existingFileEntries = $('.k-file', fileList);
if (!template) {
fileEntry = that._prepareDefaultFileEntryTemplate(name, data);
} else {
templateData = that._prepareTemplateData(name, data);
template = kendo.template(template);
fileEntry = $('
' + template(templateData) + '');
fileEntry.find('.k-upload-action').addClass('k-button k-button-bare');
that.angular('compile', function () {
return {
elements: fileEntry,
data: [templateData]
};
});
}
fileEntry.attr(kendo.attr('uid'), fileUid).appendTo(fileList).data(data);
if (!that._async) {
$('.k-progress', fileEntry).width('100%');
}
if (!that.multiple && existingFileEntries.length > 0) {
removeEventArgs = { files: existingFileEntries.data('fileNames') };
if (!that.trigger(REMOVE, removeEventArgs)) {
that._module.onRemove({ target: $(existingFileEntries, that.wrapper) }, removeEventArgs.data);
}
}
return fileEntry;
},
_removeFileEntry: function (fileEntry) {
var that = this;
var fileList = fileEntry.closest('.k-upload-files');
var allFiles;
var allCompletedFiles;
fileEntry.remove();
allFiles = $('.k-file', fileList);
allCompletedFiles = $('.k-file-success, .k-file-error', fileList);
if (allCompletedFiles.length === allFiles.length) {
this._hideUploadButton();
}
if (allFiles.length === 0) {
fileList.remove();
that.wrapper.addClass('k-upload-empty');
that._hideHeaderUploadstatus();
}
},
_fileAction: function (fileElement, actionKey) {
var classDictionary = {
remove: 'k-delete',
cancel: 'k-cancel',
retry: 'k-retry'
};
var iconsClassDictionary = {
remove: 'k-i-close',
cancel: 'k-i-close',
retry: 'k-i-refresh'
};
if (!classDictionary.hasOwnProperty(actionKey)) {
return;
}
this._clearFileAction(fileElement);
if (!this.options.template) {
fileElement.find('.k-upload-status .k-upload-action').remove();
fileElement.find('.k-upload-status').append(this._renderAction(classDictionary[actionKey], this.localization[actionKey], iconsClassDictionary[actionKey]));
} else {
fileElement.find('.k-upload-action').addClass('k-button k-button-bare').append('
').show();
}
},
_fileState: function (fileEntry, stateKey) {
var localization = this.localization, states = {
uploading: { text: localization.statusUploading },
uploaded: { text: localization.statusUploaded },
failed: { text: localization.statusFailed }
}, currentState = states[stateKey];
if (currentState) {
$('.k-icon:not(.k-delete, .k-cancel, .k-retry)', fileEntry).text(currentState.text);
}
},
_renderAction: function (actionClass, actionText, iconClass) {
if (actionClass !== '') {
return $('
');
} else {
return $('
');
}
},
_clearFileAction: function (fileElement) {
$('.k-upload-action', fileElement).empty().hide();
},
_onFileAction: function (e) {
var that = this;
if (!that.wrapper.hasClass('k-state-disabled')) {
var button = $(e.target).closest('.k-upload-action'), icon = button.find('.k-icon'), fileEntry = button.closest('.k-file'), eventArgs = { files: fileEntry.data('fileNames') };
if (icon.hasClass('k-delete')) {
if (!that.trigger(REMOVE, eventArgs)) {
that._module.onRemove({ target: $(fileEntry, that.wrapper) }, eventArgs.data);
}
} else if (icon.hasClass('k-cancel')) {
that.trigger(CANCEL, eventArgs);
that._module.onCancel({ target: $(fileEntry, that.wrapper) });
this._checkAllComplete();
that._updateHeaderUploadStatus();
} else if (icon.hasClass('k-retry')) {
$('.k-warning', fileEntry).remove();
that._module.onRetry({ target: $(fileEntry, that.wrapper) });
}
}
return false;
},
_onUploadSelected: function () {
var that = this;
var wrapper = that.wrapper;
if (!wrapper.hasClass('k-state-disabled')) {
this._module.onSaveSelected();
}
return false;
},
_onFileProgress: function (e, percentComplete) {
var progressPct;
if (percentComplete > 100) {
percentComplete = 100;
}
if (!this.options.template) {
progressPct = $('.k-upload-pct', e.target);
if (progressPct.length === 0) {
$('.k-upload-status', e.target).prepend('
');
}
$('.k-upload-pct', e.target).text(percentComplete + '%');
$('.k-progress', e.target).width(percentComplete + '%');
} else {
$('.k-progress', e.target).width(percentComplete + '%');
}
this.trigger(PROGRESS, {
files: getFileEntry(e).data('fileNames'),
percentComplete: percentComplete
});
},
_onUploadSuccess: function (e, response, xhr) {
var fileEntry = getFileEntry(e);
this._fileState(fileEntry, 'uploaded');
fileEntry.removeClass('k-file-progress').addClass('k-file-success');
this._updateHeaderUploadStatus();
this.trigger(SUCCESS, {
files: fileEntry.data('fileNames'),
response: response,
operation: 'upload',
XMLHttpRequest: xhr
});
if (this._supportsRemove()) {
this._fileAction(fileEntry, REMOVE);
} else {
this._clearFileAction(fileEntry);
}
this._checkAllComplete();
},
_onUploadError: function (e, xhr) {
var fileEntry = getFileEntry(e);
var uploadPercentage = $('.k-upload-pct', fileEntry);
this._fileState(fileEntry, 'failed');
fileEntry.removeClass('k-file-progress').addClass('k-file-error');
$('.k-progress', fileEntry).width('100%');
if (uploadPercentage.length > 0) {
uploadPercentage.empty().removeClass('k-upload-pct').addClass('k-icon k-warning');
} else {
$('.k-upload-status', fileEntry).prepend('
');
}
this._updateHeaderUploadStatus();
this._fileAction(fileEntry, 'retry');
this.trigger(ERROR, {
operation: 'upload',
files: fileEntry.data('fileNames'),
XMLHttpRequest: xhr
});
logToConsole('Server response: ' + xhr.responseText);
this._checkAllComplete();
},
_showUploadButton: function () {
var uploadButton = $('.k-upload-selected', this.wrapper);
if (uploadButton.length === 0) {
uploadButton = this._renderAction('', this.localization.uploadSelectedFiles).addClass('k-upload-selected');
}
this.wrapper.append(uploadButton);
},
_hideUploadButton: function () {
$('.k-upload-selected', this.wrapper).remove();
},
_showHeaderUploadStatus: function () {
var localization = this.localization;
var dropZone = $('.k-dropzone', this.wrapper);
var headerUploadStatus = $('.k-upload-status-total', this.wrapper);
if (headerUploadStatus.length !== 0) {
headerUploadStatus.remove();
}
headerUploadStatus = '
' + localization.headerStatusUploading + '' + localization.statusUploading + '' + '';
if (dropZone.length > 0) {
dropZone.append(headerUploadStatus);
} else {
$('.k-upload-button', this.wrapper).after(headerUploadStatus);
}
},
_updateHeaderUploadStatus: function () {
var that = this;
var localization = that.localization;
var currentlyUploading = $('.k-file', that.wrapper).not('.k-file-success, .k-file-error');
var failedUploads;
var headerUploadStatus;
var headerUploadStatusIcon;
if (currentlyUploading.length === 0) {
failedUploads = $('.k-file.k-file-error', that.wrapper);
headerUploadStatus = $('.k-upload-status-total', that.wrapper);
headerUploadStatusIcon = $('.k-icon', headerUploadStatus).removeClass('k-loading').addClass(failedUploads.length !== 0 ? 'k-warning' : 'k-i-tick').text(failedUploads.length !== 0 ? localization.statusWarning : localization.statusUploaded);
headerUploadStatus.text(that.localization.headerStatusUploaded).append(headerUploadStatusIcon);
}
},
_hideHeaderUploadstatus: function () {
$('.k-upload-status-total', this.wrapper).remove();
},
_onParentFormSubmit: function () {
var upload = this, element = upload.element;
if (typeof this._module.onAbort !== 'undefined') {
this._module.onAbort();
}
if (!element.value) {
var input = $(element);
input.attr('disabled', 'disabled');
window.setTimeout(function () {
input.removeAttr('disabled');
}, 0);
}
},
_onParentFormReset: function () {
$('.k-upload-files', this.wrapper).remove();
},
_supportsFormData: function () {
return typeof FormData != 'undefined';
},
_supportsMultiple: function () {
var windows = this._userAgent().indexOf('Windows') > -1;
return !kendo.support.browser.opera && !(kendo.support.browser.safari && windows);
},
_supportsDrop: function () {
var userAgent = this._userAgent().toLowerCase(), isChrome = /chrome/.test(userAgent), isSafari = !isChrome && /safari/.test(userAgent), isWindowsSafari = isSafari && /windows/.test(userAgent);
return !isWindowsSafari && this._supportsFormData() && this.options.async.saveUrl;
},
_userAgent: function () {
return navigator.userAgent;
},
_setupDropZone: function () {
var that = this;
$('.k-upload-button', this.wrapper).wrap('
');
var ns = that._ns;
var dropZone = $('.k-dropzone', that.wrapper).append($('
' + that.localization.dropFilesHere + '')).on('dragenter' + ns, stopEvent).on('dragover' + ns, function (e) {
e.preventDefault();
}).on('drop' + ns, $.proxy(this._onDrop, this));
bindDragEventWrappers(dropZone, ns, function () {
if (!dropZone.closest('.k-upload').hasClass('k-state-disabled')) {
dropZone.addClass('k-dropzone-hovered');
}
}, function () {
dropZone.removeClass('k-dropzone-hovered');
});
bindDragEventWrappers($(document), ns, function () {
if (!dropZone.closest('.k-upload').hasClass('k-state-disabled')) {
dropZone.addClass('k-dropzone-active');
dropZone.closest('.k-upload').removeClass('k-upload-empty');
}
}, function () {
dropZone.removeClass('k-dropzone-active');
if ($('li.k-file', dropZone.closest('.k-upload')).length === 0) {
dropZone.closest('.k-upload').addClass('k-upload-empty');
}
});
},
_supportsRemove: function () {
return !!this.options.async.removeUrl;
},
_submitRemove: function (fileNames, data, onSuccess, onError) {
var upload = this, removeField = upload.options.async.removeField || 'fileNames', params = $.extend(data, antiForgeryTokens());
params[removeField] = fileNames;
jQuery.ajax({
type: this.options.async.removeVerb,
dataType: 'json',
dataFilter: normalizeJSON,
url: this.options.async.removeUrl,
traditional: true,
data: params,
success: onSuccess,
error: onError,
xhrFields: { withCredentials: this.options.async.withCredentials }
});
},
_wrapInput: function (input) {
var that = this;
var options = that.options;
input.wrap('
');
if (!options.async.saveUrl) {
input.closest('.k-upload').addClass('k-upload-sync');
}
input.closest('.k-upload').addClass('k-upload-empty');
input.closest('.k-button').append('
' + this.localization.select + '');
return input.closest('.k-upload');
},
_checkAllComplete: function () {
if ($('.k-file.k-file-progress', this.wrapper).length === 0) {
this.trigger(COMPLETE);
}
},
_inputFiles: function (sourceInput) {
return inputFiles(sourceInput);
}
});
var syncUploadModule = function (upload) {
this.name = 'syncUploadModule';
this.element = upload.wrapper;
this.upload = upload;
this.element.closest('form').attr('enctype', 'multipart/form-data').attr('encoding', 'multipart/form-data');
};
syncUploadModule.prototype = {
onSelect: function (e, files) {
var upload = this.upload;
var sourceInput = $(e.target);
upload._addInput(sourceInput);
var file = upload._enqueueFile(getFileName(sourceInput), {
'relatedInput': sourceInput,
'fileNames': files
});
upload._fileAction(file, REMOVE);
},
onRemove: function (e) {
var fileEntry = getFileEntry(e);
fileEntry.data('relatedInput').remove();
this.upload._removeFileEntry(fileEntry);
}
};
var iframeUploadModule = function (upload) {
this.name = 'iframeUploadModule';
this.element = upload.wrapper;
this.upload = upload;
this.iframes = [];
};
Upload._frameId = 0;
iframeUploadModule.prototype = {
onSelect: function (e, files) {
var upload = this.upload, sourceInput = $(e.target);
var fileEntry = this.prepareUpload(sourceInput, files);
if (upload.options.async.autoUpload) {
this.performUpload(fileEntry);
} else {
if (upload._supportsRemove()) {
this.upload._fileAction(fileEntry, REMOVE);
}
upload._showUploadButton();
}
},
prepareUpload: function (sourceInput, files) {
var upload = this.upload;
var activeInput = $(upload.element);
var name = upload.options.async.saveField || sourceInput.attr('name');
upload._addInput(sourceInput);
sourceInput.attr('name', name);
var iframe = this.createFrame(upload.name + '_' + Upload._frameId++);
this.registerFrame(iframe);
var form = this.createForm(upload.options.async.saveUrl, iframe.attr('name')).append(activeInput);
var fileEntry = upload._enqueueFile(getFileName(sourceInput), {
'frame': iframe,
'relatedInput': activeInput,
'fileNames': files
});
iframe.data({
'form': form,
'file': fileEntry
});
return fileEntry;
},
performUpload: function (fileEntry) {
var e = { files: fileEntry.data('fileNames') }, iframe = fileEntry.data('frame'), upload = this.upload;
if (!upload.trigger(UPLOAD, e)) {
upload._hideUploadButton();
upload._showHeaderUploadStatus();
iframe.appendTo(document.body);
var form = iframe.data('form').attr('action', upload.options.async.saveUrl).appendTo(document.body);
e.data = $.extend({}, e.data, antiForgeryTokens());
for (var key in e.data) {
var dataInput = form.find('input[name=\'' + key + '\']');
if (dataInput.length === 0) {
dataInput = $('
', {
type: 'hidden',
name: key
}).prependTo(form);
}
dataInput.val(e.data[key]);
}
upload._fileAction(fileEntry, CANCEL);
upload._fileState(fileEntry, 'uploading');
$(fileEntry).removeClass('k-file-error').addClass('k-file-progress');
iframe.one('load', $.proxy(this.onIframeLoad, this));
form[0].submit();
} else {
upload._removeFileEntry(iframe.data('file'));
this.cleanupFrame(iframe);
this.unregisterFrame(iframe);
}
},
onSaveSelected: function () {
var module = this;
$('.k-file', this.element).each(function () {
var fileEntry = $(this), started = isFileUploadStarted(fileEntry);
if (!started) {
module.performUpload(fileEntry);
}
});
},
onIframeLoad: function (e) {
var iframe = $(e.target), responseText;
try {
responseText = iframe.contents().text();
} catch (ex) {
responseText = 'Error trying to get server response: ' + ex;
}
this.processResponse(iframe, responseText);
},
processResponse: function (iframe, responseText) {
var fileEntry = iframe.data('file'), module = this, fakeXHR = { responseText: responseText };
tryParseJSON(responseText, function (jsonResult) {
$.extend(fakeXHR, {
statusText: 'OK',
status: '200'
});
module.upload._onFileProgress({ target: $(fileEntry, module.upload.wrapper) }, 100);
module.upload._onUploadSuccess({ target: $(fileEntry, module.upload.wrapper) }, jsonResult, fakeXHR);
module.cleanupFrame(iframe);
module.unregisterFrame(iframe);
}, function () {
$.extend(fakeXHR, {
statusText: 'error',
status: '500'
});
module.upload._onUploadError({ target: $(fileEntry, module.upload.wrapper) }, fakeXHR);
});
},
onCancel: function (e) {
var iframe = $(e.target).data('frame');
this.stopFrameSubmit(iframe);
this.cleanupFrame(iframe);
this.unregisterFrame(iframe);
this.upload._removeFileEntry(iframe.data('file'));
},
onRetry: function (e) {
var fileEntry = getFileEntry(e);
this.performUpload(fileEntry);
},
onRemove: function (e, data) {
var fileEntry = getFileEntry(e);
var iframe = fileEntry.data('frame');
if (iframe) {
this.unregisterFrame(iframe);
this.upload._removeFileEntry(fileEntry);
this.cleanupFrame(iframe);
} else {
removeUploadedFile(fileEntry, this.upload, data);
}
},
onAbort: function () {
var element = this.element, module = this;
$.each(this.iframes, function () {
$('input', this.data('form')).appendTo(element);
module.stopFrameSubmit(this[0]);
this.data('form').remove();
this.remove();
});
this.iframes = [];
},
createFrame: function (id) {
return $('
');
},
createForm: function (action, target) {
return $('
');
},
stopFrameSubmit: function (frame) {
if (typeof frame.stop != 'undefined') {
frame.stop();
} else if (frame.document) {
frame.document.execCommand('Stop');
}
},
registerFrame: function (frame) {
this.iframes.push(frame);
},
unregisterFrame: function (frame) {
this.iframes = $.grep(this.iframes, function (value) {
return value.attr('name') != frame.attr('name');
});
},
cleanupFrame: function (frame) {
var form = frame.data('form');
frame.data('file').data('frame', null);
setTimeout(function () {
form.remove();
frame.remove();
}, 1);
}
};
var formDataUploadModule = function (upload) {
this.name = 'formDataUploadModule';
this.element = upload.wrapper;
this.upload = upload;
};
formDataUploadModule.prototype = {
onSelect: function (e, files) {
var upload = this.upload, module = this, sourceElement = $(e.target), fileEntries = this.prepareUpload(sourceElement, files);
$.each(fileEntries, function () {
if (upload.options.async.autoUpload) {
module.performUpload(this);
} else {
if (upload._supportsRemove()) {
upload._fileAction(this, REMOVE);
}
upload._showUploadButton();
}
});
},
prepareUpload: function (sourceElement, files) {
var fileEntries = this.enqueueFiles(files);
if (sourceElement.is('input')) {
$.each(fileEntries, function () {
$(this).data('relatedInput', sourceElement);
});
sourceElement.data('relatedFileEntries', fileEntries);
this.upload._addInput(sourceElement);
}
return fileEntries;
},
enqueueFiles: function (files) {
var upload = this.upload, name, i, filesLength = files.length, currentFile, fileEntry, fileEntries = [];
if (upload.options.async.batch === true) {
name = $.map(files, function (file) {
return file.name;
}).join(', ');
fileEntry = upload._enqueueFile(name, { fileNames: files });
fileEntry.data('files', files);
fileEntries.push(fileEntry);
} else {
for (i = 0; i < filesLength; i++) {
currentFile = files[i];
name = currentFile.name;
fileEntry = upload._enqueueFile(name, { fileNames: [currentFile] });
fileEntry.data('files', [currentFile]);
fileEntries.push(fileEntry);
}
}
return fileEntries;
},
performUpload: function (fileEntry) {
var upload = this.upload, formData = this.createFormData(), xhr = this.createXHR(), e = {
files: fileEntry.data('fileNames'),
XMLHttpRequest: xhr
};
if (!upload.trigger(UPLOAD, e)) {
upload._fileAction(fileEntry, CANCEL);
upload._hideUploadButton();
upload._showHeaderUploadStatus();
if (e.formData) {
formData = e.formData;
} else {
e.data = $.extend({}, e.data, antiForgeryTokens());
for (var key in e.data) {
formData.append(key, e.data[key]);
}
this.populateFormData(formData, fileEntry.data('files'));
}
upload._fileState(fileEntry, 'uploading');
$(fileEntry).removeClass('k-file-error').addClass('k-file-progress');
this.postFormData(upload.options.async.saveUrl, formData, fileEntry, xhr);
} else {
this.removeFileEntry(fileEntry);
}
},
onSaveSelected: function () {
var module = this;
$('.k-file', this.element).each(function () {
var fileEntry = $(this), started = isFileUploadStarted(fileEntry);
if (!started) {
module.performUpload(fileEntry);
}
});
},
onCancel: function (e) {
var fileEntry = getFileEntry(e);
this.stopUploadRequest(fileEntry);
this.removeFileEntry(fileEntry);
},
onRetry: function (e) {
var fileEntry = getFileEntry(e);
this.performUpload(fileEntry);
},
onRemove: function (e, data) {
var fileEntry = getFileEntry(e);
if (fileEntry.hasClass('k-file-success')) {
removeUploadedFile(fileEntry, this.upload, data);
} else {
this.removeFileEntry(fileEntry);
}
},
createXHR: function () {
return new XMLHttpRequest();
},
postFormData: function (url, data, fileEntry, xhr) {
var module = this;
fileEntry.data('request', xhr);
xhr.addEventListener('load', function (e) {
module.onRequestSuccess.call(module, e, fileEntry);
}, false);
xhr.addEventListener(ERROR, function (e) {
module.onRequestError.call(module, e, fileEntry);
}, false);
xhr.upload.addEventListener('progress', function (e) {
module.onRequestProgress.call(module, e, fileEntry);
}, false);
xhr.open('POST', url, true);
xhr.withCredentials = this.upload.options.async.withCredentials;
xhr.send(data);
},
createFormData: function () {
return new FormData();
},
populateFormData: function (data, files) {
var upload = this.upload, i, length = files.length;
for (i = 0; i < length; i++) {
data.append(upload.options.async.saveField || upload.name, files[i].rawFile);
}
return data;
},
onRequestSuccess: function (e, fileEntry) {
var xhr = e.target, module = this;
function raiseError() {
module.upload._onUploadError({ target: $(fileEntry, module.upload.wrapper) }, xhr);
}
if (xhr.status >= 200 && xhr.status <= 299) {
tryParseJSON(xhr.responseText, function (jsonResult) {
module.upload._onFileProgress({ target: $(fileEntry, module.upload.wrapper) }, 100);
module.upload._onUploadSuccess({ target: $(fileEntry, module.upload.wrapper) }, jsonResult, xhr);
module.cleanupFileEntry(fileEntry);
}, raiseError);
} else {
raiseError();
}
},
onRequestError: function (e, fileEntry) {
var xhr = e.target;
this.upload._onUploadError({ target: $(fileEntry, this.upload.wrapper) }, xhr);
},
cleanupFileEntry: function (fileEntry) {
var relatedInput = fileEntry.data('relatedInput'), uploadComplete = true;
if (relatedInput) {
$.each(relatedInput.data('relatedFileEntries') || [], function () {
if (this.parent().length > 0 && this[0] != fileEntry[0]) {
uploadComplete = uploadComplete && this.hasClass('k-file-success');
}
});
if (uploadComplete) {
relatedInput.remove();
}
}
},
removeFileEntry: function (fileEntry) {
this.cleanupFileEntry(fileEntry);
this.upload._removeFileEntry(fileEntry);
},
onRequestProgress: function (e, fileEntry) {
var percentComplete = Math.round(e.loaded * 100 / e.total);
this.upload._onFileProgress({ target: $(fileEntry, this.upload.wrapper) }, percentComplete);
},
stopUploadRequest: function (fileEntry) {
fileEntry.data('request').abort();
}
};
function getFileName(input) {
return $.map(inputFiles(input), function (file) {
return file.name;
}).join(', ');
}
function inputFiles($input) {
var input = $input[0];
if (input.files) {
return getAllFileInfo(input.files);
} else {
return [{
name: stripPath(input.value),
extension: getFileExtension(input.value),
size: null
}];
}
}
function getAllFileInfo(rawFiles) {
return $.map(rawFiles, function (file) {
return getFileInfo(file);
});
}
function getFileInfo(rawFile) {
var fileName = rawFile.name || rawFile.fileName;
return {
name: kendo.htmlEncode(fileName),
extension: getFileExtension(fileName),
size: rawFile.size || rawFile.fileSize,
rawFile: rawFile
};
}
function getFileExtension(fileName) {
var matches = fileName.match(rFileExtension);
return matches ? matches[0] : '';
}
function stripPath(name) {
var slashIndex = name.lastIndexOf('\\');
return slashIndex != -1 ? name.substr(slashIndex + 1) : name;
}
function assignGuidToFiles(files, unique) {
var uid = kendo.guid();
return $.map(files, function (file) {
file.uid = unique ? kendo.guid() : uid;
return file;
});
}
function shouldRemoveFileEntry(upload) {
return !upload.multiple && $('.k-file', upload.wrapper).length > 1;
}
function removeUploadedFile(fileEntry, upload, data) {
if (!upload._supportsRemove()) {
if (shouldRemoveFileEntry(upload)) {
upload._removeFileEntry(fileEntry);
}
return;
}
var files = fileEntry.data('fileNames');
var fileNames = $.map(files, function (file) {
return file.name;
});
upload._submitRemove(fileNames, data, function onSuccess(data, textStatus, xhr) {
upload._removeFileEntry(fileEntry);
upload.trigger(SUCCESS, {
operation: 'remove',
files: files,
response: data,
XMLHttpRequest: xhr
});
}, function onError(xhr) {
if (shouldRemoveFileEntry(upload)) {
upload._removeFileEntry(fileEntry);
}
upload.trigger(ERROR, {
operation: 'remove',
files: files,
XMLHttpRequest: xhr
});
logToConsole('Server response: ' + xhr.responseText);
});
}
function tryParseJSON(input, onSuccess, onError) {
var success = false, json = '';
try {
json = $.parseJSON(normalizeJSON(input));
success = true;
} catch (e) {
onError();
}
if (success) {
onSuccess(json);
}
}
function normalizeJSON(input) {
if (typeof input === 'undefined' || input === '') {
input = '{}';
}
return input;
}
function stopEvent(e) {
e.stopPropagation();
e.preventDefault();
}
function bindDragEventWrappers(element, namespace, onDragEnter, onDragLeave) {
var hideInterval, lastDrag;
element.on('dragenter' + namespace, function () {
onDragEnter();
lastDrag = new Date();
if (!hideInterval) {
hideInterval = setInterval(function () {
var sinceLastDrag = new Date() - lastDrag;
if (sinceLastDrag > 100) {
onDragLeave();
clearInterval(hideInterval);
hideInterval = null;
}
}, 100);
}
}).on('dragover' + namespace, function () {
lastDrag = new Date();
});
}
function isFileUploadStarted(fileEntry) {
return fileEntry.is('.k-file-progress, .k-file-success, .k-file-error');
}
function getFileEntry(e) {
return $(e.target).closest('.k-file');
}
kendo.ui.plugin(Upload);
}(window.kendo.jQuery));
return window.kendo;
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('kendo.filebrowser', [
'kendo.listview',
'kendo.dropdownlist',
'kendo.upload'
], f);
}(function () {
var __meta__ = {
id: 'filebrowser',
name: 'FileBrowser',
category: 'web',
description: '',
hidden: true,
depends: [
'selectable',
'listview',
'dropdownlist',
'upload'
]
};
(function ($, undefined) {
var kendo = window.kendo, Widget = kendo.ui.Widget, isPlainObject = $.isPlainObject, proxy = $.proxy, extend = $.extend, placeholderSupported = kendo.support.placeholder, browser = kendo.support.browser, isFunction = kendo.isFunction, trimSlashesRegExp = /(^\/|\/$)/g, CHANGE = 'change', APPLY = 'apply', ERROR = 'error', CLICK = 'click', NS = '.kendoFileBrowser', BREADCRUBMSNS = '.kendoBreadcrumbs', SEARCHBOXNS = '.kendoSearchBox', NAMEFIELD = 'name', SIZEFIELD = 'size', TYPEFIELD = 'type', DEFAULTSORTORDER = {
field: TYPEFIELD,
dir: 'asc'
}, EMPTYTILE = kendo.template('
${text}'), TOOLBARTMPL = '';
extend(true, kendo.data, {
schemas: {
'filebrowser': {
data: function (data) {
return data.items || data || [];
},
model: {
id: 'name',
fields: {
name: 'name',
size: 'size',
type: 'type'
}
}
}
}
});
extend(true, kendo.data, {
transports: {
'filebrowser': kendo.data.RemoteTransport.extend({
init: function (options) {
kendo.data.RemoteTransport.fn.init.call(this, $.extend(true, {}, this.options, options));
},
_call: function (type, options) {
options.data = $.extend({}, options.data, { path: this.options.path() });
if (isFunction(this.options[type])) {
this.options[type].call(this, options);
} else {
kendo.data.RemoteTransport.fn[type].call(this, options);
}
},
read: function (options) {
this._call('read', options);
},
create: function (options) {
this._call('create', options);
},
destroy: function (options) {
this._call('destroy', options);
},
update: function () {
},
options: {
read: { type: 'POST' },
update: { type: 'POST' },
create: { type: 'POST' },
destroy: { type: 'POST' }
}
})
}
});
function bindDragEventWrappers(element, onDragEnter, onDragLeave) {
var hideInterval, lastDrag;
element.on('dragenter' + NS, function () {
onDragEnter();
lastDrag = new Date();
if (!hideInterval) {
hideInterval = setInterval(function () {
var sinceLastDrag = new Date() - lastDrag;
if (sinceLastDrag > 100) {
onDragLeave();
clearInterval(hideInterval);
hideInterval = null;
}
}, 100);
}
}).on('dragover' + NS, function () {
lastDrag = new Date();
});
}
var offsetTop;
if (browser.msie && browser.version < 8) {
offsetTop = function (element) {
return element.offsetTop;
};
} else {
offsetTop = function (element) {
return element.offsetTop - $(element).height();
};
}
function concatPaths(path, name) {
if (path === undefined || !path.match(/\/$/)) {
path = (path || '') + '/';
}
return path + name;
}
function sizeFormatter(value) {
if (!value) {
return '';
}
var suffix = ' bytes';
if (value >= 1073741824) {
suffix = ' GB';
value /= 1073741824;
} else if (value >= 1048576) {
suffix = ' MB';
value /= 1048576;
} else if (value >= 1024) {
suffix = ' KB';
value /= 1024;
}
return Math.round(value * 100) / 100 + suffix;
}
function fieldName(fields, name) {
var descriptor = fields[name];
if (isPlainObject(descriptor)) {
return descriptor.from || descriptor.field || name;
}
return descriptor;
}
var FileBrowser = Widget.extend({
init: function (element, options) {
var that = this;
options = options || {};
Widget.fn.init.call(that, element, options);
that.element.addClass('k-filebrowser');
that.element.on(CLICK + NS, '.k-filebrowser-toolbar button:not(.k-state-disabled):has(.k-delete)', proxy(that._deleteClick, that)).on(CLICK + NS, '.k-filebrowser-toolbar button:not(.k-state-disabled):has(.k-addfolder)', proxy(that._addClick, that)).on('keydown' + NS, 'li.k-state-selected input', proxy(that._directoryKeyDown, that)).on('blur' + NS, 'li.k-state-selected input', proxy(that._directoryBlur, that));
that._dataSource();
that.refresh();
that.path(that.options.path);
},
options: {
name: 'FileBrowser',
messages: {
uploadFile: 'Upload',
orderBy: 'Arrange by',
orderByName: 'Name',
orderBySize: 'Size',
directoryNotFound: 'A directory with this name was not found.',
emptyFolder: 'Empty Folder',
deleteFile: 'Are you sure you want to delete "{0}"?',
invalidFileType: 'The selected file "{0}" is not valid. Supported file types are {1}.',
overwriteFile: 'A file with name "{0}" already exists in the current directory. Do you want to overwrite it?',
dropFilesHere: 'drop file here to upload',
search: 'Search'
},
transport: {},
path: '/',
fileTypes: '*.*'
},
events: [
ERROR,
CHANGE,
APPLY
],
destroy: function () {
var that = this;
Widget.fn.destroy.call(that);
that.dataSource.unbind(ERROR, that._errorHandler);
that.element.add(that.list).add(that.toolbar).off(NS);
kendo.destroy(that.element);
},
value: function () {
var that = this, selected = that._selectedItem(), path, fileUrl = that.options.transport.fileUrl;
if (selected && selected.get(TYPEFIELD) === 'f') {
path = concatPaths(that.path(), selected.get(NAMEFIELD)).replace(trimSlashesRegExp, '');
if (fileUrl) {
path = isFunction(fileUrl) ? fileUrl(path) : kendo.format(fileUrl, encodeURIComponent(path));
}
return path;
}
},
_selectedItem: function () {
var listView = this.listView, selected = listView.select();
if (selected.length) {
return this.dataSource.getByUid(selected.attr(kendo.attr('uid')));
}
},
_toolbar: function () {
var that = this, template = kendo.template(TOOLBARTMPL), messages = that.options.messages, arrangeBy = [
{
text: messages.orderByName,
value: 'name'
},
{
text: messages.orderBySize,
value: 'size'
}
];
that.toolbar = $(template({
messages: messages,
showUpload: that.options.transport.uploadUrl,
showCreate: that.options.transport.create,
showDelete: that.options.transport.destroy
})).appendTo(that.element).find('.k-upload input').kendoUpload({
multiple: false,
localization: { dropFilesHere: messages.dropFilesHere },
async: {
saveUrl: that.options.transport.uploadUrl,
autoUpload: true
},
upload: proxy(that._fileUpload, that),
error: function (e) {
that._error({
xhr: e.XMLHttpRequest,
status: 'error'
});
}
}).end();
that.upload = that.toolbar.find('.k-upload input').data('kendoUpload');
that.arrangeBy = that.toolbar.find('.k-tiles-arrange select').kendoDropDownList({
dataSource: arrangeBy,
dataTextField: 'text',
dataValueField: 'value',
change: function () {
that.orderBy(this.value());
}
}).data('kendoDropDownList');
that._attachDropzoneEvents();
},
_attachDropzoneEvents: function () {
var that = this;
if (that.options.transport.uploadUrl) {
bindDragEventWrappers($(document.documentElement), $.proxy(that._dropEnter, that), $.proxy(that._dropLeave, that));
that._scrollHandler = proxy(that._positionDropzone, that);
}
},
_dropEnter: function () {
this._positionDropzone();
$(document).on('scroll' + NS, this._scrollHandler);
},
_dropLeave: function () {
this._removeDropzone();
$(document).off('scroll' + NS, this._scrollHandler);
},
_positionDropzone: function () {
var that = this, element = that.element, offset = element.offset();
that.toolbar.find('.k-dropzone').addClass('k-filebrowser-dropzone').offset(offset).css({
width: element[0].clientWidth,
height: element[0].clientHeight,
lineHeight: element[0].clientHeight + 'px'
});
},
_removeDropzone: function () {
this.toolbar.find('.k-dropzone').removeClass('k-filebrowser-dropzone').css({
width: '',
height: '',
lineHeight: '',
top: '',
left: ''
});
},
_deleteClick: function () {
var that = this, item = that.listView.select(), message = kendo.format(that.options.messages.deleteFile, item.find('strong').text());
if (item.length && that._showMessage(message, 'confirm')) {
that.listView.remove(item);
}
},
_addClick: function () {
this.createDirectory();
},
_getFieldName: function (name) {
return fieldName(this.dataSource.reader.model.fields, name);
},
_fileUpload: function (e) {
var that = this, options = that.options, fileTypes = options.fileTypes, filterRegExp = new RegExp(('(' + fileTypes.split(',').join(')|(') + ')').replace(/\*\./g, '.*.'), 'i'), fileName = e.files[0].name, fileNameField = NAMEFIELD, sizeField = SIZEFIELD, model;
if (filterRegExp.test(fileName)) {
e.data = { path: that.path() };
model = that._createFile(fileName);
if (!model) {
e.preventDefault();
} else {
that.upload.one('success', function (e) {
model.set(fileNameField, e.response[that._getFieldName(fileNameField)]);
model.set(sizeField, e.response[that._getFieldName(sizeField)]);
that._tiles = that.listView.items().filter('[' + kendo.attr('type') + '=f]');
});
}
} else {
e.preventDefault();
that._showMessage(kendo.format(options.messages.invalidFileType, fileName, fileTypes));
}
},
_findFile: function (name) {
var data = this.dataSource.data(), idx, result, typeField = TYPEFIELD, nameField = NAMEFIELD, length;
name = name.toLowerCase();
for (idx = 0, length = data.length; idx < length; idx++) {
if (data[idx].get(typeField) === 'f' && data[idx].get(nameField).toLowerCase() === name) {
result = data[idx];
break;
}
}
return result;
},
_createFile: function (fileName) {
var that = this, idx, length, index = 0, model = {}, typeField = TYPEFIELD, view = that.dataSource.view(), file = that._findFile(fileName);
if (file) {
if (!that._showMessage(kendo.format(that.options.messages.overwriteFile, fileName), 'confirm')) {
return null;
} else {
file._forceReload = true;
return file;
}
}
for (idx = 0, length = view.length; idx < length; idx++) {
if (view[idx].get(typeField) === 'f') {
index = idx;
break;
}
}
model[typeField] = 'f';
model[NAMEFIELD] = fileName;
model[SIZEFIELD] = 0;
return that.dataSource.insert(++index, model);
},
createDirectory: function () {
var that = this, idx, length, lastDirectoryIdx = 0, typeField = TYPEFIELD, nameField = NAMEFIELD, view = that.dataSource.data(), name = that._nameDirectory(), model = new that.dataSource.reader.model();
for (idx = 0, length = view.length; idx < length; idx++) {
if (view[idx].get(typeField) === 'd') {
lastDirectoryIdx = idx;
}
}
model.set(typeField, 'd');
model.set(nameField, name);
that.listView.one('dataBound', function () {
var selected = that.listView.items().filter('[' + kendo.attr('uid') + '=' + model.uid + ']'), input = selected.find('input');
if (selected.length) {
this.edit(selected);
}
this.element.scrollTop(selected.attr('offsetTop') - this.element[0].offsetHeight);
setTimeout(function () {
input.select();
});
}).one('save', function (e) {
var value = e.model.get(nameField);
if (!value) {
e.model.set(nameField, name);
} else {
e.model.set(nameField, that._nameExists(value, model.uid) ? that._nameDirectory() : value);
}
});
that.dataSource.insert(++lastDirectoryIdx, model);
},
_directoryKeyDown: function (e) {
if (e.keyCode == 13) {
e.currentTarget.blur();
}
},
_directoryBlur: function () {
this.listView.save();
},
_nameExists: function (name, uid) {
var data = this.dataSource.data(), typeField = TYPEFIELD, nameField = NAMEFIELD, idx, length;
for (idx = 0, length = data.length; idx < length; idx++) {
if (data[idx].get(typeField) === 'd' && data[idx].get(nameField).toLowerCase() === name.toLowerCase() && data[idx].uid !== uid) {
return true;
}
}
return false;
},
_nameDirectory: function () {
var name = 'New folder', data = this.dataSource.data(), directoryNames = [], typeField = TYPEFIELD, nameField = NAMEFIELD, candidate, idx, length;
for (idx = 0, length = data.length; idx < length; idx++) {
if (data[idx].get(typeField) === 'd' && data[idx].get(nameField).toLowerCase().indexOf(name.toLowerCase()) > -1) {
directoryNames.push(data[idx].get(nameField));
}
}
if ($.inArray(name, directoryNames) > -1) {
idx = 2;
do {
candidate = name + ' (' + idx + ')';
idx++;
} while ($.inArray(candidate, directoryNames) > -1);
name = candidate;
}
return name;
},
orderBy: function (field) {
this.dataSource.sort([
{
field: TYPEFIELD,
dir: 'asc'
},
{
field: field,
dir: 'asc'
}
]);
},
search: function (name) {
this.dataSource.filter({
field: NAMEFIELD,
operator: 'contains',
value: name
});
},
_content: function () {
var that = this;
that.list = $('
').appendTo(that.element).on('dblclick' + NS, 'li', proxy(that._dblClick, that));
that.listView = new kendo.ui.ListView(that.list, {
dataSource: that.dataSource,
template: that._itemTmpl(),
editTemplate: that._editTmpl(),
selectable: true,
autoBind: false,
dataBinding: function (e) {
that.toolbar.find('.k-delete').parent().addClass('k-state-disabled');
if (e.action === 'remove' || e.action === 'sync') {
e.preventDefault();
}
},
dataBound: function () {
if (that.dataSource.view().length) {
that._tiles = this.items().filter('[' + kendo.attr('type') + '=f]');
} else {
this.wrapper.append(EMPTYTILE({ text: that.options.messages.emptyFolder }));
}
},
change: proxy(that._listViewChange, that)
});
},
_dblClick: function (e) {
var that = this, li = $(e.currentTarget);
if (li.hasClass('k-edit-item')) {
that._directoryBlur();
}
if (li.filter('[' + kendo.attr('type') + '=d]').length) {
var folder = that.dataSource.getByUid(li.attr(kendo.attr('uid')));
if (folder) {
that.path(concatPaths(that.path(), folder.get(NAMEFIELD)));
that.breadcrumbs.value(that.path());
}
} else if (li.filter('[' + kendo.attr('type') + '=f]').length) {
that.trigger(APPLY);
}
},
_listViewChange: function () {
var selected = this._selectedItem();
if (selected) {
this.toolbar.find('.k-delete').parent().removeClass('k-state-disabled');
if (selected.get(TYPEFIELD) === 'f') {
this.trigger(CHANGE);
}
}
},
_dataSource: function () {
var that = this, options = that.options, transport = options.transport, typeSortOrder = extend({}, DEFAULTSORTORDER), nameSortOrder = {
field: NAMEFIELD,
dir: 'asc'
}, schema, dataSource = {
type: transport.type || 'filebrowser',
sort: [
typeSortOrder,
nameSortOrder
]
};
if (isPlainObject(transport)) {
transport.path = proxy(that.path, that);
dataSource.transport = transport;
}
if (isPlainObject(options.schema)) {
dataSource.schema = options.schema;
} else if (transport.type && isPlainObject(kendo.data.schemas[transport.type])) {
schema = kendo.data.schemas[transport.type];
}
if (that.dataSource && that._errorHandler) {
that.dataSource.unbind(ERROR, that._errorHandler);
} else {
that._errorHandler = proxy(that._error, that);
}
that.dataSource = kendo.data.DataSource.create(dataSource).bind(ERROR, that._errorHandler);
},
_navigation: function () {
var that = this, navigation = $('
').appendTo(this.element);
that.breadcrumbs = navigation.find('input:first').kendoBreadcrumbs({
value: that.options.path,
change: function () {
that.path(this.value());
}
}).data('kendoBreadcrumbs');
that.searchBox = navigation.parent().find('input:last').kendoSearchBox({
label: that.options.messages.search,
change: function () {
that.search(this.value());
}
}).data('kendoSearchBox');
},
_error: function (e) {
var that = this, status;
if (!that.trigger(ERROR, e)) {
status = e.xhr.status;
if (e.status == 'error') {
if (status == '404') {
that._showMessage(that.options.messages.directoryNotFound);
} else if (status != '0') {
that._showMessage('Error! The requested URL returned ' + status + ' - ' + e.xhr.statusText);
}
} else if (status == 'timeout') {
that._showMessage('Error! Server timeout.');
}
}
},
_showMessage: function (message, type) {
return window[type || 'alert'](message);
},
refresh: function () {
var that = this;
that._navigation();
that._toolbar();
that._content();
},
_editTmpl: function () {
var html = '
';
html += '#if(' + TYPEFIELD + ' == "d") { #';
html += '
';
html += '#}else{#';
html += '
';
html += '#}#';
html += '#if(' + TYPEFIELD + ' == "d") { #';
html += '';
html += '#}#';
html += '';
return proxy(kendo.template(html), { sizeFormatter: sizeFormatter });
},
_itemTmpl: function () {
var html = '
';
html += '#if(' + TYPEFIELD + ' == "d") { #';
html += '
';
html += '#}else{#';
html += '
';
html += '#}#';
html += '${' + NAMEFIELD + '}';
html += '#if(' + TYPEFIELD + ' == "f") { # ${this.sizeFormatter(' + SIZEFIELD + ')} #}#';
html += '';
return proxy(kendo.template(html), { sizeFormatter: sizeFormatter });
},
path: function (value) {
var that = this, path = that._path || '';
if (value !== undefined) {
that._path = value.replace(trimSlashesRegExp, '') + '/';
that.dataSource.read({ path: that._path });
return;
}
if (path) {
path = path.replace(trimSlashesRegExp, '');
}
return path === '/' || path === '' ? '' : path + '/';
}
});
var SearchBox = Widget.extend({
init: function (element, options) {
var that = this;
options = options || {};
Widget.fn.init.call(that, element, options);
if (placeholderSupported) {
that.element.attr('placeholder', that.options.label);
}
that._wrapper();
that.element.on('keydown' + SEARCHBOXNS, proxy(that._keydown, that)).on('change' + SEARCHBOXNS, proxy(that._updateValue, that));
that.wrapper.on(CLICK + SEARCHBOXNS, 'a', proxy(that._click, that));
if (!placeholderSupported) {
that.element.on('focus' + SEARCHBOXNS, proxy(that._focus, that)).on('blur' + SEARCHBOXNS, proxy(that._blur, that));
}
},
options: {
name: 'SearchBox',
label: 'Search',
value: ''
},
events: [CHANGE],
destroy: function () {
var that = this;
that.wrapper.add(that.element).add(that.label).off(SEARCHBOXNS);
Widget.fn.destroy.call(that);
},
_keydown: function (e) {
if (e.keyCode === 13) {
this._updateValue();
}
},
_click: function (e) {
e.preventDefault();
this._updateValue();
},
_updateValue: function () {
var that = this, value = that.element.val();
if (value !== that.value()) {
that.value(value);
that.trigger(CHANGE);
}
},
_blur: function () {
this._updateValue();
this._toggleLabel();
},
_toggleLabel: function () {
if (!placeholderSupported) {
this.label.toggle(!this.element.val());
}
},
_focus: function () {
this.label.hide();
},
_wrapper: function () {
var element = this.element, wrapper = element.parents('.k-search-wrap');
element[0].style.width = '';
element.addClass('k-input');
if (!wrapper.length) {
wrapper = element.wrap($('
')).parent();
if (!placeholderSupported) {
$('
').insertBefore(element);
}
$('
').appendTo(wrapper);
}
this.wrapper = wrapper;
this.label = wrapper.find('>label');
},
value: function (value) {
var that = this;
if (value !== undefined) {
that.options.value = value;
that.element.val(value);
that._toggleLabel();
return;
}
return that.options.value;
}
});
var Breadcrumbs = Widget.extend({
init: function (element, options) {
var that = this;
options = options || {};
Widget.fn.init.call(that, element, options);
that._wrapper();
that.wrapper.on('focus' + BREADCRUBMSNS, 'input', proxy(that._focus, that)).on('blur' + BREADCRUBMSNS, 'input', proxy(that._blur, that)).on('keydown' + BREADCRUBMSNS, 'input', proxy(that._keydown, that)).on(CLICK + BREADCRUBMSNS, 'a.k-i-arrow-n:first', proxy(that._rootClick, that)).on(CLICK + BREADCRUBMSNS, 'a:not(.k-i-arrow-n)', proxy(that._click, that));
that.value(that.options.value);
},
options: {
name: 'Breadcrumbs',
gap: 50
},
events: [CHANGE],
destroy: function () {
var that = this;
Widget.fn.destroy.call(that);
that.wrapper.add(that.wrapper.find('input')).add(that.wrapper.find('a')).off(BREADCRUBMSNS);
},
_update: function (val) {
val = (val || '').charAt(0) === '/' ? val : '/' + (val || '');
if (val !== this.value()) {
this.value(val);
this.trigger(CHANGE);
}
},
_click: function (e) {
e.preventDefault();
this._update(this._path($(e.target).prevAll('a:not(.k-i-arrow-n)').addBack()));
},
_rootClick: function (e) {
e.preventDefault();
this._update('');
},
_focus: function () {
var that = this, element = that.element;
that.overlay.hide();
that.element.val(that.value());
setTimeout(function () {
element.select();
});
},
_blur: function () {
if (this.overlay.is(':visible')) {
return;
}
var that = this, element = that.element, val = element.val().replace(/\/{2,}/g, '/');
that.overlay.show();
element.val('');
that._update(val);
},
_keydown: function (e) {
var that = this;
if (e.keyCode === 13) {
that._blur();
setTimeout(function () {
that.overlay.find('a:first').focus();
});
}
},
_wrapper: function () {
var element = this.element, wrapper = element.parents('.k-breadcrumbs'), overlay;
element[0].style.width = '';
element.addClass('k-input');
if (!wrapper.length) {
wrapper = element.wrap($('
')).parent();
}
overlay = wrapper.find('.k-breadcrumbs-wrap');
if (!overlay.length) {
overlay = $('
').appendTo(wrapper);
}
this.wrapper = wrapper;
this.overlay = overlay;
},
refresh: function () {
var html = '', value = this.value(), segments, segment, idx, length;
if (value === undefined || !value.match(/^\//)) {
value = '/' + (value || '');
}
segments = value.split('/');
for (idx = 0, length = segments.length; idx < length; idx++) {
segment = segments[idx];
if (segment) {
if (!html) {
html += '
root';
}
html += '
' + segments[idx] + '';
html += '
>';
}
}
this.overlay.empty().append($(html));
this._adjustSectionWidth();
},
_adjustSectionWidth: function () {
var that = this, wrapper = that.wrapper, width = wrapper.width() - that.options.gap, links = that.overlay.find('a'), a;
links.each(function (index) {
a = $(this);
if (a.parent().width() > width) {
if (index == links.length - 1) {
a.width(width);
} else {
a.prev().addBack().hide();
}
}
});
},
value: function (val) {
if (val !== undefined) {
this._value = val.replace(/\/{2,}/g, '/');
this.refresh();
return;
}
return this._value;
},
_path: function (trail) {
return '/' + $.map(trail, function (b) {
return $(b).text();
}).join('/');
}
});
kendo.ui.plugin(FileBrowser);
kendo.ui.plugin(Breadcrumbs);
kendo.ui.plugin(SearchBox);
}(window.kendo.jQuery));
return window.kendo;
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('kendo.imagebrowser', ['kendo.filebrowser'], f);
}(function () {
var __meta__ = {
id: 'imagebrowser',
name: 'ImageBrowser',
category: 'web',
description: '',
hidden: true,
depends: ['filebrowser']
};
(function ($, undefined) {
var kendo = window.kendo, FileBrowser = kendo.ui.FileBrowser, isPlainObject = $.isPlainObject, proxy = $.proxy, extend = $.extend, browser = kendo.support.browser, isFunction = kendo.isFunction, trimSlashesRegExp = /(^\/|\/$)/g, ERROR = 'error', NS = '.kendoImageBrowser', NAMEFIELD = 'name', SIZEFIELD = 'size', TYPEFIELD = 'type', DEFAULTSORTORDER = {
field: TYPEFIELD,
dir: 'asc'
}, EMPTYTILE = kendo.template('
${text}');
extend(true, kendo.data, {
schemas: {
'imagebrowser': {
data: function (data) {
return data.items || data || [];
},
model: {
id: 'name',
fields: {
name: 'name',
size: 'size',
type: 'type'
}
}
}
}
});
extend(true, kendo.data, {
transports: {
'imagebrowser': kendo.data.RemoteTransport.extend({
init: function (options) {
kendo.data.RemoteTransport.fn.init.call(this, $.extend(true, {}, this.options, options));
},
_call: function (type, options) {
options.data = $.extend({}, options.data, { path: this.options.path() });
if (isFunction(this.options[type])) {
this.options[type].call(this, options);
} else {
kendo.data.RemoteTransport.fn[type].call(this, options);
}
},
read: function (options) {
this._call('read', options);
},
create: function (options) {
this._call('create', options);
},
destroy: function (options) {
this._call('destroy', options);
},
update: function () {
},
options: {
read: { type: 'POST' },
update: { type: 'POST' },
create: { type: 'POST' },
destroy: { type: 'POST' }
}
})
}
});
var offsetTop;
if (browser.msie && browser.version < 8) {
offsetTop = function (element) {
return element.offsetTop;
};
} else {
offsetTop = function (element) {
return element.offsetTop - $(element).height();
};
}
function concatPaths(path, name) {
if (path === undefined || !path.match(/\/$/)) {
path = (path || '') + '/';
}
return path + name;
}
function sizeFormatter(value) {
if (!value) {
return '';
}
var suffix = ' bytes';
if (value >= 1073741824) {
suffix = ' GB';
value /= 1073741824;
} else if (value >= 1048576) {
suffix = ' MB';
value /= 1048576;
} else if (value >= 1024) {
suffix = ' KB';
value /= 1024;
}
return Math.round(value * 100) / 100 + suffix;
}
var ImageBrowser = FileBrowser.extend({
init: function (element, options) {
var that = this;
options = options || {};
FileBrowser.fn.init.call(that, element, options);
that.element.addClass('k-imagebrowser');
},
options: {
name: 'ImageBrowser',
fileTypes: '*.png,*.gif,*.jpg,*.jpeg'
},
value: function () {
var that = this, selected = that._selectedItem(), path, imageUrl = that.options.transport.imageUrl;
if (selected && selected.get(TYPEFIELD) === 'f') {
path = concatPaths(that.path(), selected.get(NAMEFIELD)).replace(trimSlashesRegExp, '');
if (imageUrl) {
path = isFunction(imageUrl) ? imageUrl(path) : kendo.format(imageUrl, encodeURIComponent(path));
}
return path;
}
},
_fileUpload: function (e) {
var that = this, options = that.options, fileTypes = options.fileTypes, filterRegExp = new RegExp(('(' + fileTypes.split(',').join(')|(') + ')').replace(/\*\./g, '.*.'), 'i'), fileName = e.files[0].name, fileNameField = NAMEFIELD, sizeField = SIZEFIELD, model;
if (filterRegExp.test(fileName)) {
e.data = { path: that.path() };
model = that._createFile(fileName);
if (!model) {
e.preventDefault();
} else {
model._uploading = true;
that.upload.one('success', function (e) {
delete model._uploading;
model.set(fileNameField, e.response[that._getFieldName(fileNameField)]);
model.set(sizeField, e.response[that._getFieldName(sizeField)]);
that._tiles = that.listView.items().filter('[' + kendo.attr('type') + '=f]');
that._scroll();
});
}
} else {
e.preventDefault();
that._showMessage(kendo.format(options.messages.invalidFileType, fileName, fileTypes));
}
},
_content: function () {
var that = this;
that.list = $('
').appendTo(that.element).on('scroll' + NS, proxy(that._scroll, that)).on('dblclick' + NS, 'li', proxy(that._dblClick, that));
that.listView = new kendo.ui.ListView(that.list, {
dataSource: that.dataSource,
template: that._itemTmpl(),
editTemplate: that._editTmpl(),
selectable: true,
autoBind: false,
dataBinding: function (e) {
that.toolbar.find('.k-delete').parent().addClass('k-state-disabled');
if (e.action === 'remove' || e.action === 'sync') {
e.preventDefault();
}
},
dataBound: function () {
if (that.dataSource.view().length) {
that._tiles = this.items().filter('[' + kendo.attr('type') + '=f]');
that._scroll();
} else {
this.wrapper.append(EMPTYTILE({ text: that.options.messages.emptyFolder }));
}
},
change: proxy(that._listViewChange, that)
});
},
_dataSource: function () {
var that = this, options = that.options, transport = options.transport, typeSortOrder = extend({}, DEFAULTSORTORDER), nameSortOrder = {
field: NAMEFIELD,
dir: 'asc'
}, schema, dataSource = {
type: transport.type || 'imagebrowser',
sort: [
typeSortOrder,
nameSortOrder
]
};
if (isPlainObject(transport)) {
transport.path = proxy(that.path, that);
dataSource.transport = transport;
}
if (isPlainObject(options.schema)) {
dataSource.schema = options.schema;
} else if (transport.type && isPlainObject(kendo.data.schemas[transport.type])) {
schema = kendo.data.schemas[transport.type];
}
if (that.dataSource && that._errorHandler) {
that.dataSource.unbind(ERROR, that._errorHandler);
} else {
that._errorHandler = proxy(that._error, that);
}
that.dataSource = kendo.data.DataSource.create(dataSource).bind(ERROR, that._errorHandler);
},
_loadImage: function (li) {
var that = this, element = $(li), dataItem = that.dataSource.getByUid(element.attr(kendo.attr('uid'))), name = dataItem.get(NAMEFIELD), thumbnailUrl = that.options.transport.thumbnailUrl, img = $('
![]()
', { alt: name }), urlJoin = '?';
if (dataItem._uploading) {
return;
}
img.hide().on('load' + NS, function () {
$(this).prev().remove().end().addClass('k-image').fadeIn();
});
element.find('.k-loading').after(img);
if (isFunction(thumbnailUrl)) {
thumbnailUrl = thumbnailUrl(that.path(), encodeURIComponent(name));
} else {
if (thumbnailUrl.indexOf('?') >= 0) {
urlJoin = '&';
}
thumbnailUrl = thumbnailUrl + urlJoin + 'path=' + encodeURIComponent(that.path() + name);
if (dataItem._forceReload) {
thumbnailUrl += '&_=' + new Date().getTime();
delete dataItem._forceReload;
}
}
img.attr('src', thumbnailUrl);
li.loaded = true;
},
_scroll: function () {
var that = this;
if (that.options.transport && that.options.transport.thumbnailUrl) {
clearTimeout(that._timeout);
that._timeout = setTimeout(function () {
var height = that.list.outerHeight(), viewTop = that.list.scrollTop(), viewBottom = viewTop + height;
that._tiles.each(function () {
var top = offsetTop(this), bottom = top + this.offsetHeight;
if (top >= viewTop && top < viewBottom || bottom >= viewTop && bottom < viewBottom) {
that._loadImage(this);
}
if (top > viewBottom) {
return false;
}
});
that._tiles = that._tiles.filter(function () {
return !this.loaded;
});
}, 250);
}
},
_itemTmpl: function () {
var that = this, html = '
';
html += '#if(' + TYPEFIELD + ' == "d") { #';
html += '
';
html += '#}else{#';
if (that.options.transport && that.options.transport.thumbnailUrl) {
html += '
';
} else {
html += '
';
}
html += '#}#';
html += '${' + NAMEFIELD + '}';
html += '#if(' + TYPEFIELD + ' == "f") { # ${this.sizeFormatter(' + SIZEFIELD + ')} #}#';
html += '';
return proxy(kendo.template(html), { sizeFormatter: sizeFormatter });
}
});
kendo.ui.plugin(ImageBrowser);
}(window.kendo.jQuery));
return window.kendo;
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('util/undoredostack', ['kendo.core'], f);
}(function () {
(function (kendo) {
var UndoRedoStack = kendo.Observable.extend({
init: function (options) {
kendo.Observable.fn.init.call(this, options);
this.clear();
},
events: [
'undo',
'redo'
],
push: function (command) {
this.stack = this.stack.slice(0, this.currentCommandIndex + 1);
this.currentCommandIndex = this.stack.push(command) - 1;
},
undo: function () {
if (this.canUndo()) {
var command = this.stack[this.currentCommandIndex--];
command.undo();
this.trigger('undo', { command: command });
}
},
redo: function () {
if (this.canRedo()) {
var command = this.stack[++this.currentCommandIndex];
command.redo();
this.trigger('redo', { command: command });
}
},
clear: function () {
this.stack = [];
this.currentCommandIndex = -1;
},
canUndo: function () {
return this.currentCommandIndex >= 0;
},
canRedo: function () {
return this.currentCommandIndex != this.stack.length - 1;
}
});
kendo.deepExtend(kendo, { util: { UndoRedoStack: UndoRedoStack } });
}(kendo));
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('editor/main', [
'util/undoredostack',
'kendo.combobox',
'kendo.dropdownlist',
'kendo.window',
'kendo.colorpicker'
], f);
}(function () {
(function ($, undefined) {
var kendo = window.kendo, Class = kendo.Class, Widget = kendo.ui.Widget, os = kendo.support.mobileOS, browser = kendo.support.browser, extend = $.extend, proxy = $.proxy, deepExtend = kendo.deepExtend, keys = kendo.keys;
var ToolTemplate = Class.extend({
init: function (options) {
this.options = options;
},
getHtml: function () {
var options = this.options;
return kendo.template(options.template, { useWithBlock: false })(options);
}
});
var EditorUtils = {
editorWrapperTemplate: '',
buttonTemplate: '
#= data.title #',
colorPickerTemplate: '
',
comboBoxTemplate: '
',
dropDownListTemplate: '
',
separatorTemplate: '
',
overflowAnchorTemplate: '
',
formatByName: function (name, format) {
for (var i = 0; i < format.length; i++) {
if ($.inArray(name, format[i].tags) >= 0) {
return format[i];
}
}
},
registerTool: function (toolName, tool) {
var toolOptions = tool.options;
if (toolOptions && toolOptions.template) {
toolOptions.template.options.cssClass = 'k-' + toolName;
}
if (!tool.name) {
tool.options.name = toolName;
tool.name = toolName.toLowerCase();
}
Editor.defaultTools[toolName] = tool;
},
registerFormat: function (formatName, format) {
Editor.fn.options.formats[formatName] = format;
}
};
var messages = {
bold: 'Bold',
italic: 'Italic',
underline: 'Underline',
strikethrough: 'Strikethrough',
superscript: 'Superscript',
subscript: 'Subscript',
justifyCenter: 'Center text',
justifyLeft: 'Align text left',
justifyRight: 'Align text right',
justifyFull: 'Justify',
insertUnorderedList: 'Insert unordered list',
insertOrderedList: 'Insert ordered list',
indent: 'Indent',
outdent: 'Outdent',
createLink: 'Insert hyperlink',
unlink: 'Remove hyperlink',
insertImage: 'Insert image',
insertFile: 'Insert file',
insertHtml: 'Insert HTML',
viewHtml: 'View HTML',
fontName: 'Select font family',
fontNameInherit: '(inherited font)',
fontSize: 'Select font size',
fontSizeInherit: '(inherited size)',
formatBlock: 'Format',
formatting: 'Format',
foreColor: 'Color',
backColor: 'Background color',
style: 'Styles',
emptyFolder: 'Empty Folder',
editAreaTitle: 'Editable area. Press F10 for toolbar.',
uploadFile: 'Upload',
orderBy: 'Arrange by:',
orderBySize: 'Size',
orderByName: 'Name',
invalidFileType: 'The selected file "{0}" is not valid. Supported file types are {1}.',
deleteFile: 'Are you sure you want to delete "{0}"?',
overwriteFile: 'A file with name "{0}" already exists in the current directory. Do you want to overwrite it?',
directoryNotFound: 'A directory with this name was not found.',
imageWebAddress: 'Web address',
imageAltText: 'Alternate text',
imageWidth: 'Width (px)',
imageHeight: 'Height (px)',
fileWebAddress: 'Web address',
fileTitle: 'Title',
linkWebAddress: 'Web address',
linkText: 'Text',
linkToolTip: 'ToolTip',
linkOpenInNewWindow: 'Open link in new window',
dialogUpdate: 'Update',
dialogInsert: 'Insert',
dialogCancel: 'Cancel',
createTable: 'Create table',
createTableHint: 'Create a {0} x {1} table',
addColumnLeft: 'Add column on the left',
addColumnRight: 'Add column on the right',
addRowAbove: 'Add row above',
addRowBelow: 'Add row below',
deleteRow: 'Delete row',
deleteColumn: 'Delete column'
};
var supportedBrowser = !os || os.ios && os.flatVersion >= 500 || !os.ios && typeof document.documentElement.contentEditable != 'undefined';
var toolGroups = {
basic: [
'bold',
'italic',
'underline'
],
alignment: [
'justifyLeft',
'justifyCenter',
'justifyRight'
],
lists: [
'insertUnorderedList',
'insertOrderedList'
],
indenting: [
'indent',
'outdent'
],
links: [
'createLink',
'unlink'
],
tables: [
'createTable',
'addColumnLeft',
'addColumnRight',
'addRowAbove',
'addRowBelow',
'deleteRow',
'deleteColumn'
]
};
var Editor = Widget.extend({
init: function (element, options) {
var that = this, value, editorNS = kendo.ui.editor, toolbarContainer, toolbarOptions, type;
var domElement;
var dom = editorNS.Dom;
if (!supportedBrowser) {
return;
}
Widget.fn.init.call(that, element, options);
that.options = deepExtend({}, that.options, options);
that.options.tools = that.options.tools.slice();
element = that.element;
domElement = element[0];
type = dom.name(domElement);
this._registerHandler(element.closest('form'), 'submit', proxy(that.update, that, undefined));
toolbarOptions = extend({}, that.options);
toolbarOptions.editor = that;
if (type == 'textarea') {
that._wrapTextarea();
toolbarContainer = that.wrapper.find('.k-editor-toolbar');
if (domElement.id) {
toolbarContainer.attr('aria-controls', domElement.id);
}
} else {
that.element.attr('contenteditable', true).addClass('k-widget k-editor k-editor-inline');
toolbarOptions.popup = true;
toolbarContainer = $('
').insertBefore(element);
}
that.toolbar = new editorNS.Toolbar(toolbarContainer[0], toolbarOptions);
that.toolbar.bindTo(that);
if (type == 'textarea') {
setTimeout(function () {
var heightStyle = that.wrapper[0].style.height;
var expectedHeight = parseInt(heightStyle, 10);
var actualHeight = that.wrapper.height();
if (heightStyle.indexOf('px') > 0 && !isNaN(expectedHeight) && actualHeight > expectedHeight) {
that.wrapper.height(expectedHeight - (actualHeight - expectedHeight));
}
});
}
that._resizable();
that._initializeContentElement(that);
that.keyboard = new editorNS.Keyboard([
new editorNS.BackspaceHandler(that),
new editorNS.TypingHandler(that),
new editorNS.SystemHandler(that)
]);
that.clipboard = new editorNS.Clipboard(this);
that.undoRedoStack = new kendo.util.UndoRedoStack();
if (options && options.value) {
value = options.value;
} else if (that.textarea) {
value = domElement.value;
if (that.options.encoded && $.trim(domElement.defaultValue).length) {
value = domElement.defaultValue;
}
value = value.replace(/[\r\n\v\f\t ]+/gi, ' ');
} else {
value = domElement.innerHTML;
}
that.value(value || kendo.ui.editor.emptyElementContent);
this._registerHandler(document, {
'mousedown': function () {
that._endTyping();
},
'mouseup': function () {
that._mouseup();
}
});
that.toolbar.resize();
kendo.notify(that);
},
_endTyping: function () {
var keyboard = this.keyboard;
try {
if (keyboard.isTypingInProgress()) {
keyboard.endTyping(true);
this.saveSelection();
}
} catch (e) {
}
},
_selectionChange: function () {
if (!browser.msie) {
kendo.ui.editor.Dom.ensureTrailingBreaks(this.body);
}
this._selectionStarted = false;
this.saveSelection();
this.trigger('select', {});
},
_resizable: function () {
var resizable = this.options.resizable;
var isResizable = $.isPlainObject(resizable) ? resizable.content === undefined || resizable.content === true : resizable;
if (isResizable && this.textarea) {
$('
').insertAfter(this.textarea);
this.wrapper.kendoResizable(extend({}, this.options.resizable, {
start: function (e) {
var editor = this.editor = $(e.currentTarget).closest('.k-editor');
this.initialSize = editor.height();
editor.find('td:last').append('
');
},
resize: function (e) {
var delta = e.y.initialDelta;
var newSize = this.initialSize + delta;
var min = this.options.min || 0;
var max = this.options.max || Infinity;
newSize = Math.min(max, Math.max(min, newSize));
this.editor.height(newSize);
},
resizeend: function () {
this.editor.find('.k-overlay').remove();
this.editor = null;
}
}));
}
},
_wrapTextarea: function () {
var that = this, textarea = that.element, w = textarea[0].style.width, h = textarea[0].style.height, template = EditorUtils.editorWrapperTemplate, editorWrap = $(template).insertBefore(textarea).width(w).height(h), editArea = editorWrap.find('.k-editable-area');
textarea.attr('autocomplete', 'off').appendTo(editArea).addClass('k-content k-raw-content').css('display', 'none');
that.textarea = textarea;
that.wrapper = editorWrap;
},
_createContentElement: function (stylesheets) {
var editor = this;
var iframe, wnd, doc;
var textarea = editor.textarea;
var specifiedDomain = editor.options.domain;
var domain = specifiedDomain || document.domain;
var domainScript = '';
var src = 'javascript:""';
if (specifiedDomain || domain != location.hostname) {
domainScript = '';
src = 'javascript:document.write(\'' + domainScript + '\')';
}
textarea.hide();
iframe = $('
', {
title: editor.options.messages.editAreaTitle,
frameBorder: '0'
})[0];
$(iframe).css('display', '').addClass('k-content').attr('tabindex', textarea[0].tabIndex).insertBefore(textarea);
iframe.src = src;
wnd = iframe.contentWindow || iframe;
doc = wnd.document || iframe.contentDocument;
$(iframe).one('load', function () {
editor.toolbar.decorateFrom(doc.body);
});
doc.open();
doc.write('' + '
' + '' + domainScript + '' + $.map(stylesheets, function (href) {
return '
';
}).join('') + '');
doc.close();
return wnd;
},
_blur: function () {
var textarea = this.textarea;
var old = textarea ? textarea.val() : this._oldValue;
var value = this.options.encoded ? this.encodedValue() : this.value();
this.update();
if (textarea) {
textarea.trigger('blur');
}
if (value != old) {
this.trigger('change');
}
},
_spellCorrect: function (editor) {
var beforeCorrection;
var falseTrigger = false;
this._registerHandler(editor.body, {
'contextmenu': function () {
editor.one('select', function () {
beforeCorrection = null;
});
editor._spellCorrectTimeout = setTimeout(function () {
beforeCorrection = new kendo.ui.editor.RestorePoint(editor.getRange());
falseTrigger = false;
}, 10);
},
'input': function () {
if (!beforeCorrection) {
return;
}
if (kendo.support.browser.mozilla && !falseTrigger) {
falseTrigger = true;
return;
}
kendo.ui.editor._finishUpdate(editor, beforeCorrection);
}
});
},
_registerHandler: function (element, type, handler) {
element = $(element);
if (!this._handlers) {
this._handlers = [];
}
if (element.length) {
if ($.isPlainObject(type)) {
for (var t in type) {
if (type.hasOwnProperty(t)) {
this._registerHandler(element, t, type[t]);
}
}
} else {
this._handlers.push({
element: element,
type: type,
handler: handler
});
element.on(type, handler);
}
}
},
_deregisterHandlers: function () {
var handlers = this._handlers;
for (var i = 0; i < handlers.length; i++) {
var h = handlers[i];
h.element.off(h.type, h.handler);
}
this._handlers = [];
},
_initializeContentElement: function () {
var editor = this;
var doc;
var blurTrigger;
if (editor.textarea) {
editor.window = editor._createContentElement(editor.options.stylesheets);
doc = editor.document = editor.window.contentDocument || editor.window.document;
editor.body = doc.body;
blurTrigger = editor.window;
this._registerHandler(doc, 'mouseup', proxy(this._mouseup, this));
} else {
editor.window = window;
doc = editor.document = document;
editor.body = editor.element[0];
blurTrigger = editor.body;
editor.toolbar.decorateFrom(editor.body);
}
this._registerHandler(blurTrigger, 'blur', proxy(this._blur, this));
try {
doc.execCommand('enableInlineTableEditing', null, false);
} catch (e) {
}
if (kendo.support.touch) {
this._registerHandler(doc, {
'selectionchange': proxy(this._selectionChange, this),
'keydown': function () {
if (kendo._activeElement() != doc.body) {
editor.window.focus();
}
}
});
}
this._spellCorrect(editor);
this._registerHandler(editor.body, {
'dragstart': function (e) {
e.preventDefault();
},
'keydown': function (e) {
var range;
if ((e.keyCode === keys.BACKSPACE || e.keyCode === keys.DELETE) && editor.body.getAttribute('contenteditable') !== 'true') {
return false;
}
if (e.keyCode === keys.F10) {
setTimeout(proxy(editor.toolbar.focus, editor.toolbar), 100);
e.preventDefault();
return;
} else if (e.keyCode == keys.LEFT || e.keyCode == keys.RIGHT) {
range = editor.getRange();
var left = e.keyCode == keys.LEFT;
var container = range[left ? 'startContainer' : 'endContainer'];
var offset = range[left ? 'startOffset' : 'endOffset'];
var direction = left ? -1 : 1;
if (left) {
offset -= 1;
}
if (offset + direction > 0 && container.nodeType == 3 && container.nodeValue[offset] == '\uFEFF') {
range.setStart(container, offset + direction);
range.collapse(true);
editor.selectRange(range);
}
}
var toolName = editor.keyboard.toolFromShortcut(editor.toolbar.tools, e);
if (toolName) {
e.preventDefault();
if (!/^(undo|redo)$/.test(toolName)) {
editor.keyboard.endTyping(true);
}
editor.trigger('keydown', e);
editor.exec(toolName);
return false;
}
editor.keyboard.clearTimeout();
editor.keyboard.keydown(e);
},
'keyup': function (e) {
var selectionCodes = [
8,
9,
33,
34,
35,
36,
37,
38,
39,
40,
40,
45,
46
];
if ($.inArray(e.keyCode, selectionCodes) > -1 || e.keyCode == 65 && e.ctrlKey && !e.altKey && !e.shiftKey) {
editor._selectionChange();
}
editor.keyboard.keyup(e);
},
'mousedown': function (e) {
editor._selectionStarted = true;
if (browser.gecko) {
return;
}
var target = $(e.target);
if ((e.which == 2 || e.which == 1 && e.ctrlKey) && target.is('a[href]')) {
window.open(target.attr('href'), '_new');
}
},
'click': function (e) {
var dom = kendo.ui.editor.Dom, range;
if (dom.name(e.target) === 'img') {
range = editor.createRange();
range.selectNode(e.target);
editor.selectRange(range);
}
},
'cut copy paste': function (e) {
editor.clipboard['on' + e.type](e);
},
'focusin': function () {
if (editor.body.hasAttribute('contenteditable')) {
$(this).addClass('k-state-active');
editor.toolbar.show();
}
},
'focusout': function () {
setTimeout(function () {
var active = kendo._activeElement();
var body = editor.body;
var toolbar = editor.toolbar;
if (active != body && !$.contains(body, active) && !$(active).is('.k-editortoolbar-dragHandle') && !toolbar.focused()) {
$(body).removeClass('k-state-active');
toolbar.hide();
}
}, 10);
}
});
},
_mouseup: function () {
var that = this;
if (that._selectionStarted) {
setTimeout(function () {
that._selectionChange();
}, 1);
}
},
refresh: function () {
var that = this;
if (that.textarea) {
that.textarea.val(that.value());
that.wrapper.find('iframe').remove();
that._initializeContentElement(that);
that.value(that.textarea.val());
}
},
events: [
'select',
'change',
'execute',
'error',
'paste',
'keydown',
'keyup'
],
options: {
name: 'Editor',
messages: messages,
formats: {},
encoded: true,
domain: null,
resizable: false,
serialization: {
entities: true,
semantic: true,
scripts: false
},
stylesheets: [],
dialogOptions: {
modal: true,
resizable: false,
draggable: true,
animation: false
},
imageBrowser: null,
fileBrowser: null,
fontName: [
{
text: 'Arial',
value: 'Arial,Helvetica,sans-serif'
},
{
text: 'Courier New',
value: '\'Courier New\',Courier,monospace'
},
{
text: 'Georgia',
value: 'Georgia,serif'
},
{
text: 'Impact',
value: 'Impact,Charcoal,sans-serif'
},
{
text: 'Lucida Console',
value: '\'Lucida Console\',Monaco,monospace'
},
{
text: 'Tahoma',
value: 'Tahoma,Geneva,sans-serif'
},
{
text: 'Times New Roman',
value: '\'Times New Roman\',Times,serif'
},
{
text: 'Trebuchet MS',
value: '\'Trebuchet MS\',Helvetica,sans-serif'
},
{
text: 'Verdana',
value: 'Verdana,Geneva,sans-serif'
}
],
fontSize: [
{
text: '1 (8pt)',
value: 'xx-small'
},
{
text: '2 (10pt)',
value: 'x-small'
},
{
text: '3 (12pt)',
value: 'small'
},
{
text: '4 (14pt)',
value: 'medium'
},
{
text: '5 (18pt)',
value: 'large'
},
{
text: '6 (24pt)',
value: 'x-large'
},
{
text: '7 (36pt)',
value: 'xx-large'
}
],
formatBlock: [
{
text: 'Paragraph',
value: 'p'
},
{
text: 'Quotation',
value: 'blockquote'
},
{
text: 'Heading 1',
value: 'h1'
},
{
text: 'Heading 2',
value: 'h2'
},
{
text: 'Heading 3',
value: 'h3'
},
{
text: 'Heading 4',
value: 'h4'
},
{
text: 'Heading 5',
value: 'h5'
},
{
text: 'Heading 6',
value: 'h6'
}
],
tools: [].concat.call(['formatting'], toolGroups.basic, toolGroups.alignment, toolGroups.lists, toolGroups.indenting, toolGroups.links, ['insertImage'], toolGroups.tables)
},
destroy: function () {
Widget.fn.destroy.call(this);
this._deregisterHandlers();
clearTimeout(this._spellCorrectTimeout);
this._focusOutside();
this.toolbar.destroy();
kendo.destroy(this.wrapper);
},
_focusOutside: function () {
if (kendo.support.browser.msie && this.textarea) {
var tempInput = $('
').appendTo(document.body).focus();
tempInput.blur().remove();
}
},
state: function (toolName) {
var tool = Editor.defaultTools[toolName];
var finder = tool && (tool.options.finder || tool.finder);
var RangeUtils = kendo.ui.editor.RangeUtils;
var range, textNodes;
if (finder) {
range = this.getRange();
textNodes = RangeUtils.textNodes(range);
if (!textNodes.length && range.collapsed) {
textNodes = [range.startContainer];
}
return finder.getFormat ? finder.getFormat(textNodes) : finder.isFormatted(textNodes);
}
return false;
},
value: function (html) {
var body = this.body, editorNS = kendo.ui.editor, currentHtml = editorNS.Serializer.domToXhtml(body, this.options.serialization);
if (html === undefined) {
return currentHtml;
}
if (html == currentHtml) {
return;
}
editorNS.Serializer.htmlToDom(html, body);
if (!browser.msie) {
kendo.ui.editor.Dom.ensureTrailingBreaks(this.body);
}
this.selectionRestorePoint = null;
this.update();
this.toolbar.refreshTools();
},
saveSelection: function (range) {
range = range || this.getRange();
var container = range.commonAncestorContainer, body = this.body;
if (container == body || $.contains(body, container)) {
this.selectionRestorePoint = new kendo.ui.editor.RestorePoint(range);
}
},
_focusBody: function () {
var body = this.body;
var iframe = this.wrapper && this.wrapper.find('iframe')[0];
var documentElement = this.document.documentElement;
var activeElement = kendo._activeElement();
if (activeElement != body && activeElement != iframe) {
var scrollTop = documentElement.scrollTop;
body.focus();
documentElement.scrollTop = scrollTop;
}
},
restoreSelection: function () {
this._focusBody();
if (this.selectionRestorePoint) {
this.selectRange(this.selectionRestorePoint.toRange());
}
},
focus: function () {
this.restoreSelection();
},
update: function (value) {
value = value || this.options.encoded ? this.encodedValue() : this.value();
if (this.textarea) {
this.textarea.val(value);
} else {
this._oldValue = value;
}
},
encodedValue: function () {
return kendo.ui.editor.Dom.encode(this.value());
},
createRange: function (document) {
return kendo.ui.editor.RangeUtils.createRange(document || this.document);
},
getSelection: function () {
return kendo.ui.editor.SelectionUtils.selectionFromDocument(this.document);
},
selectRange: function (range) {
this._focusBody();
var selection = this.getSelection();
selection.removeAllRanges();
selection.addRange(range);
this.saveSelection(range);
},
getRange: function () {
var selection = this.getSelection(), range = selection && selection.rangeCount > 0 ? selection.getRangeAt(0) : this.createRange(), doc = this.document;
if (range.startContainer == doc && range.endContainer == doc && !range.startOffset && !range.endOffset) {
range.setStart(this.body, 0);
range.collapse(true);
}
return range;
},
selectedHtml: function () {
return kendo.ui.editor.Serializer.domToXhtml(this.getRange().cloneContents());
},
paste: function (html, options) {
this.focus();
var command = new kendo.ui.editor.InsertHtmlCommand($.extend({
range: this.getRange(),
html: html
}, options));
command.editor = this;
command.exec();
},
exec: function (name, params) {
var that = this;
var command = null;
var range, tool, prevented;
if (!name) {
throw new Error('kendoEditor.exec(): `name` parameter cannot be empty');
}
if (that.body.getAttribute('contenteditable') !== 'true' && name !== 'print') {
return false;
}
name = name.toLowerCase();
if (!that.keyboard.isTypingInProgress()) {
that.restoreSelection();
}
tool = that.toolbar.toolById(name);
if (!tool) {
for (var id in Editor.defaultTools) {
if (id.toLowerCase() == name) {
tool = Editor.defaultTools[id];
break;
}
}
}
if (tool) {
range = that.getRange();
if (tool.command) {
command = tool.command(extend({ range: range }, params));
}
prevented = that.trigger('execute', {
name: name,
command: command
});
if (prevented) {
return;
}
if (/^(undo|redo)$/i.test(name)) {
that.undoRedoStack[name]();
} else if (command) {
if (!command.managesUndoRedo) {
that.undoRedoStack.push(command);
}
command.editor = that;
command.exec();
if (command.async) {
command.change = proxy(that._selectionChange, that);
return;
}
}
that._selectionChange();
}
}
});
Editor.defaultTools = {
undo: {
options: {
key: 'Z',
ctrl: true
}
},
redo: {
options: {
key: 'Y',
ctrl: true
}
}
};
kendo.ui.plugin(Editor);
var Tool = Class.extend({
init: function (options) {
this.options = options;
},
initialize: function (ui, options) {
ui.attr({
unselectable: 'on',
title: options.title
});
ui.children('.k-tool-text').html(options.title);
},
command: function (commandArguments) {
return new this.options.command(commandArguments);
},
update: $.noop
});
Tool.exec = function (editor, name, value) {
editor.exec(name, { value: value });
};
var FormatTool = Tool.extend({
init: function (options) {
Tool.fn.init.call(this, options);
},
command: function (commandArguments) {
var that = this;
return new kendo.ui.editor.FormatCommand(extend(commandArguments, { formatter: that.options.formatter }));
},
update: function (ui, nodes) {
var isFormatted = this.options.finder.isFormatted(nodes);
ui.toggleClass('k-state-selected', isFormatted);
ui.attr('aria-pressed', isFormatted);
}
});
EditorUtils.registerTool('separator', new Tool({ template: new ToolTemplate({ template: EditorUtils.separatorTemplate }) }));
var bomFill = browser.msie && browser.version < 9 ? '\uFEFF' : '';
var emptyElementContent = '
';
if (browser.msie) {
if (browser.version < 10) {
emptyElementContent = '\uFEFF';
} else if (browser.version < 11) {
emptyElementContent = ' ';
}
}
extend(kendo.ui, {
editor: {
ToolTemplate: ToolTemplate,
EditorUtils: EditorUtils,
Tool: Tool,
FormatTool: FormatTool,
_bomFill: bomFill,
emptyElementContent: emptyElementContent
}
});
if (kendo.PDFMixin) {
kendo.PDFMixin.extend(Editor.prototype);
Editor.prototype._drawPDF = function () {
return kendo.drawing.drawDOM(this.body, this.options.pdf);
};
Editor.prototype.saveAsPDF = function () {
var progress = new $.Deferred();
var promise = progress.promise();
var args = { promise: promise };
if (this.trigger('pdfExport', args)) {
return;
}
var options = this.options.pdf;
var paperSize = options.paperSize;
this._drawPDF(progress).then(function (root) {
options.paperSize = 'auto';
return kendo.drawing.exportPDF(root, options);
}).done(function (dataURI) {
kendo.saveAs({
dataURI: dataURI,
fileName: options.fileName,
proxyURL: options.proxyURL,
forceProxy: options.forceProxy
});
options.paperSize = paperSize;
progress.resolve();
}).fail(function (err) {
progress.reject(err);
});
return promise;
};
}
}(window.jQuery));
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('editor/dom', ['editor/main'], f);
}(function () {
(function ($) {
var kendo = window.kendo, map = $.map, extend = $.extend, browser = kendo.support.browser, STYLE = 'style', FLOAT = 'float', CSSFLOAT = 'cssFloat', STYLEFLOAT = 'styleFloat', CLASS = 'class', KMARKER = 'k-marker';
function makeMap(items) {
var obj = {}, i, len;
for (i = 0, len = items.length; i < len; i++) {
obj[items[i]] = true;
}
return obj;
}
var empty = makeMap('area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed'.split(',')), nonListBlockElements = 'div,p,h1,h2,h3,h4,h5,h6,address,applet,blockquote,button,center,dd,dir,dl,dt,fieldset,form,frameset,hr,iframe,isindex,map,menu,noframes,noscript,object,pre,script,table,tbody,td,tfoot,th,thead,tr,header,article,nav,footer,section,aside,main,figure,figcaption'.split(','), blockElements = nonListBlockElements.concat([
'ul',
'ol',
'li'
]), block = makeMap(blockElements), inlineElements = 'span,em,a,abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,code,del,dfn,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,strike,strong,sub,sup,textarea,tt,u,var,data,time,mark,ruby'.split(','), inline = makeMap(inlineElements), fillAttrs = makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected'.split(','));
var normalize = function (node) {
if (node.nodeType == 1) {
node.normalize();
}
};
if (browser.msie && browser.version >= 8) {
normalize = function (parent) {
if (parent.nodeType == 1 && parent.firstChild) {
var prev = parent.firstChild, node = prev;
while (true) {
node = node.nextSibling;
if (!node) {
break;
}
if (node.nodeType == 3 && prev.nodeType == 3) {
node.nodeValue = prev.nodeValue + node.nodeValue;
Dom.remove(prev);
}
prev = node;
}
}
};
}
var whitespace = /^\s+$/, emptyspace = /^[\n\r\t]+$/, rgb = /rgb\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/i, bom = /\ufeff/g, whitespaceOrBom = /^(\s+|\ufeff)$/, persistedScrollTop, cssAttributes = ('color,padding-left,padding-right,padding-top,padding-bottom,' + 'background-color,background-attachment,background-image,background-position,background-repeat,' + 'border-top-style,border-top-width,border-top-color,' + 'border-bottom-style,border-bottom-width,border-bottom-color,' + 'border-left-style,border-left-width,border-left-color,' + 'border-right-style,border-right-width,border-right-color,' + 'font-family,font-size,font-style,font-variant,font-weight,line-height').split(','), htmlRe = /[<>\&]/g, entityRe = /[\u00A0-\u2666<>\&]/g, entityTable = {
34: 'quot',
38: 'amp',
39: 'apos',
60: 'lt',
62: 'gt',
160: 'nbsp',
161: 'iexcl',
162: 'cent',
163: 'pound',
164: 'curren',
165: 'yen',
166: 'brvbar',
167: 'sect',
168: 'uml',
169: 'copy',
170: 'ordf',
171: 'laquo',
172: 'not',
173: 'shy',
174: 'reg',
175: 'macr',
176: 'deg',
177: 'plusmn',
178: 'sup2',
179: 'sup3',
180: 'acute',
181: 'micro',
182: 'para',
183: 'middot',
184: 'cedil',
185: 'sup1',
186: 'ordm',
187: 'raquo',
188: 'frac14',
189: 'frac12',
190: 'frac34',
191: 'iquest',
192: 'Agrave',
193: 'Aacute',
194: 'Acirc',
195: 'Atilde',
196: 'Auml',
197: 'Aring',
198: 'AElig',
199: 'Ccedil',
200: 'Egrave',
201: 'Eacute',
202: 'Ecirc',
203: 'Euml',
204: 'Igrave',
205: 'Iacute',
206: 'Icirc',
207: 'Iuml',
208: 'ETH',
209: 'Ntilde',
210: 'Ograve',
211: 'Oacute',
212: 'Ocirc',
213: 'Otilde',
214: 'Ouml',
215: 'times',
216: 'Oslash',
217: 'Ugrave',
218: 'Uacute',
219: 'Ucirc',
220: 'Uuml',
221: 'Yacute',
222: 'THORN',
223: 'szlig',
224: 'agrave',
225: 'aacute',
226: 'acirc',
227: 'atilde',
228: 'auml',
229: 'aring',
230: 'aelig',
231: 'ccedil',
232: 'egrave',
233: 'eacute',
234: 'ecirc',
235: 'euml',
236: 'igrave',
237: 'iacute',
238: 'icirc',
239: 'iuml',
240: 'eth',
241: 'ntilde',
242: 'ograve',
243: 'oacute',
244: 'ocirc',
245: 'otilde',
246: 'ouml',
247: 'divide',
248: 'oslash',
249: 'ugrave',
250: 'uacute',
251: 'ucirc',
252: 'uuml',
253: 'yacute',
254: 'thorn',
255: 'yuml',
402: 'fnof',
913: 'Alpha',
914: 'Beta',
915: 'Gamma',
916: 'Delta',
917: 'Epsilon',
918: 'Zeta',
919: 'Eta',
920: 'Theta',
921: 'Iota',
922: 'Kappa',
923: 'Lambda',
924: 'Mu',
925: 'Nu',
926: 'Xi',
927: 'Omicron',
928: 'Pi',
929: 'Rho',
931: 'Sigma',
932: 'Tau',
933: 'Upsilon',
934: 'Phi',
935: 'Chi',
936: 'Psi',
937: 'Omega',
945: 'alpha',
946: 'beta',
947: 'gamma',
948: 'delta',
949: 'epsilon',
950: 'zeta',
951: 'eta',
952: 'theta',
953: 'iota',
954: 'kappa',
955: 'lambda',
956: 'mu',
957: 'nu',
958: 'xi',
959: 'omicron',
960: 'pi',
961: 'rho',
962: 'sigmaf',
963: 'sigma',
964: 'tau',
965: 'upsilon',
966: 'phi',
967: 'chi',
968: 'psi',
969: 'omega',
977: 'thetasym',
978: 'upsih',
982: 'piv',
8226: 'bull',
8230: 'hellip',
8242: 'prime',
8243: 'Prime',
8254: 'oline',
8260: 'frasl',
8472: 'weierp',
8465: 'image',
8476: 'real',
8482: 'trade',
8501: 'alefsym',
8592: 'larr',
8593: 'uarr',
8594: 'rarr',
8595: 'darr',
8596: 'harr',
8629: 'crarr',
8656: 'lArr',
8657: 'uArr',
8658: 'rArr',
8659: 'dArr',
8660: 'hArr',
8704: 'forall',
8706: 'part',
8707: 'exist',
8709: 'empty',
8711: 'nabla',
8712: 'isin',
8713: 'notin',
8715: 'ni',
8719: 'prod',
8721: 'sum',
8722: 'minus',
8727: 'lowast',
8730: 'radic',
8733: 'prop',
8734: 'infin',
8736: 'ang',
8743: 'and',
8744: 'or',
8745: 'cap',
8746: 'cup',
8747: 'int',
8756: 'there4',
8764: 'sim',
8773: 'cong',
8776: 'asymp',
8800: 'ne',
8801: 'equiv',
8804: 'le',
8805: 'ge',
8834: 'sub',
8835: 'sup',
8836: 'nsub',
8838: 'sube',
8839: 'supe',
8853: 'oplus',
8855: 'otimes',
8869: 'perp',
8901: 'sdot',
8968: 'lceil',
8969: 'rceil',
8970: 'lfloor',
8971: 'rfloor',
9001: 'lang',
9002: 'rang',
9674: 'loz',
9824: 'spades',
9827: 'clubs',
9829: 'hearts',
9830: 'diams',
338: 'OElig',
339: 'oelig',
352: 'Scaron',
353: 'scaron',
376: 'Yuml',
710: 'circ',
732: 'tilde',
8194: 'ensp',
8195: 'emsp',
8201: 'thinsp',
8204: 'zwnj',
8205: 'zwj',
8206: 'lrm',
8207: 'rlm',
8211: 'ndash',
8212: 'mdash',
8216: 'lsquo',
8217: 'rsquo',
8218: 'sbquo',
8220: 'ldquo',
8221: 'rdquo',
8222: 'bdquo',
8224: 'dagger',
8225: 'Dagger',
8240: 'permil',
8249: 'lsaquo',
8250: 'rsaquo',
8364: 'euro'
};
var Dom = {
block: block,
inline: inline,
findNodeIndex: function (node, skipText) {
var i = 0;
if (!node) {
return -1;
}
while (true) {
node = node.previousSibling;
if (!node) {
break;
}
if (!(skipText && node.nodeType == 3)) {
i++;
}
}
return i;
},
isDataNode: function (node) {
return node && node.nodeValue !== null && node.data !== null;
},
isAncestorOf: function (parent, node) {
try {
return !Dom.isDataNode(parent) && ($.contains(parent, Dom.isDataNode(node) ? node.parentNode : node) || node.parentNode == parent);
} catch (e) {
return false;
}
},
isAncestorOrSelf: function (root, node) {
return Dom.isAncestorOf(root, node) || root == node;
},
findClosestAncestor: function (root, node) {
if (Dom.isAncestorOf(root, node)) {
while (node && node.parentNode != root) {
node = node.parentNode;
}
}
return node;
},
getNodeLength: function (node) {
return Dom.isDataNode(node) ? node.length : node.childNodes.length;
},
splitDataNode: function (node, offset) {
var newNode = node.cloneNode(false);
var denormalizedText = '';
var iterator = node.nextSibling;
var temp;
while (iterator && iterator.nodeType == 3 && iterator.nodeValue) {
denormalizedText += iterator.nodeValue;
temp = iterator;
iterator = iterator.nextSibling;
Dom.remove(temp);
}
node.deleteData(offset, node.length);
newNode.deleteData(0, offset);
newNode.nodeValue += denormalizedText;
Dom.insertAfter(newNode, node);
},
attrEquals: function (node, attributes) {
for (var key in attributes) {
var value = node[key];
if (key == FLOAT) {
value = node[kendo.support.cssFloat ? CSSFLOAT : STYLEFLOAT];
}
if (typeof value == 'object') {
if (!Dom.attrEquals(value, attributes[key])) {
return false;
}
} else if (value != attributes[key]) {
return false;
}
}
return true;
},
blockParentOrBody: function (node) {
return Dom.parentOfType(node, blockElements) || node.ownerDocument.body;
},
blockParents: function (nodes) {
var blocks = [], i, len;
for (i = 0, len = nodes.length; i < len; i++) {
var block = Dom.parentOfType(nodes[i], Dom.blockElements);
if (block && $.inArray(block, blocks) < 0) {
blocks.push(block);
}
}
return blocks;
},
windowFromDocument: function (document) {
return document.defaultView || document.parentWindow;
},
normalize: normalize,
blockElements: blockElements,
nonListBlockElements: nonListBlockElements,
inlineElements: inlineElements,
empty: empty,
fillAttrs: fillAttrs,
toHex: function (color) {
var matches = rgb.exec(color);
if (!matches) {
return color;
}
return '#' + map(matches.slice(1), function (x) {
x = parseInt(x, 10).toString(16);
return x.length > 1 ? x : '0' + x;
}).join('');
},
encode: function (value, options) {
var encodableChars = !options || options.entities ? entityRe : htmlRe;
return value.replace(encodableChars, function (c) {
var charCode = c.charCodeAt(0);
var entity = entityTable[charCode];
return entity ? '&' + entity + ';' : c;
});
},
stripBom: function (text) {
return (text || '').replace(bom, '');
},
insignificant: function (node) {
var attr = node.attributes;
return node.className == 'k-marker' || Dom.is(node, 'br') && (node.className == 'k-br' || attr._moz_dirty || attr._moz_editor_bogus_node);
},
significantNodes: function (nodes) {
return $.grep(nodes, function (child) {
var name = Dom.name(child);
if (name == 'br') {
return false;
} else if (Dom.insignificant(child)) {
return false;
} else if (child.nodeType == 3 && whitespaceOrBom.test(child.nodeValue)) {
return false;
} else if (child.nodeType == 1 && !empty[name] && Dom.emptyNode(child)) {
return false;
}
return true;
});
},
emptyNode: function (node) {
return node.nodeType == 1 && !Dom.significantNodes(node.childNodes).length;
},
name: function (node) {
return node.nodeName.toLowerCase();
},
significantChildNodes: function (node) {
return $.grep(node.childNodes, function (child) {
return child.nodeType != 3 || !Dom.isWhitespace(child);
});
},
lastTextNode: function (node) {
var result = null;
if (node.nodeType == 3) {
return node;
}
for (var child = node.lastChild; child; child = child.previousSibling) {
result = Dom.lastTextNode(child);
if (result) {
return result;
}
}
return result;
},
is: function (node, nodeName) {
return Dom.name(node) == nodeName;
},
isMarker: function (node) {
return node.className == KMARKER;
},
isWhitespace: function (node) {
return whitespace.test(node.nodeValue);
},
isEmptyspace: function (node) {
return emptyspace.test(node.nodeValue);
},
isBlock: function (node) {
return block[Dom.name(node)];
},
isEmpty: function (node) {
return empty[Dom.name(node)];
},
isInline: function (node) {
return inline[Dom.name(node)];
},
scrollContainer: function (doc) {
var wnd = Dom.windowFromDocument(doc), scrollContainer = (wnd.contentWindow || wnd).document || wnd.ownerDocument || wnd;
if (kendo.support.browser.webkit || scrollContainer.compatMode == 'BackCompat') {
scrollContainer = scrollContainer.body;
} else {
scrollContainer = scrollContainer.documentElement;
}
return scrollContainer;
},
scrollTo: function (node) {
var element = $(Dom.isDataNode(node) ? node.parentNode : node), wnd = Dom.windowFromDocument(node.ownerDocument), windowHeight = wnd.innerHeight, elementTop, elementHeight, scrollContainer = Dom.scrollContainer(node.ownerDocument);
elementTop = element.offset().top;
elementHeight = element[0].offsetHeight;
if (!elementHeight) {
elementHeight = parseInt(element.css('line-height'), 10) || Math.ceil(1.2 * parseInt(element.css('font-size'), 10)) || 15;
}
if (elementHeight + elementTop > scrollContainer.scrollTop + windowHeight) {
scrollContainer.scrollTop = elementHeight + elementTop - windowHeight;
}
},
persistScrollTop: function (doc) {
persistedScrollTop = Dom.scrollContainer(doc).scrollTop;
},
restoreScrollTop: function (doc) {
Dom.scrollContainer(doc).scrollTop = persistedScrollTop;
},
insertAt: function (parent, newElement, position) {
parent.insertBefore(newElement, parent.childNodes[position] || null);
},
insertBefore: function (newElement, referenceElement) {
if (referenceElement.parentNode) {
return referenceElement.parentNode.insertBefore(newElement, referenceElement);
} else {
return referenceElement;
}
},
insertAfter: function (newElement, referenceElement) {
return referenceElement.parentNode.insertBefore(newElement, referenceElement.nextSibling);
},
remove: function (node) {
node.parentNode.removeChild(node);
},
removeTextSiblings: function (node) {
var parentNode = node.parentNode;
while (node.nextSibling && node.nextSibling.nodeType == 3) {
parentNode.removeChild(node.nextSibling);
}
while (node.previousSibling && node.previousSibling.nodeType == 3) {
parentNode.removeChild(node.previousSibling);
}
},
trim: function (parent) {
for (var i = parent.childNodes.length - 1; i >= 0; i--) {
var node = parent.childNodes[i];
if (Dom.isDataNode(node)) {
if (!Dom.stripBom(node.nodeValue).length) {
Dom.remove(node);
}
if (Dom.isWhitespace(node)) {
Dom.insertBefore(node, parent);
}
} else if (node.className != KMARKER) {
Dom.trim(node);
if (!node.childNodes.length && !Dom.isEmpty(node)) {
Dom.remove(node);
}
}
}
return parent;
},
closest: function (node, tag) {
while (node && Dom.name(node) != tag) {
node = node.parentNode;
}
return node;
},
sibling: function (node, direction) {
do {
node = node[direction];
} while (node && node.nodeType != 1);
return node;
},
next: function (node) {
return Dom.sibling(node, 'nextSibling');
},
prev: function (node) {
return Dom.sibling(node, 'previousSibling');
},
parentOfType: function (node, tags) {
do {
node = node.parentNode;
} while (node && !Dom.ofType(node, tags));
return node;
},
ofType: function (node, tags) {
return $.inArray(Dom.name(node), tags) >= 0;
},
changeTag: function (referenceElement, tagName, skipAttributes) {
var newElement = Dom.create(referenceElement.ownerDocument, tagName), attributes = referenceElement.attributes, i, len, name, value, attribute;
if (!skipAttributes) {
for (i = 0, len = attributes.length; i < len; i++) {
attribute = attributes[i];
if (attribute.specified) {
name = attribute.nodeName;
value = attribute.nodeValue;
if (name == CLASS) {
newElement.className = value;
} else if (name == STYLE) {
newElement.style.cssText = referenceElement.style.cssText;
} else {
newElement.setAttribute(name, value);
}
}
}
}
while (referenceElement.firstChild) {
newElement.appendChild(referenceElement.firstChild);
}
Dom.insertBefore(newElement, referenceElement);
Dom.remove(referenceElement);
return newElement;
},
editableParent: function (node) {
while (node && (node.nodeType == 3 || node.contentEditable !== 'true')) {
node = node.parentNode;
}
return node;
},
wrap: function (node, wrapper) {
Dom.insertBefore(wrapper, node);
wrapper.appendChild(node);
return wrapper;
},
unwrap: function (node) {
var parent = node.parentNode;
while (node.firstChild) {
parent.insertBefore(node.firstChild, node);
}
parent.removeChild(node);
},
create: function (document, tagName, attributes) {
return Dom.attr(document.createElement(tagName), attributes);
},
attr: function (element, attributes) {
attributes = extend({}, attributes);
if (attributes && STYLE in attributes) {
Dom.style(element, attributes.style);
delete attributes.style;
}
for (var attr in attributes) {
if (attributes[attr] === null) {
element.removeAttribute(attr);
delete attributes[attr];
} else if (attr == 'className') {
element[attr] = attributes[attr];
}
}
return extend(element, attributes);
},
style: function (node, value) {
$(node).css(value || {});
},
unstyle: function (node, value) {
for (var key in value) {
if (key == FLOAT) {
key = kendo.support.cssFloat ? CSSFLOAT : STYLEFLOAT;
}
node.style[key] = '';
}
if (node.style.cssText === '') {
node.removeAttribute(STYLE);
}
},
inlineStyle: function (body, name, attributes) {
var span = $(Dom.create(body.ownerDocument, name, attributes)), style;
body.appendChild(span[0]);
style = map(cssAttributes, function (value) {
if (browser.msie && value == 'line-height' && span.css(value) == '1px') {
return 'line-height:1.5';
} else {
return value + ':' + span.css(value);
}
}).join(';');
span.remove();
return style;
},
getEffectiveBackground: function (element) {
var backgroundStyle = element.css('background-color');
if (backgroundStyle.indexOf('rgba(0, 0, 0, 0') < 0 && backgroundStyle !== 'transparent') {
return backgroundStyle;
} else if (element[0].tagName.toLowerCase() === 'html') {
return 'Window';
} else {
return Dom.getEffectiveBackground(element.parent());
}
},
removeClass: function (node, classNames) {
var className = ' ' + node.className + ' ', classes = classNames.split(' '), i, len;
for (i = 0, len = classes.length; i < len; i++) {
className = className.replace(' ' + classes[i] + ' ', ' ');
}
className = $.trim(className);
if (className.length) {
node.className = className;
} else {
node.removeAttribute(CLASS);
}
},
commonAncestor: function () {
var count = arguments.length, paths = [], minPathLength = Infinity, output = null, i, ancestors, node, first, j;
if (!count) {
return null;
}
if (count == 1) {
return arguments[0];
}
for (i = 0; i < count; i++) {
ancestors = [];
node = arguments[i];
while (node) {
ancestors.push(node);
node = node.parentNode;
}
paths.push(ancestors.reverse());
minPathLength = Math.min(minPathLength, ancestors.length);
}
if (count == 1) {
return paths[0][0];
}
for (i = 0; i < minPathLength; i++) {
first = paths[0][i];
for (j = 1; j < count; j++) {
if (first != paths[j][i]) {
return output;
}
}
output = first;
}
return output;
},
closestSplittableParent: function (nodes) {
var result;
if (nodes.length == 1) {
result = Dom.parentOfType(nodes[0], [
'ul',
'ol'
]);
} else {
result = Dom.commonAncestor.apply(null, nodes);
}
if (!result) {
result = Dom.parentOfType(nodes[0], [
'p',
'td'
]) || nodes[0].ownerDocument.body;
}
if (Dom.isInline(result)) {
result = Dom.blockParentOrBody(result);
}
var editableParents = map(nodes, Dom.editableParent);
var editableAncestor = Dom.commonAncestor(editableParents)[0];
if ($.contains(result, editableAncestor)) {
result = editableAncestor;
}
return result;
},
closestEditable: function (node, types) {
var closest;
var editable = Dom.editableParent(node);
if (Dom.ofType(node, types)) {
closest = node;
} else {
closest = Dom.parentOfType(node, types);
}
if (closest && editable && $.contains(closest, editable)) {
closest = editable;
} else if (!closest && editable) {
closest = editable;
}
return closest;
},
closestEditableOfType: function (node, types) {
var editable = Dom.closestEditable(node, types);
if (editable && Dom.ofType(editable, types)) {
return editable;
}
},
filter: function (tagName, nodes, invert) {
var i = 0;
var len = nodes.length;
var result = [];
var name;
for (; i < len; i++) {
name = Dom.name(nodes[i]);
if (!invert && name == tagName || invert && name != tagName) {
result.push(nodes[i]);
}
}
return result;
},
ensureTrailingBreaks: function (node) {
var elements = $(node).find('p,td,th');
var length = elements.length;
var i = 0;
if (length) {
for (; i < length; i++) {
Dom.ensureTrailingBreak(elements[i]);
}
} else {
Dom.ensureTrailingBreak(node);
}
},
removeTrailingBreak: function (node) {
$(node).find('br[type=_moz],.k-br').remove();
},
ensureTrailingBreak: function (node) {
Dom.removeTrailingBreak(node);
var lastChild = node.lastChild;
var name = lastChild && Dom.name(lastChild);
var br;
if (!name || name != 'br' && name != 'img' || name == 'br' && lastChild.className != 'k-br') {
br = node.ownerDocument.createElement('br');
br.className = 'k-br';
node.appendChild(br);
}
}
};
kendo.ui.editor.Dom = Dom;
}(window.kendo.jQuery));
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('editor/serializer', ['editor/dom'], f);
}(function () {
(function ($, undefined) {
var kendo = window.kendo;
var Editor = kendo.ui.editor;
var dom = Editor.Dom;
var extend = $.extend;
var fontSizeMappings = 'xx-small,x-small,small,medium,large,x-large,xx-large'.split(',');
var quoteRe = /"/g;
var brRe = /
]*>/i;
var pixelRe = /^\d+(\.\d*)?(px)?$/i;
var emptyPRe = /
<\/p>/i;
var cssDeclaration = /(\*?[-#\/\*\\\w]+(?:\[[0-9a-z_-]+\])?)\s*:\s*((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^\)]*?\)|[^};])+)/g;
var sizzleAttr = /^sizzle-\d+/i;
var scriptAttr = /^k-script-/i;
var onerrorRe = /\s*onerror\s*=\s*(?:'|")?([^'">\s]*)(?:'|")?/i;
var div = document.createElement('div');
div.innerHTML = '
';
var supportsLeadingWhitespace = div.firstChild.nodeType === 3;
div = null;
var Serializer = {
toEditableHtml: function (html) {
var br = '
';
html = html || '';
return html.replace(//g, '').replace(/<(\/?)script([^>]*)>/gi, '<$1k:script$2>').replace(/
![]()
]*)>/gi, function (match) {
return match.replace(onerrorRe, '');
}).replace(/(<\/?img[^>]*>)[\r\n\v\f\t ]+/gi, '$1').replace(/^<(table|blockquote)/i, br + '<$1').replace(/^[\s]*( |\u00a0)/i, '$1').replace(/<\/(table|blockquote)>$/i, '$1>' + br);
},
_fillEmptyElements: function (body) {
$(body).find('p').each(function () {
var p = $(this);
if (/^\s*$/g.test(p.text()) && !p.find('img,input').length) {
var node = this;
while (node.firstChild && node.firstChild.nodeType != 3) {
node = node.firstChild;
}
if (node.nodeType == 1 && !dom.empty[dom.name(node)]) {
node.innerHTML = kendo.ui.editor.emptyElementContent;
}
}
});
},
_removeSystemElements: function (body) {
$('.k-paste-container', body).remove();
},
_resetOrderedLists: function (root) {
var ols = root.getElementsByTagName('ol'), i, ol, originalStart;
for (i = 0; i < ols.length; i++) {
ol = ols[i];
originalStart = ol.getAttribute('start');
ol.setAttribute('start', 1);
if (originalStart) {
ol.setAttribute('start', originalStart);
} else {
ol.removeAttribute(originalStart);
}
}
},
_preventScriptExecution: function (root) {
$(root).find('*').each(function () {
var attributes = this.attributes;
var attribute, i, l, name;
for (i = 0, l = attributes.length; i < l; i++) {
attribute = attributes[i];
name = attribute.nodeName;
if (attribute.specified && /^on/i.test(name)) {
this.setAttribute('k-script-' + name, attribute.value);
this.removeAttribute(name);
}
}
});
},
htmlToDom: function (html, root) {
var browser = kendo.support.browser;
var msie = browser.msie;
var legacyIE = msie && browser.version < 9;
var originalSrc = 'originalsrc';
var originalHref = 'originalhref';
html = Serializer.toEditableHtml(html);
if (legacyIE) {
html = '
' + html;
html = html.replace(/href\s*=\s*(?:'|")?([^'">\s]*)(?:'|")?/, originalHref + '="$1"');
html = html.replace(/src\s*=\s*(?:'|")?([^'">\s]*)(?:'|")?/, originalSrc + '="$1"');
}
root.innerHTML = html;
if (legacyIE) {
dom.remove(root.firstChild);
$(root).find('k\\:script,script,link,img,a').each(function () {
var node = this;
if (node[originalHref]) {
node.setAttribute('href', node[originalHref]);
node.removeAttribute(originalHref);
}
if (node[originalSrc]) {
node.setAttribute('src', node[originalSrc]);
node.removeAttribute(originalSrc);
}
});
} else if (msie) {
dom.normalize(root);
Serializer._resetOrderedLists(root);
}
Serializer._preventScriptExecution(root);
Serializer._fillEmptyElements(root);
Serializer._removeSystemElements(root);
$('table', root).addClass('k-table');
return root;
},
domToXhtml: function (root, options) {
var result = [];
function semanticFilter(attributes) {
return $.grep(attributes, function (attr) {
return attr.name != 'style';
});
}
var tagMap = {
iframe: {
start: function (node) {
result.push('
');
}
},
'k:script': {
start: function (node) {
result.push('');
},
skipEncoding: true
},
span: {
semantic: true,
start: function (node) {
var style = node.style;
var attributes = specifiedAttributes(node);
var semanticAttributes = semanticFilter(attributes);
if (semanticAttributes.length) {
result.push('
');
}
if (style.textDecoration == 'underline') {
result.push('');
}
var font = [];
if (style.color) {
font.push('color="' + dom.toHex(style.color) + '"');
}
if (style.fontFamily) {
font.push('face="' + style.fontFamily + '"');
}
if (style.fontSize) {
var size = $.inArray(style.fontSize, fontSizeMappings);
font.push('size="' + size + '"');
}
if (font.length) {
result.push('');
}
},
end: function (node) {
var style = node.style;
if (style.color || style.fontFamily || style.fontSize) {
result.push('');
}
if (style.textDecoration == 'underline') {
result.push('');
}
if (semanticFilter(specifiedAttributes(node)).length) {
result.push('');
}
}
},
strong: {
semantic: true,
start: function () {
result.push('
');
},
end: function () {
result.push('');
}
},
em: {
semantic: true,
start: function () {
result.push('
');
},
end: function () {
result.push('');
}
},
b: {
semantic: false,
start: function () {
result.push('
');
},
end: function () {
result.push('');
}
},
i: {
semantic: false,
start: function () {
result.push('
');
},
end: function () {
result.push('');
}
},
u: {
semantic: false,
start: function () {
result.push('
');
},
end: function () {
result.push('');
}
},
font: {
semantic: false,
start: function (node) {
result.push('
');
},
end: function () {
result.push('');
}
}
};
tagMap.script = tagMap['k:script'];
options = options || {};
if (typeof options.semantic == 'undefined') {
options.semantic = true;
}
function cssProperties(cssText) {
var trim = $.trim;
var css = trim(cssText);
var match;
var property, value;
var properties = [];
cssDeclaration.lastIndex = 0;
while (true) {
match = cssDeclaration.exec(css);
if (!match) {
break;
}
property = trim(match[1].toLowerCase());
value = trim(match[2]);
if (property == 'font-size-adjust' || property == 'font-stretch') {
continue;
}
if (property.indexOf('color') >= 0) {
value = dom.toHex(value);
} else if (property.indexOf('font') >= 0) {
value = value.replace(quoteRe, '\'');
} else if (/\burl\(/g.test(value)) {
value = value.replace(quoteRe, '');
}
properties.push({
property: property,
value: value
});
}
return properties;
}
function styleAttr(cssText) {
var properties = cssProperties(cssText);
var i;
for (i = 0; i < properties.length; i++) {
result.push(properties[i].property);
result.push(':');
result.push(properties[i].value);
result.push(';');
}
}
function specifiedAttributes(node) {
var result = [];
var attributes = node.attributes;
var attribute, i, l;
var name, value, specified;
for (i = 0, l = attributes.length; i < l; i++) {
attribute = attributes[i];
name = attribute.nodeName;
value = attribute.value;
specified = attribute.specified;
if (name == 'value' && 'value' in node && node.value) {
specified = true;
} else if (name == 'type' && value == 'text') {
specified = true;
} else if (name == 'class' && !value) {
specified = false;
} else if (sizzleAttr.test(name)) {
specified = false;
} else if (name == 'complete') {
specified = false;
} else if (name == 'altHtml') {
specified = false;
} else if (name == 'start' && dom.is(node, 'ul')) {
specified = false;
} else if (name == 'start' && dom.is(node, 'ol') && value == '1') {
specified = false;
} else if (name.indexOf('_moz') >= 0) {
specified = false;
} else if (scriptAttr.test(name)) {
specified = !!options.scripts;
}
if (specified) {
result.push(attribute);
}
}
return result;
}
function attr(node, attributes) {
var i, l, attribute, name, value;
attributes = attributes || specifiedAttributes(node);
if (dom.is(node, 'img')) {
var width = node.style.width, height = node.style.height, $node = $(node);
if (width && pixelRe.test(width)) {
$node.attr('width', parseInt(width, 10));
dom.unstyle(node, { width: undefined });
}
if (height && pixelRe.test(height)) {
$node.attr('height', parseInt(height, 10));
dom.unstyle(node, { height: undefined });
}
}
if (!attributes.length) {
return;
}
attributes.sort(function (a, b) {
return a.nodeName > b.nodeName ? 1 : a.nodeName < b.nodeName ? -1 : 0;
});
for (i = 0, l = attributes.length; i < l; i++) {
attribute = attributes[i];
name = attribute.nodeName;
value = attribute.value;
if (name == 'class' && value == 'k-table') {
continue;
}
name = name.replace(scriptAttr, '');
result.push(' ');
result.push(name);
result.push('="');
if (name == 'style') {
styleAttr(value || node.style.cssText);
} else if (name == 'src' || name == 'href') {
result.push(kendo.htmlEncode(node.getAttribute(name, 2)));
} else {
result.push(dom.fillAttrs[name] ? name : value);
}
result.push('"');
}
}
function children(node, skip, skipEncoding) {
for (var childNode = node.firstChild; childNode; childNode = childNode.nextSibling) {
child(childNode, skip, skipEncoding);
}
}
function text(node) {
return node.nodeValue.replace(/\ufeff/g, '');
}
function child(node, skip, skipEncoding) {
var nodeType = node.nodeType, tagName, mapper, parent, value, previous;
if (nodeType == 1) {
tagName = dom.name(node);
if (!tagName || dom.insignificant(node)) {
return;
}
if (dom.isInline(node) && node.childNodes.length == 1 && node.firstChild.nodeType == 3 && !text(node.firstChild)) {
return;
}
if (!options.scripts && (tagName == 'script' || tagName == 'k:script')) {
return;
}
mapper = tagMap[tagName];
if (mapper) {
if (typeof mapper.semantic == 'undefined' || options.semantic ^ mapper.semantic) {
mapper.start(node);
children(node, false, mapper.skipEncoding);
mapper.end(node);
return;
}
}
result.push('<');
result.push(tagName);
attr(node);
if (dom.empty[tagName]) {
result.push(' />');
} else {
result.push('>');
children(node, skip || dom.is(node, 'pre'));
result.push('');
result.push(tagName);
result.push('>');
}
} else if (nodeType == 3) {
value = text(node);
if (!skip && supportsLeadingWhitespace) {
parent = node.parentNode;
previous = node.previousSibling;
if (!previous) {
previous = (dom.isInline(parent) ? parent : node).previousSibling;
}
if (!previous || previous.innerHTML === '' || dom.isBlock(previous)) {
value = value.replace(/^[\r\n\v\f\t ]+/, '');
}
value = value.replace(/ +/, ' ');
}
result.push(skipEncoding ? value : dom.encode(value, options));
} else if (nodeType == 4) {
result.push('');
} else if (nodeType == 8) {
if (node.data.indexOf('[CDATA[') < 0) {
result.push('');
} else {
result.push('');
}
}
}
function textOnly(root) {
var childrenCount = root.childNodes.length;
var textChild = childrenCount && root.firstChild.nodeType == 3;
return textChild && (childrenCount == 1 || childrenCount == 2 && dom.insignificant(root.lastChild));
}
if (textOnly(root)) {
return dom.encode(text(root.firstChild).replace(/[\r\n\v\f\t ]+/, ' '), options);
}
children(root);
result = result.join('');
if (result.replace(brRe, '').replace(emptyPRe, '') === '') {
return '';
}
return result;
}
};
extend(Editor, { Serializer: Serializer });
}(window.kendo.jQuery));
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('editor/range', ['editor/serializer'], f);
}(function () {
(function ($) {
var kendo = window.kendo, Class = kendo.Class, extend = $.extend, Editor = kendo.ui.editor, browser = kendo.support.browser, dom = Editor.Dom, findNodeIndex = dom.findNodeIndex, isDataNode = dom.isDataNode, findClosestAncestor = dom.findClosestAncestor, getNodeLength = dom.getNodeLength, normalize = dom.normalize;
var SelectionUtils = {
selectionFromWindow: function (window) {
if (!('getSelection' in window)) {
return new W3CSelection(window.document);
}
return window.getSelection();
},
selectionFromRange: function (range) {
var rangeDocument = RangeUtils.documentFromRange(range);
return SelectionUtils.selectionFromDocument(rangeDocument);
},
selectionFromDocument: function (document) {
return SelectionUtils.selectionFromWindow(dom.windowFromDocument(document));
}
};
var W3CRange = Class.extend({
init: function (doc) {
$.extend(this, {
ownerDocument: doc,
startContainer: doc,
endContainer: doc,
commonAncestorContainer: doc,
startOffset: 0,
endOffset: 0,
collapsed: true
});
},
setStart: function (node, offset) {
this.startContainer = node;
this.startOffset = offset;
updateRangeProperties(this);
fixIvalidRange(this, true);
},
setEnd: function (node, offset) {
this.endContainer = node;
this.endOffset = offset;
updateRangeProperties(this);
fixIvalidRange(this, false);
},
setStartBefore: function (node) {
this.setStart(node.parentNode, findNodeIndex(node));
},
setStartAfter: function (node) {
this.setStart(node.parentNode, findNodeIndex(node) + 1);
},
setEndBefore: function (node) {
this.setEnd(node.parentNode, findNodeIndex(node));
},
setEndAfter: function (node) {
this.setEnd(node.parentNode, findNodeIndex(node) + 1);
},
selectNode: function (node) {
this.setStartBefore(node);
this.setEndAfter(node);
},
selectNodeContents: function (node) {
this.setStart(node, 0);
this.setEnd(node, node[node.nodeType === 1 ? 'childNodes' : 'nodeValue'].length);
},
collapse: function (toStart) {
var that = this;
if (toStart) {
that.setEnd(that.startContainer, that.startOffset);
} else {
that.setStart(that.endContainer, that.endOffset);
}
},
deleteContents: function () {
var that = this, range = that.cloneRange();
if (that.startContainer != that.commonAncestorContainer) {
that.setStartAfter(findClosestAncestor(that.commonAncestorContainer, that.startContainer));
}
that.collapse(true);
(function deleteSubtree(iterator) {
while (iterator.next()) {
if (iterator.hasPartialSubtree()) {
deleteSubtree(iterator.getSubtreeIterator());
} else {
iterator.remove();
}
}
}(new RangeIterator(range)));
},
cloneContents: function () {
var document = RangeUtils.documentFromRange(this);
return function cloneSubtree(iterator) {
var node, frag = document.createDocumentFragment();
while (node = iterator.next()) {
node = node.cloneNode(!iterator.hasPartialSubtree());
if (iterator.hasPartialSubtree()) {
node.appendChild(cloneSubtree(iterator.getSubtreeIterator()));
}
frag.appendChild(node);
}
return frag;
}(new RangeIterator(this));
},
extractContents: function () {
var that = this, range = that.cloneRange();
if (that.startContainer != that.commonAncestorContainer) {
that.setStartAfter(findClosestAncestor(that.commonAncestorContainer, that.startContainer));
}
that.collapse(true);
var document = RangeUtils.documentFromRange(that);
return function extractSubtree(iterator) {
var node, frag = document.createDocumentFragment();
while (node = iterator.next()) {
if (iterator.hasPartialSubtree()) {
node = node.cloneNode(false);
node.appendChild(extractSubtree(iterator.getSubtreeIterator()));
} else {
iterator.remove(that.originalRange);
}
frag.appendChild(node);
}
return frag;
}(new RangeIterator(range));
},
insertNode: function (node) {
var that = this;
if (isDataNode(that.startContainer)) {
if (that.startOffset != that.startContainer.nodeValue.length) {
dom.splitDataNode(that.startContainer, that.startOffset);
}
dom.insertAfter(node, that.startContainer);
} else {
dom.insertAt(that.startContainer, node, that.startOffset);
}
that.setStart(that.startContainer, that.startOffset);
},
cloneRange: function () {
return $.extend(new W3CRange(this.ownerDocument), {
startContainer: this.startContainer,
endContainer: this.endContainer,
commonAncestorContainer: this.commonAncestorContainer,
startOffset: this.startOffset,
endOffset: this.endOffset,
collapsed: this.collapsed,
originalRange: this
});
},
toString: function () {
var startNodeName = this.startContainer.nodeName, endNodeName = this.endContainer.nodeName;
return [
startNodeName == '#text' ? this.startContainer.nodeValue : startNodeName,
'(',
this.startOffset,
') : ',
endNodeName == '#text' ? this.endContainer.nodeValue : endNodeName,
'(',
this.endOffset,
')'
].join('');
}
});
W3CRange.fromNode = function (node) {
return new W3CRange(node.ownerDocument);
};
function compareBoundaries(start, end, startOffset, endOffset) {
if (start == end) {
return endOffset - startOffset;
}
var container = end;
while (container && container.parentNode != start) {
container = container.parentNode;
}
if (container) {
return findNodeIndex(container) - startOffset;
}
container = start;
while (container && container.parentNode != end) {
container = container.parentNode;
}
if (container) {
return endOffset - findNodeIndex(container) - 1;
}
var root = dom.commonAncestor(start, end);
var startAncestor = start;
while (startAncestor && startAncestor.parentNode != root) {
startAncestor = startAncestor.parentNode;
}
if (!startAncestor) {
startAncestor = root;
}
var endAncestor = end;
while (endAncestor && endAncestor.parentNode != root) {
endAncestor = endAncestor.parentNode;
}
if (!endAncestor) {
endAncestor = root;
}
if (startAncestor == endAncestor) {
return 0;
}
return findNodeIndex(endAncestor) - findNodeIndex(startAncestor);
}
function fixIvalidRange(range, toStart) {
function isInvalidRange(range) {
try {
return compareBoundaries(range.startContainer, range.endContainer, range.startOffset, range.endOffset) < 0;
} catch (ex) {
return true;
}
}
if (isInvalidRange(range)) {
if (toStart) {
range.commonAncestorContainer = range.endContainer = range.startContainer;
range.endOffset = range.startOffset;
} else {
range.commonAncestorContainer = range.startContainer = range.endContainer;
range.startOffset = range.endOffset;
}
range.collapsed = true;
}
}
function updateRangeProperties(range) {
range.collapsed = range.startContainer == range.endContainer && range.startOffset == range.endOffset;
var node = range.startContainer;
while (node && node != range.endContainer && !dom.isAncestorOf(node, range.endContainer)) {
node = node.parentNode;
}
range.commonAncestorContainer = node;
}
var RangeIterator = Class.extend({
init: function (range) {
$.extend(this, {
range: range,
_current: null,
_next: null,
_end: null
});
if (range.collapsed) {
return;
}
var root = range.commonAncestorContainer;
this._next = range.startContainer == root && !isDataNode(range.startContainer) ? range.startContainer.childNodes[range.startOffset] : findClosestAncestor(root, range.startContainer);
this._end = range.endContainer == root && !isDataNode(range.endContainer) ? range.endContainer.childNodes[range.endOffset] : findClosestAncestor(root, range.endContainer).nextSibling;
},
hasNext: function () {
return !!this._next;
},
next: function () {
var that = this, current = that._current = that._next;
that._next = that._current && that._current.nextSibling != that._end ? that._current.nextSibling : null;
if (isDataNode(that._current)) {
if (that.range.endContainer == that._current) {
current = current.cloneNode(true);
current.deleteData(that.range.endOffset, current.length - that.range.endOffset);
}
if (that.range.startContainer == that._current) {
current = current.cloneNode(true);
current.deleteData(0, that.range.startOffset);
}
}
return current;
},
traverse: function (callback) {
var that = this, current;
function next() {
that._current = that._next;
that._next = that._current && that._current.nextSibling != that._end ? that._current.nextSibling : null;
return that._current;
}
while (current = next()) {
if (that.hasPartialSubtree()) {
that.getSubtreeIterator().traverse(callback);
} else {
callback(current);
}
}
return current;
},
remove: function (originalRange) {
var that = this, inStartContainer = that.range.startContainer == that._current, inEndContainer = that.range.endContainer == that._current, start, end, delta;
if (isDataNode(that._current) && (inStartContainer || inEndContainer)) {
start = inStartContainer ? that.range.startOffset : 0;
end = inEndContainer ? that.range.endOffset : that._current.length;
delta = end - start;
if (originalRange && (inStartContainer || inEndContainer)) {
if (that._current == originalRange.startContainer && start <= originalRange.startOffset) {
originalRange.startOffset -= delta;
}
if (that._current == originalRange.endContainer && end <= originalRange.endOffset) {
originalRange.endOffset -= delta;
}
}
that._current.deleteData(start, delta);
} else {
var parent = that._current.parentNode;
if (originalRange && (that.range.startContainer == parent || that.range.endContainer == parent)) {
var nodeIndex = findNodeIndex(that._current);
if (parent == originalRange.startContainer && nodeIndex <= originalRange.startOffset) {
originalRange.startOffset -= 1;
}
if (parent == originalRange.endContainer && nodeIndex < originalRange.endOffset) {
originalRange.endOffset -= 1;
}
}
dom.remove(that._current);
}
},
hasPartialSubtree: function () {
return !isDataNode(this._current) && (dom.isAncestorOrSelf(this._current, this.range.startContainer) || dom.isAncestorOrSelf(this._current, this.range.endContainer));
},
getSubtreeIterator: function () {
var that = this, subRange = that.range.cloneRange();
subRange.selectNodeContents(that._current);
if (dom.isAncestorOrSelf(that._current, that.range.startContainer)) {
subRange.setStart(that.range.startContainer, that.range.startOffset);
}
if (dom.isAncestorOrSelf(that._current, that.range.endContainer)) {
subRange.setEnd(that.range.endContainer, that.range.endOffset);
}
return new RangeIterator(subRange);
}
});
var W3CSelection = Class.extend({
init: function (doc) {
this.ownerDocument = doc;
this.rangeCount = 1;
},
addRange: function (range) {
var textRange = this.ownerDocument.body.createTextRange();
adoptContainer(textRange, range, false);
adoptContainer(textRange, range, true);
textRange.select();
},
removeAllRanges: function () {
var selection = this.ownerDocument.selection;
if (selection.type != 'None') {
selection.empty();
}
},
getRangeAt: function () {
var textRange, range = new W3CRange(this.ownerDocument), selection = this.ownerDocument.selection, element, commonAncestor;
try {
textRange = selection.createRange();
element = textRange.item ? textRange.item(0) : textRange.parentElement();
if (element.ownerDocument != this.ownerDocument) {
return range;
}
} catch (ex) {
return range;
}
if (selection.type == 'Control') {
range.selectNode(textRange.item(0));
} else {
commonAncestor = textRangeContainer(textRange);
adoptEndPoint(textRange, range, commonAncestor, true);
adoptEndPoint(textRange, range, commonAncestor, false);
if (range.startContainer.nodeType == 9) {
range.setStart(range.endContainer, range.startOffset);
}
if (range.endContainer.nodeType == 9) {
range.setEnd(range.startContainer, range.endOffset);
}
if (textRange.compareEndPoints('StartToEnd', textRange) === 0) {
range.collapse(false);
}
var startContainer = range.startContainer, endContainer = range.endContainer, body = this.ownerDocument.body;
if (!range.collapsed && range.startOffset === 0 && range.endOffset == getNodeLength(range.endContainer) && !(startContainer == endContainer && isDataNode(startContainer) && startContainer.parentNode == body)) {
var movedStart = false, movedEnd = false;
while (findNodeIndex(startContainer) === 0 && startContainer == startContainer.parentNode.firstChild && startContainer != body) {
startContainer = startContainer.parentNode;
movedStart = true;
}
while (findNodeIndex(endContainer) == getNodeLength(endContainer.parentNode) - 1 && endContainer == endContainer.parentNode.lastChild && endContainer != body) {
endContainer = endContainer.parentNode;
movedEnd = true;
}
if (startContainer == body && endContainer == body && movedStart && movedEnd) {
range.setStart(startContainer, 0);
range.setEnd(endContainer, getNodeLength(body));
}
}
}
return range;
}
});
function textRangeContainer(textRange) {
var left = textRange.duplicate(), right = textRange.duplicate();
left.collapse(true);
right.collapse(false);
return dom.commonAncestor(textRange.parentElement(), left.parentElement(), right.parentElement());
}
function adoptContainer(textRange, range, start) {
var container = range[start ? 'startContainer' : 'endContainer'], offset = range[start ? 'startOffset' : 'endOffset'], textOffset = 0, isData = isDataNode(container), anchorNode = isData ? container : container.childNodes[offset] || null, anchorParent = isData ? container.parentNode : container, doc = range.ownerDocument, cursor = doc.body.createTextRange(), cursorNode;
if (container.nodeType == 3 || container.nodeType == 4) {
textOffset = offset;
}
if (!anchorParent) {
anchorParent = doc.body;
}
if (anchorParent.nodeName.toLowerCase() == 'img') {
cursor.moveToElementText(anchorParent);
cursor.collapse(false);
textRange.setEndPoint(start ? 'StartToStart' : 'EndToStart', cursor);
} else {
cursorNode = anchorParent.insertBefore(dom.create(doc, 'a'), anchorNode);
cursor.moveToElementText(cursorNode);
dom.remove(cursorNode);
cursor[start ? 'moveStart' : 'moveEnd']('character', textOffset);
cursor.collapse(false);
textRange.setEndPoint(start ? 'StartToStart' : 'EndToStart', cursor);
}
}
function adoptEndPoint(textRange, range, commonAncestor, start) {
var cursorNode = dom.create(range.ownerDocument, 'a'), cursor = textRange.duplicate(), comparison = start ? 'StartToStart' : 'StartToEnd', result, parent, target, previous, next, args, index, appended = false;
cursorNode.innerHTML = '\uFEFF';
cursor.collapse(start);
parent = cursor.parentElement();
if (!dom.isAncestorOrSelf(commonAncestor, parent)) {
parent = commonAncestor;
}
do {
if (appended) {
parent.insertBefore(cursorNode, cursorNode.previousSibling);
} else {
parent.appendChild(cursorNode);
appended = true;
}
cursor.moveToElementText(cursorNode);
} while ((result = cursor.compareEndPoints(comparison, textRange)) > 0 && cursorNode.previousSibling);
target = cursorNode.nextSibling;
if (result == -1 && isDataNode(target)) {
cursor.setEndPoint(start ? 'EndToStart' : 'EndToEnd', textRange);
dom.remove(cursorNode);
args = [
target,
cursor.text.length
];
} else {
previous = !start && cursorNode.previousSibling;
next = start && cursorNode.nextSibling;
if (isDataNode(next)) {
args = [
next,
0
];
} else if (isDataNode(previous)) {
args = [
previous,
previous.length
];
} else {
index = findNodeIndex(cursorNode);
if (parent.nextSibling && index == parent.childNodes.length - 1) {
args = [
parent.nextSibling,
0
];
} else {
args = [
parent,
index
];
}
}
dom.remove(cursorNode);
}
range[start ? 'setStart' : 'setEnd'].apply(range, args);
}
var RangeEnumerator = Class.extend({
init: function (range) {
this.enumerate = function () {
var nodes = [];
function visit(node) {
if (dom.is(node, 'img') || node.nodeType == 3 && (!dom.isEmptyspace(node) || node.nodeValue == '\uFEFF')) {
nodes.push(node);
} else {
node = node.firstChild;
while (node) {
visit(node);
node = node.nextSibling;
}
}
}
new RangeIterator(range).traverse(visit);
return nodes;
};
}
});
var RestorePoint = Class.extend({
init: function (range, body) {
var that = this;
that.range = range;
that.rootNode = RangeUtils.documentFromRange(range);
that.body = body || that.getEditable(range);
if (dom.name(that.body) != 'body') {
that.rootNode = that.body;
}
that.html = that.body.innerHTML;
that.startContainer = that.nodeToPath(range.startContainer);
that.endContainer = that.nodeToPath(range.endContainer);
that.startOffset = that.offset(range.startContainer, range.startOffset);
that.endOffset = that.offset(range.endContainer, range.endOffset);
},
index: function (node) {
var result = 0, lastType = node.nodeType;
while (node = node.previousSibling) {
var nodeType = node.nodeType;
if (nodeType != 3 || lastType != nodeType) {
result++;
}
lastType = nodeType;
}
return result;
},
getEditable: function (range) {
var root = range.commonAncestorContainer;
while (root && (root.nodeType == 3 || root.attributes && !root.attributes.contentEditable)) {
root = root.parentNode;
}
return root;
},
restoreHtml: function () {
this.body.innerHTML = this.html;
},
offset: function (node, value) {
if (node.nodeType == 3) {
while ((node = node.previousSibling) && node.nodeType == 3) {
value += node.nodeValue.length;
}
}
return value;
},
nodeToPath: function (node) {
var path = [];
while (node != this.rootNode) {
path.push(this.index(node));
node = node.parentNode;
}
return path;
},
toRangePoint: function (range, start, path, denormalizedOffset) {
var node = this.rootNode, length = path.length, offset = denormalizedOffset;
while (length--) {
node = node.childNodes[path[length]];
}
while (node && node.nodeType == 3 && node.nodeValue.length < offset) {
offset -= node.nodeValue.length;
node = node.nextSibling;
}
if (node && offset >= 0) {
range[start ? 'setStart' : 'setEnd'](node, offset);
}
},
toRange: function () {
var that = this, result = that.range.cloneRange();
that.toRangePoint(result, true, that.startContainer, that.startOffset);
that.toRangePoint(result, false, that.endContainer, that.endOffset);
return result;
}
});
var Marker = Class.extend({
init: function () {
this.caret = null;
},
addCaret: function (range) {
var that = this;
that.caret = dom.create(RangeUtils.documentFromRange(range), 'span', { className: 'k-marker' });
range.insertNode(that.caret);
range.selectNode(that.caret);
return that.caret;
},
removeCaret: function (range) {
var that = this, previous = that.caret.previousSibling, startOffset = 0;
if (previous) {
startOffset = isDataNode(previous) ? previous.nodeValue.length : findNodeIndex(previous);
}
var container = that.caret.parentNode;
var containerIndex = previous ? findNodeIndex(previous) : 0;
dom.remove(that.caret);
normalize(container);
var node = container.childNodes[containerIndex];
if (isDataNode(node)) {
range.setStart(node, startOffset);
} else if (node) {
var textNode = dom.lastTextNode(node);
if (textNode) {
range.setStart(textNode, textNode.nodeValue.length);
} else {
range[previous ? 'setStartAfter' : 'setStartBefore'](node);
}
} else {
if (!browser.msie && !container.innerHTML) {
container.innerHTML = '
';
}
range.selectNodeContents(container);
}
range.collapse(true);
},
add: function (range, expand) {
var that = this;
var collapsed = range.collapsed && !RangeUtils.isExpandable(range);
var doc = RangeUtils.documentFromRange(range);
if (expand && range.collapsed) {
that.addCaret(range);
range = RangeUtils.expand(range);
}
var rangeBoundary = range.cloneRange();
rangeBoundary.collapse(false);
that.end = dom.create(doc, 'span', { className: 'k-marker' });
rangeBoundary.insertNode(that.end);
rangeBoundary = range.cloneRange();
rangeBoundary.collapse(true);
that.start = that.end.cloneNode(true);
rangeBoundary.insertNode(that.start);
that._removeDeadMarkers(that.start, that.end);
if (collapsed) {
var bom = doc.createTextNode('\uFEFF');
dom.insertAfter(bom.cloneNode(), that.start);
dom.insertBefore(bom, that.end);
}
normalize(range.commonAncestorContainer);
range.setStartBefore(that.start);
range.setEndAfter(that.end);
return range;
},
_removeDeadMarkers: function (start, end) {
if (start.previousSibling && start.previousSibling.nodeValue == '\uFEFF') {
dom.remove(start.previousSibling);
}
if (end.nextSibling && end.nextSibling.nodeValue == '\uFEFF') {
dom.remove(end.nextSibling);
}
},
_normalizedIndex: function (node) {
var index = findNodeIndex(node);
var pointer = node;
while (pointer.previousSibling) {
if (pointer.nodeType == 3 && pointer.previousSibling.nodeType == 3) {
index--;
}
pointer = pointer.previousSibling;
}
return index;
},
remove: function (range) {
var that = this, start = that.start, end = that.end, shouldNormalizeStart, shouldNormalizeEnd, shouldNormalize;
normalize(range.commonAncestorContainer);
while (!start.nextSibling && start.parentNode) {
start = start.parentNode;
}
while (!end.previousSibling && end.parentNode) {
end = end.parentNode;
}
shouldNormalizeStart = start.previousSibling && start.previousSibling.nodeType == 3 && (start.nextSibling && start.nextSibling.nodeType == 3);
shouldNormalizeEnd = end.previousSibling && end.previousSibling.nodeType == 3 && (end.nextSibling && end.nextSibling.nodeType == 3);
shouldNormalize = shouldNormalizeStart && shouldNormalizeEnd;
start = start.nextSibling;
end = end.previousSibling;
var collapsed = false;
var collapsedToStart = false;
if (start == that.end) {
collapsedToStart = !!that.start.previousSibling;
start = end = that.start.previousSibling || that.end.nextSibling;
collapsed = true;
}
dom.remove(that.start);
dom.remove(that.end);
if (!start || !end) {
range.selectNodeContents(range.commonAncestorContainer);
range.collapse(true);
return;
}
var startOffset = collapsed ? isDataNode(start) ? start.nodeValue.length : start.childNodes.length : 0;
var endOffset = isDataNode(end) ? end.nodeValue.length : end.childNodes.length;
if (start.nodeType == 3) {
while (start.previousSibling && start.previousSibling.nodeType == 3) {
start = start.previousSibling;
startOffset += start.nodeValue.length;
}
}
if (end.nodeType == 3) {
while (end.previousSibling && end.previousSibling.nodeType == 3) {
end = end.previousSibling;
endOffset += end.nodeValue.length;
}
}
var startParent = start.parentNode;
var endParent = end.parentNode;
var startIndex = this._normalizedIndex(start);
var endIndex = this._normalizedIndex(end);
normalize(startParent);
if (start.nodeType == 3) {
start = startParent.childNodes[startIndex];
}
normalize(endParent);
if (end.nodeType == 3) {
end = endParent.childNodes[endIndex];
}
if (collapsed) {
if (start.nodeType == 3) {
range.setStart(start, startOffset);
} else {
range[collapsedToStart ? 'setStartAfter' : 'setStartBefore'](start);
}
range.collapse(true);
} else {
if (start.nodeType == 3) {
range.setStart(start, startOffset);
} else {
range.setStartBefore(start);
}
if (end.nodeType == 3) {
range.setEnd(end, endOffset);
} else {
range.setEndAfter(end);
}
}
if (that.caret) {
that.removeCaret(range);
}
}
});
var boundary = /[\u0009-\u000d]|\u0020|\u00a0|\ufeff|\.|,|;|:|!|\(|\)|\?/;
var RangeUtils = {
nodes: function (range) {
var nodes = RangeUtils.textNodes(range);
if (!nodes.length) {
range.selectNodeContents(range.commonAncestorContainer);
nodes = RangeUtils.textNodes(range);
if (!nodes.length) {
nodes = dom.significantChildNodes(range.commonAncestorContainer);
}
}
return nodes;
},
textNodes: function (range) {
return new RangeEnumerator(range).enumerate();
},
documentFromRange: function (range) {
var startContainer = range.startContainer;
return startContainer.nodeType == 9 ? startContainer : startContainer.ownerDocument;
},
createRange: function (document) {
if (browser.msie && browser.version < 9) {
return new W3CRange(document);
}
return document.createRange();
},
selectRange: function (range) {
var image = RangeUtils.image(range);
if (image) {
range.setStartAfter(image);
range.setEndAfter(image);
}
var selection = SelectionUtils.selectionFromRange(range);
selection.removeAllRanges();
selection.addRange(range);
},
stringify: function (range) {
return kendo.format('{0}:{1} - {2}:{3}', dom.name(range.startContainer), range.startOffset, dom.name(range.endContainer), range.endOffset);
},
split: function (range, node, trim) {
function partition(start) {
var partitionRange = range.cloneRange();
partitionRange.collapse(start);
partitionRange[start ? 'setStartBefore' : 'setEndAfter'](node);
var contents = partitionRange.extractContents();
if (trim) {
contents = dom.trim(contents);
}
dom[start ? 'insertBefore' : 'insertAfter'](contents, node);
}
partition(true);
partition(false);
},
mapAll: function (range, map) {
var nodes = [];
new RangeIterator(range).traverse(function (node) {
var mapped = map(node);
if (mapped && $.inArray(mapped, nodes) < 0) {
nodes.push(mapped);
}
});
return nodes;
},
getAll: function (range, predicate) {
var selector = predicate;
if (typeof predicate == 'string') {
predicate = function (node) {
return dom.is(node, selector);
};
}
return RangeUtils.mapAll(range, function (node) {
if (predicate(node)) {
return node;
}
});
},
getMarkers: function (range) {
return RangeUtils.getAll(range, function (node) {
return node.className == 'k-marker';
});
},
image: function (range) {
var nodes = RangeUtils.getAll(range, 'img');
if (nodes.length == 1) {
return nodes[0];
}
},
isStartOf: function (originalRange, node) {
if (originalRange.startOffset !== 0) {
return false;
}
var range = originalRange.cloneRange();
while (range.startOffset === 0 && range.startContainer != node) {
var index = dom.findNodeIndex(range.startContainer);
var parent = range.startContainer.parentNode;
while (index > 0 && parent[index - 1] && dom.insignificant(parent[index - 1])) {
index--;
}
range.setStart(parent, index);
}
return range.startOffset === 0 && range.startContainer == node;
},
isEndOf: function (originalRange, node) {
var range = originalRange.cloneRange();
range.collapse(false);
var start = range.startContainer;
if (dom.isDataNode(start) && range.startOffset == dom.getNodeLength(start)) {
range.setStart(start.parentNode, dom.findNodeIndex(start) + 1);
range.collapse(true);
}
range.setEnd(node, dom.getNodeLength(node));
var nodes = [];
function visit(node) {
if (!dom.insignificant(node)) {
nodes.push(node);
}
}
new RangeIterator(range).traverse(visit);
return !nodes.length;
},
wrapSelectedElements: function (range) {
var startEditable = dom.editableParent(range.startContainer);
var endEditable = dom.editableParent(range.endContainer);
while (range.startOffset === 0 && range.startContainer != startEditable) {
range.setStart(range.startContainer.parentNode, dom.findNodeIndex(range.startContainer));
}
function isEnd(offset, container) {
var length = dom.getNodeLength(container);
if (offset == length) {
return true;
}
for (var i = offset; i < length; i++) {
if (!dom.insignificant(container.childNodes[i])) {
return false;
}
}
return true;
}
while (isEnd(range.endOffset, range.endContainer) && range.endContainer != endEditable) {
range.setEnd(range.endContainer.parentNode, dom.findNodeIndex(range.endContainer) + 1);
}
return range;
},
expand: function (range) {
var result = range.cloneRange();
var startContainer = result.startContainer.childNodes[result.startOffset === 0 ? 0 : result.startOffset - 1];
var endContainer = result.endContainer.childNodes[result.endOffset];
if (!isDataNode(startContainer) || !isDataNode(endContainer)) {
return result;
}
var beforeCaret = startContainer.nodeValue;
var afterCaret = endContainer.nodeValue;
if (!beforeCaret || !afterCaret) {
return result;
}
var startOffset = beforeCaret.split('').reverse().join('').search(boundary);
var endOffset = afterCaret.search(boundary);
if (!startOffset || !endOffset) {
return result;
}
endOffset = endOffset == -1 ? afterCaret.length : endOffset;
startOffset = startOffset == -1 ? 0 : beforeCaret.length - startOffset;
result.setStart(startContainer, startOffset);
result.setEnd(endContainer, endOffset);
return result;
},
isExpandable: function (range) {
var node = range.startContainer;
var rangeDocument = RangeUtils.documentFromRange(range);
if (node == rangeDocument || node == rangeDocument.body) {
return false;
}
var result = range.cloneRange();
var value = node.nodeValue;
if (!value) {
return false;
}
var beforeCaret = value.substring(0, result.startOffset);
var afterCaret = value.substring(result.startOffset);
var startOffset = 0, endOffset = 0;
if (beforeCaret) {
startOffset = beforeCaret.split('').reverse().join('').search(boundary);
}
if (afterCaret) {
endOffset = afterCaret.search(boundary);
}
return startOffset && endOffset;
}
};
extend(Editor, {
SelectionUtils: SelectionUtils,
W3CRange: W3CRange,
RangeIterator: RangeIterator,
W3CSelection: W3CSelection,
RangeEnumerator: RangeEnumerator,
RestorePoint: RestorePoint,
Marker: Marker,
RangeUtils: RangeUtils
});
}(window.kendo.jQuery));
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('editor/system', ['editor/range'], f);
}(function () {
(function ($) {
var kendo = window.kendo, Class = kendo.Class, editorNS = kendo.ui.editor, EditorUtils = editorNS.EditorUtils, registerTool = EditorUtils.registerTool, dom = editorNS.Dom, Tool = editorNS.Tool, ToolTemplate = editorNS.ToolTemplate, RestorePoint = editorNS.RestorePoint, Marker = editorNS.Marker, extend = $.extend;
function finishUpdate(editor, startRestorePoint) {
var endRestorePoint = editor.selectionRestorePoint = new RestorePoint(editor.getRange());
var command = new GenericCommand(startRestorePoint, endRestorePoint);
command.editor = editor;
editor.undoRedoStack.push(command);
return endRestorePoint;
}
var Command = Class.extend({
init: function (options) {
this.options = options;
this.restorePoint = new RestorePoint(options.range);
this.marker = new Marker();
this.formatter = options.formatter;
},
getRange: function () {
return this.restorePoint.toRange();
},
lockRange: function (expand) {
return this.marker.add(this.getRange(), expand);
},
releaseRange: function (range) {
this.marker.remove(range);
this.editor.selectRange(range);
},
undo: function () {
var point = this.restorePoint;
point.restoreHtml();
this.editor.selectRange(point.toRange());
},
redo: function () {
this.exec();
},
createDialog: function (content, options) {
var editor = this.editor;
return $(content).appendTo(document.body).kendoWindow(extend({}, editor.options.dialogOptions, options)).closest('.k-window').toggleClass('k-rtl', kendo.support.isRtl(editor.wrapper)).end();
},
exec: function () {
var range = this.lockRange(true);
this.formatter.editor = this.editor;
this.formatter.toggle(range);
this.releaseRange(range);
}
});
var GenericCommand = Class.extend({
init: function (startRestorePoint, endRestorePoint) {
this.body = startRestorePoint.body;
this.startRestorePoint = startRestorePoint;
this.endRestorePoint = endRestorePoint;
},
redo: function () {
this.body.innerHTML = this.endRestorePoint.html;
this.editor.selectRange(this.endRestorePoint.toRange());
},
undo: function () {
this.body.innerHTML = this.startRestorePoint.html;
this.editor.selectRange(this.startRestorePoint.toRange());
}
});
var InsertHtmlCommand = Command.extend({
init: function (options) {
Command.fn.init.call(this, options);
this.managesUndoRedo = true;
},
exec: function () {
var editor = this.editor;
var options = this.options;
var range = options.range;
var body = editor.body;
var startRestorePoint = new RestorePoint(range, body);
var html = options.html || options.value || '';
editor.selectRange(range);
editor.clipboard.paste(html, options);
if (options.postProcess) {
options.postProcess(editor, editor.getRange());
}
var genericCommand = new GenericCommand(startRestorePoint, new RestorePoint(editor.getRange(), body));
genericCommand.editor = editor;
editor.undoRedoStack.push(genericCommand);
editor.focus();
}
});
var InsertHtmlTool = Tool.extend({
initialize: function (ui, initOptions) {
var editor = initOptions.editor, options = this.options, dataSource = options.items ? options.items : editor.options.insertHtml;
this._selectBox = new editorNS.SelectBox(ui, {
dataSource: dataSource,
dataTextField: 'text',
dataValueField: 'value',
change: function () {
Tool.exec(editor, 'insertHtml', this.value());
},
title: editor.options.messages.insertHtml,
highlightFirst: false
});
},
command: function (commandArguments) {
return new InsertHtmlCommand(commandArguments);
},
update: function (ui) {
var selectbox = ui.data('kendoSelectBox') || ui.find('select').data('kendoSelectBox');
selectbox.close();
selectbox.value(selectbox.options.title);
}
});
var TypingHandler = Class.extend({
init: function (editor) {
this.editor = editor;
},
keydown: function (e) {
var that = this, editor = that.editor, keyboard = editor.keyboard, isTypingKey = keyboard.isTypingKey(e), evt = extend($.Event(), e);
that.editor.trigger('keydown', evt);
if (evt.isDefaultPrevented()) {
e.preventDefault();
return true;
}
if (!evt.isDefaultPrevented() && isTypingKey && !keyboard.isTypingInProgress()) {
var range = editor.getRange();
that.startRestorePoint = new RestorePoint(range);
keyboard.startTyping(function () {
that.endRestorePoint = finishUpdate(editor, that.startRestorePoint);
});
return true;
}
return false;
},
keyup: function (e) {
var keyboard = this.editor.keyboard;
this.editor.trigger('keyup', e);
if (keyboard.isTypingInProgress()) {
keyboard.endTyping();
return true;
}
return false;
}
});
var BackspaceHandler = Class.extend({
init: function (editor) {
this.editor = editor;
},
_addCaret: function (container) {
var caret = dom.create(this.editor.document, 'a');
dom.insertAt(container, caret, 0);
return caret;
},
_restoreCaret: function (caret) {
var range = this.editor.createRange();
range.setStartAfter(caret);
range.collapse(true);
this.editor.selectRange(range);
dom.remove(caret);
},
_handleDelete: function (range) {
var node = range.endContainer;
var block = dom.closestEditableOfType(node, dom.blockElements);
if (block && editorNS.RangeUtils.isEndOf(range, block)) {
var next = dom.next(block);
if (!next || dom.name(next) != 'p') {
return false;
}
var caret = this._addCaret(next);
this._merge(block, next);
this._restoreCaret(caret);
return true;
}
return false;
},
_cleanBomBefore: function (range) {
var offset = range.startOffset;
var node = range.startContainer;
var text = node.nodeValue;
var count = 0;
while (offset - count >= 0 && text[offset - count - 1] == '\uFEFF') {
count++;
}
if (count > 0) {
node.deleteData(offset - count, count);
range.setStart(node, Math.max(0, offset - count));
range.collapse(true);
this.editor.selectRange(range);
}
},
_handleBackspace: function (range) {
var node = range.startContainer;
var li = dom.closestEditableOfType(node, ['li']);
var block = dom.closestEditableOfType(node, 'p,h1,h2,h3,h4,h5,h6'.split(','));
if (dom.isDataNode(node)) {
this._cleanBomBefore(range);
}
if (block && block.previousSibling && editorNS.RangeUtils.isStartOf(range, block)) {
var prev = block.previousSibling;
var caret = this._addCaret(block);
this._merge(prev, block);
this._restoreCaret(caret);
return true;
}
if (li && editorNS.RangeUtils.isStartOf(range, li)) {
var child = li.firstChild;
if (!child) {
li.innerHTML = editorNS.emptyElementContent;
child = li.firstChild;
}
var formatter = new editorNS.ListFormatter(dom.name(li.parentNode), 'p');
range.selectNodeContents(li);
formatter.toggle(range);
if (dom.insignificant(child)) {
range.setStartBefore(child);
} else {
range.setStart(child, 0);
}
this.editor.selectRange(range);
return true;
}
return false;
},
_handleSelection: function (range) {
var ancestor = range.commonAncestorContainer;
var table = dom.closest(ancestor, 'table');
var emptyParagraphContent = editorNS.emptyElementContent;
if (/t(able|body)/i.test(dom.name(ancestor))) {
range.selectNode(table);
}
var marker = new Marker();
marker.add(range, false);
range.setStartAfter(marker.start);
range.setEndBefore(marker.end);
var start = range.startContainer;
var end = range.endContainer;
range.deleteContents();
if (table && $(table).text() === '') {
range.selectNode(table);
range.deleteContents();
}
ancestor = range.commonAncestorContainer;
if (dom.name(ancestor) === 'p' && ancestor.innerHTML === '') {
ancestor.innerHTML = emptyParagraphContent;
range.setStart(ancestor, 0);
}
this._join(start, end);
dom.insertAfter(this.editor.document.createTextNode('\uFEFF'), marker.start);
marker.remove(range);
start = range.startContainer;
if (dom.name(start) == 'tr') {
start = start.childNodes[Math.max(0, range.startOffset - 1)];
range.setStart(start, dom.getNodeLength(start));
}
range.collapse(true);
this.editor.selectRange(range);
return true;
},
_root: function (node) {
while (node && node.parentNode && dom.name(node.parentNode) != 'body') {
node = node.parentNode;
}
return node;
},
_join: function (start, end) {
start = this._root(start);
end = this._root(end);
if (start != end && dom.is(end, 'p')) {
this._merge(start, end);
}
},
_merge: function (dest, src) {
dom.removeTrailingBreak(dest);
while (src.firstChild) {
if (dest.nodeType == 1) {
dest.appendChild(src.firstChild);
} else {
dest.parentNode.appendChild(src.firstChild);
}
}
dom.remove(src);
},
keydown: function (e) {
var method, startRestorePoint;
var range = this.editor.getRange();
var keyCode = e.keyCode;
var keys = kendo.keys;
var backspace = keyCode === keys.BACKSPACE;
var del = keyCode == keys.DELETE;
if ((backspace || del) && !range.collapsed) {
method = '_handleSelection';
} else if (backspace) {
method = '_handleBackspace';
} else if (del) {
method = '_handleDelete';
}
if (!method) {
return;
}
startRestorePoint = new RestorePoint(range);
if (this[method](range)) {
e.preventDefault();
finishUpdate(this.editor, startRestorePoint);
}
},
keyup: $.noop
});
var SystemHandler = Class.extend({
init: function (editor) {
this.editor = editor;
this.systemCommandIsInProgress = false;
},
createUndoCommand: function () {
this.startRestorePoint = this.endRestorePoint = finishUpdate(this.editor, this.startRestorePoint);
},
changed: function () {
if (this.startRestorePoint) {
return this.startRestorePoint.html != this.editor.body.innerHTML;
}
return false;
},
keydown: function (e) {
var that = this, editor = that.editor, keyboard = editor.keyboard;
if (keyboard.isModifierKey(e)) {
if (keyboard.isTypingInProgress()) {
keyboard.endTyping(true);
}
that.startRestorePoint = new RestorePoint(editor.getRange());
return true;
}
if (keyboard.isSystem(e)) {
that.systemCommandIsInProgress = true;
if (that.changed()) {
that.systemCommandIsInProgress = false;
that.createUndoCommand();
}
return true;
}
return false;
},
keyup: function () {
var that = this;
if (that.systemCommandIsInProgress && that.changed()) {
that.systemCommandIsInProgress = false;
that.createUndoCommand();
return true;
}
return false;
}
});
var Keyboard = Class.extend({
init: function (handlers) {
this.handlers = handlers;
this.typingInProgress = false;
},
isCharacter: function (keyCode) {
return keyCode >= 48 && keyCode <= 90 || keyCode >= 96 && keyCode <= 111 || keyCode >= 186 && keyCode <= 192 || keyCode >= 219 && keyCode <= 222 || keyCode == 229;
},
toolFromShortcut: function (tools, e) {
var key = String.fromCharCode(e.keyCode), toolName, toolOptions;
for (toolName in tools) {
toolOptions = $.extend({
ctrl: false,
alt: false,
shift: false
}, tools[toolName].options);
if ((toolOptions.key == key || toolOptions.key == e.keyCode) && toolOptions.ctrl == e.ctrlKey && toolOptions.alt == e.altKey && toolOptions.shift == e.shiftKey) {
return toolName;
}
}
},
isTypingKey: function (e) {
var keyCode = e.keyCode;
return this.isCharacter(keyCode) && !e.ctrlKey && !e.altKey || keyCode == 32 || keyCode == 13 || keyCode == 8 || keyCode == 46 && !e.shiftKey && !e.ctrlKey && !e.altKey;
},
isModifierKey: function (e) {
var keyCode = e.keyCode;
return keyCode == 17 && !e.shiftKey && !e.altKey || keyCode == 16 && !e.ctrlKey && !e.altKey || keyCode == 18 && !e.ctrlKey && !e.shiftKey;
},
isSystem: function (e) {
return e.keyCode == 46 && e.ctrlKey && !e.altKey && !e.shiftKey;
},
startTyping: function (callback) {
this.onEndTyping = callback;
this.typingInProgress = true;
},
stopTyping: function () {
if (this.typingInProgress && this.onEndTyping) {
this.onEndTyping();
}
this.typingInProgress = false;
},
endTyping: function (force) {
var that = this;
that.clearTimeout();
if (force) {
that.stopTyping();
} else {
that.timeout = window.setTimeout($.proxy(that.stopTyping, that), 1000);
}
},
isTypingInProgress: function () {
return this.typingInProgress;
},
clearTimeout: function () {
window.clearTimeout(this.timeout);
},
notify: function (e, what) {
var i, handlers = this.handlers;
for (i = 0; i < handlers.length; i++) {
if (handlers[i][what](e)) {
break;
}
}
},
keydown: function (e) {
this.notify(e, 'keydown');
},
keyup: function (e) {
this.notify(e, 'keyup');
}
});
var Clipboard = Class.extend({
init: function (editor) {
this.editor = editor;
this.cleaners = [
new ScriptCleaner(),
new TabCleaner(),
new MSWordFormatCleaner(),
new WebkitFormatCleaner()
];
},
htmlToFragment: function (html) {
var editor = this.editor, doc = editor.document, container = dom.create(doc, 'div'), fragment = doc.createDocumentFragment();
container.innerHTML = html;
while (container.firstChild) {
fragment.appendChild(container.firstChild);
}
return fragment;
},
isBlock: function (html) {
return /<(div|p|ul|ol|table|h[1-6])/i.test(html);
},
_startModification: function () {
var range;
var restorePoint;
var editor = this.editor;
if (this._inProgress) {
return;
}
this._inProgress = true;
range = editor.getRange();
restorePoint = new RestorePoint(range);
dom.persistScrollTop(editor.document);
return {
range: range,
restorePoint: restorePoint
};
},
_endModification: function (modificationInfo) {
finishUpdate(this.editor, modificationInfo.restorePoint);
this.editor._selectionChange();
this._inProgress = false;
},
_contentModification: function (before, after) {
var that = this;
var editor = that.editor;
var modificationInfo = that._startModification();
if (!modificationInfo) {
return;
}
before.call(that, editor, modificationInfo.range);
setTimeout(function () {
after.call(that, editor, modificationInfo.range);
that._endModification(modificationInfo);
});
},
_removeBomNodes: function (range) {
var nodes = editorNS.RangeUtils.textNodes(range);
for (var i = 0; i < nodes.length; i++) {
nodes[i].nodeValue = dom.stripBom(nodes[i].nodeValue);
}
},
_onBeforeCopy: function (range) {
var marker = new Marker();
marker.add(range);
this._removeBomNodes(range);
marker.remove(range);
this.editor.selectRange(range);
},
oncopy: function () {
this._onBeforeCopy(this.editor.getRange());
},
oncut: function () {
this._onBeforeCopy(this.editor.getRange());
this._contentModification($.noop, $.noop);
},
_fileToDataURL: function (blob) {
var deferred = $.Deferred();
var reader = new FileReader();
if (!(blob instanceof window.File) && blob.getAsFile) {
blob = blob.getAsFile();
}
reader.onload = $.proxy(deferred.resolve, deferred);
reader.readAsDataURL(blob);
return deferred.promise();
},
_triggerPaste: function (html, options) {
var args = { html: html || '' };
args.html = args.html.replace(/\ufeff/g, '');
this.editor.trigger('paste', args);
this.paste(args.html, options || {});
},
_handleImagePaste: function (e) {
if (!('FileReader' in window)) {
return;
}
var clipboardData = e.clipboardData || e.originalEvent.clipboardData || window.clipboardData || {};
var items = clipboardData.items || clipboardData.files;
if (!items) {
return;
}
var images = $.grep(items, function (item) {
return /^image\//i.test(item.type);
});
var html = $.grep(items, function (item) {
return /^text\/html/i.test(item.type);
});
if (html.length || !images.length) {
return;
}
var modificationInfo = this._startModification();
if (!modificationInfo) {
return;
}
$.when.apply($, $.map(images, this._fileToDataURL)).done($.proxy(function () {
var results = Array.prototype.slice.call(arguments);
var html = $.map(results, function (e) {
return '

';
}).join('');
this._triggerPaste(html);
this._endModification(modificationInfo);
}, this));
return true;
},
onpaste: function (e) {
if (this._handleImagePaste(e)) {
e.preventDefault();
return;
}
this._contentModification(function beforePaste(editor, range) {
var clipboardNode = dom.create(editor.document, 'div', {
className: 'k-paste-container',
innerHTML: '\uFEFF'
});
var browser = kendo.support.browser;
editor.body.appendChild(clipboardNode);
if (browser.msie && browser.version < 11) {
e.preventDefault();
var r = editor.createRange();
r.selectNodeContents(clipboardNode);
editor.selectRange(r);
var textRange = editor.document.body.createTextRange();
textRange.moveToElementText(clipboardNode);
$(editor.body).unbind('paste');
textRange.execCommand('Paste');
$(editor.body).bind('paste', $.proxy(this.onpaste, this));
} else {
var clipboardRange = editor.createRange();
clipboardRange.selectNodeContents(clipboardNode);
editor.selectRange(clipboardRange);
}
range.deleteContents();
}, function afterPaste(editor, range) {
var html = '', containers;
editor.selectRange(range);
containers = $(editor.body).children('.k-paste-container');
containers.each(function () {
var lastChild = this.lastChild;
if (lastChild && dom.is(lastChild, 'br')) {
dom.remove(lastChild);
}
html += this.innerHTML;
});
containers.remove();
this._triggerPaste(html, { clean: true });
});
},
splittableParent: function (block, node) {
var parentNode, body;
if (block) {
return dom.closestEditableOfType(node, [
'p',
'ul',
'ol'
]) || node.parentNode;
}
parentNode = node.parentNode;
body = node.ownerDocument.body;
if (dom.isInline(parentNode)) {
while (parentNode.parentNode != body && !dom.isBlock(parentNode.parentNode)) {
parentNode = parentNode.parentNode;
}
}
return parentNode;
},
paste: function (html, options) {
var editor = this.editor, i, l;
options = extend({
clean: false,
split: true
}, options);
for (i = 0, l = this.cleaners.length; i < l; i++) {
if (this.cleaners[i].applicable(html)) {
html = this.cleaners[i].clean(html);
}
}
if (options.clean) {
html = html.replace(/(
(\s| )*)+(<\/?(div|p|li|col|t))/gi, '$3');
html = html.replace(/<(a|span)[^>]*><\/\1>/gi, '');
}
html = html.replace(/^
$/g, 'li>');
var block = this.isBlock(html);
editor.focus();
var range = editor.getRange();
range.deleteContents();
if (range.startContainer == editor.document) {
range.selectNodeContents(editor.body);
}
var marker = new Marker();
var caret = marker.addCaret(range);
var parent = this.splittableParent(block, caret);
var unwrap = false;
var splittable = parent != editor.body && !dom.is(parent, 'td');
if (options.split && splittable && (block || dom.isInline(parent))) {
range.selectNode(caret);
editorNS.RangeUtils.split(range, parent, true);
unwrap = true;
}
var fragment = this.htmlToFragment(html);
if (fragment.firstChild && fragment.firstChild.className === 'k-paste-container') {
var fragmentsHtml = [];
for (i = 0, l = fragment.childNodes.length; i < l; i++) {
fragmentsHtml.push(fragment.childNodes[i].innerHTML);
}
fragment = this.htmlToFragment(fragmentsHtml.join('
'));
}
$(fragment.childNodes).filter('table').addClass('k-table').end().find('table').addClass('k-table');
range.insertNode(fragment);
parent = this.splittableParent(block, caret);
if (unwrap) {
while (caret.parentNode != parent) {
dom.unwrap(caret.parentNode);
}
dom.unwrap(caret.parentNode);
}
dom.normalize(range.commonAncestorContainer);
caret.style.display = 'inline';
dom.restoreScrollTop(editor.document);
dom.scrollTo(caret);
marker.removeCaret(range);
var rangeEnd = range.commonAncestorContainer.parentNode;
if (range.collapsed && dom.name(rangeEnd) == 'tbody') {
range.setStartAfter($(rangeEnd).closest('table')[0]);
range.collapse(true);
}
editor.selectRange(range);
}
});
var Cleaner = Class.extend({
clean: function (html) {
var that = this, replacements = that.replacements, i, l;
for (i = 0, l = replacements.length; i < l; i += 2) {
html = html.replace(replacements[i], replacements[i + 1]);
}
return html;
}
});
var ScriptCleaner = Cleaner.extend({
init: function () {
this.replacements = [
/<(\/?)script([^>]*)>/i,
'<$1telerik:script$2>'
];
},
applicable: function (html) {
return /' + '' + '' + '' + '' + '' + '
'
},
_generateFormats: function () {
var options = this.options;
if (!options.currencies) {
options.currencies = FormatCellsDialog.currenciesFrom(kendo.cultures);
}
if (!options.numberFormats) {
options.numberFormats = [
{
value: '#.00%',
name: '100.00%'
},
{
value: '#%',
name: '100%'
},
{
value: '#.00',
name: '1024.00'
},
{
value: '#,###.00',
name: '1,024.00'
}
];
}
if (!options.dateFormats) {
var calendarPatterns = kendo.cultures.current.calendars.standard.patterns;
options.dateFormats = uniqueBy('value', $.map(calendarPatterns, function (format) {
format = FormatCellsViewModel.convert.date(format);
if (!format) {
return;
}
return {
value: format,
name: formattedValue(34567.7678, format)
};
}));
}
},
open: function (range) {
var options = this.options;
var value = range.value();
var categories = options.categories.slice(0);
var element;
this.viewModel = new FormatCellsViewModel({
currencies: options.currencies.slice(0),
allFormats: {
numberFormats: options.numberFormats.slice(0),
dateFormats: options.dateFormats.slice(0)
},
categories: categories,
format: range.format(),
category: value instanceof Date ? categories[2] : categories[0],
apply: this.apply.bind(this),
close: this.close.bind(this),
value: value
});
SpreadsheetDialog.fn.open.call(this);
element = this.dialog().element;
kendo.bind(element, this.viewModel);
var currencyFilter = element.find('select.k-format-filter').data('kendoDropDownList');
if (options.currencies.length > 10) {
currencyFilter.setOptions({ filter: 'contains' });
}
element.find(kendo.roleSelector('staticlist')).parent().addClass('k-list-wrapper');
},
apply: function () {
var format = this.viewModel.format;
SpreadsheetDialog.fn.apply.call(this);
this.trigger('action', {
command: 'PropertyChangeCommand',
options: {
property: 'format',
value: format
}
});
}
});
FormatCellsDialog.currenciesFrom = function (cultures) {
return uniqueBy('description', $.map(cultures, function (culture, name) {
if (!/-/.test(name)) {
return;
}
var currency = culture.numberFormat.currency;
var description = kendo.format('{0} ({1}, {2})', currency.name, currency.abbr, currency.symbol);
return {
description: description,
value: currency
};
}));
};
kendo.spreadsheet.dialogs.register('formatCells', FormatCellsDialog);
kendo.spreadsheet.dialogs.FormatCellsDialog = FormatCellsDialog;
var MessageDialog = SpreadsheetDialog.extend({
options: {
className: 'k-spreadsheet-message',
title: '',
text: '',
template: '' + '' + '' + '
'
},
open: function () {
SpreadsheetDialog.fn.open.call(this);
kendo.bind(this.dialog().element, {
text: this.options.text,
okText: MESSAGES.okText,
close: this.close.bind(this)
});
}
});
kendo.spreadsheet.dialogs.register('message', MessageDialog);
var FontFamilyDialog = SpreadsheetDialog.extend({
init: function (options) {
SpreadsheetDialog.fn.init.call(this, options);
this._list();
},
options: {
title: MESSAGES.fontFamilyDialog.title,
template: ''
},
_list: function () {
var ul = this.dialog().element.find('ul');
var fonts = this.options.fonts;
var defaultFont = this.options.defaultFont;
this.list = new kendo.ui.StaticList(ul, {
dataSource: new kendo.data.DataSource({ data: fonts }),
template: '#:data#',
value: defaultFont,
change: this.apply.bind(this)
});
this.list.dataSource.fetch();
},
apply: function (e) {
SpreadsheetDialog.fn.apply.call(this);
this.trigger('action', {
command: 'PropertyChangeCommand',
options: {
property: 'fontFamily',
value: e.sender.value()[0]
}
});
}
});
kendo.spreadsheet.dialogs.register('fontFamily', FontFamilyDialog);
var FontSizeDialog = SpreadsheetDialog.extend({
init: function (options) {
SpreadsheetDialog.fn.init.call(this, options);
this._list();
},
options: {
title: MESSAGES.fontSizeDialog.title,
template: ''
},
_list: function () {
var ul = this.dialog().element.find('ul');
var sizes = this.options.sizes;
var defaultSize = this.options.defaultSize;
this.list = new kendo.ui.StaticList(ul, {
dataSource: new kendo.data.DataSource({ data: sizes }),
template: '#:data#',
value: defaultSize,
change: this.apply.bind(this)
});
this.list.dataSource.fetch();
},
apply: function (e) {
SpreadsheetDialog.fn.apply.call(this);
this.trigger('action', {
command: 'PropertyChangeCommand',
options: {
property: 'fontSize',
value: kendo.parseInt(e.sender.value()[0])
}
});
}
});
kendo.spreadsheet.dialogs.register('fontSize', FontSizeDialog);
var BordersDialog = SpreadsheetDialog.extend({
init: function (options) {
SpreadsheetDialog.fn.init.call(this, options);
this.element = this.dialog().element;
this._borderPalette();
this.viewModel = kendo.observable({
apply: this.apply.bind(this),
close: this.close.bind(this)
});
kendo.bind(this.element.find('.k-action-buttons'), this.viewModel);
},
options: {
title: MESSAGES.bordersDialog.title,
width: 177,
template: '' + '' + '' + '' + '
'
},
apply: function () {
SpreadsheetDialog.fn.apply.call(this);
var state = this.value();
this.trigger('action', {
command: 'BorderChangeCommand',
options: {
border: state.type,
style: {
size: 1,
color: state.color
}
}
});
},
_borderPalette: function () {
var element = this.dialog().element.find('div:first');
this.borderPalette = new kendo.spreadsheet.BorderPalette(element, { change: this.value.bind(this) });
},
value: function (state) {
if (state === undefined) {
return this._state;
} else {
this._state = state;
}
}
});
kendo.spreadsheet.dialogs.register('borders', BordersDialog);
var ColorChooser = SpreadsheetDialog.extend({
init: function (options) {
SpreadsheetDialog.fn.init.call(this, options);
this.element = this.dialog().element;
this.property = options.property;
this.options.title = options.title;
this.viewModel = kendo.observable({
apply: this.apply.bind(this),
close: this.close.bind(this)
});
kendo.bind(this.element.find('.k-action-buttons'), this.viewModel);
},
options: { template: '' + '' + '' + '' + '
' },
apply: function () {
SpreadsheetDialog.fn.apply.call(this);
this.trigger('action', {
command: 'PropertyChangeCommand',
options: {
property: this.property,
value: this.value()
}
});
},
value: function (e) {
if (e === undefined) {
return this._value;
} else {
this._value = e.value;
}
}
});
var ColorPickerDialog = ColorChooser.extend({
init: function (options) {
options.width = 177;
ColorChooser.fn.init.call(this, options);
this._colorPalette();
},
_colorPalette: function () {
var element = this.dialog().element.find('div:first');
this.colorPalette = element.kendoColorPalette({
palette: [
'#ffffff',
'#000000',
'#d6ecff',
'#4e5b6f',
'#7fd13b',
'#ea157a',
'#feb80a',
'#00addc',
'#738ac8',
'#1ab39f',
'#f2f2f2',
'#7f7f7f',
'#a7d6ff',
'#d9dde4',
'#e5f5d7',
'#fad0e4',
'#fef0cd',
'#c5f2ff',
'#e2e7f4',
'#c9f7f1',
'#d8d8d8',
'#595959',
'#60b5ff',
'#b3bcca',
'#cbecb0',
'#f6a1c9',
'#fee29c',
'#8be6ff',
'#c7d0e9',
'#94efe3',
'#bfbfbf',
'#3f3f3f',
'#007dea',
'#8d9baf',
'#b2e389',
'#f272af',
'#fed46b',
'#51d9ff',
'#aab8de',
'#5fe7d5',
'#a5a5a5',
'#262626',
'#003e75',
'#3a4453',
'#5ea226',
'#af0f5b',
'#c58c00',
'#0081a5',
'#425ea9',
'#138677',
'#7f7f7f',
'#0c0c0c',
'#00192e',
'#272d37',
'#3f6c19',
'#750a3d',
'#835d00',
'#00566e',
'#2c3f71',
'#0c594f'
],
change: this.value.bind(this)
}).data('kendoColorPalette');
}
});
kendo.spreadsheet.dialogs.register('colorPicker', ColorPickerDialog);
var CustomColorDialog = ColorChooser.extend({
init: function (options) {
options.width = 268;
ColorChooser.fn.init.call(this, options);
this.dialog().setOptions({ animation: false });
this.dialog().one('activate', this._colorPicker.bind(this));
},
_colorPicker: function () {
var element = this.dialog().element.find('div:first');
this.colorPicker = element.kendoFlatColorPicker({ change: this.value.bind(this) }).data('kendoFlatColorPicker');
}
});
kendo.spreadsheet.dialogs.register('customColor', CustomColorDialog);
var AlignmentDialog = SpreadsheetDialog.extend({
init: function (options) {
SpreadsheetDialog.fn.init.call(this, options);
this._list();
},
options: {
title: 'Alignment',
template: '',
buttons: [
{
property: 'textAlign',
value: 'left',
iconClass: 'justify-left',
text: MESSAGES.alignmentDialog.buttons.justtifyLeft
},
{
property: 'textAlign',
value: 'center',
iconClass: 'justify-center',
text: MESSAGES.alignmentDialog.buttons.justifyCenter
},
{
property: 'textAlign',
value: 'right',
iconClass: 'justify-right',
text: MESSAGES.alignmentDialog.buttons.justifyRight
},
{
property: 'textAlign',
value: 'justify',
iconClass: 'justify-full',
text: MESSAGES.alignmentDialog.buttons.justifyFull
},
{
property: 'verticalAlign',
value: 'top',
iconClass: 'align-top',
text: MESSAGES.alignmentDialog.buttons.alignTop
},
{
property: 'verticalAlign',
value: 'center',
iconClass: 'align-middle',
text: MESSAGES.alignmentDialog.buttons.alignMiddle
},
{
property: 'verticalAlign',
value: 'bottom',
iconClass: 'align-bottom',
text: MESSAGES.alignmentDialog.buttons.alignBottom
}
]
},
_list: function () {
var ul = this.dialog().element.find('ul');
this.list = new kendo.ui.StaticList(ul, {
dataSource: new kendo.data.DataSource({ data: this.options.buttons }),
template: '' + '' + '#=text#' + '',
change: this.apply.bind(this)
});
this.list.dataSource.fetch();
},
apply: function (e) {
var dataItem = e.sender.value()[0];
SpreadsheetDialog.fn.apply.call(this);
this.trigger('action', {
command: 'PropertyChangeCommand',
options: {
property: dataItem.property,
value: dataItem.value
}
});
}
});
kendo.spreadsheet.dialogs.register('alignment', AlignmentDialog);
var MergeDialog = SpreadsheetDialog.extend({
init: function (options) {
SpreadsheetDialog.fn.init.call(this, options);
this._list();
},
options: {
title: MESSAGES.mergeDialog.title,
template: '',
buttons: [
{
value: 'cells',
iconClass: 'merge-cells',
text: MESSAGES.mergeDialog.buttons.mergeCells
},
{
value: 'horizontally',
iconClass: 'merge-horizontally',
text: MESSAGES.mergeDialog.buttons.mergeHorizontally
},
{
value: 'vertically',
iconClass: 'merge-vertically',
text: MESSAGES.mergeDialog.buttons.mergeVertically
},
{
value: 'unmerge',
iconClass: 'normal-layout',
text: MESSAGES.mergeDialog.buttons.unmerge
}
]
},
_list: function () {
var ul = this.dialog().element.find('ul');
this.list = new kendo.ui.StaticList(ul, {
dataSource: new kendo.data.DataSource({ data: this.options.buttons }),
template: '' + '#=text#' + '',
change: this.apply.bind(this)
});
this.list.dataSource.fetch();
},
apply: function (e) {
var dataItem = e.sender.value()[0];
SpreadsheetDialog.fn.apply.call(this);
this.trigger('action', {
command: 'MergeCellCommand',
options: { value: dataItem.value }
});
}
});
kendo.spreadsheet.dialogs.register('merge', MergeDialog);
var FreezeDialog = SpreadsheetDialog.extend({
init: function (options) {
SpreadsheetDialog.fn.init.call(this, options);
this._list();
},
options: {
title: MESSAGES.freezeDialog.title,
template: '',
buttons: [
{
value: 'panes',
iconClass: 'freeze-panes',
text: MESSAGES.freezeDialog.buttons.freezePanes
},
{
value: 'rows',
iconClass: 'freeze-row',
text: MESSAGES.freezeDialog.buttons.freezeRows
},
{
value: 'columns',
iconClass: 'freeze-col',
text: MESSAGES.freezeDialog.buttons.freezeColumns
},
{
value: 'unfreeze',
iconClass: 'normal-layout',
text: MESSAGES.freezeDialog.buttons.unfreeze
}
]
},
_list: function () {
var ul = this.dialog().element.find('ul');
this.list = new kendo.ui.StaticList(ul, {
dataSource: new kendo.data.DataSource({ data: this.options.buttons }),
template: '' + '#=text#' + '',
change: this.apply.bind(this)
});
this.list.dataSource.fetch();
},
apply: function (e) {
var dataItem = e.sender.value()[0];
SpreadsheetDialog.fn.apply.call(this);
this.trigger('action', {
command: 'FreezePanesCommand',
options: { value: dataItem.value }
});
}
});
kendo.spreadsheet.dialogs.register('freeze', FreezeDialog);
var ValidationViewModel = kendo.spreadsheet.ValidationCellsViewModel = ObservableObject.extend({
init: function (options) {
ObservableObject.fn.init.call(this, options);
this.bind('change', function (e) {
if (e.field === 'criterion') {
this.reset();
if (this.criterion === 'custom' || this.criterion === 'list') {
this.setHintMessageTemplate();
}
}
if (e.field === 'comparer') {
this.setHintMessageTemplate();
}
if ((e.field == 'hintMessage' || e.field == 'hintTitle') && !this._mute) {
this.shouldBuild = false;
}
if ((e.field == 'from' || e.field == 'to' || e.field == 'hintMessageTemplate' || e.field == 'type') && this.shouldBuild) {
this.buildMessages();
}
}.bind(this));
this.reset();
},
buildMessages: function () {
this._mute = true;
this.set('hintTitle', this.hintTitleTemplate ? kendo.format(this.hintTitleTemplate, this.type) : '');
this.set('hintMessage', this.hintMessageTemplate ? kendo.format(this.hintMessageTemplate, this.from, this.to) : '');
this._mute = false;
},
reset: function () {
this.setComparers();
this.set('comparer', this.comparers[0].type);
this.set('from', null);
this.set('to', null);
this.set('useCustomMessages', false);
this.shouldBuild = true;
this.hintTitleTemplate = this.defaultHintTitle;
this.buildMessages();
},
setComparers: function () {
var all = this.defaultComparers;
var comparers = [];
if (this.criterion === 'text') {
var text_comparers = [
'equalTo',
'notEqualTo'
];
for (var idx = 0; idx < all.length; idx++) {
if (text_comparers[0] == all[idx].type) {
comparers.push(all[idx]);
text_comparers.shift();
}
}
} else {
comparers = all.slice();
}
this.set('comparers', comparers);
},
setHintMessageTemplate: function () {
if (this.criterion !== 'custom' && this.criterion !== 'list') {
this.set('hintMessageTemplate', kendo.format(this.defaultHintMessage, this.criterion, this.comparerMessages[this.comparer]));
} else {
this.set('hintMessageTemplate', '');
this.set('hintMessage', '');
}
},
isAny: function () {
return this.get('criterion') === 'any';
},
isNumber: function () {
return this.get('criterion') === 'number';
},
showToForNumber: function () {
return this.showTo() && this.isNumber();
},
showToForDate: function () {
return this.showTo() && this.isDate();
},
isText: function () {
return this.get('criterion') === 'text';
},
isDate: function () {
return this.get('criterion') === 'date';
},
isList: function () {
return this.get('criterion') === 'list';
},
isCustom: function () {
return this.get('criterion') === 'custom';
},
showRemove: function () {
return this.get('hasValidation');
},
showTo: function () {
return this.get('comparer') == 'between' || this.get('comparer') == 'notBetween';
},
update: function (validation) {
this.set('hasValidation', !!validation);
if (validation) {
this.fromValidationObject(validation);
}
},
fromValidationObject: function (validation) {
this.set('criterion', validation.dataType);
this.set('comparer', validation.comparerType);
this.set('from', validation.from);
this.set('to', validation.to);
this.set('type', validation.type);
this.set('ignoreBlank', validation.allowNulls);
if (validation.messageTemplate || validation.titleTemplate) {
this.hintMessageTemplate = validation.messageTemplate;
this.hintMessage = validation.messageTemplate;
this.hintTitleTemplate = validation.titleTemplate;
this.hintTitle = validation.titleTemplate;
this.useCustomMessages = true;
this.buildMessages();
} else {
this.useCustomMessages = false;
}
},
toValidationObject: function () {
if (this.criterion === 'any') {
return null;
}
var options = {
type: this.type,
dataType: this.criterion,
comparerType: this.comparer,
from: this.from,
to: this.to,
allowNulls: this.ignoreBlank
};
if (this.useCustomMessages) {
options.messageTemplate = this.shouldBuild ? this.hintMessageTemplate : this.hintMessage;
options.titleTemplate = this.hintTitle;
}
return options;
}
});
var ValidationDialog = SpreadsheetDialog.extend({
init: function (options) {
SpreadsheetDialog.fn.init.call(this, options);
},
options: {
width: 420,
title: MESSAGES.validationDialog.title,
criterion: 'any',
type: 'reject',
ignoreBlank: true,
hintMessage: MESSAGES.validationDialog.hintMessage,
hintTitle: MESSAGES.validationDialog.hintTitle,
useCustomMessages: false,
criteria: [
{
type: 'any',
name: 'Any value'
},
{
type: 'number',
name: 'Number'
},
{
type: 'text',
name: 'Text'
},
{
type: 'date',
name: 'Date'
},
{
type: 'custom',
name: 'Custom Formula'
},
{
type: 'list',
name: 'List'
}
],
comparers: [
{
type: 'greaterThan',
name: MESSAGES.validationDialog.comparers.greaterThan
},
{
type: 'lessThan',
name: MESSAGES.validationDialog.comparers.lessThan
},
{
type: 'between',
name: MESSAGES.validationDialog.comparers.between
},
{
type: 'notBetween',
name: MESSAGES.validationDialog.comparers.notBetween
},
{
type: 'equalTo',
name: MESSAGES.validationDialog.comparers.equalTo
},
{
type: 'notEqualTo',
name: MESSAGES.validationDialog.comparers.notEqualTo
},
{
type: 'greaterThanOrEqualTo',
name: MESSAGES.validationDialog.comparers.greaterThanOrEqualTo
},
{
type: 'lessThanOrEqualTo',
name: MESSAGES.validationDialog.comparers.lessThanOrEqualTo
}
],
comparerMessages: MESSAGES.validationDialog.comparerMessages,
errorTemplate: '',
template: ''
},
open: function (range) {
var options = this.options;
var element;
this.viewModel = new ValidationViewModel({
type: options.type,
defaultHintMessage: options.hintMessage,
defaultHintTitle: options.hintTitle,
defaultComparers: options.comparers.slice(0),
comparerMessages: options.comparerMessages,
criteria: options.criteria.slice(0),
criterion: options.criterion,
ignoreBlank: options.ignoreBlank,
apply: this.apply.bind(this),
close: this.close.bind(this),
remove: this.remove.bind(this)
});
this.viewModel.update(range.validation());
SpreadsheetDialog.fn.open.call(this);
element = this.dialog().element;
if (this.validatable) {
this.validatable.destroy();
}
kendo.bind(element, this.viewModel);
this.validatable = new kendo.ui.Validator(element.find('.k-edit-form-container'), {
validateOnBlur: false,
errorTemplate: this.options.errorTemplate || undefined
});
},
apply: function () {
if (this.validatable.validate()) {
SpreadsheetDialog.fn.apply.call(this);
this.trigger('action', {
command: 'EditValidationCommand',
options: { value: this.viewModel.toValidationObject() }
});
}
},
remove: function () {
this.viewModel.set('criterion', 'any');
this.apply();
}
});
kendo.spreadsheet.dialogs.register('validation', ValidationDialog);
kendo.spreadsheet.dialogs.ValidationDialog = ValidationDialog;
var ExportAsDialog = SpreadsheetDialog.extend({
init: function (options) {
SpreadsheetDialog.fn.init.call(this, options);
this.viewModel = kendo.observable({
title: this.options.title,
name: this.options.name,
extension: this.options.extension,
fileFormats: this.options.fileFormats,
excel: options.excelExport,
pdf: {
proxyURL: options.pdfExport.proxyURL,
forceProxy: options.pdfExport.forceProxy,
title: options.pdfExport.title,
author: options.pdfExport.author,
subject: options.pdfExport.subject,
keywords: options.pdfExport.keywords,
creator: options.pdfExport.creator,
date: options.pdfExport.date,
fitWidth: this.options.pdf.fitWidth,
area: this.options.pdf.area,
areas: this.options.pdf.areas,
paperSize: this.options.pdf.paperSize,
paperSizes: this.options.pdf.paperSizes,
margin: this.options.pdf.margin,
margins: this.options.pdf.margins,
landscape: this.options.pdf.landscape,
guidelines: this.options.pdf.guidelines,
hCenter: this.options.pdf.hCenter,
vCenter: this.options.pdf.vCenter
},
apply: this.apply.bind(this),
close: this.close.bind(this)
});
this.viewModel.bind('change', function (e) {
if (e.field === 'extension') {
this.set('showPdfOptions', this.extension === '.pdf' ? true : false);
}
});
kendo.bind(this.dialog().element, this.viewModel);
},
options: {
title: MESSAGES.exportAsDialog.title,
name: 'Workbook',
extension: '.xlsx',
fileFormats: [
{
description: 'Excel Workbook (.xlsx)',
extension: '.xlsx'
},
{
description: 'Portable Document Format(.pdf)',
extension: '.pdf'
}
],
pdf: {
fitWidth: true,
area: 'workbook',
areas: [
{
area: 'workbook',
text: 'Entire Workbook'
},
{
area: 'sheet',
text: 'Active Sheet'
},
{
area: 'selection',
text: 'Selection'
}
],
paperSize: 'a4',
paperSizes: [
{
value: 'a2',
text: 'A2 (420 mm \xD7 594 mm) '
},
{
value: 'a3',
text: 'A3 (297 mm x 420 mm) '
},
{
value: 'a4',
text: 'A4 (210 mm x 297 mm) '
},
{
value: 'a5',
text: 'A5 (148 mm x 210 mm) '
},
{
value: 'b3',
text: 'B3 (353 mm \xD7 500 mm) '
},
{
value: 'b4',
text: 'B4 (250 mm x 353 mm) '
},
{
value: 'b5',
text: 'B5 (176 mm x 250 mm) '
},
{
value: 'folio',
text: 'Folio (8.5" x 13") '
},
{
value: 'legal',
text: 'Legal (8.5" x 14") '
},
{
value: 'letter',
text: 'Letter (8.5" x 11") '
},
{
value: 'tabloid',
text: 'Tabloid (11" x 17") '
},
{
value: 'executive',
text: 'Executive (7.25" x 10.5")'
}
],
margin: {
bottom: '0.75in',
left: '0.7in',
right: '0.7in',
top: '0.75in'
},
margins: [
{
value: {
bottom: '0.75in',
left: '0.7in',
right: '0.7in',
top: '0.75in'
},
text: 'Normal'
},
{
value: {
bottom: '0.75in',
left: '0.25in',
right: '0.25in',
top: '0.75in'
},
text: 'Narrow'
},
{
value: {
bottom: '1in',
left: '1in',
right: '1in',
top: '1in'
},
text: 'Wide'
}
],
landscape: true,
guidelines: true,
hCenter: true,
vCenter: true
},
width: 520,
template: '' + '' + '' + '
' + '' + '
' + '
' + '' + '
' + '
' + '' + '
' + '
' + '' + '
' + '
' + '
' + '' + '
' + '
' + '
' + '' + '
' + '
' + '
' + '' + '' + '
' + '
' + '
' + '' + '
' + '
' + '
' + '' + '
' + '
' + '
' + '' + '' + '
' + '
' + '
' + '' + '' + '' + '
'
},
apply: function () {
SpreadsheetDialog.fn.apply.call(this);
this.trigger('action', {
command: 'SaveAsCommand',
options: this.viewModel
});
}
});
kendo.spreadsheet.dialogs.register('exportAs', ExportAsDialog);
var ModifyMergedDialog = MessageDialog.extend({
init: function (options) {
SpreadsheetDialog.fn.init.call(this, options);
},
options: { template: MESSAGES.modifyMergedDialog.errorMessage + '' + '' + '
' }
});
kendo.spreadsheet.dialogs.register('modifyMerged', ModifyMergedDialog);
var UseKeyboardDialog = MessageDialog.extend({
init: function (options) {
SpreadsheetDialog.fn.init.call(this, options);
},
options: {
title: MESSAGES.useKeyboardDialog.title,
template: MESSAGES.useKeyboardDialog.errorMessage + 'Ctrl+C ' + MESSAGES.useKeyboardDialog.labels.forCopy + '
' + 'Ctrl+X ' + MESSAGES.useKeyboardDialog.labels.forCut + '
' + 'Ctrl+V ' + MESSAGES.useKeyboardDialog.labels.forPaste + '
' + '' + '' + '
'
}
});
kendo.spreadsheet.dialogs.register('useKeyboard', UseKeyboardDialog);
var UnsupportedSelectionDialog = MessageDialog.extend({
init: function (options) {
SpreadsheetDialog.fn.init.call(this, options);
},
options: { template: MESSAGES.unsupportedSelectionDialog.errorMessage + '' + '' + '
' }
});
kendo.spreadsheet.dialogs.register('unsupportedSelection', UnsupportedSelectionDialog);
}(window.kendo));
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('spreadsheet/sheetbinder', [
'kendo.core',
'kendo.data',
'spreadsheet/sheet'
], f);
}(function () {
(function (kendo) {
if (kendo.support.browser.msie && kendo.support.browser.version < 9) {
return;
}
var SheetDataSourceBinder = kendo.Class.extend({
init: function (options) {
this.options = $.extend({}, this.options, options);
this.columns = this._normalizeColumns(this.options.columns);
this._sheet();
this._dataSource();
this._header();
this.dataSource.fetch();
},
_sheet: function () {
this.sheet = this.options.sheet;
this._sheetChangeHandler = this._sheetChange.bind(this);
this._sheetDeleteRowHandler = this._sheetDeleteRow.bind(this);
this._sheetInsertRowHandler = this._sheetInsertRow.bind(this);
this.sheet.bind('change', this._sheetChangeHandler).bind('deleteRow', this._sheetDeleteRowHandler).bind('insertRow', this._sheetInsertRowHandler);
},
_sheetInsertRow: function (e) {
if (e.index !== undefined) {
this.dataSource.insert(Math.max(e.index - 1, 0), {});
}
},
_sheetDeleteRow: function (e) {
if (e.index !== undefined) {
var dataSource = this.dataSource;
var model = dataSource.view()[e.index - 1];
if (model) {
dataSource.remove(model);
}
}
},
_header: function () {
this.sheet.batch(function () {
this.columns.forEach(function (column, index) {
this.sheet.range(0, index).value(column.title);
}.bind(this));
}.bind(this));
},
_sheetChange: function (e) {
if (e.recalc && e.ref) {
var dataSource = this.dataSource;
var data = dataSource.view();
var columns = this.columns;
if (!columns.length && data.length) {
columns = Object.keys(data[0].toJSON());
}
this._skipRebind = true;
var values = this.sheet.range(e.ref).values();
e.ref.forEach(function (ref) {
ref = ref.toRangeRef();
var record;
var valueIndex = 0;
for (var ri = ref.topLeft.row; ri <= ref.bottomRight.row; ri++) {
record = data[ri - 1];
if (!record) {
record = dataSource.insert(ri - 1, {});
data = dataSource.view();
}
var colValueIndex = 0;
for (var ci = ref.topLeft.col; ci <= ref.bottomRight.col && ci < columns.length; ci++) {
record.set(columns[ci].field, values[valueIndex][colValueIndex++]);
}
valueIndex++;
}
});
this._skipRebind = false;
}
},
_normalizeColumns: function (columns) {
return columns.map(function (column) {
var field = column.field || column;
return {
field: field,
title: column.title || field
};
});
},
_dataSource: function () {
var options = this.options;
var dataSource = options.dataSource;
dataSource = Array.isArray(dataSource) ? { data: dataSource } : dataSource;
if (this.dataSource && this._changeHandler) {
this.dataSource.unbind('change', this._changeHandler);
} else {
this._changeHandler = this._change.bind(this);
}
this.dataSource = kendo.data.DataSource.create(dataSource).bind('change', this._changeHandler);
},
_change: function () {
if (this._skipRebind) {
return;
}
var data = this.dataSource.view();
var columns = this.columns;
if (!columns.length && data.length) {
this.columns = columns = this._normalizeColumns(Object.keys(data[0].toJSON()));
this._header();
}
var getters = columns.map(function (column) {
return kendo.getter(column.field);
});
this.sheet.batch(function () {
for (var idx = 0, length = data.length; idx < length; idx++) {
for (var getterIdx = 0; getterIdx < getters.length; getterIdx++) {
this.sheet.range(idx + 1, getterIdx).value(getters[getterIdx](data[idx]));
}
}
}.bind(this));
},
destroy: function () {
this.dataSource.unbind('change', this._changeHandler);
this.sheet.unbind('change', this._sheetChangeHandler).unbind('deleteRow', this._sheetDeleteRowHandler).unbind('insertRow', this._sheetInsertRowHandler);
},
options: { columns: [] }
});
kendo.spreadsheet.SheetDataSourceBinder = SheetDataSourceBinder;
}(kendo));
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('spreadsheet/filtermenu', [
'kendo.core',
'kendo.popup',
'kendo.treeview',
'kendo.numerictextbox',
'kendo.datepicker',
'kendo.datetimepicker'
], f);
}(function () {
(function (kendo) {
if (kendo.support.browser.msie && kendo.support.browser.version < 9) {
return;
}
var $ = kendo.jQuery;
var Widget = kendo.ui.Widget;
var classNames = {
details: 'k-details',
button: 'k-button',
detailsSummary: 'k-details-summary',
detailsContent: 'k-details-content',
icon: 'k-icon k-font-icon',
iconCollapse: 'k-i-collapse-se',
iconExpand: 'k-i-expand-e',
iconSearch: 'k-i-search',
textbox: 'k-textbox',
wrapper: 'k-spreadsheet-filter-menu',
filterByCondition: 'k-spreadsheet-condition-filter',
filterByValue: 'k-spreadsheet-value-filter',
valuesTreeViewWrapper: 'k-spreadsheet-value-treeview-wrapper',
actionButtons: 'k-action-buttons'
};
var Details = Widget.extend({
init: function (element, options) {
Widget.fn.init.call(this, element, options);
this.element.addClass(FilterMenu.classNames.details);
this._summary = this.element.find('.' + FilterMenu.classNames.detailsSummary).on('click', this._toggle.bind(this));
var iconClass = options.expanded ? FilterMenu.classNames.iconCollapse : FilterMenu.classNames.iconExpand;
this._icon = $('', { 'class': FilterMenu.classNames.icon + ' ' + iconClass }).prependTo(this._summary);
this._container = kendo.wrap(this._summary.next(), true);
if (!options.expanded) {
this._container.hide();
}
},
options: { name: 'Details' },
events: ['toggle'],
visible: function () {
return this.options.expanded;
},
toggle: function (show) {
var animation = kendo.fx(this._container).expand('vertical');
animation.stop()[show ? 'reverse' : 'play']();
this._icon.toggleClass(FilterMenu.classNames.iconExpand, show).toggleClass(FilterMenu.classNames.iconCollapse, !show);
this.options.expanded = !show;
},
_toggle: function () {
var show = this.visible();
this.toggle(show);
this.trigger('toggle', { show: show });
}
});
var FILTERMENU_MESSAGES = kendo.spreadsheet.messages.filterMenu = {
sortAscending: 'Sort range A to Z',
sortDescending: 'Sort range Z to A',
filterByValue: 'Filter by value',
filterByCondition: 'Filter by condition',
apply: 'Apply',
search: 'Search',
addToCurrent: 'Add to current selection',
clear: 'Clear',
blanks: '(Blanks)',
operatorNone: 'None',
and: 'AND',
or: 'OR',
operators: {
string: {
contains: 'Text contains',
doesnotcontain: 'Text does not contain',
startswith: 'Text starts with',
endswith: 'Text ends with'
},
date: {
eq: 'Date is',
neq: 'Date is not',
lt: 'Date is before',
gt: 'Date is after'
},
number: {
eq: 'Is equal to',
neq: 'Is not equal to',
gte: 'Is greater than or equal to',
gt: 'Is greater than',
lte: 'Is less than or equal to',
lt: 'Is less than'
}
}
};
kendo.data.binders.spreadsheetFilterValue = kendo.data.Binder.extend({
init: function (element, bindings, options) {
kendo.data.Binder.fn.init.call(this, element, bindings, options);
this._change = $.proxy(this.change, this);
$(this.element).on('change', this._change);
},
refresh: function () {
var that = this, value = that.bindings.spreadsheetFilterValue.get();
$(that.element).val(value instanceof Date ? '' : value);
},
change: function () {
var value = this.element.value;
this.bindings.spreadsheetFilterValue.set(value);
}
});
kendo.data.binders.widget.spreadsheetFilterValue = kendo.data.Binder.extend({
init: function (widget, bindings, options) {
kendo.data.Binder.fn.init.call(this, widget.element[0], bindings, options);
this.widget = widget;
this._change = $.proxy(this.change, this);
this.widget.first('change', this._change);
},
refresh: function () {
var binding = this.bindings.spreadsheetFilterValue, value = binding.get(), type = $(this.widget.element).data('filterType');
if (type === 'date' && value instanceof Date || type === 'number' && !isNaN(value)) {
this.widget.value(value);
} else {
this.widget.value(null);
}
},
change: function () {
var value = this.widget.value(), binding = this.bindings.spreadsheetFilterValue;
binding.set(value);
}
});
var templates = {
filterByValue: '#= messages.filterByValue #
' + '' + '
' + '' + '' + '
' + '
' + '
' + '
',
filterByCondition: '#= messages.filterByCondition #
' + '' + '
' + '' + '
' + '
' + '' + '
' + '
' + '' + '
' + '
' + '' + '
' + '
',
menuItem: '' + '#=text#' + '',
actionButtons: '
' + '
'
};
function distinctValues(values) {
var hash = {};
var result = [];
for (var i = 0; i < values.length; i++) {
if (!hash[values[i].value]) {
hash[values[i].value] = values[i];
result.push(values[i]);
} else if (!hash[values[i].value].checked && values[i].checked) {
hash[values[i].value].checked = true;
}
}
return result;
}
function filter(dataSource, query) {
var hasVisibleChildren = false;
var data = dataSource instanceof kendo.data.HierarchicalDataSource && dataSource.data();
for (var i = 0; i < data.length; i++) {
var item = data[i];
var text = item.text.toString().toLowerCase();
var itemVisible = query === true || query === '' || text.indexOf(query) >= 0;
var anyVisibleChildren = filter(item.children, itemVisible || query);
hasVisibleChildren = hasVisibleChildren || anyVisibleChildren || itemVisible;
item.hidden = !itemVisible && !anyVisibleChildren;
item.checked = !item.hidden;
}
if (data) {
dataSource.filter({
field: 'hidden',
operator: 'neq',
value: true
});
}
return hasVisibleChildren;
}
function uncheckAll(dataSource) {
var data = dataSource instanceof kendo.data.HierarchicalDataSource && dataSource.data();
for (var i = 0; i < data.length; i++) {
var item = data[i];
item.checked = false;
if (item.hasChildren) {
uncheckAll(item.children);
}
}
}
var FilterMenuViewModel = kendo.spreadsheet.FilterMenuViewModel = kendo.data.ObservableObject.extend({
valuesChange: function (e) {
var dataSource = e ? e.sender.dataSource : this.valuesDataSource;
var checked = function (item) {
return item.checked && item.value;
};
var value = function (item) {
return item.dataType === 'date' ? kendo.spreadsheet.dateToNumber(item.value) : item.value;
};
var unique = function (value, index, array) {
return array.lastIndexOf(value) === index;
};
var data = dataSource.data();
var values = data[0].children.data().toJSON();
var blanks = values.filter(function (item) {
return item.dataType === 'blank';
});
blanks = blanks.length ? blanks[0].checked : false;
values = values.filter(checked).map(value);
if (this.appendToSearch && this.valueFilter && this.valueFilter.values.length) {
values = values.concat(this.valueFilter.values.toJSON()).sort().filter(unique);
}
this.set('valueFilter', {
values: values,
blanks: blanks
});
},
valueSelect: function (e) {
e.preventDefault();
var node = e.sender.dataItem(e.node);
node.set('checked', !node.checked);
},
hasActiveSearch: false,
appendToSearch: false,
filterValues: function (e) {
var query = typeof e == 'string' ? e : $(e.target).val().toLowerCase();
var dataSource = this.valuesDataSource;
this.set('hasActiveSearch', !!query);
uncheckAll(dataSource);
filter(dataSource, query);
},
reset: function () {
this.set('customFilter', {
logic: 'and',
criteria: [{
operator: null,
value: null
}]
});
this.set('valueFilter', { values: [] });
},
operatorChange: function (e) {
var dataItem = e.sender.dataItem();
this.set('operatorType', dataItem.type);
this.set('customFilter.criteria[0].operator', dataItem.value);
},
isNone: function () {
return this.get('operatorType') === undefined;
},
isString: function () {
return this.get('operatorType') === 'string';
},
isNumber: function () {
return this.get('operatorType') === 'number';
},
isDate: function () {
return this.get('operatorType') === 'date';
}
});
function flattenOperators(operators) {
var messages = FILTERMENU_MESSAGES.operators;
var result = [];
for (var type in operators) {
if (!operators.hasOwnProperty(type)) {
continue;
}
for (var operator in operators[type]) {
if (!operators[type].hasOwnProperty(operator)) {
continue;
}
result.push({
text: messages[type][operator],
value: operator,
unique: type + '_' + operator,
type: type
});
}
}
return result;
}
var FilterMenuController = kendo.spreadsheet.FilterMenuController = {
valuesTree: function (range, column) {
return [{
text: 'All',
expanded: true,
checked: true,
items: this.values(range.resize({ top: 1 }), column)
}];
},
values: function (range, column) {
var values = [];
var messages = FILTERMENU_MESSAGES;
var columnRange = range.column(column);
var sheet = range.sheet();
columnRange.forEachCell(function (row, col, cell) {
if (cell.value === undefined) {
cell.dataType = 'blank';
} else if (cell.format) {
cell.dataType = kendo.spreadsheet.formatting.type(cell.value, cell.format);
} else {
cell.dataType = typeof cell.value;
}
if (cell.value !== null && cell.format) {
cell.text = kendo.spreadsheet.formatting.text(cell.value, cell.format);
} else {
cell.text = cell.value ? cell.value : messages.blanks;
}
if (cell.dataType === 'percent') {
cell.dataType = 'number';
}
if (cell.dataType === 'date') {
cell.value = kendo.spreadsheet.numberToDate(cell.value);
}
if (cell.hasOwnProperty('wrap')) {
delete cell.wrap;
}
cell.checked = !sheet.isHiddenRow(row);
values.push(cell);
});
values = distinctValues(values);
values.sort(function (a, b) {
if (a.dataType === b.dataType) {
return 0;
}
if (a.dataType === 'blank' || b.dataType === 'blank') {
return a.dataType === 'blank' ? -1 : 1;
}
if (a.dataType === 'number' || b.dataType === 'number') {
return a.dataType === 'number' ? -1 : 1;
}
if (a.dataType === 'date' || b.dataType === 'date') {
return a.dataType === 'date' ? -1 : 1;
}
return 0;
});
return values;
},
filterType: function (range, column) {
var sheet = range.sheet();
var filter = this.filterForColumn(column, sheet);
var type;
filter = filter && filter.filter.toJSON();
if (filter && filter.filter == 'custom') {
var value = filter.criteria[0].value;
if (value instanceof Date) {
type = 'date';
} else if (typeof value == 'string') {
type = 'string';
} else if (typeof value == 'number') {
type = 'number';
}
}
if (!type) {
var topValue = this.values(range.row(1), column)[0];
type = topValue && topValue.dataType;
if (type == 'blank') {
type = null;
}
}
return type;
},
filterForColumn: function (column, sheet) {
var allFilters = sheet.filter();
var filters;
if (allFilters) {
filters = allFilters.columns.filter(function (item) {
return item.index === column;
})[0];
}
return filters;
},
filter: function (column, sheet) {
var columnFilters = this.filterForColumn(column, sheet);
if (!columnFilters) {
return;
}
var options = columnFilters.filter.toJSON();
var type = options.filter;
delete options.filter;
var result = {
type: type,
options: options
};
var criteria = options.criteria;
if (criteria && criteria.length) {
result.operator = criteria[0].operator;
}
return result;
}
};
var FilterMenu = Widget.extend({
init: function (element, options) {
Widget.call(this, element, options);
this.element.addClass(FilterMenu.classNames.wrapper);
this.viewModel = new FilterMenuViewModel({
active: 'value',
operator: null,
operators: flattenOperators(this.options.operators),
clear: this.clear.bind(this),
apply: this.apply.bind(this)
});
this._filterInit();
this._popup();
this._sort();
this._filterByCondition();
this._filterByValue();
this._actionButtons();
},
options: {
name: 'FilterMenu',
column: 0,
range: null,
operators: {
string: {
contains: 'Text contains',
doesnotcontain: 'Text does not contain',
startswith: 'Text starts with',
endswith: 'Text ends with'
},
date: {
eq: 'Date is',
neq: 'Date is not',
lt: 'Date is before',
gt: 'Date is after'
},
number: {
eq: 'Is equal to',
neq: 'Is not equal to',
gte: 'Is greater than or equal to',
gt: 'Is greater than',
lte: 'Is less than or equal to',
lt: 'Is less than'
}
}
},
events: ['action'],
destroy: function () {
Widget.fn.destroy.call(this);
this.menu.destroy();
this.valuesTreeView.destroy();
this.popup.destroy();
},
openFor: function (anchor) {
this.popup.setOptions({ anchor: anchor });
this.popup.open();
},
close: function () {
this.popup.close();
},
clear: function () {
this.action({
command: 'ClearFilterCommand',
options: { column: this.options.column }
});
this.viewModel.reset();
this.close();
},
apply: function () {
this._active();
var options = {
operatingRange: this.options.range,
column: this.options.column
};
var valueFilter;
var customFilter;
if (this.viewModel.active === 'value') {
this.viewModel.valuesChange({ sender: this.valuesTreeView });
valueFilter = this.viewModel.valueFilter.toJSON();
if (valueFilter.values && valueFilter.values.length) {
options.valueFilter = valueFilter;
}
} else if (this.viewModel.active === 'custom') {
customFilter = this.viewModel.customFilter.toJSON();
if (customFilter.criteria.length && customFilter.criteria[0].value !== null) {
options.customFilter = customFilter;
}
}
if (options.valueFilter || options.customFilter) {
this.action({
command: 'ApplyFilterCommand',
options: options
});
}
},
action: function (options) {
this.trigger('action', $.extend({}, options));
},
_filterInit: function () {
var column = this.options.column;
var range = this.options.range;
var sheet = range.sheet();
var activeFilter = FilterMenuController.filter(column, sheet);
if (activeFilter) {
var filterType = FilterMenuController.filterType(range, column);
this.viewModel.set('active', activeFilter.type);
this.viewModel.set(activeFilter.type + 'Filter', activeFilter.options);
if (activeFilter.type == 'custom') {
this.viewModel.set('operator', filterType + '_' + activeFilter.operator);
this.viewModel.set('operatorType', filterType);
}
} else {
this.viewModel.reset();
}
},
_popup: function () {
this.popup = this.element.kendoPopup({ copyAnchorStyles: false }).data('kendoPopup');
},
_sort: function () {
var template = kendo.template(FilterMenu.templates.menuItem);
var messages = FILTERMENU_MESSAGES;
var items = [
{
command: 'sort',
dir: 'asc',
text: messages.sortAscending,
iconClass: 'sort-asc'
},
{
command: 'sort',
dir: 'desc',
text: messages.sortDescending,
iconClass: 'sort-desc'
}
];
var ul = $('
', { 'html': kendo.render(template, items) }).appendTo(this.element);
this.menu = ul.kendoMenu({
orientation: 'vertical',
select: function (e) {
var dir = $(e.item).data('dir');
var range = this.options.range.resize({ top: 1 });
var options = {
value: dir,
sheet: false,
operatingRange: range,
column: this.options.column
};
if (range.isSortable()) {
this.action({
command: 'SortCommand',
options: options
});
} else {
this.close();
}
}.bind(this)
}).data('kendoMenu');
},
_appendTemplate: function (template, className, details, expanded) {
var compiledTemplate = kendo.template(template);
var wrapper = $('
').html(compiledTemplate({
messages: FILTERMENU_MESSAGES,
guid: kendo.guid(),
ns: kendo.ns
}));
this.element.append(wrapper);
if (details) {
details = new Details(wrapper, {
expanded: expanded,
toggle: this._detailToggle.bind(this)
});
}
kendo.bind(wrapper, this.viewModel);
return wrapper;
},
_detailToggle: function (e) {
this.element.find('[data-role=details]').not(e.sender.element).data('kendoDetails').toggle(!e.show);
},
_filterByCondition: function () {
var isExpanded = this.viewModel.active === 'custom';
this._appendTemplate(FilterMenu.templates.filterByCondition, FilterMenu.classNames.filterByCondition, true, isExpanded);
},
_filterByValue: function () {
var isExpanded = this.viewModel.active === 'value';
var wrapper = this._appendTemplate(FilterMenu.templates.filterByValue, FilterMenu.classNames.filterByValue, true, isExpanded);
this.valuesTreeView = wrapper.find('[data-role=treeview]').data('kendoTreeView');
var values = FilterMenuController.valuesTree(this.options.range, this.options.column);
this.viewModel.set('valuesDataSource', new kendo.data.HierarchicalDataSource({ data: values }));
},
_actionButtons: function () {
this._appendTemplate(FilterMenu.templates.actionButtons, FilterMenu.classNames.actionButtons, false);
},
_active: function () {
var activeContainer = this.element.find('[data-role=details]').filter(function (index, element) {
return $(element).data('kendoDetails').visible();
});
if (activeContainer.hasClass(FilterMenu.classNames.filterByValue)) {
this.viewModel.set('active', 'value');
} else if (activeContainer.hasClass(FilterMenu.classNames.filterByCondition)) {
this.viewModel.set('active', 'custom');
}
}
});
kendo.spreadsheet.FilterMenu = FilterMenu;
$.extend(true, FilterMenu, {
classNames: classNames,
templates: templates
});
}(window.kendo));
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('spreadsheet/editor', ['kendo.core'], f);
}(function () {
(function (kendo) {
if (kendo.support.browser.msie && kendo.support.browser.version < 9) {
return;
}
var SheetEditor = kendo.Observable.extend({
init: function (view) {
kendo.Observable.fn.init.call(this);
this.view = view;
this.formulaBar = view.formulaBar;
this.barInput = view.formulaBar.formulaInput;
this.cellInput = view.formulaInput;
this.barInput.syncWith(this.cellInput);
this.cellInput.syncWith(this.barInput);
this.barInput.bind('keyup', this._triggerUpdate.bind(this));
this.cellInput.bind('keyup', this._triggerUpdate.bind(this));
this.barInput.bind('focus', this._focus.bind(this));
this.cellInput.bind('focus', this._focus.bind(this));
},
events: [
'activate',
'deactivate',
'change',
'update'
],
_focus: function (e) {
this.lastActive = e.sender == this.barInput ? 'bar' : 'cell';
},
_triggerUpdate: function () {
this.trigger('update', { value: this.value() });
},
activeEditor: function () {
var editor = null;
var activeElement = kendo._activeElement();
if (this.barElement()[0] === activeElement) {
editor = this.barInput;
} else if (this.cellElement()[0] === activeElement) {
editor = this.cellInput;
}
return editor;
},
activate: function (options) {
this._active = true;
this._rect = options.rect;
this.cellInput.position(options.rect);
this.cellInput.resize(options.rect);
this.cellInput.tooltip(options.tooltip);
this.cellInput.activeCell = this.barInput.activeCell = options.range.topLeft;
this.trigger('activate');
return this;
},
deactivate: function () {
var cellInput = this.cellInput;
if (!this._active) {
return;
}
if (cellInput.value() != this._value) {
if (this.trigger('change', { value: cellInput.value() })) {
return;
}
}
this._active = false;
this._rect = null;
cellInput.hide();
this.trigger('deactivate');
},
enable: function (enable) {
this.barInput.enable(enable);
},
barElement: function () {
return this.barInput.element;
},
cellElement: function () {
return this.cellInput.element;
},
focusLastActive: function () {
this.focus(this.lastActive);
},
focus: function (inputType) {
inputType = inputType || 'cell';
if (inputType === 'cell') {
this.cellInput.element.focus();
this.cellInput.end();
} else {
this.barInput.element.focus();
}
},
isActive: function () {
return this._active;
},
isFiltered: function () {
return this.barInput.popup.visible() || this.cellInput.popup.visible();
},
canInsertRef: function (isKeyboardAction) {
var editor = this.activeEditor();
return editor && editor.canInsertRef(isKeyboardAction);
},
highlightedRefs: function () {
var editor = this.activeEditor();
var refs = [];
if (editor) {
refs = editor.highlightedRefs();
}
return refs;
},
scale: function () {
this.cellInput.scale();
},
toggleTooltip: function (rect) {
this.cellInput.toggleTooltip(notEqual(this._rect, rect));
},
value: function (value) {
if (value === undefined) {
return this.barInput.value();
}
if (value === null) {
value = '';
}
this._value = value;
this.barInput.value(value);
this.cellInput.value(value);
}
});
function notEqual(oldRect, newRect) {
return oldRect && (oldRect.top !== newRect.top || oldRect.left !== newRect.left);
}
kendo.spreadsheet.SheetEditor = SheetEditor;
}(kendo));
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('spreadsheet/autofill', [
'spreadsheet/runtime',
'spreadsheet/range'
], f);
}(function () {
'use strict';
if (kendo.support.browser.msie && kendo.support.browser.version < 9) {
return;
}
var spreadsheet = kendo.spreadsheet;
var Range = spreadsheet.Range;
var runtime = spreadsheet.calc.runtime;
var Formula = runtime.Formula;
var MSG_INCOMPATIBLE = 'Incompatible ranges in fillFrom';
var MSG_NO_DIRECTION = 'Cannot determine fill direction';
Range.prototype._previewFillFrom = function (srcRange, direction) {
var destRange = this, sheet = destRange._sheet;
if (typeof srcRange == 'string') {
srcRange = sheet.range(srcRange);
}
var src = srcRange._ref.toRangeRef();
var dest = destRange._ref.toRangeRef();
if (src.intersects(dest)) {
if (src.eq(dest)) {
return null;
}
dest = dest.clone();
if (src.topLeft.eq(dest.topLeft)) {
if (src.width() == dest.width()) {
dest.topLeft.row += src.height();
direction = 0;
} else if (src.height() == dest.height()) {
dest.topLeft.col += src.width();
direction = 1;
} else {
throw new Error(MSG_INCOMPATIBLE);
}
} else if (src.bottomRight.eq(dest.bottomRight)) {
if (src.width() == dest.width()) {
dest.bottomRight.row -= src.height();
direction = 2;
} else if (src.height() == dest.height()) {
dest.bottomRight.col -= src.width();
direction = 3;
} else {
throw new Error(MSG_INCOMPATIBLE);
}
} else {
throw new Error(MSG_INCOMPATIBLE);
}
return sheet.range(dest)._previewFillFrom(srcRange, direction);
}
if (direction == null) {
if (src.topLeft.col == dest.topLeft.col) {
direction = src.topLeft.row < dest.topLeft.row ? 0 : 2;
} else if (src.topLeft.row == dest.topLeft.row) {
direction = src.topLeft.col < dest.topLeft.col ? 1 : 3;
} else {
throw new Error(MSG_NO_DIRECTION);
}
}
var horizontal = direction & 1;
var descending = direction & 2;
if (horizontal && src.height() != dest.height() || !horizontal && src.width() != dest.width()) {
throw new Error(MSG_INCOMPATIBLE);
}
var data = srcRange._properties(), n;
if (!horizontal) {
data = transpose(data);
n = dest.height();
} else {
n = dest.width();
}
var fill = new Array(data.length);
for (var i = 0; i < data.length; ++i) {
var s = data[i];
var f = findSeries(s);
var a = fill[i] = new Array(n);
for (var j = 0; j < n; ++j) {
var idx = descending ? -j - 1 : s.length + j;
var srcIdx = descending ? s.length - j % s.length - 1 : j % s.length;
a[descending ? n - j - 1 : j] = f(idx, srcIdx);
}
}
if (!horizontal) {
fill = transpose(fill);
}
return {
props: fill,
direction: direction,
dest: destRange
};
};
Range.prototype.fillFrom = function (srcRange, direction) {
var x = this._previewFillFrom(srcRange, direction);
x.dest._properties(x.props);
return x.dest;
};
function linearRegression(data) {
var N = data.length;
var mx = (N + 1) / 2, my = data.reduce(function (a, b) {
return a + b;
}, 0) / N;
var s1 = 0, s2 = 0;
for (var i = 0; i < N; i++) {
var t1 = i + 1 - mx, t2 = data[i] - my;
s1 += t1 * t2;
s2 += t1 * t1;
}
if (!s2) {
return function (N) {
return data[N % data.length];
};
}
var b = s1 / s2, a = my - b * mx;
return function (N) {
return a + b * (N + 1);
};
}
function findSeries(properties) {
function findStep(a) {
var diff = a[1] - a[0];
for (var i = 2; i < a.length; ++i) {
if (a[i] - a[i - 1] != diff) {
return null;
}
}
return diff;
}
function getData(a) {
return a.map(function (v) {
return v.number;
});
}
var series = [];
var data = properties.map(function (x) {
return x.formula || x.value;
});
forEachSeries(data, function (begin, end, type, a) {
var f, values;
if (type == 'number') {
values = getData(a);
if (values.length == 1 && (begin > 0 || end < data.length || formatType(values[0], properties[begin].format) == 'date')) {
values.push(values[0] + 1);
}
f = linearRegression(values);
} else if (type == 'string' || type == 'formula' || type == 'boolean') {
f = function (N, i) {
return data[i];
};
} else if (Array.isArray(type)) {
if (a.length == 1) {
f = function (N) {
return type[(a[0].number + N) % type.length];
};
} else {
var diff = findStep(getData(a));
if (diff == null) {
f = function (N) {
return a[N % a.length].value;
};
} else {
f = function (N) {
var idx = a[0].number + diff * N;
return type[idx % type.length];
};
}
}
} else if (type != 'null') {
values = getData(a);
if (values.length == 1) {
values.push(values[0] + 1);
}
values = linearRegression(values);
f = function (N, i) {
return data[i].replace(/^(.*\D)\d+/, '$1' + values(N, i));
};
} else {
f = function () {
return null;
};
}
var s = {
f: f,
begin: begin,
end: end,
len: end - begin
};
for (var i = begin; i < end; ++i) {
series[i] = s;
}
});
return function (N, i) {
var s = series[i];
var q = N / data.length | 0;
var r = N % data.length;
var n = q * s.len + r - s.begin;
var value = s.f(n, i);
var props = clone(properties[i]);
if (value instanceof Formula) {
props.formula = value;
} else {
props.value = value;
}
return props;
};
}
function formatType(value, format) {
if (format != null) {
return spreadsheet.formatting.type(value, format);
}
}
function clone(obj) {
var copy = {};
Object.keys(obj || {}).forEach(function (key) {
copy[key] = obj[key];
});
return copy;
}
function forEachSeries(data, f) {
var prev = null, start = 0, a = [], type;
for (var i = 0; i < data.length; ++i) {
type = getType(data[i]);
a.push(type);
if (prev != null && type.type !== prev.type) {
f(start, i, prev.type, a.slice(start, i));
start = i;
}
prev = type;
}
f(start, i, prev.type, a.slice(start, i));
}
function getType(el) {
if (typeof el == 'number') {
return {
type: 'number',
number: el
};
}
if (typeof el == 'string') {
var lst = findStringList(el);
if (lst) {
return lst;
}
var m = /^(.*\D)(\d+)/.exec(el);
if (m) {
el = el.replace(/^(.*\D)\d+/, '$1-######');
return {
type: el,
match: m,
number: parseFloat(m[2])
};
}
return { type: 'string' };
}
if (typeof el == 'boolean') {
return { type: 'boolean' };
}
if (el == null) {
return { type: 'null' };
}
if (el instanceof Formula) {
return { type: 'formula' };
}
window.console.error(el);
throw new Error('Cannot fill data');
}
function stringLists() {
var culture = kendo.culture();
return [
culture.calendars.standard.days.namesAbbr,
culture.calendars.standard.days.names,
culture.calendars.standard.months.namesAbbr,
culture.calendars.standard.months.names
];
}
function findStringList(str) {
var strl = str.toLowerCase();
var lists = stringLists();
for (var i = 0; i < lists.length; ++i) {
var a = lists[i];
for (var j = a.length; --j >= 0;) {
var el = a[j].toLowerCase();
if (el == strl) {
return {
type: a,
number: j,
value: str
};
}
}
}
}
function transpose(a) {
var height = a.length, width = a[0].length;
var t = [];
for (var i = 0; i < width; ++i) {
t[i] = [];
for (var j = 0; j < height; ++j) {
t[i][j] = a[j][i];
}
}
return t;
}
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('spreadsheet/print', [
'kendo.pdf',
'spreadsheet/sheet',
'spreadsheet/range',
'spreadsheet/references',
'spreadsheet/numformat',
'util/text-metrics'
], f);
}(function () {
'use strict';
if (kendo.support.browser.msie && kendo.support.browser.version < 9) {
return;
}
var spreadsheet = kendo.spreadsheet;
var CellRef = spreadsheet.CellRef;
var drawing = kendo.drawing;
var formatting = spreadsheet.formatting;
var geo = kendo.geometry;
var GUIDELINE_WIDTH = 0.8;
function distributeCoords(heights, pageHeight) {
var curr = 0;
var out = [];
var threshold = 0.2 * pageHeight;
var bottom = pageHeight;
heights.forEach(function (h) {
if (pageHeight && curr + h > bottom) {
if (bottom - curr < threshold) {
curr = pageHeight * Math.ceil(curr / pageHeight);
}
bottom += pageHeight * Math.ceil(h / pageHeight);
}
out.push(curr);
curr += h;
});
out.push(curr);
return out;
}
function getMergedCells(sheet, range) {
var grid = sheet._grid;
var primary = {};
var secondary = {};
sheet.forEachMergedCell(range, function (ref) {
var topLeft = ref.topLeft;
grid.forEach(ref, function (cellRef) {
if (topLeft.eq(cellRef)) {
primary[cellRef.print()] = ref;
} else if (range.contains(cellRef)) {
secondary[cellRef.print()] = topLeft;
}
});
});
return {
primary: primary,
secondary: secondary
};
}
function doLayout(sheet, range, options) {
var cells = [];
var rowHeights = [];
var colWidths = [];
var mergedCells = getMergedCells(sheet, range);
var maxRow = -1, maxCol = -1;
sheet.forEach(range, function (row, col, cell) {
var relrow = row - range.topLeft.row;
var relcol = col - range.topLeft.col;
if (!relcol) {
rowHeights.push(sheet.rowHeight(row));
}
if (!relrow) {
colWidths.push(sheet.columnWidth(col));
}
if (sheet.isHiddenColumn(col) || sheet.isHiddenRow(row)) {
return;
}
var nonEmpty = options.forScreen || shouldDrawCell(cell);
if (!(options.emptyCells || nonEmpty)) {
return;
}
var id = new CellRef(row, col).print();
if (mergedCells.secondary[id]) {
return;
}
if (nonEmpty) {
maxRow = Math.max(maxRow, relrow);
maxCol = Math.max(maxCol, relcol);
} else {
cell.empty = true;
}
var m = mergedCells.primary[id];
if (m) {
delete mergedCells.primary[id];
cell.merged = true;
cell.rowspan = m.height();
cell.colspan = m.width();
if (options.forScreen) {
cell.width = sheet._columns.sum(m.topLeft.col, m.bottomRight.col);
cell.height = sheet._rows.sum(m.topLeft.row, m.bottomRight.row);
}
} else {
cell.rowspan = 1;
cell.colspan = 1;
}
cell.row = relrow;
cell.col = relcol;
cells.push(cell);
});
rowHeights = rowHeights.slice(0, maxRow + 1);
colWidths = colWidths.slice(0, maxCol + 1);
var pageWidth = options.pageWidth;
var pageHeight = options.pageHeight;
var scaleFactor = 1;
if (options.fitWidth) {
var width = colWidths.reduce(sum, 0);
if (width > pageWidth) {
scaleFactor = pageWidth / width;
pageWidth /= scaleFactor;
pageHeight /= scaleFactor;
}
}
var yCoords = distributeCoords(rowHeights, pageHeight || 0);
var xCoords = distributeCoords(colWidths, pageWidth || 0);
var boxWidth = 0;
var boxHeight = 0;
cells = cells.filter(function (cell) {
if (cell.empty && (cell.row > maxRow || cell.col > maxCol)) {
return false;
}
cell.left = xCoords[cell.col];
cell.top = yCoords[cell.row];
if (cell.merged) {
if (!options.forScreen) {
cell.right = orlast(xCoords, cell.col + cell.colspan);
cell.bottom = orlast(yCoords, cell.row + cell.rowspan);
cell.width = cell.right - cell.left;
cell.height = cell.bottom - cell.top;
} else {
cell.right = cell.left + cell.width;
cell.bottom = cell.top + cell.height;
}
} else {
cell.width = colWidths[cell.col];
cell.height = rowHeights[cell.row];
cell.bottom = cell.top + cell.height;
cell.right = cell.left + cell.width;
}
boxWidth = Math.max(boxWidth, cell.right);
boxHeight = Math.max(boxHeight, cell.bottom);
return true;
});
Object.keys(mergedCells.primary).forEach(function (id) {
var ref = mergedCells.primary[id];
sheet.forEach(ref.topLeft.toRangeRef(), function (row, col, cell) {
var relrow = row - range.topLeft.row;
var relcol = col - range.topLeft.col;
cell.merged = true;
cell.colspan = ref.height();
cell.rowspan = ref.width();
if (relrow < 0) {
cell.top = -sheet._rows.sum(row, row - relrow - 1);
} else {
cell.top = yCoords[relrow];
}
if (relcol < 0) {
cell.left = -sheet._columns.sum(col, col - relcol - 1);
} else {
cell.left = xCoords[relcol];
}
cell.height = sheet._rows.sum(ref.topLeft.row, ref.bottomRight.row);
cell.width = sheet._columns.sum(ref.topLeft.col, ref.bottomRight.col);
cell.right = cell.left + cell.width;
cell.bottom = cell.top + cell.height;
cells.push(cell);
});
});
return {
width: boxWidth,
height: boxHeight,
cells: cells.sort(normalOrder),
scale: scaleFactor,
xCoords: xCoords,
yCoords: yCoords
};
}
function sum(a, b) {
return a + b;
}
function orlast(a, i) {
return i < a.length ? a[i] : a[a.length - 1];
}
function shouldDrawCell(cell) {
return cell.value != null || cell.merged || cell.background != null || cell.borderTop != null || cell.borderRight != null || cell.borderBottom != null || cell.borderLeft != null;
}
function normalOrder(a, b) {
if (a.top < b.top) {
return -1;
} else if (a.top == b.top) {
if (a.left < b.left) {
return -1;
} else if (a.left == b.left) {
return 0;
} else {
return 1;
}
} else {
return 1;
}
}
function drawLayout(layout, group, options) {
var ncols = Math.ceil(layout.width / options.pageWidth);
var nrows = Math.ceil(layout.height / options.pageHeight);
var pageWidth = options.pageWidth / layout.scale;
var pageHeight = options.pageHeight / layout.scale;
for (var i = 0; i < ncols; ++i) {
for (var j = 0; j < nrows; ++j) {
addPage(j, i);
}
}
function addPage(row, col) {
var left = col * pageWidth;
var right = left + pageWidth;
var top = row * pageHeight;
var bottom = top + pageHeight;
var endbottom = 0, endright = 0;
var cells = layout.cells.filter(function (cell) {
if (cell.right <= left || cell.left >= right || cell.bottom <= top || cell.top >= bottom) {
return false;
}
endbottom = Math.max(cell.bottom, endbottom);
endright = Math.max(cell.right, endright);
return true;
});
if (cells.length > 0) {
var page = new drawing.Group();
group.append(page);
page.clip(drawing.Path.fromRect(new geo.Rect([
0,
0
], [
options.pageWidth,
options.pageHeight
])));
var content = new drawing.Group();
page.append(content);
var matrix = geo.Matrix.scale(layout.scale, layout.scale).multiplyCopy(geo.Matrix.translate(-left, -top));
if (options.hCenter || options.vCenter) {
matrix = matrix.multiplyCopy(geo.Matrix.translate(options.hCenter ? (right - endright) / 2 : 0, options.vCenter ? (bottom - endbottom) / 2 : 0));
}
content.transform(matrix);
if (options.guidelines) {
var prev = null;
layout.xCoords.forEach(function (x) {
x = Math.min(x, endright);
if (x !== prev && x >= left && x <= right) {
prev = x;
content.append(new drawing.Path().moveTo(x, top).lineTo(x, endbottom).close().stroke('#999', GUIDELINE_WIDTH));
}
});
var prev = null;
layout.yCoords.forEach(function (y) {
y = Math.min(y, endbottom);
if (y !== prev && y >= top && y <= bottom) {
prev = y;
content.append(new drawing.Path().moveTo(left, y).lineTo(endright, y).close().stroke('#999', GUIDELINE_WIDTH));
}
});
}
var borders = new drawing.Group();
cells.forEach(function (cell) {
drawCell(cell, content, borders, options);
});
content.append(borders);
}
}
}
function drawCell(cell, content, borders, options) {
var g = new drawing.Group();
content.append(g);
var rect = new geo.Rect([
cell.left,
cell.top
], [
cell.width,
cell.height
]);
if (cell.background || cell.merged) {
var r2d2 = rect;
if (options.guidelines) {
r2d2 = rect.clone();
r2d2.origin.x += GUIDELINE_WIDTH / 2;
r2d2.origin.y += GUIDELINE_WIDTH / 2;
r2d2.size.width -= GUIDELINE_WIDTH;
r2d2.size.height -= GUIDELINE_WIDTH;
}
g.append(new drawing.Rect(r2d2).fill(cell.background || '#fff').stroke(null));
}
if (cell.borderLeft) {
borders.append(new drawing.Path().moveTo(cell.left, cell.top).lineTo(cell.left, cell.bottom).close().stroke(cell.borderLeft.color, cell.borderLeft.size));
}
if (cell.borderTop) {
borders.append(new drawing.Path().moveTo(cell.left, cell.top).lineTo(cell.right, cell.top).close().stroke(cell.borderTop.color, cell.borderTop.size));
}
if (cell.borderRight) {
borders.append(new drawing.Path().moveTo(cell.right, cell.top).lineTo(cell.right, cell.bottom).close().stroke(cell.borderRight.color, cell.borderRight.size));
}
if (cell.borderBottom) {
borders.append(new drawing.Path().moveTo(cell.left, cell.bottom).lineTo(cell.right, cell.bottom).close().stroke(cell.borderBottom.color, cell.borderBottom.size));
}
var val = cell.value;
if (val != null) {
var type = typeof val == 'number' ? 'number' : null;
var clip = new drawing.Group();
clip.clip(drawing.Path.fromRect(rect));
g.append(clip);
var f;
if (cell.format) {
f = formatting.textAndColor(val, cell.format);
val = f.text;
if (f.type) {
type = f.type;
}
} else {
val += '';
}
if (!cell.textAlign) {
switch (type) {
case 'number':
case 'date':
case 'percent':
cell.textAlign = 'right';
break;
case 'boolean':
cell.textAlign = 'center';
break;
}
}
drawText(val, f && f.color || cell.color || '#000', cell, clip);
}
}
function drawText(text, color, cell, group) {
var rect_left = cell.left + 2;
var rect_top = cell.top + 2;
var rect_width = cell.width - 4;
var rect_height = cell.height - 4;
var font = makeFontDef(cell);
var style = { font: font };
var props = {
font: font,
fill: { color: color }
};
var lines = [], text_height = 0, top = rect_top;
if (cell.wrap) {
lineBreak(text, style, rect_width).forEach(function (line) {
var tmp = new drawing.Text(line.text, [
rect_left,
top
], props);
top += line.box.height;
lines.push({
el: tmp,
box: line.box
});
});
text_height = top - rect_top;
} else {
var tmp = new drawing.Text(text, [
rect_left,
top
], props);
var box = kendo.util.measureText(text, style);
lines.push({
el: tmp,
box: box
});
text_height = box.height;
}
var cont = new drawing.Group();
group.append(cont);
var vtrans = 0;
switch (cell.verticalAlign) {
case 'center':
vtrans = rect_height - text_height >> 1;
break;
case undefined:
case null:
case 'bottom':
vtrans = rect_height - text_height;
break;
}
if (vtrans < 0) {
vtrans = 0;
}
lines.forEach(function (line) {
cont.append(line.el);
var htrans = 0;
switch (cell.textAlign) {
case 'center':
htrans = rect_width - line.box.width >> 1;
break;
case 'right':
htrans = rect_width - line.box.width;
break;
}
if (htrans < 0) {
htrans = 0;
}
if (htrans || vtrans) {
line.el.transform(geo.Matrix.translate(htrans, vtrans));
}
});
}
function lineBreak(text, style, width) {
var lines = [];
var len = text.length;
var start = 0;
while (start < len) {
split(start, len, len);
}
return lines;
function split(min, eol, max) {
var sub = text.substring(start, eol).trim();
var box = kendo.util.measureText(sub, style);
if (box.width <= width) {
if (eol < max - 1) {
split(eol, eol + max >> 1, max);
} else {
lines.push({
text: sub,
box: box
});
start = eol;
}
} else if (min < eol) {
split(min, min + eol >> 1, eol);
}
}
}
function makeFontDef(cell) {
var font = [];
if (cell.italic) {
font.push('italic');
}
if (cell.bold) {
font.push('bold');
}
font.push((cell.fontSize || 12) + 'px');
font.push(cell.fontFamily || 'Arial');
return font.join(' ');
}
function draw(sheet, range, options, callback) {
if (options == null && callback == null) {
callback = range;
options = {};
range = spreadsheet.SHEETREF;
}
if (callback == null) {
callback = options;
if (range instanceof spreadsheet.Range || range instanceof spreadsheet.Ref || typeof range == 'string') {
options = {};
} else {
options = range;
range = spreadsheet.SHEETREF;
}
}
options = kendo.jQuery.extend({
paperSize: 'A4',
landscape: true,
margin: '1cm',
guidelines: true,
emptyCells: true,
fitWidth: false,
center: false
}, options);
var group = new drawing.Group();
var paper = kendo.pdf.getPaperOptions(options);
group.options.set('pdf', {
author: options.author,
creator: options.creator,
date: options.date,
keywords: options.keywords,
margin: paper.margin,
multiPage: true,
paperSize: paper.paperSize,
subject: options.subject,
title: options.title
});
var pageWidth = paper.paperSize[0];
var pageHeight = paper.paperSize[1];
if (paper.margin) {
pageWidth -= paper.margin.left + paper.margin.right;
pageHeight -= paper.margin.top + paper.margin.bottom;
}
options.pageWidth = pageWidth;
options.pageHeight = pageHeight;
var layout = doLayout(sheet, sheet._ref(range), options);
drawLayout(layout, group, options);
callback(group);
}
spreadsheet.Sheet.prototype.draw = function (range, options, callback) {
var sheet = this;
if (sheet._workbook) {
sheet.recalc(sheet._workbook._context, function () {
draw(sheet, range, options, callback);
});
} else {
draw(sheet, range, options, callback);
}
};
spreadsheet.draw = {
doLayout: doLayout,
drawLayout: drawLayout,
shouldDrawCell: shouldDrawCell
};
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('kendo.spreadsheet', [
'util/undoredostack',
'util/text-metrics',
'util/parse-xml',
'kendo.excel',
'kendo.progressbar',
'kendo.pdf',
'spreadsheet/commands',
'spreadsheet/formulabar',
'spreadsheet/formulainput',
'spreadsheet/eventlistener',
'spreadsheet/rangelist',
'spreadsheet/propertybag',
'spreadsheet/references',
'spreadsheet/navigator',
'spreadsheet/axismanager',
'spreadsheet/clipboard',
'spreadsheet/range',
'spreadsheet/sheet',
'spreadsheet/sheetsbar',
'spreadsheet/excel-reader',
'spreadsheet/workbook',
'spreadsheet/formulacontext',
'spreadsheet/controller',
'spreadsheet/view',
'spreadsheet/grid',
'spreadsheet/axis',
'spreadsheet/filter',
'spreadsheet/sorter',
'spreadsheet/runtime',
'spreadsheet/calc',
'spreadsheet/numformat',
'spreadsheet/runtime.functions',
'spreadsheet/runtime.functions.2',
'spreadsheet/toolbar',
'spreadsheet/dialogs',
'spreadsheet/sheetbinder',
'spreadsheet/filtermenu',
'spreadsheet/editor',
'spreadsheet/autofill',
'spreadsheet/print'
], f);
}(function () {
var __meta__ = {
id: 'spreadsheet',
name: 'Spreadsheet',
category: 'web',
description: 'Spreadsheet component',
depends: [
'core',
'binder',
'colorpicker',
'combobox',
'data',
'dom',
'dropdownlist',
'menu',
'ooxml',
'popup',
'sortable',
'tabstrip',
'toolbar',
'treeview',
'window',
'validator',
'excel',
'pdf',
'drawing'
]
};
(function (kendo, undefined) {
if (kendo.support.browser.msie && kendo.support.browser.version < 9) {
return;
}
var $ = kendo.jQuery;
var Widget = kendo.ui.Widget;
var Workbook = kendo.spreadsheet.Workbook;
var Controller = kendo.spreadsheet.Controller;
var View = kendo.spreadsheet.View;
var NS = '.kendoSpreadsheet';
var ALL_REASONS = {
recalc: true,
selection: true,
activeCell: true,
layout: true,
sheetSelection: true,
resize: true,
editorChange: false,
editorClose: false
};
var classNames = { wrapper: 'k-widget k-spreadsheet' };
var Spreadsheet = kendo.ui.Widget.extend({
init: function (element, options) {
Widget.fn.init.call(this, element, options);
this.element.addClass(Spreadsheet.classNames.wrapper);
this._view = new View(this.element, {
toolbar: this.options.toolbar,
sheetsbar: this.options.sheetsbar
});
this._workbook = new Workbook(this.options, this._view);
this._controller = new Controller(this._view, this._workbook);
this._autoRefresh = true;
this._bindWorkbookEvents();
this._view.workbook(this._workbook);
this.refresh();
this._resizeHandler = function () {
this.resize();
}.bind(this);
$(window).on('resize' + NS, this._resizeHandler);
},
_resize: function () {
this.refresh({ layout: true });
},
_workbookChange: function (e) {
if (this._autoRefresh) {
this.refresh(e);
}
if (e.recalc && e.ref) {
var range = new kendo.spreadsheet.Range(e.ref, this.activeSheet());
this.trigger('change', { range: range });
}
},
activeSheet: function (sheet) {
return this._workbook.activeSheet(sheet);
},
moveSheetToIndex: function (sheet, index) {
return this._workbook.moveSheetToIndex(sheet, index);
},
insertSheet: function (options) {
return this._workbook.insertSheet(options);
},
sheets: function () {
return this._workbook.sheets();
},
removeSheet: function (sheet) {
return this._workbook.removeSheet(sheet);
},
sheetByName: function (sheetName) {
return this._workbook.sheetByName(sheetName);
},
sheetIndex: function (sheet) {
return this._workbook.sheetIndex(sheet);
},
sheetByIndex: function (index) {
return this._workbook.sheetByIndex(index);
},
renameSheet: function (sheet, newSheetName) {
return this._workbook.renameSheet(sheet, newSheetName);
},
refresh: function (reason) {
if (!reason) {
reason = ALL_REASONS;
}
if (!reason.editorClose) {
this._view.sheet(this._workbook.activeSheet());
this._controller.sheet(this._workbook.activeSheet());
this._workbook.refresh(reason);
}
if (!reason.editorChange) {
this._view.refresh(reason);
this._controller.refresh();
this._view.render();
this.trigger('render');
}
return this;
},
openDialog: function (name, options) {
return this._view.openDialog(name, options);
},
autoRefresh: function (value) {
if (value !== undefined) {
this._autoRefresh = value;
if (value === true) {
this.refresh();
}
return this;
}
return this._autoRefresh;
},
toJSON: function () {
return this._workbook.toJSON();
},
fromJSON: function (json) {
if (json.sheets) {
this._workbook.destroy();
this._workbook = new Workbook($.extend({}, this.options, json));
this._bindWorkbookEvents();
this._view.workbook(this._workbook);
this._controller.workbook(this._workbook);
this.activeSheet(this.activeSheet());
} else {
this.refresh();
}
},
fromFile: function (blob, name) {
return this._workbook.fromFile(blob, name);
},
saveAsPDF: function (options) {
this._workbook.saveAsPDF($.extend({}, this.options.pdf, options, { workbook: this._workbook }));
},
saveAsExcel: function (options) {
this._workbook.saveAsExcel(options);
},
draw: function (options, callback) {
this._workbook.draw(options, callback);
},
_workbookExcelExport: function (e) {
if (this.trigger('excelExport', e)) {
e.preventDefault();
}
},
_workbookExcelImport: function (e) {
if (this.trigger('excelImport', e)) {
e.preventDefault();
} else {
this._initProgress(e.promise);
}
},
_initProgress: function (deferred) {
var loading = $('
' + '
' + '
').appendTo(this.element);
var pb = $('
').appendTo(loading).kendoProgressBar({
type: 'chunk',
chunkCount: 10,
min: 0,
max: 1,
value: 0
}).data('kendoProgressBar');
deferred.progress(function (e) {
pb.value(e.progress);
}).always(function () {
kendo.destroy(loading);
loading.remove();
});
},
_workbookPdfExport: function (e) {
if (this.trigger('pdfExport', e)) {
e.preventDefault();
}
},
_bindWorkbookEvents: function () {
this._workbook.bind('change', this._workbookChange.bind(this));
this._workbook.bind('excelExport', this._workbookExcelExport.bind(this));
this._workbook.bind('excelImport', this._workbookExcelImport.bind(this));
this._workbook.bind('pdfExport', this._workbookPdfExport.bind(this));
},
destroy: function () {
kendo.ui.Widget.fn.destroy.call(this);
this._workbook.destroy();
this._controller.destroy();
this._view.destroy();
if (this._resizeHandler) {
$(window).off('resize' + NS, this._resizeHandler);
}
},
options: {
name: 'Spreadsheet',
toolbar: true,
sheetsbar: true,
rows: 200,
columns: 50,
rowHeight: 20,
columnWidth: 64,
headerHeight: 20,
headerWidth: 32,
excel: {
proxyURL: '',
fileName: 'Workbook.xlsx'
},
pdf: {
area: 'workbook',
fileName: 'Workbook.pdf',
proxyURL: '',
paperSize: 'a4',
landscape: true,
margin: null,
title: null,
author: null,
subject: null,
keywords: null,
creator: 'Kendo UI PDF Generator v.' + kendo.version,
date: null
}
},
events: [
'pdfExport',
'excelExport',
'excelImport',
'change',
'render'
]
});
kendo.spreadsheet.ALL_REASONS = ALL_REASONS;
kendo.ui.plugin(Spreadsheet);
$.extend(true, Spreadsheet, { classNames: classNames });
}(window.kendo));
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('kendo.pivot.configurator', ['kendo.dom'], f);
}(function () {
var __meta__ = {
id: 'pivot.configurator',
name: 'PivotConfigurator',
category: 'web',
depends: [
'dropdownlist',
'treeview',
'pivot.fieldmenu'
],
hidden: true
};
(function ($, undefined) {
var kendo = window.kendo, ui = kendo.ui, Widget = ui.Widget, ns = '.kendoPivotConfigurator', HOVEREVENTS = 'mouseenter' + ns + ' mouseleave' + ns, SETTING_CONTAINER_TEMPLATE = kendo.template('
${name}
' + '
');
function addKPI(data) {
var found;
var idx = 0;
var length = data.length;
for (; idx < length; idx++) {
if (data[idx].type == 2) {
found = true;
break;
}
}
if (found) {
data.splice(idx + 1, 0, {
caption: 'KPIs',
defaultHierarchy: '[KPIs]',
name: 'KPIs',
uniqueName: '[KPIs]'
});
}
}
function kpiNode(node) {
return {
name: node.uniqueName,
type: node.type
};
}
function normalizeKPIs(data) {
for (var idx = 0, length = data.length; idx < length; idx++) {
data[idx].uniqueName = data[idx].name;
data[idx].type = 'kpi';
}
return data;
}
function settingTargetFromNode(node) {
var target = $(node).closest('.k-pivot-setting');
if (target.length) {
return target.data('kendoPivotSettingTarget');
}
return null;
}
var PivotConfigurator = Widget.extend({
init: function (element, options) {
Widget.fn.init.call(this, element, options);
this.element.addClass('k-widget k-fieldselector k-alt k-edit-form-container');
this._dataSource();
this._layout();
this.refresh();
kendo.notify(this);
},
events: [],
options: {
name: 'PivotConfigurator',
filterable: false,
sortable: false,
messages: {
measures: 'Drop Data Fields Here',
columns: 'Drop Column Fields Here',
rows: 'Drop Rows Fields Here',
measuresLabel: 'Measures',
columnsLabel: 'Columns',
rowsLabel: 'Rows',
fieldsLabel: 'Fields'
}
},
_dataSource: function () {
var that = this;
if (that.dataSource && that._refreshHandler) {
that.dataSource.unbind('change', that._refreshHandler).unbind('error', that._errorHandler).unbind('progress', that._progressHandler);
} else {
that._errorHandler = $.proxy(that._error, that);
that._refreshHandler = $.proxy(that.refresh, that);
that._progressHandler = $.proxy(that._requestStart, that);
}
that.dataSource = kendo.data.PivotDataSource.create(that.options.dataSource);
that.dataSource.bind('change', that._refreshHandler).bind('error', that._errorHandler).bind('progress', that._progressHandler);
},
setDataSource: function (dataSource) {
this.options.dataSource = dataSource;
this._dataSource();
if (this.measures) {
this.measures.setDataSource(dataSource);
}
if (this.rows) {
this.rows.setDataSource(dataSource);
}
if (this.columns) {
this.columns.setDataSource(dataSource);
}
this.refresh();
},
_treeViewDataSource: function () {
var that = this;
return kendo.data.HierarchicalDataSource.create({
schema: {
model: {
id: 'uniqueName',
hasChildren: function (item) {
return !('hierarchyUniqueName' in item) && !('aggregator' in item);
}
}
},
transport: {
read: function (options) {
var promise;
var node;
var kpi;
if ($.isEmptyObject(options.data)) {
promise = that.dataSource.schemaDimensions();
promise.done(function (data) {
if (!that.dataSource.cubeBuilder) {
addKPI(data);
}
options.success(data);
}).fail(options.error);
} else {
node = that.treeView.dataSource.get(options.data.uniqueName);
if (node.uniqueName === '[KPIs]') {
kpi = true;
promise = that.dataSource.schemaKPIs();
promise.done(function (data) {
options.success(normalizeKPIs(data));
}).fail(options.error);
} else if (node.type == 'kpi') {
kpi = true;
options.success(buildKPImeasures(node));
}
if (!kpi) {
if (node.type == 2) {
promise = that.dataSource.schemaMeasures();
} else if (node.dimensionUniqueName) {
promise = that.dataSource.schemaLevels(options.data.uniqueName);
} else {
promise = that.dataSource.schemaHierarchies(options.data.uniqueName);
}
promise.done(options.success).fail(options.error);
}
}
}
}
});
},
_progress: function (toggle) {
kendo.ui.progress(this.element, toggle);
},
_error: function () {
this._progress(false);
},
_requestStart: function () {
this._progress(true);
},
_layout: function () {
this.form = $('
').appendTo(this.element);
this._fields();
this._targets();
},
_fields: function () {
var container = $('
' + this.options.messages.fieldsLabel + '
').appendTo(this.form);
var template = '# if (item.type == 2 || item.uniqueName == "[KPIs]") { #' + '
' + '# } else if (item.type && item.type !== "kpi") { #' + '
' + '# } #' + '#: item.caption || item.name #';
this.treeView = $('
').appendTo(container).kendoTreeView({
template: template,
dataTextField: 'caption',
dragAndDrop: true,
autoBind: false,
dataSource: this._treeViewDataSource(),
dragstart: function (e) {
var dataItem = this.dataItem(e.sourceNode);
if (!dataItem.hasChildren && !dataItem.aggregator && !dataItem.measure || dataItem.type == 2 || dataItem.uniqueName === '[KPIs]') {
e.preventDefault();
}
},
drag: function (e) {
var status = 'k-denied';
var setting = settingTargetFromNode(e.dropTarget);
if (setting && setting.validate(this.dataItem(e.sourceNode))) {
status = 'k-add';
}
e.setStatusClass(status);
},
drop: function (e) {
e.preventDefault();
var setting = settingTargetFromNode(e.dropTarget);
var node = this.dataItem(e.sourceNode);
var idx, length, measures;
var name;
if (setting && setting.validate(node)) {
name = node.defaultHierarchy || node.uniqueName;
if (node.type === 'kpi') {
measures = buildKPImeasures(node);
length = measures.length;
name = [];
for (idx = 0; idx < length; idx++) {
name.push(kpiNode(measures[idx]));
}
} else if (node.kpi) {
name = [kpiNode(node)];
}
setting.add(name);
}
}
}).data('kendoTreeView');
},
_createTarget: function (element, options) {
var template = '';
return new kendo.ui.PivotSettingTarget(element, $.extend({
dataSource: this.dataSource,
hint: function (element) {
var wrapper = $('
');
wrapper.find('.k-list').append(element.clone());
return wrapper;
},
template: template,
emptyTemplate: '
${data}'
}, options));
},
_targets: function () {
var container = $('
').appendTo(this.form);
var columnsContainer = $(SETTING_CONTAINER_TEMPLATE({
name: this.options.messages.columnsLabel,
icon: 'k-i-vbars'
})).appendTo(container);
var columns = $('
').appendTo(columnsContainer.last());
var rowsContainer = $(SETTING_CONTAINER_TEMPLATE({
name: this.options.messages.rowsLabel,
icon: 'k-i-hbars'
})).appendTo(container);
var rows = $('
').appendTo(rowsContainer.last());
var measuresContainer = $(SETTING_CONTAINER_TEMPLATE({
name: this.options.messages.measuresLabel,
icon: 'k-i-sum'
})).appendTo(container);
var measures = $('
').appendTo(measuresContainer.last());
var options = this.options;
this.columns = this._createTarget(columns, {
filterable: options.filterable,
sortable: options.sortable,
connectWith: rows,
messages: {
empty: options.messages.columns,
fieldMenu: options.messages.fieldMenu
}
});
this.rows = this._createTarget(rows, {
filterable: options.filterable,
setting: 'rows',
connectWith: columns,
messages: {
empty: this.options.messages.rows,
fieldMenu: this.options.messages.fieldMenu
}
});
this.measures = this._createTarget(measures, {
setting: 'measures',
messages: { empty: options.messages.measures }
});
columns.add(rows).add(measures).on(HOVEREVENTS, '.k-item:not(.k-empty)', this._toggleHover);
},
_toggleHover: function (e) {
$(e.currentTarget).toggleClass('k-state-hover', e.type === 'mouseenter');
},
_resize: function () {
var element = this.element;
var height = this.options.height;
var border, fields;
if (!height) {
return;
}
element.height(height);
if (element.is(':visible')) {
fields = element.children('.k-columns').children('div.k-state-default');
height = element.innerHeight();
border = (element.outerHeight() - height) / 2;
height = height - (fields.outerHeight(true) - fields.height()) - border;
fields.height(height);
}
},
refresh: function () {
var dataSource = this.dataSource;
if (dataSource.cubeBuilder || this._cube !== dataSource.cube() || this._catalog !== dataSource.catalog()) {
this.treeView.dataSource.fetch();
}
this._catalog = this.dataSource.catalog();
this._cube = this.dataSource.cube();
this._resize();
this._progress(false);
},
destroy: function () {
Widget.fn.destroy.call(this);
this.dataSource.unbind('change', this._refreshHandler);
this.form.find('.k-list').off(ns);
this.rows.destroy();
this.columns.destroy();
this.measures.destroy();
this.treeView.destroy();
this.element = null;
this._refreshHandler = null;
}
});
function kpiMeasure(name, measure, type) {
return {
hierarchyUniqueName: name,
uniqueName: measure,
caption: measure,
measure: measure,
name: measure,
type: type,
kpi: true
};
}
function buildKPImeasures(node) {
var name = node.name;
return [
kpiMeasure(name, node.value, 'value'),
kpiMeasure(name, node.goal, 'goal'),
kpiMeasure(name, node.status, 'status'),
kpiMeasure(name, node.trend, 'trend')
];
}
ui.plugin(PivotConfigurator);
}(window.kendo.jQuery));
return window.kendo;
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('kendo.angular', ['kendo.core'], f);
}(function () {
var __meta__ = {
id: 'angular',
name: 'AngularJS Directives',
category: 'framework',
description: 'Adds Kendo UI for AngularJS directives',
depends: ['core'],
defer: true
};
(function ($, angular, undefined) {
'use strict';
if (!angular || !angular.injector) {
return;
}
var module = angular.module('kendo.directives', []), $injector = angular.injector(['ng']), $parse = $injector.get('$parse'), $timeout = $injector.get('$timeout'), $defaultCompile, $log = $injector.get('$log');
function withoutTimeout(f) {
var save = $timeout;
try {
$timeout = function (f) {
return f();
};
return f();
} finally {
$timeout = save;
}
}
var OPTIONS_NOW;
var createDataSource = function () {
var types = {
TreeList: 'TreeListDataSource',
TreeView: 'HierarchicalDataSource',
Scheduler: 'SchedulerDataSource',
PanelBar: '$PLAIN',
Menu: '$PLAIN',
ContextMenu: '$PLAIN'
};
var toDataSource = function (dataSource, type) {
if (type == '$PLAIN') {
return dataSource;
}
return kendo.data[type].create(dataSource);
};
return function (scope, element, role, source) {
var type = types[role] || 'DataSource';
var current = scope.$eval(source);
var ds = toDataSource(current, type);
scope.$watch(source, function (mew) {
var widget = kendoWidgetInstance(element);
if (widget && typeof widget.setDataSource == 'function') {
if (mew !== current) {
var ds = toDataSource(mew, type);
widget.setDataSource(ds);
current = mew;
}
}
});
return ds;
};
}();
var ignoredAttributes = {
kDataSource: true,
kOptions: true,
kRebind: true,
kNgModel: true,
kNgDelay: true
};
var ignoredOwnProperties = {
name: true,
title: true,
style: true
};
function createWidget(scope, element, attrs, widget, origAttr, controllers) {
if (!(element instanceof jQuery)) {
throw new Error('The Kendo UI directives require jQuery to be available before AngularJS. Please include jquery before angular in the document.');
}
var kNgDelay = attrs.kNgDelay, delayValue = scope.$eval(kNgDelay);
controllers = controllers || [];
var ngModel = controllers[0], ngForm = controllers[1];
var ctor = $(element)[widget];
if (!ctor) {
window.console.error('Could not find: ' + widget);
return null;
}
var parsed = parseOptions(scope, element, attrs, widget, ctor);
var options = parsed.options;
if (parsed.unresolved.length) {
var promises = [];
for (var i = 0, len = parsed.unresolved.length; i < len; i++) {
var unresolved = parsed.unresolved[i];
var promise = $.Deferred(function (d) {
var unwatch = scope.$watch(unresolved.path, function (newValue) {
if (newValue !== undefined) {
unwatch();
d.resolve();
}
});
}).promise();
promises.push(promise);
}
$.when.apply(null, promises).then(createIt);
return;
}
if (kNgDelay && !delayValue) {
var root = scope.$root || scope;
var register = function () {
var unregister = scope.$watch(kNgDelay, function (newValue) {
if (newValue !== undefined) {
unregister();
element.removeAttr(attrs.$attr.kNgDelay);
kNgDelay = null;
$timeout(createIt);
}
});
};
if (/^\$(digest|apply)$/.test(root.$$phase)) {
register();
} else {
scope.$apply(register);
}
return;
} else {
return createIt();
}
function createIt() {
var originalElement;
if (attrs.kRebind) {
originalElement = $($(element)[0].cloneNode(true));
}
options = parseOptions(scope, element, attrs, widget, ctor).options;
if (element.is('select')) {
(function (options) {
if (options.length > 0) {
var first = $(options[0]);
if (!/\S/.test(first.text()) && /^\?/.test(first.val())) {
first.remove();
}
}
}(element[0].options));
}
var object = ctor.call(element, OPTIONS_NOW = options).data(widget);
exposeWidget(object, scope, attrs, widget, origAttr);
scope.$emit('kendoWidgetCreated', object);
var destroyRegister = destroyWidgetOnScopeDestroy(scope, object);
if (attrs.kRebind) {
setupRebind(object, scope, element, originalElement, attrs.kRebind, destroyRegister, attrs);
}
if (attrs.kNgDisabled) {
var kNgDisabled = attrs.kNgDisabled;
var isDisabled = scope.$eval(kNgDisabled);
if (isDisabled) {
object.enable(!isDisabled);
}
bindToKNgDisabled(object, scope, element, kNgDisabled);
}
if (attrs.kNgReadonly) {
var kNgReadonly = attrs.kNgReadonly;
var isReadonly = scope.$eval(kNgReadonly);
if (isReadonly) {
object.readonly(isReadonly);
}
bindToKNgReadonly(object, scope, element, kNgReadonly);
}
if (attrs.kNgModel) {
bindToKNgModel(object, scope, attrs.kNgModel);
}
if (ngModel) {
bindToNgModel(object, scope, element, ngModel, ngForm);
}
if (object) {
propagateClassToWidgetWrapper(object, element);
}
return object;
}
}
function parseOptions(scope, element, attrs, widget, ctor) {
var role = widget.replace(/^kendo/, '');
var unresolved = [];
var optionsPath = attrs.kOptions || attrs.options;
var optionsValue = scope.$eval(optionsPath);
if (optionsPath && optionsValue === undefined) {
unresolved.push({
option: 'options',
path: optionsPath
});
}
var options = angular.extend({}, attrs.defaultOptions, optionsValue);
function addOption(name, value) {
var scopeValue = angular.copy(scope.$eval(value));
if (scopeValue === undefined) {
unresolved.push({
option: name,
path: value
});
} else {
options[name] = scopeValue;
}
}
var widgetOptions = ctor.widget.prototype.options;
var widgetEvents = ctor.widget.prototype.events;
$.each(attrs, function (name, value) {
if (name === 'source' || name === 'kDataSource' || name === 'kScopeField' || name === 'scopeField') {
return;
}
var dataName = 'data' + name.charAt(0).toUpperCase() + name.slice(1);
if (name.indexOf('on') === 0) {
var eventKey = name.replace(/^on./, function (prefix) {
return prefix.charAt(2).toLowerCase();
});
if (widgetEvents.indexOf(eventKey) > -1) {
options[eventKey] = value;
}
}
if (widgetOptions.hasOwnProperty(dataName)) {
addOption(dataName, value);
} else if (widgetOptions.hasOwnProperty(name) && !ignoredOwnProperties[name]) {
addOption(name, value);
} else if (!ignoredAttributes[name]) {
var match = name.match(/^k(On)?([A-Z].*)/);
if (match) {
var optionName = match[2].charAt(0).toLowerCase() + match[2].slice(1);
if (match[1] && name != 'kOnLabel') {
options[optionName] = value;
} else {
if (name == 'kOnLabel') {
optionName = 'onLabel';
}
addOption(optionName, value);
}
}
}
});
var dataSource = attrs.kDataSource || attrs.source;
if (dataSource) {
options.dataSource = createDataSource(scope, element, role, dataSource);
}
options.$angular = [scope];
return {
options: options,
unresolved: unresolved
};
}
function bindToKNgDisabled(widget, scope, element, kNgDisabled) {
if (kendo.ui.PanelBar && widget instanceof kendo.ui.PanelBar || kendo.ui.Menu && widget instanceof kendo.ui.Menu) {
$log.warn('k-ng-disabled specified on a widget that does not have the enable() method: ' + widget.options.name);
return;
}
scope.$watch(kNgDisabled, function (newValue, oldValue) {
if (newValue != oldValue) {
widget.enable(!newValue);
}
});
}
function bindToKNgReadonly(widget, scope, element, kNgReadonly) {
if (typeof widget.readonly != 'function') {
$log.warn('k-ng-readonly specified on a widget that does not have the readonly() method: ' + widget.options.name);
return;
}
scope.$watch(kNgReadonly, function (newValue, oldValue) {
if (newValue != oldValue) {
widget.readonly(newValue);
}
});
}
function exposeWidget(widget, scope, attrs, kendoWidget, origAttr) {
if (attrs[origAttr]) {
var set = $parse(attrs[origAttr]).assign;
if (set) {
set(scope, widget);
} else {
throw new Error(origAttr + ' attribute used but expression in it is not assignable: ' + attrs[kendoWidget]);
}
}
}
function formValue(element) {
if (/checkbox|radio/i.test(element.attr('type'))) {
return element.prop('checked');
}
return element.val();
}
var formRegExp = /^(input|select|textarea)$/i;
function isForm(element) {
return formRegExp.test(element[0].tagName);
}
function bindToNgModel(widget, scope, element, ngModel, ngForm) {
if (!widget.value) {
return;
}
var value;
if (isForm(element)) {
value = function () {
return formValue(element);
};
} else {
value = function () {
return widget.value();
};
}
ngModel.$render = function () {
var val = ngModel.$viewValue;
if (val === undefined) {
val = ngModel.$modelValue;
}
if (val === undefined) {
val = null;
}
setTimeout(function () {
if (widget) {
var kNgModel = scope[widget.element.attr('k-ng-model')];
if (kNgModel) {
val = kNgModel;
}
if (widget.options.autoBind === false && !widget.listView.bound()) {
if (val) {
widget.value(val);
}
} else {
widget.value(val);
}
}
}, 0);
};
var haveChangeOnElement = false;
if (isForm(element)) {
element.on('change', function () {
haveChangeOnElement = true;
});
}
var onChange = function (pristine) {
return function () {
var formPristine;
if (haveChangeOnElement) {
return;
}
if (pristine && ngForm) {
formPristine = ngForm.$pristine;
}
ngModel.$setViewValue(value());
if (pristine) {
ngModel.$setPristine();
if (formPristine) {
ngForm.$setPristine();
}
}
digest(scope);
};
};
widget.first('change', onChange(false));
if (!(kendo.ui.AutoComplete && widget instanceof kendo.ui.AutoComplete)) {
widget.first('dataBound', onChange(true));
}
var currentVal = value();
if (!isNaN(ngModel.$viewValue) && currentVal != ngModel.$viewValue) {
if (!ngModel.$isEmpty(ngModel.$viewValue)) {
widget.value(ngModel.$viewValue);
} else if (currentVal != null && currentVal !== '' && currentVal != ngModel.$viewValue) {
ngModel.$setViewValue(currentVal);
}
}
ngModel.$setPristine();
}
function bindToKNgModel(widget, scope, kNgModel) {
if (typeof widget.value != 'function') {
$log.warn('k-ng-model specified on a widget that does not have the value() method: ' + widget.options.name);
return;
}
var form = $(widget.element).parents('form');
var ngForm = scope[form.attr('name')];
var getter = $parse(kNgModel);
var setter = getter.assign;
var updating = false;
var valueIsCollection = kendo.ui.MultiSelect && widget instanceof kendo.ui.MultiSelect;
var length = function (value) {
return valueIsCollection ? value.length : 0;
};
var currentValueLength = length(getter(scope));
widget.$angular_setLogicValue(getter(scope));
var watchHandler = function (newValue, oldValue) {
if (newValue === undefined) {
newValue = null;
}
if (updating || newValue == oldValue && length(newValue) == currentValueLength) {
return;
}
currentValueLength = length(newValue);
widget.$angular_setLogicValue(newValue);
};
if (valueIsCollection) {
scope.$watchCollection(kNgModel, watchHandler);
} else {
scope.$watch(kNgModel, watchHandler);
}
widget.first('change', function () {
updating = true;
if (ngForm && ngForm.$pristine) {
ngForm.$setDirty();
}
digest(scope, function () {
setter(scope, widget.$angular_getLogicValue());
currentValueLength = length(getter(scope));
});
updating = false;
});
}
function destroyWidgetOnScopeDestroy(scope, widget) {
var deregister = scope.$on('$destroy', function () {
deregister();
if (widget) {
if (widget.element) {
widget.destroy();
}
widget = null;
}
});
return deregister;
}
function propagateClassToWidgetWrapper(widget, element) {
if (!(window.MutationObserver && widget.wrapper)) {
return;
}
var prevClassList = [].slice.call($(element)[0].classList);
var mo = new MutationObserver(function (changes) {
suspend();
if (!widget) {
return;
}
changes.forEach(function (chg) {
var w = $(widget.wrapper)[0];
switch (chg.attributeName) {
case 'class':
var currClassList = [].slice.call(chg.target.classList);
currClassList.forEach(function (cls) {
if (prevClassList.indexOf(cls) < 0) {
w.classList.add(cls);
if (kendo.ui.ComboBox && widget instanceof kendo.ui.ComboBox) {
widget.input[0].classList.add(cls);
}
}
});
prevClassList.forEach(function (cls) {
if (currClassList.indexOf(cls) < 0) {
w.classList.remove(cls);
if (kendo.ui.ComboBox && widget instanceof kendo.ui.ComboBox) {
widget.input[0].classList.remove(cls);
}
}
});
prevClassList = currClassList;
break;
case 'disabled':
if (typeof widget.enable == 'function' && !widget.element.attr('readonly')) {
widget.enable(!$(chg.target).attr('disabled'));
}
break;
case 'readonly':
if (typeof widget.readonly == 'function' && !widget.element.attr('disabled')) {
widget.readonly(!!$(chg.target).attr('readonly'));
}
break;
}
});
resume();
});
function suspend() {
mo.disconnect();
}
function resume() {
mo.observe($(element)[0], { attributes: true });
}
resume();
widget.first('destroy', suspend);
}
function setupRebind(widget, scope, element, originalElement, rebindAttr, destroyRegister, attrs) {
var unregister = scope.$watch(rebindAttr, function (newValue, oldValue) {
if (!widget._muteRebind && newValue !== oldValue) {
unregister();
var templateOptions = WIDGET_TEMPLATE_OPTIONS[widget.options.name];
if (templateOptions) {
templateOptions.forEach(function (name) {
var templateContents = scope.$eval(attrs['k' + name]);
if (templateContents) {
originalElement.append($(templateContents).attr(kendo.toHyphens('k' + name), ''));
}
});
}
var _wrapper = $(widget.wrapper)[0];
var _element = $(widget.element)[0];
var isUpload = widget.options.name === 'Upload';
if (isUpload) {
element = $(_element);
}
var compile = element.injector().get('$compile');
widget._destroy();
if (destroyRegister) {
destroyRegister();
}
widget = null;
if (_element) {
if (_wrapper) {
_wrapper.parentNode.replaceChild(_element, _wrapper);
}
$(element).replaceWith(originalElement);
}
compile(originalElement)(scope);
}
}, true);
digest(scope);
}
module.factory('directiveFactory', [
'$compile',
function (compile) {
var kendoRenderedTimeout;
var RENDERED = false;
$defaultCompile = compile;
var create = function (role, origAttr) {
return {
restrict: 'AC',
require: [
'?ngModel',
'^?form'
],
scope: false,
controller: [
'$scope',
'$attrs',
'$element',
function ($scope, $attrs) {
var that = this;
that.template = function (key, value) {
$attrs[key] = kendo.stringify(value);
};
$scope.$on('$destroy', function () {
that.template = null;
that = null;
});
}
],
link: function (scope, element, attrs, controllers) {
var $element = $(element);
var roleattr = role.replace(/([A-Z])/g, '-$1');
$element.attr(roleattr, $element.attr('data-' + roleattr));
$element[0].removeAttribute('data-' + roleattr);
var widget = createWidget(scope, element, attrs, role, origAttr, controllers);
if (!widget) {
return;
}
if (kendoRenderedTimeout) {
clearTimeout(kendoRenderedTimeout);
}
kendoRenderedTimeout = setTimeout(function () {
scope.$emit('kendoRendered');
if (!RENDERED) {
RENDERED = true;
$('form').each(function () {
var form = $(this).controller('form');
if (form) {
form.$setPristine();
}
});
}
});
}
};
};
return { create: create };
}
]);
var TAGNAMES = {
Editor: 'textarea',
NumericTextBox: 'input',
DatePicker: 'input',
DateTimePicker: 'input',
TimePicker: 'input',
AutoComplete: 'input',
ColorPicker: 'input',
MaskedTextBox: 'input',
MultiSelect: 'input',
Upload: 'input',
Validator: 'form',
Button: 'button',
MobileButton: 'a',
MobileBackButton: 'a',
MobileDetailButton: 'a',
ListView: 'ul',
MobileListView: 'ul',
TreeView: 'ul',
Menu: 'ul',
ContextMenu: 'ul',
ActionSheet: 'ul'
};
var SKIP_SHORTCUTS = [
'MobileView',
'MobileDrawer',
'MobileLayout',
'MobileSplitView',
'MobilePane',
'MobileModalView'
];
var MANUAL_DIRECTIVES = [
'MobileApplication',
'MobileView',
'MobileModalView',
'MobileLayout',
'MobileActionSheet',
'MobileDrawer',
'MobileSplitView',
'MobilePane',
'MobileScrollView',
'MobilePopOver'
];
angular.forEach([
'MobileNavBar',
'MobileButton',
'MobileBackButton',
'MobileDetailButton',
'MobileTabStrip',
'MobileScrollView',
'MobileScroller'
], function (widget) {
MANUAL_DIRECTIVES.push(widget);
widget = 'kendo' + widget;
module.directive(widget, function () {
return {
restrict: 'A',
link: function (scope, element, attrs) {
createWidget(scope, element, attrs, widget, widget);
}
};
});
});
function createDirectives(klass, isMobile) {
function make(directiveName, widgetName) {
module.directive(directiveName, [
'directiveFactory',
function (directiveFactory) {
return directiveFactory.create(widgetName, directiveName);
}
]);
}
var name = isMobile ? 'Mobile' : '';
name += klass.fn.options.name;
var className = name;
var shortcut = 'kendo' + name.charAt(0) + name.substr(1).toLowerCase();
name = 'kendo' + name;
var dashed = name.replace(/([A-Z])/g, '-$1');
if (SKIP_SHORTCUTS.indexOf(name.replace('kendo', '')) == -1) {
var names = name === shortcut ? [name] : [
name,
shortcut
];
angular.forEach(names, function (directiveName) {
module.directive(directiveName, function () {
return {
restrict: 'E',
replace: true,
template: function (element, attributes) {
var tag = TAGNAMES[className] || 'div';
var scopeField = attributes.kScopeField || attributes.scopeField;
return '<' + tag + ' ' + dashed + (scopeField ? '="' + scopeField + '"' : '') + '>' + element.html() + '' + tag + '>';
}
};
});
});
}
if (MANUAL_DIRECTIVES.indexOf(name.replace('kendo', '')) > -1) {
return;
}
make(name, name);
if (shortcut != name) {
make(shortcut, name);
}
}
function kendoWidgetInstance(el) {
el = $(el);
return kendo.widgetInstance(el, kendo.ui) || kendo.widgetInstance(el, kendo.mobile.ui) || kendo.widgetInstance(el, kendo.dataviz.ui);
}
function digest(scope, func) {
var root = scope.$root || scope;
var isDigesting = /^\$(digest|apply)$/.test(root.$$phase);
if (func) {
if (isDigesting) {
func();
} else {
root.$apply(func);
}
} else if (!isDigesting) {
root.$digest();
}
}
function destroyScope(scope, el) {
scope.$destroy();
if (el) {
$(el).removeData('$scope').removeData('$$kendoScope').removeData('$isolateScope').removeData('$isolateScopeNoTemplate').removeClass('ng-scope');
}
}
var pendingPatches = [];
function defadvice(klass, methodName, func) {
if ($.isArray(klass)) {
return angular.forEach(klass, function (klass) {
defadvice(klass, methodName, func);
});
}
if (typeof klass == 'string') {
var a = klass.split('.');
var x = kendo;
while (x && a.length > 0) {
x = x[a.shift()];
}
if (!x) {
pendingPatches.push([
klass,
methodName,
func
]);
return false;
}
klass = x.prototype;
}
var origMethod = klass[methodName];
klass[methodName] = function () {
var self = this, args = arguments;
return func.apply({
self: self,
next: function () {
return origMethod.apply(self, arguments.length > 0 ? arguments : args);
}
}, args);
};
return true;
}
kendo.onWidgetRegistered(function (entry) {
pendingPatches = $.grep(pendingPatches, function (args) {
return !defadvice.apply(null, args);
});
createDirectives(entry.widget, entry.prefix == 'Mobile');
});
defadvice([
'ui.Widget',
'mobile.ui.Widget'
], 'angular', function (cmd, arg) {
var self = this.self;
if (cmd == 'init') {
if (!arg && OPTIONS_NOW) {
arg = OPTIONS_NOW;
}
OPTIONS_NOW = null;
if (arg && arg.$angular) {
self.$angular_scope = arg.$angular[0];
self.$angular_init(self.element, arg);
}
return;
}
var scope = self.$angular_scope;
if (scope) {
withoutTimeout(function () {
var x = arg(), elements = x.elements, data = x.data;
if (elements.length > 0) {
switch (cmd) {
case 'cleanup':
angular.forEach(elements, function (el) {
var itemScope = $(el).data('$$kendoScope');
if (itemScope && itemScope !== scope && itemScope.$$kendoScope) {
destroyScope(itemScope, el);
}
});
break;
case 'compile':
var injector = self.element.injector();
var compile = injector ? injector.get('$compile') : $defaultCompile;
angular.forEach(elements, function (el, i) {
var itemScope;
if (x.scopeFrom) {
itemScope = x.scopeFrom;
} else {
var vars = data && data[i];
if (vars !== undefined) {
itemScope = $.extend(scope.$new(), vars);
itemScope.$$kendoScope = true;
} else {
itemScope = scope;
}
}
$(el).data('$$kendoScope', itemScope);
compile(el)(itemScope);
});
digest(scope);
break;
}
}
});
}
});
defadvice('ui.Widget', '$angular_getLogicValue', function () {
return this.self.value();
});
defadvice('ui.Widget', '$angular_setLogicValue', function (val) {
this.self.value(val);
});
defadvice('ui.Select', '$angular_getLogicValue', function () {
var item = this.self.dataItem(), valueField = this.self.options.dataValueField;
if (item) {
if (this.self.options.valuePrimitive) {
if (!!valueField) {
return item[valueField];
} else {
return item;
}
} else {
return item.toJSON();
}
} else {
return null;
}
});
defadvice('ui.Select', '$angular_setLogicValue', function (val) {
var self = this.self;
var options = self.options;
var valueField = options.dataValueField;
var text = options.text || '';
if (val === undefined) {
val = '';
}
if (valueField && !options.valuePrimitive && val) {
text = val[options.dataTextField] || '';
val = val[valueField || options.dataTextField];
}
if (self.options.autoBind === false && !self.listView.bound()) {
if (!text && val && options.valuePrimitive) {
self.value(val);
} else {
self._preselect(val, text);
}
} else {
self.value(val);
}
});
defadvice('ui.MultiSelect', '$angular_getLogicValue', function () {
var value = this.self.dataItems().slice(0);
var valueField = this.self.options.dataValueField;
if (valueField && this.self.options.valuePrimitive) {
value = $.map(value, function (item) {
return item[valueField];
});
}
return value;
});
defadvice('ui.MultiSelect', '$angular_setLogicValue', function (val) {
if (val == null) {
val = [];
}
var self = this.self;
var options = self.options;
var valueField = options.dataValueField;
var data = val;
if (valueField && !options.valuePrimitive) {
val = $.map(val, function (item) {
return item[valueField];
});
}
if (options.autoBind === false && !options.valuePrimitive && !self.listView.bound()) {
self._preselect(data, val);
} else {
self.value(val);
}
});
defadvice('ui.AutoComplete', '$angular_getLogicValue', function () {
var options = this.self.options;
var values = this.self.value().split(options.separator);
var valuePrimitive = options.valuePrimitive;
var data = this.self.dataSource.data();
var dataItems = [];
for (var idx = 0, length = data.length; idx < length; idx++) {
var item = data[idx];
var dataValue = options.dataTextField ? item[options.dataTextField] : item;
for (var j = 0; j < values.length; j++) {
if (dataValue === values[j]) {
if (valuePrimitive) {
dataItems.push(dataValue);
} else {
dataItems.push(item.toJSON());
}
break;
}
}
}
return dataItems;
});
defadvice('ui.AutoComplete', '$angular_setLogicValue', function (value) {
if (value == null) {
value = [];
}
var self = this.self, dataTextField = self.options.dataTextField;
if (dataTextField && !self.options.valuePrimitive) {
if (value.length !== undefined) {
value = $.map(value, function (item) {
return item[dataTextField];
});
} else {
value = value[dataTextField];
}
}
self.value(value);
});
defadvice('ui.Widget', '$angular_init', function (element, options) {
var self = this.self;
if (options && !$.isArray(options)) {
var scope = self.$angular_scope;
for (var i = self.events.length; --i >= 0;) {
var event = self.events[i];
var handler = options[event];
if (handler && typeof handler == 'string') {
options[event] = self.$angular_makeEventHandler(event, scope, handler);
}
}
}
});
defadvice('ui.Widget', '$angular_makeEventHandler', function (event, scope, handler) {
handler = $parse(handler);
return function (e) {
digest(scope, function () {
handler(scope, { kendoEvent: e });
});
};
});
defadvice([
'ui.Grid',
'ui.ListView',
'ui.TreeView'
], '$angular_makeEventHandler', function (event, scope, handler) {
if (event != 'change') {
return this.next();
}
handler = $parse(handler);
return function (ev) {
var widget = ev.sender;
var options = widget.options;
var cell, multiple, locals = { kendoEvent: ev }, elems, items, columns, colIdx;
if (angular.isString(options.selectable)) {
cell = options.selectable.indexOf('cell') !== -1;
multiple = options.selectable.indexOf('multiple') !== -1;
}
elems = locals.selected = this.select();
items = locals.data = [];
columns = locals.columns = [];
for (var i = 0; i < elems.length; i++) {
var item = cell ? elems[i].parentNode : elems[i];
var dataItem = widget.dataItem(item);
if (cell) {
if (angular.element.inArray(dataItem, items) < 0) {
items.push(dataItem);
}
colIdx = angular.element(elems[i]).index();
if (angular.element.inArray(colIdx, columns) < 0) {
columns.push(colIdx);
}
} else {
items.push(dataItem);
}
}
if (!multiple) {
locals.dataItem = locals.data = items[0];
locals.angularDataItem = kendo.proxyModelSetters(locals.dataItem);
locals.selected = elems[0];
}
digest(scope, function () {
handler(scope, locals);
});
};
});
defadvice('ui.Grid', '$angular_init', function (element, options) {
this.next();
if (options.columns) {
var settings = $.extend({}, kendo.Template, options.templateSettings);
angular.forEach(options.columns, function (col) {
if (col.field && !col.template && !col.format && !col.values && (col.encoded === undefined || col.encoded)) {
col.template = '
#: ' + kendo.expr(col.field, settings.paramName) + '#';
}
});
}
});
{
defadvice('mobile.ui.ButtonGroup', 'value', function (mew) {
var self = this.self;
if (mew != null) {
self.select(self.element.children('li.km-button').eq(mew));
self.trigger('change');
self.trigger('select', { index: self.selectedIndex });
}
return self.selectedIndex;
});
defadvice('mobile.ui.ButtonGroup', '_select', function () {
this.next();
this.self.trigger('change');
});
}
module.directive('kendoMobileApplication', function () {
return {
terminal: true,
link: function (scope, element, attrs) {
createWidget(scope, element, attrs, 'kendoMobileApplication', 'kendoMobileApplication');
}
};
}).directive('kendoMobileView', function () {
return {
scope: true,
link: {
pre: function (scope, element, attrs) {
attrs.defaultOptions = scope.viewOptions;
attrs._instance = createWidget(scope, element, attrs, 'kendoMobileView', 'kendoMobileView');
},
post: function (scope, element, attrs) {
attrs._instance._layout();
attrs._instance._scroller();
}
}
};
}).directive('kendoMobileDrawer', function () {
return {
scope: true,
link: {
pre: function (scope, element, attrs) {
attrs.defaultOptions = scope.viewOptions;
attrs._instance = createWidget(scope, element, attrs, 'kendoMobileDrawer', 'kendoMobileDrawer');
},
post: function (scope, element, attrs) {
attrs._instance._layout();
attrs._instance._scroller();
}
}
};
}).directive('kendoMobileModalView', function () {
return {
scope: true,
link: {
pre: function (scope, element, attrs) {
attrs.defaultOptions = scope.viewOptions;
attrs._instance = createWidget(scope, element, attrs, 'kendoMobileModalView', 'kendoMobileModalView');
},
post: function (scope, element, attrs) {
attrs._instance._layout();
attrs._instance._scroller();
}
}
};
}).directive('kendoMobileSplitView', function () {
return {
terminal: true,
link: {
pre: function (scope, element, attrs) {
attrs.defaultOptions = scope.viewOptions;
attrs._instance = createWidget(scope, element, attrs, 'kendoMobileSplitView', 'kendoMobileSplitView');
},
post: function (scope, element, attrs) {
attrs._instance._layout();
}
}
};
}).directive('kendoMobilePane', function () {
return {
terminal: true,
link: {
pre: function (scope, element, attrs) {
attrs.defaultOptions = scope.viewOptions;
createWidget(scope, element, attrs, 'kendoMobilePane', 'kendoMobilePane');
}
}
};
}).directive('kendoMobileLayout', function () {
return {
link: {
pre: function (scope, element, attrs) {
createWidget(scope, element, attrs, 'kendoMobileLayout', 'kendoMobileLayout');
}
}
};
}).directive('kendoMobileActionSheet', function () {
return {
restrict: 'A',
link: function (scope, element, attrs) {
element.find('a[k-action]').each(function () {
$(this).attr('data-' + kendo.ns + 'action', $(this).attr('k-action'));
});
createWidget(scope, element, attrs, 'kendoMobileActionSheet', 'kendoMobileActionSheet');
}
};
}).directive('kendoMobilePopOver', function () {
return {
terminal: true,
link: {
pre: function (scope, element, attrs) {
attrs.defaultOptions = scope.viewOptions;
createWidget(scope, element, attrs, 'kendoMobilePopOver', 'kendoMobilePopOver');
}
}
};
}).directive('kendoViewTitle', function () {
return {
restrict: 'E',
replace: true,
template: function (element) {
return '
' + element.html() + '';
}
};
}).directive('kendoMobileHeader', function () {
return {
restrict: 'E',
link: function (scope, element) {
element.addClass('km-header').attr('data-role', 'header');
}
};
}).directive('kendoMobileFooter', function () {
return {
restrict: 'E',
link: function (scope, element) {
element.addClass('km-footer').attr('data-role', 'footer');
}
};
}).directive('kendoMobileScrollViewPage', function () {
return {
restrict: 'E',
replace: true,
template: function (element) {
return '
' + element.html() + '
';
}
};
});
angular.forEach([
'align',
'icon',
'rel',
'transition',
'actionsheetContext'
], function (attr) {
var kAttr = 'k' + attr.slice(0, 1).toUpperCase() + attr.slice(1);
module.directive(kAttr, function () {
return {
restrict: 'A',
priority: 2,
link: function (scope, element, attrs) {
element.attr(kendo.attr(kendo.toHyphens(attr)), scope.$eval(attrs[kAttr]));
}
};
});
});
var WIDGET_TEMPLATE_OPTIONS = {
'TreeMap': ['Template'],
'MobileListView': [
'HeaderTemplate',
'Template'
],
'MobileScrollView': [
'EmptyTemplate',
'Template'
],
'Grid': [
'AltRowTemplate',
'DetailTemplate',
'RowTemplate'
],
'ListView': [
'EditTemplate',
'Template',
'AltTemplate'
],
'Pager': [
'SelectTemplate',
'LinkTemplate'
],
'PivotGrid': [
'ColumnHeaderTemplate',
'DataCellTemplate',
'RowHeaderTemplate'
],
'Scheduler': [
'AllDayEventTemplate',
'DateHeaderTemplate',
'EventTemplate',
'MajorTimeHeaderTemplate',
'MinorTimeHeaderTemplate'
],
'TreeView': ['Template'],
'Validator': ['ErrorTemplate']
};
(function () {
var templateDirectives = {};
angular.forEach(WIDGET_TEMPLATE_OPTIONS, function (templates, widget) {
angular.forEach(templates, function (template) {
if (!templateDirectives[template]) {
templateDirectives[template] = [];
}
templateDirectives[template].push('?^^kendo' + widget);
});
});
angular.forEach(templateDirectives, function (parents, directive) {
var templateName = 'k' + directive;
var attrName = kendo.toHyphens(templateName);
module.directive(templateName, function () {
return {
restrict: 'A',
require: parents,
terminal: true,
compile: function ($element, $attrs) {
if ($attrs[templateName] !== '') {
return;
}
$element.removeAttr(attrName);
var template = $element[0].outerHTML;
return function (scope, element, attrs, controllers) {
var controller;
while (!controller && controllers.length) {
controller = controllers.shift();
}
if (!controller) {
$log.warn(attrName + ' without a matching parent widget found. It can be one of the following: ' + parents.join(', '));
} else {
controller.template(templateName, template);
$element.remove();
}
};
}
};
});
});
}());
}(window.kendo.jQuery, window.angular));
return window.kendo;
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('kendo.webcomponents', ['kendo.core'], f);
}(function () {
var __meta__ = {
id: 'webcomponents',
name: 'Web Components',
category: 'framework',
description: 'Adds Kendo UI custom elements for Web Components',
depends: ['core']
};
(function ($, angular, undefined) {
if (!kendo.support.customElements || kendo.webComponents.length) {
return;
}
if (angular && (angular.version.major == 1 || angular.injector)) {
return;
}
var TAGNAMES = {
editor: 'textarea',
numerictextbox: 'input',
datepicker: 'input',
datetimepicker: 'input',
timepicker: 'input',
autocomplete: 'input',
colorpicker: 'input',
maskedtextbox: 'input',
dropdownlist: 'select',
multiselect: 'select',
upload: 'input',
validator: 'form',
button: 'button',
mobilebutton: 'a',
mobilebackbutton: 'a',
mobiledetailbutton: 'a',
listview: 'ul',
mobilelistview: 'ul',
treeview: 'ul',
menu: 'ul',
contextmenu: 'ul',
actionsheet: 'ul'
};
var EVENT_PREFIX = 'on-';
var registered = [];
kendo.onWidgetRegistered(function (entry) {
var elementName = entry.prefix + entry.widget.prototype.options.name.toLowerCase();
if (registered.indexOf(elementName) === -1) {
registered.push(elementName);
registerElement(elementName, entry.widget);
}
});
var jsonRegExp = /^\s*(?:\{(?:.|\r\n|\n)*\}|\[(?:.|\r\n|\n)*\])\s*$/;
var jsonFormatRegExp = /^\{(\d+)(:[^\}]+)?\}|^\[[A-Za-z_]*\]$/;
var numberRegExp = /^(\+|-?)\d+(\.?)\d*$/;
function parseOption(element, option) {
var value = element.getAttribute(option);
if (value === null) {
value = undefined;
} else if (value === 'null') {
value = null;
} else if (value === 'true') {
value = true;
} else if (value === 'false') {
value = false;
} else if (numberRegExp.test(value)) {
value = parseFloat(value);
} else if (jsonRegExp.test(value) && !jsonFormatRegExp.test(value)) {
value = new Function('return (' + value + ')')();
}
return value;
}
function parseOptions(element, options) {
var result = {};
Object.keys(options).concat('dataSource').forEach(function (name) {
if (element.hasAttribute(kendo.toHyphens(name))) {
result[name] = parseOption(element, kendo.toHyphens(name));
}
});
return result;
}
function cloneEvent(e) {
var result = {};
Object.keys(e).forEach(function (key) {
if (key[0] != '_') {
result[key] = e[key];
}
});
return result;
}
function eventHandler(eventName, e) {
var event = document.createEvent('CustomEvent');
event.initCustomEvent(eventName, false, true, cloneEvent(e));
this.dispatchEvent(event);
if (event.defaultPrevented) {
e.preventDefault();
}
}
function expose(component, obj) {
var props = Object.keys(obj);
for (var idx = 0; idx <= props.length; idx++) {
if (typeof obj[props[idx]] === 'function') {
if (!component[props[idx]]) {
component[props[idx]] = obj[props[idx]].bind(component.widget);
}
} else {
if (props[idx] === 'options') {
continue;
}
component[props[idx]] = component[props[idx]] || obj[props[idx]];
}
}
}
function registerElement(name, widget) {
var options = widget.prototype.options;
var prototype = Object.create(HTMLElement.prototype);
Object.defineProperty(prototype, 'options', {
get: function () {
return this.widget.options;
},
set: function (options) {
var instance = this.widget;
options = $.extend(true, {}, instance.options, options);
var _wrapper = $(instance.wrapper)[0];
var _element = $(instance.element)[0];
instance._destroy();
var newElement = document.createElement(TAGNAMES[name] || 'div');
if (_wrapper && _element) {
_wrapper.parentNode.replaceChild(_element, _wrapper);
$(_element).replaceWith(newElement);
}
if (instance.value) {
options.value = instance.value();
}
instance.init(newElement, options);
this.bindEvents();
}
});
prototype.bindEvents = function () {
widget.prototype.events.forEach(function (eventName) {
this.widget.bind(eventName, eventHandler.bind(this, eventName));
if (this.hasAttribute(EVENT_PREFIX + eventName)) {
this.bind(eventName, function (e) {
window[this.getAttribute(EVENT_PREFIX + eventName)].call(this, e);
}.bind(this));
}
}.bind(this));
};
prototype.attachedCallback = function () {
var that = this;
var element = document.createElement(TAGNAMES[name] || 'div');
$(element).append(that.childNodes);
$(element).attr('class', $(that).attr('class'));
$(element).attr('style', $(that).attr('style'));
that.appendChild(element);
that.widget = new widget(element, parseOptions(that, options));
var obj = that.widget;
do {
expose(that, obj);
} while (obj = Object.getPrototypeOf(obj));
this.bindEvents();
};
prototype.detachedCallback = function () {
kendo.destroy(this.element);
};
kendo.webComponents.push('kendo-' + name);
document.registerElement('kendo-' + name, { prototype: prototype });
}
}(window.kendo.jQuery, window.angular));
return window.kendo;
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('kendo.angular2', [
'kendo.core',
'kendo.webcomponents'
], f);
}(function () {
var __meta__ = {
id: 'angular2',
name: 'Angular 2',
category: 'framework',
description: 'Supports angular2 value accessors',
depends: ['core']
};
(function (kendo, System) {
if (!System || !System.register) {
return;
}
var __decorate = this && this.__decorate || function (decorators, target, key, desc) {
if (typeof Reflect === 'object' && typeof Reflect.decorate === 'function') {
return Reflect.decorate(decorators, target, key, desc);
}
switch (arguments.length) {
case 2:
return decorators.reduceRight(function (o, d) {
return d && d(o) || o;
}, target);
case 3:
return decorators.reduceRight(function (o, d) {
return d && d(target, key), void 0;
}, void 0);
case 4:
return decorators.reduceRight(function (o, d) {
return d && d(target, key, o) || o;
}, desc);
}
};
var __metadata = this && this.__metadata || function (k, v) {
if (typeof Reflect === 'object' && typeof Reflect.metadata === 'function') {
return Reflect.metadata(k, v);
}
};
System.register('kendo/angular2', ['angular2/angular2'], function (exports_1) {
var angular2_1;
var KendoValueAccessor;
return {
setters: [function (_angular2_1) {
angular2_1 = _angular2_1;
}],
execute: function () {
KendoValueAccessor = function () {
function KendoValueAccessor(cd, elementRef) {
var _this = this;
this.elementRef = elementRef;
this.onChange = function (_) {
};
this.onTouched = function () {
};
this.element = elementRef.nativeElement;
this.element.addEventListener('change', function () {
_this.onChange(_this.element.value());
});
this.element.addEventListener('spin', function () {
_this.onChange(_this.element.value());
});
cd.valueAccessor = this;
this.cd = cd;
cd.valueAccessor = this;
}
KendoValueAccessor.prototype.writeValue = function (value) {
this.element.value(value);
};
KendoValueAccessor.prototype.registerOnChange = function (fn) {
this.onChange = fn;
};
KendoValueAccessor.prototype.registerOnTouched = function (fn) {
this.onTouched = fn;
};
KendoValueAccessor = __decorate([
angular2_1.Directive({ selector: kendo.webComponents.join(',') }),
__metadata('design:paramtypes', [
angular2_1.NgControl,
angular2_1.ElementRef
])
], KendoValueAccessor);
return KendoValueAccessor;
}();
exports_1('KendoValueAccessor', KendoValueAccessor);
}
};
});
}(window.kendo, window.System));
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));
(function (f, define) {
define('kendo.web', [
'kendo.core',
'kendo.router',
'kendo.view',
'kendo.fx',
'kendo.dom',
'kendo.data.odata',
'kendo.data.xml',
'kendo.data',
'kendo.ooxml',
'kendo.excel',
'kendo.data.signalr',
'kendo.binder',
'kendo.drawing',
'kendo.validator',
'kendo.userevents',
'kendo.draganddrop',
'kendo.mobile.scroller',
'kendo.groupable',
'kendo.reorderable',
'kendo.resizable',
'kendo.sortable',
'kendo.selectable',
'kendo.button',
'kendo.pager',
'kendo.popup',
'kendo.notification',
'kendo.tooltip',
'kendo.list',
'kendo.calendar',
'kendo.datepicker',
'kendo.autocomplete',
'kendo.dropdownlist',
'kendo.combobox',
'kendo.multiselect',
'kendo.colorpicker',
'kendo.columnmenu',
'kendo.columnsorter',
'kendo.grid',
'kendo.listview',
'kendo.filebrowser',
'kendo.imagebrowser',
'kendo.editor',
'kendo.numerictextbox',
'kendo.maskedtextbox',
'kendo.menu',
'kendo.editable',
'kendo.pivot.fieldmenu',
'kendo.filtercell',
'kendo.panelbar',
'kendo.progressbar',
'kendo.responsivepanel',
'kendo.tabstrip',
'kendo.timepicker',
'kendo.toolbar',
'kendo.datetimepicker',
'kendo.treeview.draganddrop',
'kendo.treeview',
'kendo.slider',
'kendo.splitter',
'kendo.upload',
'kendo.window',
'kendo.virtuallist',
'kendo.scheduler.view',
'kendo.scheduler.dayview',
'kendo.scheduler.agendaview',
'kendo.scheduler.monthview',
'kendo.scheduler.recurrence',
'kendo.scheduler',
'kendo.gantt.list',
'kendo.gantt.timeline',
'kendo.gantt',
'kendo.treelist',
'kendo.pivotgrid',
'kendo.spreadsheet',
'kendo.pivot.configurator',
'kendo.angular',
'kendo.webcomponents',
'kendo.angular2'
], f);
}(function () {
'bundle all';
return window.kendo;
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));