@progress/kendo-ui
Version:
This package is part of the [Kendo UI for jQuery](http://www.telerik.com/kendo-ui) suite.
1,351 lines (1,155 loc) • 625 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
require('./kendo.combobox.js');
require('./kendo.dropdownlist.js');
require('./kendo.resizable.js');
require('./kendo.window.js');
require('./kendo.colorpicker.js');
require('./kendo.imagebrowser.js');
require('./kendo.numerictextbox.js');
require('./kendo.textarea.js');
require('./kendo.core.js');
require('./kendo.toolbar.js');
require('./kendo.icons.js');
require('./kendo.form.js');
require('./kendo.filebrowser.js');
require('./kendo.draganddrop.js');
require('./kendo.html.button.js');
require('./kendo.tabstrip.js');
require('./kendo.list.js');
require('./kendo.data.js');
require('./kendo.data.odata.js');
require('./kendo.licensing.js');
require('@progress/kendo-licensing');
require('./kendo.data.xml.js');
require('./kendo.popup.js');
require('./kendo.label.js');
require('./kendo.floatinglabel.js');
require('./kendo.actionsheet.js');
require('./kendo.html.icon.js');
require('./kendo.html.base.js');
require('@progress/kendo-svg-icons');
require('./dropdowns-loader-Bc4IELFi.js');
require('./kendo.mobile.scroller.js');
require('./kendo.fx.js');
require('./kendo.userevents.js');
require('./kendo.virtuallist.js');
require('./valueMapper-q_OtZ-Tj.js');
require('./prefix-suffix-containers-BmDm564f.js');
require('./kendo.color.js');
require('@progress/kendo-drawing');
require('./kendo.slider.js');
require('./kendo.button.js');
require('./kendo.badge.js');
require('./kendo.binder.js');
require('./kendo.textbox.js');
require('./kendo.listview.js');
require('./kendo.editable.js');
require('./kendo.checkbox.js');
require('./kendo.toggleinputbase.js');
require('./kendo.html.input.js');
require('./kendo.datepicker.js');
require('./kendo.calendar.js');
require('./kendo.selectable.js');
require('./kendo.dateinput.js');
require('@progress/kendo-dateinputs-common');
require('./kendo.validator.js');
require('./kendo.otpinput.js');
require('./kendo.pager.js');
require('./kendo.upload.js');
require('./kendo.progressbar.js');
require('./kendo.breadcrumb.js');
require('./kendo.splitbutton.js');
require('./kendo.button.menu.js');
require('./kendo.dropdownbutton.js');
require('./kendo.buttongroup.js');
require('./kendo.togglebutton.js');
require('./kendo.menu.js');
require('./kendo.sortable.js');
(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);
(function($,undefined$1) {
// Imports ================================================================
var kendo = window.kendo,
Class = kendo.Class,
Widget = kendo.ui.Widget,
os = kendo.support.mobileOS,
browser = kendo.support.browser,
extend = $.extend,
deepExtend = kendo.deepExtend,
keys = kendo.keys,
outerWidth = kendo._outerWidth,
outerHeight = kendo._outerHeight,
NS = ".kendoEditor";
const FORMATTING_MARKS_STYLE_ID = "formatting-marks-style",
FORMATTING_MARKS_OVERLAY_ID = "formatting-marks-overlay",
FORMATTING_MARKS_OVERLAY_WRAPPER_ID = "formatting-marks-overlay-wrapper";
var SELECT = "select";
var SELECT_OVERLAY_SELECTOR = "select.k-select-overlay";
var PLACEHOLDER_CLASS = "k-placeholder";
var PLACEHOLDER_TAG_ID = "placeholder";
var REFRESH_INTERVAL = 200;
var DEFAULT_LANGUAGE = "en";
var NATIVE_TOOLS = [
"insertLineBreak",
"insertParagraph",
"redo",
"undo",
"autoLink"
];
const TOOLBAR_ALLOWED_CLOSE_SELECTORS = ".k-icon,.k-svg-icon,svg,path,.k-editor-window,.k-editor-toolbar,.k-editortoolbar-dragHandle,[ref-toolbar-tool],[ref-toolbar-tool] *";
var EditorUtils = {
editorWrapperTemplate: () =>
'<div class="k-editor">' +
'<div class="k-editor-toolbar" role="toolbar"></div>' +
'<div class="k-editable-area k-editor-content"></div>' +
'</div>',
formatByName: function(name, format) {
for (var i = 0; i < format.length; i++) {
if ($.inArray(name, format[i].tags) >= 0) {
return format[i];
}
}
},
getToolCssClass: function(name, icon) {
var toolCssClassNames = {
superscript: "supscript",
subscript: "subscript",
justifyLeft: "align-left",
justifyCenter: "align-center",
justifyRight: "align-right",
justifyFull: "align-justify",
insertUnorderedList: "list-unordered",
insertOrderedList: "list-ordered",
insertUpperRomanList: "list-roman-upper",
insertLowerRomanList: "list-roman-lower",
"import": "import",
indent: "indent",
outdent: "outdent",
createLink: "link",
unlink: "unlink",
insertImage: "image",
insertFile: "file-add",
viewHtml: "code",
foreColor: "foreground-color",
backColor: "droplet",
createTable: "table-add",
addColumnLeft: "table-column-insert-left",
addColumnRight: "table-column-insert-right",
addRowAbove: "table-row-insert-above",
addRowBelow: "table-row-insert-below",
deleteRow: "table-row-delete",
deleteColumn: "table-column-delete",
mergeCellsHorizontally: "cells-merge-horizontally",
mergeCellsVertically: "cells-merge-vertically",
splitCellHorizontally: "cell-split-horizontally",
splitCellVertically: "cell-split-vertically",
tableProperties: "table-properties",
tableCellProperties: "table-cell-properties",
tableWizardInsert: "table-wizard",
tableAlignLeft: "table-position-start",
tableAlignCenter: "table-position-center",
tableAlignRight: "table-position-end",
cleanFormatting: "clear-css",
copyFormat: "copy-format",
applyFormat: "apply-format",
pdf: "file-pdf"
};
var cssClass = toolCssClassNames[name];
if (cssClass) {
return cssClass;
}
if (icon) {
return icon;
}
return EditorUtils.nameToKebab(name);
},
nameToKebab: function(name) {
return name.replace(/([a-z])([A-Z])/g, "$1-$2")
.replace(/[\s_]+/g, '-')
.toLowerCase();
},
registerTool: function(toolName, tool) {
if (!tool.name) {
tool.options.name = toolName;
tool.name = toolName.toLowerCase();
}
if (!tool.options.ui) {
tool.options.ui = {};
}
tool.options.ui.command = toolName;
Editor.defaultTools[toolName] = tool;
},
registerFormat: function(formatName, format) {
Editor.fn.options.formats[formatName] = format;
},
cacheComments: function(content, comments) {
for (var index in comments) {
content = content.replace(comments[index], "{" + index + "}");
}
return content;
},
retrieveComments: function(content, comments) {
for (var index in comments) {
content = content.replace("{" + index + "}", comments[index]);
}
return content;
}
};
var messages = {
auto: "Auto",
bold: "Bold",
italic: "Italic",
underline: "Underline",
strikethrough: "Strikethrough",
superscript: "Superscript",
subscript: "Subscript",
fitToCell: "Fit to cell",
justifyCenter: "Center text",
justifyLeft: "Align text left",
justifyRight: "Align text right",
justifyFull: "Justify",
insertUnorderedList: "Insert unordered list",
insertOrderedList: "Insert ordered list",
lineHeight: "Set line height",
formattingMarks: "Toggle formatting marks",
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",
overflowAnchor: "More tools",
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",
fileText: "Text",
linkWebAddress: "Web address",
linkText: "Text",
linkToolTip: "ToolTip",
linkOpenInNewWindow: "Open link in new window",
dialogUpdate: "Update",
dialogInsert: "Insert",
dialogOk: "Confirm",
dialogCancel: "Cancel",
cleanFormatting: "Clean formatting",
createTable: "Create a 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",
mergeCellsHorizontally: "Merge cells horizontally",
mergeCellsVertically: "Merge cells vertically",
splitCellHorizontally: "Split cells horizontally",
splitCellVertically: "Split cells vertically",
tableAlignLeft: "Table Align Left",
tableAlignCenter: "Table Align Center",
tableAlignRight: "Table Align Right",
tableWizard: "Table Wizard",
tableProperties: "Table Properties",
tableCellProperties: "Cell Properties",
tableTab: "General",
cellTab: "Cell",
accessibilityTab: "Advanced",
caption: "Caption",
summary: "Summary",
width: "Width",
height: "Height",
units: "Units",
cellSpacing: "Cell Spacing",
cellPadding: "Cell Padding",
topPadding: "Top",
leftPadding: "Left",
bottomPadding: "Bottom",
rightPadding: "Right",
independentCellPaddings: "Independent Cell Paddings",
cellMargin: "Cell Margin",
alignment: "Alignment",
captionAlignment: "Caption alignment",
position: "Position",
background: "Background",
tableBackground: "Table background",
cssClass: "CSS Class",
id: "ID",
border: "Border",
borderStyle: "Border Style",
borderWidth: "Border Width",
borderColor: "Border Color",
collapseBorders: "Collapse borders",
wrapText: "Wrap text",
associateCellsWithHeaders: "Associate headers",
alignLeft: "Align Left",
alignCenter: "Align Center",
alignRight: "Align Right",
alignLeftTop: "Align Left Top",
alignCenterTop: "Align Center Top",
alignRightTop: "Align Right Top",
alignLeftMiddle: "Align Left Middle",
alignCenterMiddle: "Align Center Middle",
alignRightMiddle: "Align Right Middle",
alignLeftBottom: "Align Left Bottom",
alignCenterBottom: "Align Center Bottom",
alignRightBottom: "Align Right Bottom",
alignRemove: "Remove Alignment",
columns: "Columns",
rows: "Rows",
selectAllCells: "Apply to all cells",
applyToColumn: "apply to column",
applyToRow: "apply to row",
exportAs: "Export As",
"import": "Import",
print: "Print",
headerRows: "Header Rows",
headerColumns: "Header Cols",
tableSummaryPlaceholder: "Summary attribute is not HTML5 compatible.",
associateNone: "None",
associateScope: "Associate using 'scope' attribute",
associateIds: "Associate using Ids",
copyFormat: "Copy format",
applyFormat: "Apply format",
borderNone: "None",
undo: "Undo",
redo: "Redo"
};
var supportedContentEditable = typeof(document.documentElement.contentEditable) != 'undefined';
var toolGroups = {
basic: ["bold", "italic", "underline", "strikethrough"],
undo: ["undo", "redo"],
scripts: ["subscript", "superscript" ],
alignment: ["justifyLeft", "justifyCenter", "justifyRight", "justifyFull" ],
lines: ["lineHeight"],
symbols: ["formattingMarks"],
links: ["insertImage", "insertFile", "createLink", "unlink"],
lists: ["insertUnorderedList", "insertOrderedList", "insertUpperRomanList", "insertLowerRomanList",],
dent: ["indent", "outdent"],
tablesWizard: ["tableProperties", "tableCellProperties"],
tablesInsert: ["createTable"],
tablesAddDelete: [ "addColumnLeft", "addColumnRight", "addRowAbove", "addRowBelow", "deleteRow", "deleteColumn" ],
tablesMerge: [ "mergeCellsHorizontally", "mergeCellsVertically", "splitCellHorizontally", "splitCellVertically" ],
tablesPosition: [ "tableAlignLeft", "tableAlignCenter", "tableAlignRight" ],
formatPainter: [ "copyFormat", "applyFormat" ]
};
var Editor = Widget.extend({
__suppressEditableCheck: false,
init: function(element, options) {
var that = this,
editorNS = kendo.ui.editor,
dom = editorNS.Dom,
toolbarContainer,
type, domElement;
/* suppress initialization in devices w/o proper contenteditable support */
if (!supportedContentEditable && !that.__suppressEditableCheck) {
return;
}
Widget.fn.init.call(that, element, options);
that.options = deepExtend({}, that.options, options);
element = that.element;
domElement = element[0];
type = dom.name(domElement);
this._registerHandler(
element.closest("form"), "submit", that.update.bind(that, undefined$1)
);
toolbarContainer = that._setupType(element);
that._initToolbar(toolbarContainer);
that._setupHeight(type);
that._resizable();
that._initializeContentElement(that);
that._setupKeyboard();
that.clipboard = new editorNS.Clipboard(this);
that.undoRedoStack = new kendo.util.UndoRedoStack();
that._populateValue(options, domElement);
that._registerHandler(document, {
"mousedown": function() { that._endTyping(); },
"mouseup": function(e) { that._mouseup(e); }
});
that._registerHandler(window, "resize", that._handleSpaceAndNewLines.bind(that));
that._initializeImmutables();
if (type == "textarea") {
that._ariaLabel(that.wrapper.find("iframe"));
}
that.toolbar.resize();
that._initInlineOverflowWrapper();
kendo.notify(that);
if (that._showWatermarkOverlay) {
that._showWatermarkOverlay((that.wrapper && that.wrapper[0]) || that.element[0]);
}
},
events: [
"select",
"change",
"execute",
"error",
"paste",
"keydown",
"keyup"
],
options: {
name: "Editor",
messages: messages,
placeholder: "",
nonce: "",
unsafeInline: true,
formats: {},
encoded: true,
formattingMarksRefreshDelay: 250,
domain: null,
resizable: false,
deserialization: {
custom: null
},
serialization: {
entities: true,
semantic: true,
scripts: false,
optimizeTags: false,
keepEOL: false
},
pasteCleanup: {
all: false,
css: false,
custom: null,
keepNewLines: false,
msAllFormatting: false,
msConvertLists: true,
msTags: true,
none: false,
span: false
},
stylesheets: [],
dialogOptions: {
modal: true, resizable: false, draggable: true,
animation: false
},
imageBrowser: null,
fileBrowser: null,
navigateOnTab: false,
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: [
"formatting",
"bold",
"italic",
"underline",
"undo",
"redo",
"justifyLeft",
"justifyCenter",
"justifyRight",
"copyFormat",
"applyFormat",
"insertUnorderedList",
"insertOrderedList",
"indent",
"outdent",
"createLink",
"unlink",
"insertImage",
"tableProperties",
"tableCellProperties",
"createTable",
"addRowAbove",
"addRowBelow",
"addColumnLeft",
"addColumnRight",
"deleteRow",
"deleteColumn",
"mergeCellsHorizontally",
"mergeCellsVertically",
"splitCellHorizontally",
"splitCellVertically",
"tableAlignLeft",
"tableAlignCenter",
"tableAlignRight"
]
},
destroy: function() {
var editor = this;
Widget.fn.destroy.call(this);
this._endTyping(true);
this._deregisterHandlers();
clearTimeout(this._spellCorrectTimeout);
this._focusOutside();
this.toolbar.destroy();
if (this.windowInstance) {
this.windowInstance.destroy();
}
if (this.tablePopup) {
this.tablePopup.destroy();
}
editor._destroyUploadWidget();
if (this.interSectionObserver) {
this.interSectionObserver.disconnect();
this.interSectionObserver = null;
}
if (this.resizeObserver) {
this.resizeObserver.disconnect();
this.resizeObserver = null;
this.wrapper.css("min-height", "");
this.wrapper.css("max-height", "");
}
editor._destroyResizings();
editor._destroyFormattingMarksOverlay();
kendo.destroy(this.wrapper);
},
setOptions: function(options) {
var editor = this;
Widget.fn.setOptions.call(editor, options);
if (options.tools) {
this._setOptionsTools(options.tools);
}
this._initializePlaceholder();
},
createRange: function(document) {
return kendo.ui.editor.RangeUtils.createRange(document || this.document);
},
encodedValue: function() {
return kendo.ui.editor.Dom.encode(this.value());
},
exec: function(name, params) {
var that = this;
var command = null;
var defaultTools = kendo.ui.Editor.defaultTools;
var range, tool, prevented;
if (!name) {
throw new Error("kendoEditor.exec(): `name` parameter cannot be empty");
}
if (that.body.getAttribute("contenteditable") !== "true" &&
name !== "print" &&
name !== "pdf" &&
name !== "exportAs") {
return false;
}
if (!that.keyboard.isTypingInProgress()) {
that._focusBody();
that.selectRange(that._range || that.getRange());
}
tool = that.tools[name] || defaultTools[name];
if (!tool) {
Object.keys(defaultTools).map(key => {
if (key.toLowerCase() === name) {
tool = defaultTools[key];
}
});
}
if (tool) {
range = that.getRange();
if (tool.command) {
command = tool.command(extend({ range: range, body: that.body, immutables: !!that.immutables }, params));
}
prevented = that.trigger("execute", { name: name, command: command });
if (prevented) {
return;
}
if (/^(undo|redo)$/i.test(name)) {
that.undoRedoStack[name]();
} else if (command) {
that.execCommand(command);
if (command.async) {
command.change = that._commandChange.bind(that);
return;
}
}
// Prevent double execution when the formatting marks tool is used.
if (name !== "formattingMarks") {
that._handleSpaceAndNewLines();
}
that._selectionChange();
}
},
_commandChange: function() {
const that = this;
that._selectionChange();
that._handleSpaceAndNewLines();
},
execCommand: function(command) {
if (!command.managesUndoRedo) {
this.undoRedoStack.push(command);
}
command.editor = this;
command.exec();
},
focus: function() {
this.restoreSelection();
},
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;
},
getSelection: function() {
return kendo.ui.editor.SelectionUtils.selectionFromDocument(this.document);
},
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();
},
refresh: function() {
var that = this;
if (that.textarea) {
that._destroyResizings();
// preserve updated value before re-initializing
// don't use update() to prevent the editor from encoding the content too early
var value = that.value();
that.textarea.val(value);
that.wrapper.find("iframe").remove();
that._initializeContentElement(that);
that.value(value);
}
},
restoreSelection: function() {
this._focusBody();
if (this.selectionRestorePoint) {
this.selectRange(this.selectionRestorePoint.toRange());
}
},
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, body);
}
},
selectedHtml: function() {
return kendo.ui.editor.Serializer.domToXhtml(this.getRange().cloneContents());
},
selectRange: function(range) {
this._focusBody();
var selection = this.getSelection();
selection.removeAllRanges();
selection.addRange(range);
this.saveSelection(range);
},
state: function(toolName) {
var tool = kendo.ui.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;
},
update: function(value) {
value = value || this.options.encoded ? this.encodedValue() : this.value();
if (this.textarea) {
this.textarea.val(value);
this._togglePlaceholder(!value.trim());
} else {
this._oldValue = value;
}
},
value: function(html) {
var body = this.body,
editorNS = kendo.ui.editor,
options = this.options,
currentHtml = editorNS.Serializer.domToXhtml(body, options.serialization);
if (html === undefined$1) {
return currentHtml;
}
if (html == currentHtml) {
return;
}
editorNS.Serializer.htmlToDom(html, body, options.deserialization);
this.selectionRestorePoint = null;
this.update();
this._refreshTools();
},
_bindTools: function() {
var that = this,
defaultTools = this.tools;
that.unbind("select", that.toolbar.resize.bind(that.toolbar));
that.toolbar.element.find("[data-command]")
.filter((i, el) => $(el).find("[data-command]").length === 0)
.each((i, el) => {
var toolName = el.getAttribute("data-command"),
tool = defaultTools[toolName];
if (tool && tool.initialize) {
tool.initialize($(el), that);
}
});
that.bind("select", that.toolbar.resize.bind(that.toolbar));
},
_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");
if (textarea) {
textarea.trigger("change");
}
}
},
_containsRange: function(range) {
var dom = kendo.ui.editor.Dom;
var body = this.body;
return range && dom.isAncestorOrSelf(body, range.startContainer) &&
dom.isAncestorOrSelf(body, range.endContainer);
},
_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:""';
var lang = "";
textarea.hide();
iframe = $("<iframe />", { title: editor.options.messages.editAreaTitle, frameBorder: "0" })[0];
$(iframe)
.css("display", "")
.addClass("k-content k-iframe")
.attr("tabindex", textarea[0].tabIndex)
.insertBefore(textarea);
// automatically relax same-origin policy if document.domain != location.hostname,
// or forcefully relax if options.domain is specified (for document.domain = document.domain scenario)
if (specifiedDomain || domain != location.hostname) {
// relax same-origin policy
domainScript = `<script ${editor.options.nonce ? `nonce="${editor.options.nonce}"` : "" }>document.domain="${domain}"</script>`;
src = "javascript:document.write('" + domainScript + "')";
iframe.src = src;
}
if (!iframe.src) {
iframe.src = "";
}
wnd = iframe.contentWindow || iframe;
doc = wnd.document || iframe.contentDocument;
// https://github.com/telerik/kendo-ui-core/issues/7561
const observer = editor.interSectionObserver = new IntersectionObserver(entries => {
for (const entry of entries) {
if (entry.isIntersecting) {
editor._decorateFormatting(doc.body);
observer.unobserve(iframe);
}
}
});
observer.observe(iframe);
lang = document.getElementsByTagName("html")[0].getAttribute("lang") || DEFAULT_LANGUAGE;
doc.open();
doc.write(
"<!DOCTYPE html><html lang='" + lang + "'><head>" +
"<meta charset='utf-8' />" +
"<title>Kendo UI Editor content</title>" +
`<style ${editor.options.nonce ? `nonce="${editor.options.nonce}"` : "" }>` +
"html{padding:0;margin:0;height:100%;min-height:100%;cursor:text;}" +
"body{padding:0;margin:0;}" +
"body{box-sizing:border-box;font-size:12px;font-family:Verdana,Geneva,sans-serif;margin-top:-1px;padding:5px .4em 0;" +
"word-wrap: break-word;-webkit-nbsp-mode: space;-webkit-line-break: after-white-space;" +
(kendo.support.isRtl(textarea) ? "direction:rtl;" : "") +
(os.ios ? "word-break:keep-all;" : "") +
(browser.edge || browser.chrome ? "height:100%;" : "") +
"}" +
"h1{font-size:2em;margin:.67em 0}h2{font-size:1.5em}h3{font-size:1.16em}h4{font-size:1em}h5{font-size:.83em}h6{font-size:.7em}" +
"p{margin:0 0 1em;}.k-marker{display:none;}.k-paste-container,.Apple-style-span{position:absolute;left:-10000px;width:1px;height:1px;overflow:hidden}" +
"ul,ol{padding-left:2.5em}" +
"span{-ms-high-contrast-adjust:none;}" +
"a{color:#00a}" +
"code{font-size:1.23em}" +
"telerik\\3Ascript{display: none;}" +
".k-table{width:100%;border-spacing:0;margin: 0 0 1em;}" +
".k-table td{min-width:1px;padding:.2em .3em;}" +
".k-table,.k-table td{outline:0;border: 1px dotted #ccc;}" +
".k-table th{outline:0;border: 1px dotted #999;}" +
".k-table p{margin:0;padding:0;}" +
".k-column-resize-handle-wrapper {position: absolute; height: 10px; width:10px; cursor: col-resize; z-index: 2;}" +
".k-column-resize-handle {width: 100%; height: 100%;}" +
".k-column-resize-handle > .k-column-resize-marker {width:2px; height:100%; margin:0 auto; background-color:#00b0ff; display:none; opacity:0.8;}" +
".k-row-resize-handle-wrapper {position: absolute; cursor: row-resize; z-index:2; width: 10px; height: 10px;}" +
".k-row-resize-handle {display: table; width: 100%; height: 100%;}" +
".k-row-resize-marker-wrapper{display: table-cell; height:100%; width:100%; margin:0; padding:0; vertical-align: middle;}" +
".k-row-resize-marker{margin: 0; padding:0; width:100%; height:2px; background-color: #00b0ff; opacity:0.8; display:none;}" +
".k-element-resize-handle-wrapper {position: absolute; background-color: #fff; border: 1px solid #000; z-index: 100; width: 5px; height: 5px;}" +
".k-element-resize-handle {width: 100%; height: 100%;}" +
".k-element-resize-handle.k-resize-east{cursor:e-resize;}" +
".k-element-resize-handle.k-resize-north{cursor:n-resize;}" +
".k-element-resize-handle.k-resize-northeast{cursor:ne-resize;}" +
".k-element-resize-handle.k-resize-northwest{cursor:nw-resize;}" +
".k-element-resize-handle.k-resize-south{cursor:s-resize;}" +
".k-element-resize-handle.k-resize-southeast{cursor:se-resize;}" +
".k-element-resize-handle.k-resize-southwest{cursor:sw-resize;}" +
".k-element-resize-handle.k-resize-west{cursor:w-resize;}" +
".k-table.k-element-resizing{opacity:0.6;}" +
".k-placeholder{color:grey}" +
"k\\:script{display:none;}" +
"</style>" +
domainScript +
$.map(stylesheets, function(href) {
return `<link rel='stylesheet' href='${href}' ${editor.options.nonce ? `nonce="${editor.options.nonce}"` : "" }>`;
}).join("") +
`</head><body id='${editor.element.attr("id")}' autocorrect='off' contenteditable='true'></body></html>`
);
doc.close();
return wnd;
},
_deleteSavedRange: function() {
if ("_range" in this) {
delete this._range;
}
},
_decorateFormatting: function(body) {
var formattingElement = this.toolbar.element.find("input[data-command=formatting]"),
dom = kendo.ui.editor.Dom,
component, dataSource, items, i, tag, className, style;
if (formattingElement.length) {
component = formattingElement.getKendoDropDownList();
if (!component) {
return;
}
dataSource = component.dataSource;
items = dataSource.data();
if (body) {
component.list.css("background-color", dom.getEffectiveBackground($(body)));
}
if (this.options.unsafeInline !== false) {
for (i = 0; i < items.length; i++) {
tag = items[i].tag || "span";
className = items[i].className;
style = dom.inlineStyle(body, tag, { className: className });
style = style.replace(/"/g, "'");
items[i].style = style + ";display:inline-block";
}
}
dataSource.trigger("change");
}
},
_appendFormattingMarksStyles: function() {
const that = this,
elementId = that.element.attr("id");
let style, $head;
style = `<style id='${FORMATTING_MARKS_STYLE_ID + "-" + elementId}' ${that.options.nonce ? `nonce="${that.options.nonce}"` : "" } >
#${elementId} p::after,
#${elementId} li::after,
#${elementId} h1::after,
#${elementId} h2::after,
#${elementId} h3::after,
#${elementId} h4::after,
#${elementId} h5::after,
#${elementId} h6::after {content: '\\00B6'; color: #6098f2;}
#${FORMATTING_MARKS_OVERLAY_WRAPPER_ID + "-" + elementId} {
position: absolute;
top: 0;
left: 0;
width: 100%;
z-index: 9999;
pointer-events: none;
}
#${FORMATTING_MARKS_OVERLAY_ID + "-" + elementId} {
width: 100%;
height: 100%;
}
</style>`;
$head = $(that.document.head);
$head.find("#" + FORMATTING_MARKS_STYLE_ID + "-" + elementId).remove();
$head.append(style);
},
_appendFormattingMarksOverlay: function() {
const that = this,
elementId = that.element.attr("id");
that._formattingMarksOverlayWrapper = $(`<div id='${FORMATTING_MARKS_OVERLAY_WRAPPER_ID + "-" + elementId}'></div>`);
that._formattingMarksOverlay = $(`<svg id='${FORMATTING_MARKS_OVERLAY_ID + "-" + elementId}'></svg>`).appendTo(that._formattingMarksOverlayWrapper);
that._bodyTopBottomPaddings = parseFloat($(that.body).css("padding-top")) + parseFloat($(that.body).css("padding-bottom"));
if (that._isInlineEditor()) {
that._formattingMarksOverlayWrapper.insertAfter(that.element);
} else {
that._formattingMarksOverlayWrapper.appendTo($(that.document).find("html"));
}
},
_destroyFormattingMarksOverlay: function() {
const that = this,
elementId = that.element.attr("id");
$(that.document).find("#" + FORMATTING_MARKS_OVERLAY_WRAPPER_ID + "-" + elementId).remove();
$(that.document.head).find("#" + FORMATTING_MARKS_STYLE_ID + "-" + elementId).remove();
},
_updateFormattingMarksOverlayHeight: function() {
const that = this;
if (that._isInlineEditor()) {
that._formattingMarksOverlayWrapper.height($(that.body).outerHeight());
} else {
that._formattingMarksOverlayWrapper.height(that.body.scrollHeight - that._bodyTopBottomPaddings);
}
},
_initInlineOverflowWrapper: function() {
const that = this,
inlineHeight = that.options.inlineHeight;
if (that._isInlineEditor() && inlineHeight > -1) {
that._inlineOverflowWrapper = that.element.wrap(`<div class='k-inline-editor-overflow-wrapper k-pos-relative k-overflow-auto'></div>`).parent();
that._inlineOverflowWrapper.height(inlineHeight);
}
},
_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 = [];
},
_destroyUploadWidget: function() {
var editor = this;
if (editor._uploadWidget) {
editor._uploadWidget.destroy();
editor._uploadWidget = null;
}
},
_endTyping: function() {
var keyboard = this.keyboard;
try {
if (keyboard.isTypingInProgress()) {
keyboard.endTyping(true);
this.saveSelection();
}
} catch (e) { }
},
_focusBody: function() {
var body = this.body;
var iframe = this.wrapper && this.wrapper.find("iframe")[0];
var documentElement = this.document.documentElement;
var activeElement = kendo._activeElement();
var scrollTop;
if (!iframe && body.scrollHeight > body.clientHeight) {
scrollTop = body.scrollTop;
body.focus();
body.scrollTop = scrollTop;
} else if (activeElement != body && activeElement != iframe) {
scrollTop = documentElement.scrollTop;
body.focus();
documentElement.scrollTop = scrollTop;
}
},
_focusOutside: function() {
// move focus outside the Editor, see https://github.com/telerik/kendo/issues/3673
if (kendo.support.browser.msie && this.textarea) {
var tempInput = $("<input />")
.css({
position: "fixed",
left: "1px",
top: "1px",
width: "1px",
height: "1px",
"font-size": "0",
border: "0",
opacity: "0"
})
.appendTo(document.body).trigger("focus");
tempInput.trigger("blur").remove();
}
},
_handleToolbarClick: function(e) {
var toolName = e.target.data("command");
if (toolName && toolName !== "createTable") {
this.exec(toolName);
}
},
_immutablesContext: function(range) {
var editorNS = kendo.ui.editor;
if (this.options.immutables) {
if (range.collapsed) {
return editorNS.Immutables.immutablesContext(range);
} else {
return editorNS.RangeUtils.editableTextNodes(range).length === 0;
}
}
},
_initializeContentElement: function() {
var editor = this;
var doc;
var blurTrigger;
var mousedownTrigger;
if (editor.textarea) {
editor.window = editor._createContentElement(editor.options.stylesheets);
doc = editor.document = editor.window.contentDocument || editor.window.document;
// Ensure that body exists as various Firefox plugins can cause a delay of the body creation
// https://github.com/telerik/kendo-ui-core/issues/3515
if (!doc.body) {
var body = doc.createElement("body");
body.setAttribute("contenteditable", "true");
body.setAttribute("autocorrect", "off");
doc.getElementsByTagName("html")[0].appendChild(body);
var interval = setInterval(function() {
if ($(editor.document).find("body").length > 1) {
$(editor.document).find("body").last().remove();
window.clearInterval(interval);
}
},10);
}
editor.body = doc.body;
blurTrigger = editor.window;
mousedownTrigger = doc;
this._registerHandler(doc, "mouseup", this._mouseup.bind(this));
} else {
editor.window = window;
doc = editor.document = document;
editor.body = editor.element[0];
blurTrigger = editor.body;
mousedownTrigger = editor.body;
const dom = kendo.ui.editor.Dom;
const childNodes = editor.body.childNodes;
if (childNodes.length === 1 && childNodes[0].nodeType === dom.nodeTypes.TEXT_NODE) {
dom.wrap(childNodes[0], doc.createElement("p"));
}
setTimeout(() => {
editor._decorateFormatting(editor.body);
});
}
this._registerHandler(blurTrigger, "blur", this._blur.bind(this));
editor._registerHandler(mousedownTrigger, "down", editor._mousedown.bind(editor));
try {
doc.execCommand("enableInlineTableEditing", null, false);
} catch (e) { }
if (kendo.support.touch) {
this._registerHandler(doc, {
"keydown": function() {
// necessary in iOS when touch events are bound to the page
if (kendo._activeElement() != doc.body) {
editor.window.focus();
}
}
});
}
this._initializePlaceholder();
this._spellCorrect(editor);
this._registerHandler(editor.document, {
"mouseover dragenter": function(e) {
var height = $(editor.body).height();
var htmlHeight = $(editor.body.parentElement).height();
if (htmlHeight > height && e.target.nodeName.toLowerCase() === "html") {
editor._cachedHeight = "" + editor.body.style.height;
editor.body.style.height = "100%";
}
},
"mouseout dragleave drop contextmenu": function(e) {
var restoreHeight = function() {
if (editor._cachedHeight !== undefined$1 && e.target === editor.body) {
editor.body.style.height = editor._cachedHeight;
delete editor._cachedHeight;
}
};
if (e.type === "contextmenu") {
setTimeout(function() {
restoreHeight();
}, 10);
} else {
restoreHeight();
}
}
});
this._registerHandler(editor.body, {
"keydown": function(e) {
var range;
if ((e.keyCode === keys.BACKSPACE || e.keyCode === keys.DELETE) && editor.body.getAttribute("contenteditable") !== "true") {