1 | "use strict";
|
2 | var __extends = (this && this.__extends) || (function () {
|
3 | var extendStatics = function (d, b) {
|
4 | extendStatics = Object.setPrototypeOf ||
|
5 | ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
6 | function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
7 | return extendStatics(d, b);
|
8 | };
|
9 | return function (d, b) {
|
10 | if (typeof b !== "function" && b !== null)
|
11 | throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
12 | extendStatics(d, b);
|
13 | function __() { this.constructor = d; }
|
14 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
15 | };
|
16 | })();
|
17 | var __assign = (this && this.__assign) || function () {
|
18 | __assign = Object.assign || function(t) {
|
19 | for (var s, i = 1, n = arguments.length; i < n; i++) {
|
20 | s = arguments[i];
|
21 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
22 | t[p] = s[p];
|
23 | }
|
24 | return t;
|
25 | };
|
26 | return __assign.apply(this, arguments);
|
27 | };
|
28 | Object.defineProperty(exports, "__esModule", { value: true });
|
29 | exports.Editor = void 0;
|
30 | var React = require("react");
|
31 | var ScriptLoader2_1 = require("../ScriptLoader2");
|
32 | var TinyMCE_1 = require("../TinyMCE");
|
33 | var Utils_1 = require("../Utils");
|
34 | var EditorPropTypes_1 = require("./EditorPropTypes");
|
35 | var Editor = (function (_super) {
|
36 | __extends(Editor, _super);
|
37 | function Editor(props) {
|
38 | var _this = this;
|
39 | var _a, _b, _c;
|
40 | _this = _super.call(this, props) || this;
|
41 | _this.rollbackTimer = undefined;
|
42 | _this.valueCursor = undefined;
|
43 | _this.rollbackChange = function () {
|
44 | var editor = _this.editor;
|
45 | var value = _this.props.value;
|
46 | if (editor && value && value !== _this.currentContent) {
|
47 | editor.undoManager.ignore(function () {
|
48 | editor.setContent(value);
|
49 |
|
50 |
|
51 | if (_this.valueCursor && (!_this.inline || editor.hasFocus())) {
|
52 | try {
|
53 | editor.selection.moveToBookmark(_this.valueCursor);
|
54 | }
|
55 | catch (e) { }
|
56 | }
|
57 | });
|
58 | }
|
59 | _this.rollbackTimer = undefined;
|
60 | };
|
61 | _this.handleBeforeInput = function (_evt) {
|
62 | if (_this.props.value !== undefined && _this.props.value === _this.currentContent && _this.editor) {
|
63 | if (!_this.inline || _this.editor.hasFocus()) {
|
64 | try {
|
65 |
|
66 |
|
67 | _this.valueCursor = _this.editor.selection.getBookmark(3);
|
68 | }
|
69 | catch (e) { }
|
70 | }
|
71 | }
|
72 | };
|
73 | _this.handleBeforeInputSpecial = function (evt) {
|
74 | if (evt.key === 'Enter' || evt.key === 'Backspace' || evt.key === 'Delete') {
|
75 | _this.handleBeforeInput(evt);
|
76 | }
|
77 | };
|
78 | _this.handleEditorChange = function (_evt) {
|
79 | var editor = _this.editor;
|
80 | if (editor && editor.initialized) {
|
81 | var newContent = editor.getContent();
|
82 | if (_this.props.value !== undefined && _this.props.value !== newContent && _this.props.rollback !== false) {
|
83 |
|
84 | if (!_this.rollbackTimer) {
|
85 | _this.rollbackTimer = window.setTimeout(_this.rollbackChange, typeof _this.props.rollback === 'number' ? _this.props.rollback : 200);
|
86 | }
|
87 | }
|
88 | if (newContent !== _this.currentContent) {
|
89 | _this.currentContent = newContent;
|
90 | if ((0, Utils_1.isFunction)(_this.props.onEditorChange)) {
|
91 | _this.props.onEditorChange(newContent, editor);
|
92 | }
|
93 | }
|
94 | }
|
95 | };
|
96 | _this.handleEditorChangeSpecial = function (evt) {
|
97 | if (evt.key === 'Backspace' || evt.key === 'Delete') {
|
98 | _this.handleEditorChange(evt);
|
99 | }
|
100 | };
|
101 | _this.initialise = function (attempts) {
|
102 | var _a, _b, _c;
|
103 | if (attempts === void 0) { attempts = 0; }
|
104 | var target = _this.elementRef.current;
|
105 | if (!target) {
|
106 | return;
|
107 | }
|
108 | if (!(0, Utils_1.isInDoc)(target)) {
|
109 |
|
110 |
|
111 |
|
112 | if (attempts === 0) {
|
113 |
|
114 | setTimeout(function () { return _this.initialise(1); }, 1);
|
115 | }
|
116 | else if (attempts < 100) {
|
117 |
|
118 | setTimeout(function () { return _this.initialise(attempts + 1); }, 100);
|
119 | }
|
120 | else {
|
121 |
|
122 | throw new Error('tinymce can only be initialised when in a document');
|
123 | }
|
124 | return;
|
125 | }
|
126 | var tinymce = (0, TinyMCE_1.getTinymce)(_this.view);
|
127 | if (!tinymce) {
|
128 | throw new Error('tinymce should have been loaded into global scope');
|
129 | }
|
130 | var finalInit = __assign(__assign({}, _this.props.init), { selector: undefined, target: target, readonly: _this.props.disabled, inline: _this.inline, plugins: (0, Utils_1.mergePlugins)((_a = _this.props.init) === null || _a === void 0 ? void 0 : _a.plugins, _this.props.plugins), toolbar: (_b = _this.props.toolbar) !== null && _b !== void 0 ? _b : (_c = _this.props.init) === null || _c === void 0 ? void 0 : _c.toolbar, setup: function (editor) {
|
131 | _this.editor = editor;
|
132 | _this.bindHandlers({});
|
133 |
|
134 |
|
135 |
|
136 |
|
137 |
|
138 |
|
139 | if (_this.inline && !(0, Utils_1.isTextareaOrInput)(target)) {
|
140 | editor.once('PostRender', function (_evt) {
|
141 | editor.setContent(_this.getInitialValue(), { no_events: true });
|
142 | });
|
143 | }
|
144 | if (_this.props.init && (0, Utils_1.isFunction)(_this.props.init.setup)) {
|
145 | _this.props.init.setup(editor);
|
146 | }
|
147 | }, init_instance_callback: function (editor) {
|
148 | var _a, _b;
|
149 |
|
150 | var initialValue = _this.getInitialValue();
|
151 | _this.currentContent = (_a = _this.currentContent) !== null && _a !== void 0 ? _a : editor.getContent();
|
152 | if (_this.currentContent !== initialValue) {
|
153 | _this.currentContent = initialValue;
|
154 |
|
155 | editor.setContent(initialValue);
|
156 | editor.undoManager.clear();
|
157 | editor.undoManager.add();
|
158 | editor.setDirty(false);
|
159 | }
|
160 | var disabled = (_b = _this.props.disabled) !== null && _b !== void 0 ? _b : false;
|
161 | (0, Utils_1.setMode)(_this.editor, disabled ? 'readonly' : 'design');
|
162 |
|
163 | if (_this.props.init && (0, Utils_1.isFunction)(_this.props.init.init_instance_callback)) {
|
164 | _this.props.init.init_instance_callback(editor);
|
165 | }
|
166 | } });
|
167 | if (!_this.inline) {
|
168 | target.style.visibility = '';
|
169 | }
|
170 | if ((0, Utils_1.isTextareaOrInput)(target)) {
|
171 | target.value = _this.getInitialValue();
|
172 | }
|
173 | tinymce.init(finalInit);
|
174 | };
|
175 | _this.id = _this.props.id || (0, Utils_1.uuid)('tiny-react');
|
176 | _this.elementRef = React.createRef();
|
177 | _this.inline = (_c = (_a = _this.props.inline) !== null && _a !== void 0 ? _a : (_b = _this.props.init) === null || _b === void 0 ? void 0 : _b.inline) !== null && _c !== void 0 ? _c : false;
|
178 | _this.boundHandlers = {};
|
179 | return _this;
|
180 | }
|
181 | Object.defineProperty(Editor.prototype, "view", {
|
182 | get: function () {
|
183 | var _a, _b;
|
184 | return (_b = (_a = this.elementRef.current) === null || _a === void 0 ? void 0 : _a.ownerDocument.defaultView) !== null && _b !== void 0 ? _b : window;
|
185 | },
|
186 | enumerable: false,
|
187 | configurable: true
|
188 | });
|
189 | Editor.prototype.componentDidUpdate = function (prevProps) {
|
190 | var _this = this;
|
191 | var _a, _b;
|
192 | if (this.rollbackTimer) {
|
193 | clearTimeout(this.rollbackTimer);
|
194 | this.rollbackTimer = undefined;
|
195 | }
|
196 | if (this.editor) {
|
197 | this.bindHandlers(prevProps);
|
198 | if (this.editor.initialized) {
|
199 | this.currentContent = (_a = this.currentContent) !== null && _a !== void 0 ? _a : this.editor.getContent();
|
200 | if (typeof this.props.initialValue === 'string' && this.props.initialValue !== prevProps.initialValue) {
|
201 |
|
202 | this.editor.setContent(this.props.initialValue);
|
203 | this.editor.undoManager.clear();
|
204 | this.editor.undoManager.add();
|
205 | this.editor.setDirty(false);
|
206 | }
|
207 | else if (typeof this.props.value === 'string' && this.props.value !== this.currentContent) {
|
208 | var localEditor_1 = this.editor;
|
209 | localEditor_1.undoManager.transact(function () {
|
210 |
|
211 |
|
212 | var cursor;
|
213 | if (!_this.inline || localEditor_1.hasFocus()) {
|
214 | try {
|
215 |
|
216 |
|
217 | cursor = localEditor_1.selection.getBookmark(3);
|
218 | }
|
219 | catch (e) { }
|
220 | }
|
221 | var valueCursor = _this.valueCursor;
|
222 | localEditor_1.setContent(_this.props.value);
|
223 | if (!_this.inline || localEditor_1.hasFocus()) {
|
224 | for (var _i = 0, _a = [cursor, valueCursor]; _i < _a.length; _i++) {
|
225 | var bookmark = _a[_i];
|
226 | if (bookmark) {
|
227 | try {
|
228 | localEditor_1.selection.moveToBookmark(bookmark);
|
229 | _this.valueCursor = bookmark;
|
230 | break;
|
231 | }
|
232 | catch (e) { }
|
233 | }
|
234 | }
|
235 | }
|
236 | });
|
237 | }
|
238 | if (this.props.disabled !== prevProps.disabled) {
|
239 | var disabled = (_b = this.props.disabled) !== null && _b !== void 0 ? _b : false;
|
240 | (0, Utils_1.setMode)(this.editor, disabled ? 'readonly' : 'design');
|
241 | }
|
242 | }
|
243 | }
|
244 | };
|
245 | Editor.prototype.componentDidMount = function () {
|
246 | var _this = this;
|
247 | var _a, _b, _c, _d, _e;
|
248 | if ((0, TinyMCE_1.getTinymce)(this.view) !== null) {
|
249 | this.initialise();
|
250 | }
|
251 | else if (Array.isArray(this.props.tinymceScriptSrc) && this.props.tinymceScriptSrc.length === 0) {
|
252 | (_b = (_a = this.props).onScriptsLoadError) === null || _b === void 0 ? void 0 : _b.call(_a, new Error('No `tinymce` global is present but the `tinymceScriptSrc` prop was an empty array.'));
|
253 | }
|
254 | else if ((_c = this.elementRef.current) === null || _c === void 0 ? void 0 : _c.ownerDocument) {
|
255 | var successHandler = function () {
|
256 | var _a, _b;
|
257 | (_b = (_a = _this.props).onScriptsLoad) === null || _b === void 0 ? void 0 : _b.call(_a);
|
258 | _this.initialise();
|
259 | };
|
260 | var errorHandler = function (err) {
|
261 | var _a, _b;
|
262 | (_b = (_a = _this.props).onScriptsLoadError) === null || _b === void 0 ? void 0 : _b.call(_a, err);
|
263 | };
|
264 | ScriptLoader2_1.ScriptLoader.loadList(this.elementRef.current.ownerDocument, this.getScriptSources(), (_e = (_d = this.props.scriptLoading) === null || _d === void 0 ? void 0 : _d.delay) !== null && _e !== void 0 ? _e : 0, successHandler, errorHandler);
|
265 | }
|
266 | };
|
267 | Editor.prototype.componentWillUnmount = function () {
|
268 | var _this = this;
|
269 | var editor = this.editor;
|
270 | if (editor) {
|
271 | editor.off(this.changeEvents(), this.handleEditorChange);
|
272 | editor.off(this.beforeInputEvent(), this.handleBeforeInput);
|
273 | editor.off('keypress', this.handleEditorChangeSpecial);
|
274 | editor.off('keydown', this.handleBeforeInputSpecial);
|
275 | editor.off('NewBlock', this.handleEditorChange);
|
276 | Object.keys(this.boundHandlers).forEach(function (eventName) {
|
277 | editor.off(eventName, _this.boundHandlers[eventName]);
|
278 | });
|
279 | this.boundHandlers = {};
|
280 | editor.remove();
|
281 | this.editor = undefined;
|
282 | }
|
283 | };
|
284 | Editor.prototype.render = function () {
|
285 | return this.inline ? this.renderInline() : this.renderIframe();
|
286 | };
|
287 | Editor.prototype.changeEvents = function () {
|
288 | var _a, _b, _c;
|
289 | var isIE = (_c = (_b = (_a = (0, TinyMCE_1.getTinymce)(this.view)) === null || _a === void 0 ? void 0 : _a.Env) === null || _b === void 0 ? void 0 : _b.browser) === null || _c === void 0 ? void 0 : _c.isIE();
|
290 | return (isIE
|
291 | ? 'change keyup compositionend setcontent CommentChange'
|
292 | : 'change input compositionend setcontent CommentChange');
|
293 | };
|
294 | Editor.prototype.beforeInputEvent = function () {
|
295 | return (0, Utils_1.isBeforeInputEventAvailable)() ? 'beforeinput SelectionChange' : 'SelectionChange';
|
296 | };
|
297 | Editor.prototype.renderInline = function () {
|
298 | var _a = this.props.tagName, tagName = _a === void 0 ? 'div' : _a;
|
299 | return React.createElement(tagName, {
|
300 | ref: this.elementRef,
|
301 | id: this.id
|
302 | });
|
303 | };
|
304 | Editor.prototype.renderIframe = function () {
|
305 | return React.createElement('textarea', {
|
306 | ref: this.elementRef,
|
307 | style: { visibility: 'hidden' },
|
308 | name: this.props.textareaName,
|
309 | id: this.id
|
310 | });
|
311 | };
|
312 | Editor.prototype.getScriptSources = function () {
|
313 | var _a, _b;
|
314 | var async = (_a = this.props.scriptLoading) === null || _a === void 0 ? void 0 : _a.async;
|
315 | var defer = (_b = this.props.scriptLoading) === null || _b === void 0 ? void 0 : _b.defer;
|
316 | if (this.props.tinymceScriptSrc !== undefined) {
|
317 | if (typeof this.props.tinymceScriptSrc === 'string') {
|
318 | return [{ src: this.props.tinymceScriptSrc, async: async, defer: defer }];
|
319 | }
|
320 |
|
321 | return this.props.tinymceScriptSrc.map(function (item) {
|
322 | if (typeof item === 'string') {
|
323 |
|
324 |
|
325 | return { src: item, async: async, defer: defer };
|
326 | }
|
327 | else {
|
328 | return item;
|
329 | }
|
330 | });
|
331 | }
|
332 |
|
333 | var channel = this.props.cloudChannel;
|
334 | var apiKey = this.props.apiKey ? this.props.apiKey : 'no-api-key';
|
335 | var cloudTinyJs = "https://cdn.tiny.cloud/1/".concat(apiKey, "/tinymce/").concat(channel, "/tinymce.min.js");
|
336 | return [{ src: cloudTinyJs, async: async, defer: defer }];
|
337 | };
|
338 | Editor.prototype.getInitialValue = function () {
|
339 | if (typeof this.props.initialValue === 'string') {
|
340 | return this.props.initialValue;
|
341 | }
|
342 | else if (typeof this.props.value === 'string') {
|
343 | return this.props.value;
|
344 | }
|
345 | else {
|
346 | return '';
|
347 | }
|
348 | };
|
349 | Editor.prototype.bindHandlers = function (prevProps) {
|
350 | var _this = this;
|
351 | if (this.editor !== undefined) {
|
352 |
|
353 | (0, Utils_1.configHandlers)(this.editor, prevProps, this.props, this.boundHandlers, function (key) { return _this.props[key]; });
|
354 |
|
355 | var isValueControlled = function (p) { return p.onEditorChange !== undefined || p.value !== undefined; };
|
356 | var wasControlled = isValueControlled(prevProps);
|
357 | var nowControlled = isValueControlled(this.props);
|
358 | if (!wasControlled && nowControlled) {
|
359 | this.editor.on(this.changeEvents(), this.handleEditorChange);
|
360 | this.editor.on(this.beforeInputEvent(), this.handleBeforeInput);
|
361 | this.editor.on('keydown', this.handleBeforeInputSpecial);
|
362 | this.editor.on('keyup', this.handleEditorChangeSpecial);
|
363 | this.editor.on('NewBlock', this.handleEditorChange);
|
364 | }
|
365 | else if (wasControlled && !nowControlled) {
|
366 | this.editor.off(this.changeEvents(), this.handleEditorChange);
|
367 | this.editor.off(this.beforeInputEvent(), this.handleBeforeInput);
|
368 | this.editor.off('keydown', this.handleBeforeInputSpecial);
|
369 | this.editor.off('keyup', this.handleEditorChangeSpecial);
|
370 | this.editor.off('NewBlock', this.handleEditorChange);
|
371 | }
|
372 | }
|
373 | };
|
374 | Editor.propTypes = EditorPropTypes_1.EditorPropTypes;
|
375 | Editor.defaultProps = {
|
376 | cloudChannel: '6'
|
377 | };
|
378 | return Editor;
|
379 | }(React.Component));
|
380 | exports.Editor = Editor;
|