@progress/kendo-react-editor
Version:
Kendo UI for React Editor package
351 lines • 15 kB
JavaScript
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
var React = require("react");
var PropTypes = require("prop-types");
var kendo_react_buttons_1 = require("@progress/kendo-react-buttons");
var kendo_editor_common_1 = require("@progress/kendo-editor-common");
var schema_1 = require("./config/schema");
var defaultStyles_1 = require("./config/defaultStyles");
var toolsSettings_1 = require("./config/toolsSettings");
var main_1 = require("./dialogs/main");
var utils_1 = require("./utils");
var controlled_value_1 = require("./utils/controlled-value");
var link = toolsSettings_1.EditorToolsSettings.link, bold = toolsSettings_1.EditorToolsSettings.bold, italic = toolsSettings_1.EditorToolsSettings.italic, underline = toolsSettings_1.EditorToolsSettings.underline;
var browser_detection_1 = require("./utils/browser-detection");
var kendo_licensing_1 = require("@progress/kendo-licensing");
var package_metadata_1 = require("./package-metadata");
/**
* Represents the [KendoReact Editor component]({% slug overview_editor %}).
*
* @example
* ```jsx
* class App extends React.Component {
* render() {
* return (
* <Editor
* defaultContent="<p>Hello World</p>"
* tools={[
* [ EditorTools.Bold, EditorTools.Italic ]
* ]}
* />
* );
* }
* }
* ReactDOM.render(<App />, document.querySelector('my-app'));
* ```
*/
var Editor = /** @class */ (function (_super) {
__extends(Editor, _super);
function Editor(props) {
var _this = _super.call(this, props) || this;
/**
* @hidden
*/
_this.state = {
view: undefined,
linkDialog: false
};
_this.trOnChange = null;
_this.htmlOnChange = null;
/**
* @hidden
*/
_this.focus = function () {
if (_this.state.view) {
_this.state.view.focus();
}
};
_this.renderDialog = function (Component, settings, stateFlag) {
return _this.state[stateFlag] && (React.createElement(Component, { view: _this.state.view, settings: settings, dir: _this.props.dir, onClose: function () {
var _a;
return _this.setState((_a = {}, _a[stateFlag] = false, _a));
} }));
};
_this.renderTool = function (Tool, index) {
var tool = (React.createElement(Tool, { view: _this.state.view, dir: _this.props.dir, key: index }));
return tool.type === kendo_react_buttons_1.ToolbarSeparator ? React.createElement(Tool, { key: index }) : tool;
};
_this.updateTools = function (view, _prevViewState) {
_this.setState({ view: view });
};
_this.onPasteHtml = function (html) {
if (_this.props.onPasteHtml) {
var newHtml = _this.props.onPasteHtml.call(undefined, {
target: _this,
pastedHtml: html
});
if (typeof newHtml === 'string') {
return newHtml;
}
}
return html;
};
_this.dispatchTransaction = function (transaction) {
var docChanged = transaction.docChanged;
if (_this.props.onChange && docChanged) {
_this.trOnChange = transaction;
var doc_1 = transaction.doc, schema_2 = transaction.doc.type.schema;
var target_1 = _this;
_this.props.onChange.call(undefined, {
target: target_1,
value: doc_1,
get html() {
target_1.htmlOnChange = utils_1.EditorUtils.getHtml({ doc: doc_1, schema: schema_2 });
return target_1.htmlOnChange;
},
transaction: transaction,
schema: schema_2
});
}
if (_this.view && (_this.props.value === undefined || !docChanged)) {
_this.view.updateState(_this.view.state.apply(transaction));
}
};
_this.onFocus = function (_view, nativeEvent) {
if (_this.props.onFocus) {
_this.props.onFocus.call(undefined, { target: _this, nativeEvent: nativeEvent });
}
return false;
};
_this.onBlur = function (_view, nativeEvent) {
if (_this.props.onBlur) {
_this.props.onBlur.call(undefined, { target: _this, nativeEvent: nativeEvent });
}
return false;
};
kendo_licensing_1.validatePackage(package_metadata_1.packageMetadata);
return _this;
}
Object.defineProperty(Editor.prototype, "value", {
/**
* The value of the Editor.
*/
get: function () {
if (this.trOnChange !== null) {
return this.trOnChange.doc;
}
else if (this.props.value !== undefined) {
return this.props.value;
}
else if (this.view) {
return this.view.state.doc;
}
return this.props.defaultContent || '';
},
enumerable: true,
configurable: true
});
Object.defineProperty(Editor.prototype, "element", {
/**
* Returns the DOM element of the Editor.
*/
get: function () {
return this._element;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Editor.prototype, "contentElement", {
/**
* Returns the content-editable DOM element of the Editor.
*/
get: function () {
return this._contentElement;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Editor.prototype, "view", {
/**
* Returns the `view` object of the Editor.
*/
get: function () {
return this.state.view;
},
enumerable: true,
configurable: true
});
/**
* @hidden
*/
Editor.prototype.componentDidMount = function () {
if (!this.iframe || !browser_detection_1.firefox) {
this.initialize();
}
};
/**
* @hidden
*/
Editor.prototype.componentDidUpdate = function (prevProps) {
var value = this.props.value;
var view = this.view;
if (value === undefined || !view) {
return;
}
controlled_value_1.updateEditorValue(view, value, prevProps.value, this.trOnChange, this.htmlOnChange);
this.trOnChange = null;
this.htmlOnChange = null;
};
/**
* @hidden
*/
Editor.prototype.componentWillUnmount = function () {
if (this.state.view) {
this.state.view.destroy();
}
};
/**
* @hidden
*/
Editor.prototype.render = function () {
var _this = this;
var _a = this.props, _b = _a.tools, tools = _b === void 0 ? [] : _b, _c = _a.defaultEditMode, defaultEditMode = _c === void 0 ? 'iframe' : _c, style = _a.style, className = _a.className;
var contentStyle = this.props.contentStyle;
if (contentStyle === undefined && (style || {}).height === undefined) {
contentStyle = { height: '300px' };
}
var buttons = tools.map(function (item, index) {
return Array.isArray(item) ?
React.createElement(kendo_react_buttons_1.ButtonGroup, { key: index }, item.map(_this.renderTool, index)) :
_this.renderTool(item, index);
});
return (React.createElement("div", { ref: function (e) { return _this._element = e; }, className: 'k-widget k-editor' + (className ? " " + className : ''), dir: this.props.dir, style: style },
buttons.length > 0 && (React.createElement(kendo_react_buttons_1.Toolbar, { keyboardNavigation: this.props.keyboardNavigation }, buttons)),
defaultEditMode === 'iframe' ?
(React.createElement("div", { className: "k-editor-content" },
React.createElement("iframe", { onLoad: browser_detection_1.firefox ? function () {
_this.initialize();
} : undefined, ref: function (e) { return _this.iframe = e; }, frameBorder: "0", style: contentStyle, className: "k-iframe" }))) :
(React.createElement("div", { style: contentStyle, className: "k-editor-content" },
React.createElement("div", { ref: function (e) { return _this._contentElement = e; }, suppressContentEditableWarning: true }))),
this.renderDialog(main_1.EditorDialogs.InsertLinkDialog, link, 'linkDialog')));
};
Editor.prototype.initialize = function () {
var _this = this;
var iframeWindow = this.iframe && this.iframe.contentWindow;
if (iframeWindow) {
var iframeDocument_1 = iframeWindow.document;
[defaultStyles_1.defaultStyle, defaultStyles_1.tablesStyles, this.props.dir === 'rtl' ? defaultStyles_1.rtlStyles : undefined].forEach(function (styles) {
if (styles) {
var style = iframeDocument_1.createElement('style');
style.appendChild(iframeDocument_1.createTextNode(styles));
iframeDocument_1.head.appendChild(style);
}
});
var meta = iframeDocument_1.createElement('meta');
meta.setAttribute('charset', 'utf-8');
iframeDocument_1.head.appendChild(meta);
// The content has to be wrapped because the `dropCursor` plugin raises a `body.offsetParent is null` error.
this._contentElement = iframeDocument_1.createElement('div');
iframeDocument_1.body.appendChild(this._contentElement);
this._contentElement.classList.add('k-content');
}
var dom = this._contentElement;
if (!dom) {
return;
}
var target = this;
var plugins = [
// https://prosemirror.net/docs/ref/#state.PluginSpec
new kendo_editor_common_1.Plugin({
view: function () { return ({ update: _this.updateTools }); },
key: new kendo_editor_common_1.PluginKey('toolbar-tools-update-plugin')
}),
new kendo_editor_common_1.Plugin({
filterTransaction: function (transaction, state) {
return (_this.props.onExecute &&
_this.props.onExecute.call(undefined, { target: target, transaction: transaction, state: state })) !== false;
},
key: new kendo_editor_common_1.PluginKey('onExecute-event-plugin')
}),
kendo_editor_common_1.spacesFix(),
kendo_editor_common_1.history(),
kendo_editor_common_1.dropCursor(),
kendo_editor_common_1.gapCursor(),
kendo_editor_common_1.tableEditing()
];
var shortcuts = __assign({}, utils_1.EditorUtils.getShortcuts({
types: { listItem: 'list_item', hardBreak: 'hard_break' },
toolsSettings: { bold: bold, italic: italic, underline: underline }
}), { 'Mod-k': function () {
var _a = _this.state, linkDialog = _a.linkDialog, editorView = _a.view;
if (editorView) {
var editorState = editorView.state;
var collapsed = editorState.selection.empty;
var linkMark = kendo_editor_common_1.getMark(editorState, editorState.schema.marks[link.mark]);
var disabled = collapsed && !linkMark;
if (!linkDialog && !disabled) {
_this.setState({ linkDialog: true });
}
}
return !linkDialog;
} });
var _a = this.props, _b = _a.defaultContent, defaultContent = _b === void 0 ? '' : _b, value = _a.value, onMount = _a.onMount;
var doc = (value && typeof value !== 'string') ? value :
utils_1.EditorUtils.createDocument(new kendo_editor_common_1.Schema({ nodes: schema_1.nodes, marks: schema_1.marks }), (value || defaultContent));
var viewProps = {
state: kendo_editor_common_1.EditorState.create({
plugins: plugins.concat([kendo_editor_common_1.keymap(shortcuts), kendo_editor_common_1.keymap(kendo_editor_common_1.baseKeymap)]),
doc: doc
}),
transformPastedHTML: this.onPasteHtml,
dispatchTransaction: this.dispatchTransaction,
handleDOMEvents: {
focus: this.onFocus,
blur: this.onBlur
}
};
var view = (onMount && onMount.call(undefined, { plugins: plugins, shortcuts: shortcuts, target: target, viewProps: viewProps, dom: dom })) ||
new kendo_editor_common_1.EditorView({ mount: dom }, viewProps);
this.setState({
view: view
});
};
/**
* @hidden
*/
Editor.propTypes = {
defaultContent: PropTypes.string,
value: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
defaultEditMode: PropTypes.oneOf(['iframe', 'div']),
contentStyle: PropTypes.object,
dir: PropTypes.string,
className: PropTypes.string,
style: PropTypes.object,
tools: PropTypes.arrayOf(PropTypes.any),
keyboardNavigation: PropTypes.bool,
onMount: PropTypes.func,
onFocus: PropTypes.func,
onBlur: PropTypes.func,
onChange: PropTypes.func,
onPasteHtml: PropTypes.func,
onExecute: PropTypes.func
};
return Editor;
}(React.Component));
exports.default = Editor;
//# sourceMappingURL=Editor.js.map