truerte-react 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +58 -0
- package/LICENSE.txt +22 -0
- package/README.md +54 -0
- package/lib/cjs/main/ts/EventNames.d.ts +8 -0
- package/lib/cjs/main/ts/EventNames.js +87 -0
- package/lib/cjs/main/ts/Events.d.ts +94 -0
- package/lib/cjs/main/ts/Events.js +2 -0
- package/lib/cjs/main/ts/ScriptLoader2.d.ts +10 -0
- package/lib/cjs/main/ts/ScriptLoader2.js +138 -0
- package/lib/cjs/main/ts/TrueRTE.d.ts +3 -0
- package/lib/cjs/main/ts/TrueRTE.js +8 -0
- package/lib/cjs/main/ts/Utils.d.ts +18 -0
- package/lib/cjs/main/ts/Utils.js +53 -0
- package/lib/cjs/main/ts/Uuid.d.ts +6 -0
- package/lib/cjs/main/ts/Uuid.js +16 -0
- package/lib/cjs/main/ts/components/Editor.d.ts +171 -0
- package/lib/cjs/main/ts/components/Editor.js +358 -0
- package/lib/cjs/main/ts/index.d.ts +2 -0
- package/lib/cjs/main/ts/index.js +5 -0
- package/lib/es2015/main/ts/EventNames.d.ts +8 -0
- package/lib/es2015/main/ts/EventNames.js +84 -0
- package/lib/es2015/main/ts/Events.d.ts +94 -0
- package/lib/es2015/main/ts/Events.js +1 -0
- package/lib/es2015/main/ts/ScriptLoader2.d.ts +10 -0
- package/lib/es2015/main/ts/ScriptLoader2.js +135 -0
- package/lib/es2015/main/ts/TrueRTE.d.ts +3 -0
- package/lib/es2015/main/ts/TrueRTE.js +5 -0
- package/lib/es2015/main/ts/Utils.d.ts +18 -0
- package/lib/es2015/main/ts/Utils.js +43 -0
- package/lib/es2015/main/ts/Uuid.d.ts +6 -0
- package/lib/es2015/main/ts/Uuid.js +12 -0
- package/lib/es2015/main/ts/components/Editor.d.ts +171 -0
- package/lib/es2015/main/ts/components/Editor.js +354 -0
- package/lib/es2015/main/ts/index.d.ts +2 -0
- package/lib/es2015/main/ts/index.js +2 -0
- package/package.json +63 -0
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Official TrueRTE React component
|
|
3
|
+
* Copyright (c) 2022 Ephox Corporation DBA Tiny Technologies, Inc.
|
|
4
|
+
* Copyright (c) 2024 TrueRTE contributors
|
|
5
|
+
* Licensed under the MIT license (https://github.com/truerte/truerte-react/blob/main/LICENSE.TXT)
|
|
6
|
+
*/
|
|
7
|
+
import * as React from 'react';
|
|
8
|
+
import { ScriptLoader } from '../ScriptLoader2';
|
|
9
|
+
import { getTrueRTE } from '../TrueRTE';
|
|
10
|
+
import { isFunction, isTextareaOrInput, mergePlugins, configHandlers, isBeforeInputEventAvailable, setMode } from '../Utils';
|
|
11
|
+
import { uuid } from '../Uuid';
|
|
12
|
+
const changeEvents = 'change keyup compositionend setcontent CommentChange';
|
|
13
|
+
/**
|
|
14
|
+
* @see {@link https://www.truerte.org/docs/truerte/1/react-ref/ TrueRTE React Technical Reference}
|
|
15
|
+
*/
|
|
16
|
+
export class Editor extends React.Component {
|
|
17
|
+
constructor(props) {
|
|
18
|
+
var _a, _b, _c;
|
|
19
|
+
super(props);
|
|
20
|
+
this.rollbackTimer = undefined;
|
|
21
|
+
this.valueCursor = undefined;
|
|
22
|
+
this.rollbackChange = () => {
|
|
23
|
+
const editor = this.editor;
|
|
24
|
+
const value = this.props.value;
|
|
25
|
+
if (editor && value && value !== this.currentContent) {
|
|
26
|
+
editor.undoManager.ignore(() => {
|
|
27
|
+
editor.setContent(value);
|
|
28
|
+
// only restore cursor on inline editors when they are focused
|
|
29
|
+
// as otherwise it will cause a focus grab
|
|
30
|
+
if (this.valueCursor && (!this.inline || editor.hasFocus())) {
|
|
31
|
+
try {
|
|
32
|
+
editor.selection.moveToBookmark(this.valueCursor);
|
|
33
|
+
}
|
|
34
|
+
catch (e) { /* ignore */ }
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
this.rollbackTimer = undefined;
|
|
39
|
+
};
|
|
40
|
+
this.handleBeforeInput = (_evt) => {
|
|
41
|
+
if (this.props.value !== undefined && this.props.value === this.currentContent && this.editor) {
|
|
42
|
+
if (!this.inline || this.editor.hasFocus()) {
|
|
43
|
+
try {
|
|
44
|
+
// getBookmark throws exceptions when the editor has not been focused
|
|
45
|
+
// possibly only in inline mode but I'm not taking chances
|
|
46
|
+
this.valueCursor = this.editor.selection.getBookmark(3);
|
|
47
|
+
}
|
|
48
|
+
catch (e) { /* ignore */ }
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
this.handleBeforeInputSpecial = (evt) => {
|
|
53
|
+
if (evt.key === 'Enter' || evt.key === 'Backspace' || evt.key === 'Delete') {
|
|
54
|
+
this.handleBeforeInput(evt);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
this.handleEditorChange = (_evt) => {
|
|
58
|
+
const editor = this.editor;
|
|
59
|
+
if (editor && editor.initialized) {
|
|
60
|
+
const newContent = editor.getContent();
|
|
61
|
+
if (this.props.value !== undefined && this.props.value !== newContent && this.props.rollback !== false) {
|
|
62
|
+
// start a timer and revert to the value if not applied in time
|
|
63
|
+
if (!this.rollbackTimer) {
|
|
64
|
+
this.rollbackTimer = window.setTimeout(this.rollbackChange, typeof this.props.rollback === 'number' ? this.props.rollback : 200);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (newContent !== this.currentContent) {
|
|
68
|
+
this.currentContent = newContent;
|
|
69
|
+
if (isFunction(this.props.onEditorChange)) {
|
|
70
|
+
this.props.onEditorChange(newContent, editor);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
this.handleEditorChangeSpecial = (evt) => {
|
|
76
|
+
if (evt.key === 'Backspace' || evt.key === 'Delete') {
|
|
77
|
+
this.handleEditorChange(evt);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
this.assignEditorRef = (editorRef, editor) => {
|
|
81
|
+
if (editorRef === undefined || editorRef === null) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (typeof editorRef === 'function') {
|
|
85
|
+
editorRef(editor);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
editorRef.current = editor;
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
this.initialise = (attempts = 0) => {
|
|
92
|
+
var _a, _b, _c, _d, _e, _f;
|
|
93
|
+
const target = this.elementRef.current;
|
|
94
|
+
if (!target) {
|
|
95
|
+
return; // Editor has been unmounted
|
|
96
|
+
}
|
|
97
|
+
if (!target.isConnected) {
|
|
98
|
+
// this is probably someone trying to help by rendering us offscreen
|
|
99
|
+
// but we can't do that because the editor iframe must be in the document
|
|
100
|
+
// in order to have state
|
|
101
|
+
// TODO: how will this do when we use web component?
|
|
102
|
+
if (attempts === 0) {
|
|
103
|
+
// we probably just need to wait for the current events to be processed
|
|
104
|
+
setTimeout(() => this.initialise(1), 1);
|
|
105
|
+
}
|
|
106
|
+
else if (attempts < 100) {
|
|
107
|
+
// wait for ten seconds, polling every tenth of a second
|
|
108
|
+
setTimeout(() => this.initialise(attempts + 1), 100);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
// give up, at this point it seems that more polling is unlikely to help
|
|
112
|
+
throw new Error('truerte can only be initialised when in a document');
|
|
113
|
+
}
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const truerte = getTrueRTE(this.view);
|
|
117
|
+
if (!truerte) {
|
|
118
|
+
throw new Error('truerte should have been loaded into global scope');
|
|
119
|
+
}
|
|
120
|
+
const resolvedPlugins = mergePlugins((_a = this.props.init) === null || _a === void 0 ? void 0 : _a.plugins, this.props.plugins);
|
|
121
|
+
const hasExplicitIconConfig = ((_b = this.props.init) === null || _b === void 0 ? void 0 : _b.icons) !== undefined || ((_c = this.props.init) === null || _c === void 0 ? void 0 : _c.icons_url) !== undefined;
|
|
122
|
+
const resolvedIconPack = this.props.useLucideIcons === true && !hasExplicitIconConfig
|
|
123
|
+
? 'truerte-lucide'
|
|
124
|
+
: (_d = this.props.init) === null || _d === void 0 ? void 0 : _d.icons;
|
|
125
|
+
const finalInit = Object.assign(Object.assign({}, this.props.init), { selector: undefined, target, readonly: this.props.disabled, inline: this.inline, plugins: resolvedPlugins, icons: resolvedIconPack, toolbar: (_e = this.props.toolbar) !== null && _e !== void 0 ? _e : (_f = this.props.init) === null || _f === void 0 ? void 0 : _f.toolbar, setup: (editor) => {
|
|
126
|
+
this.editor = editor;
|
|
127
|
+
this.assignEditorRef(this.props.editorRef, editor);
|
|
128
|
+
this.bindHandlers({});
|
|
129
|
+
// When running in inline mode the editor gets the initial value
|
|
130
|
+
// from the innerHTML of the element it is initialized on.
|
|
131
|
+
// However we don't want to take on the responsibility of sanitizing
|
|
132
|
+
// to remove XSS in the react integration so we have a chicken and egg
|
|
133
|
+
// problem... We avoid it by sneaking in a set content before the first
|
|
134
|
+
// "official" setContent and using TrueRTE to do the sanitization.
|
|
135
|
+
if (this.inline && !isTextareaOrInput(target)) {
|
|
136
|
+
editor.once('PostRender', (_evt) => {
|
|
137
|
+
editor.setContent(this.getInitialValue(), { no_events: true });
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
if (this.props.init && isFunction(this.props.init.setup)) {
|
|
141
|
+
this.props.init.setup(editor);
|
|
142
|
+
}
|
|
143
|
+
}, init_instance_callback: (editor) => {
|
|
144
|
+
var _a, _b;
|
|
145
|
+
// check for changes that happened since truerte.init() was called
|
|
146
|
+
const initialValue = this.getInitialValue();
|
|
147
|
+
this.currentContent = (_a = this.currentContent) !== null && _a !== void 0 ? _a : editor.getContent();
|
|
148
|
+
if (this.currentContent !== initialValue) {
|
|
149
|
+
this.currentContent = initialValue;
|
|
150
|
+
// same as resetContent in TrueRTE 5
|
|
151
|
+
editor.setContent(initialValue);
|
|
152
|
+
editor.undoManager.clear();
|
|
153
|
+
editor.undoManager.add();
|
|
154
|
+
editor.setDirty(false);
|
|
155
|
+
}
|
|
156
|
+
const disabled = (_b = this.props.disabled) !== null && _b !== void 0 ? _b : false;
|
|
157
|
+
setMode(this.editor, disabled ? 'readonly' : 'design');
|
|
158
|
+
// ensure existing init_instance_callback is called
|
|
159
|
+
if (this.props.init && isFunction(this.props.init.init_instance_callback)) {
|
|
160
|
+
this.props.init.init_instance_callback(editor);
|
|
161
|
+
}
|
|
162
|
+
} });
|
|
163
|
+
if (!this.inline) {
|
|
164
|
+
target.style.visibility = '';
|
|
165
|
+
}
|
|
166
|
+
if (isTextareaOrInput(target)) {
|
|
167
|
+
target.value = this.getInitialValue();
|
|
168
|
+
}
|
|
169
|
+
truerte.init(finalInit);
|
|
170
|
+
};
|
|
171
|
+
this.id = this.props.id || uuid('truerte-react');
|
|
172
|
+
this.elementRef = React.createRef();
|
|
173
|
+
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;
|
|
174
|
+
this.boundHandlers = {};
|
|
175
|
+
}
|
|
176
|
+
get view() {
|
|
177
|
+
var _a, _b;
|
|
178
|
+
return (_b = (_a = this.elementRef.current) === null || _a === void 0 ? void 0 : _a.ownerDocument.defaultView) !== null && _b !== void 0 ? _b : window;
|
|
179
|
+
}
|
|
180
|
+
componentDidUpdate(prevProps) {
|
|
181
|
+
var _a, _b, _c;
|
|
182
|
+
if (this.props.editorRef !== prevProps.editorRef) {
|
|
183
|
+
this.assignEditorRef(prevProps.editorRef, null);
|
|
184
|
+
this.assignEditorRef(this.props.editorRef, (_a = this.editor) !== null && _a !== void 0 ? _a : null);
|
|
185
|
+
}
|
|
186
|
+
if (this.rollbackTimer) {
|
|
187
|
+
clearTimeout(this.rollbackTimer);
|
|
188
|
+
this.rollbackTimer = undefined;
|
|
189
|
+
}
|
|
190
|
+
if (this.editor) {
|
|
191
|
+
this.bindHandlers(prevProps);
|
|
192
|
+
if (this.editor.initialized) {
|
|
193
|
+
this.currentContent = (_b = this.currentContent) !== null && _b !== void 0 ? _b : this.editor.getContent();
|
|
194
|
+
if (typeof this.props.initialValue === 'string' && this.props.initialValue !== prevProps.initialValue) {
|
|
195
|
+
// same as resetContent in TinyMCE 5 – TODO what does this mean for TrueRTE?
|
|
196
|
+
this.editor.setContent(this.props.initialValue);
|
|
197
|
+
this.editor.undoManager.clear();
|
|
198
|
+
this.editor.undoManager.add();
|
|
199
|
+
this.editor.setDirty(false);
|
|
200
|
+
}
|
|
201
|
+
else if (typeof this.props.value === 'string' && this.props.value !== this.currentContent) {
|
|
202
|
+
const localEditor = this.editor;
|
|
203
|
+
localEditor.undoManager.transact(() => {
|
|
204
|
+
// inline editors grab focus when restoring selection
|
|
205
|
+
// so we don't try to keep their selection unless they are currently focused
|
|
206
|
+
let cursor;
|
|
207
|
+
if (!this.inline || localEditor.hasFocus()) {
|
|
208
|
+
try {
|
|
209
|
+
// getBookmark throws exceptions when the editor has not been focused
|
|
210
|
+
// possibly only in inline mode but I'm not taking chances
|
|
211
|
+
cursor = localEditor.selection.getBookmark(3);
|
|
212
|
+
}
|
|
213
|
+
catch (e) { /* ignore */ }
|
|
214
|
+
}
|
|
215
|
+
const valueCursor = this.valueCursor;
|
|
216
|
+
localEditor.setContent(this.props.value);
|
|
217
|
+
if (!this.inline || localEditor.hasFocus()) {
|
|
218
|
+
for (const bookmark of [cursor, valueCursor]) {
|
|
219
|
+
if (bookmark) {
|
|
220
|
+
try {
|
|
221
|
+
localEditor.selection.moveToBookmark(bookmark);
|
|
222
|
+
this.valueCursor = bookmark;
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
225
|
+
catch (e) { /* ignore */ }
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
if (this.props.disabled !== prevProps.disabled) {
|
|
232
|
+
const disabled = (_c = this.props.disabled) !== null && _c !== void 0 ? _c : false;
|
|
233
|
+
setMode(this.editor, disabled ? 'readonly' : 'design');
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
componentDidMount() {
|
|
239
|
+
var _a, _b, _c, _d, _e;
|
|
240
|
+
if (getTrueRTE(this.view) !== null) {
|
|
241
|
+
this.initialise();
|
|
242
|
+
}
|
|
243
|
+
else if (Array.isArray(this.props.truerteScriptSrc) && this.props.truerteScriptSrc.length === 0) {
|
|
244
|
+
(_b = (_a = this.props).onScriptsLoadError) === null || _b === void 0 ? void 0 : _b.call(_a, new Error('No `truerte` global is present but the `truerteScriptSrc` prop was an empty array.'));
|
|
245
|
+
}
|
|
246
|
+
else if ((_c = this.elementRef.current) === null || _c === void 0 ? void 0 : _c.ownerDocument) {
|
|
247
|
+
const successHandler = () => {
|
|
248
|
+
var _a, _b;
|
|
249
|
+
(_b = (_a = this.props).onScriptsLoad) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
250
|
+
this.initialise();
|
|
251
|
+
};
|
|
252
|
+
const errorHandler = (err) => {
|
|
253
|
+
var _a, _b;
|
|
254
|
+
(_b = (_a = this.props).onScriptsLoadError) === null || _b === void 0 ? void 0 : _b.call(_a, err);
|
|
255
|
+
};
|
|
256
|
+
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);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
componentWillUnmount() {
|
|
260
|
+
const editor = this.editor;
|
|
261
|
+
if (editor) {
|
|
262
|
+
editor.off(changeEvents, this.handleEditorChange);
|
|
263
|
+
editor.off(this.beforeInputEvent(), this.handleBeforeInput);
|
|
264
|
+
editor.off('keypress', this.handleEditorChangeSpecial);
|
|
265
|
+
editor.off('keydown', this.handleBeforeInputSpecial);
|
|
266
|
+
editor.off('NewBlock', this.handleEditorChange);
|
|
267
|
+
Object.keys(this.boundHandlers).forEach((eventName) => {
|
|
268
|
+
editor.off(eventName, this.boundHandlers[eventName]);
|
|
269
|
+
});
|
|
270
|
+
this.boundHandlers = {};
|
|
271
|
+
editor.remove();
|
|
272
|
+
this.editor = undefined;
|
|
273
|
+
}
|
|
274
|
+
this.assignEditorRef(this.props.editorRef, null);
|
|
275
|
+
}
|
|
276
|
+
render() {
|
|
277
|
+
return this.inline ? this.renderInline() : this.renderIframe();
|
|
278
|
+
}
|
|
279
|
+
getEditor() {
|
|
280
|
+
return this.editor;
|
|
281
|
+
}
|
|
282
|
+
beforeInputEvent() {
|
|
283
|
+
return isBeforeInputEventAvailable() ? 'beforeinput SelectionChange' : 'SelectionChange';
|
|
284
|
+
}
|
|
285
|
+
renderInline() {
|
|
286
|
+
const { tagName = 'div' } = this.props;
|
|
287
|
+
return React.createElement(tagName, {
|
|
288
|
+
ref: this.elementRef,
|
|
289
|
+
id: this.id,
|
|
290
|
+
tabIndex: this.props.tabIndex
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
renderIframe() {
|
|
294
|
+
return React.createElement('textarea', {
|
|
295
|
+
ref: this.elementRef,
|
|
296
|
+
style: { visibility: 'hidden' },
|
|
297
|
+
name: this.props.textareaName,
|
|
298
|
+
id: this.id,
|
|
299
|
+
tabIndex: this.props.tabIndex
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
getScriptSources() {
|
|
303
|
+
var _a, _b;
|
|
304
|
+
const async = (_a = this.props.scriptLoading) === null || _a === void 0 ? void 0 : _a.async;
|
|
305
|
+
const defer = (_b = this.props.scriptLoading) === null || _b === void 0 ? void 0 : _b.defer;
|
|
306
|
+
if (this.props.truerteScriptSrc !== undefined) {
|
|
307
|
+
if (typeof this.props.truerteScriptSrc === 'string') {
|
|
308
|
+
return [{ src: this.props.truerteScriptSrc, async, defer }];
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
// fallback to jsDelivr CDN when the truerteScriptSrc is not specified
|
|
312
|
+
// `cdnVersion` is in `defaultProps`, so it's always defined.
|
|
313
|
+
const cdnLink = `https://cdn.jsdelivr.net/npm/truerte@${this.props.cdnVersion}/truerte.min.js`;
|
|
314
|
+
return [{ src: cdnLink, async, defer }];
|
|
315
|
+
}
|
|
316
|
+
getInitialValue() {
|
|
317
|
+
if (typeof this.props.initialValue === 'string') {
|
|
318
|
+
return this.props.initialValue;
|
|
319
|
+
}
|
|
320
|
+
else if (typeof this.props.value === 'string') {
|
|
321
|
+
return this.props.value;
|
|
322
|
+
}
|
|
323
|
+
else {
|
|
324
|
+
return '';
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
bindHandlers(prevProps) {
|
|
328
|
+
if (this.editor !== undefined) {
|
|
329
|
+
// typescript chokes trying to understand the type of the lookup function
|
|
330
|
+
configHandlers(this.editor, prevProps, this.props, this.boundHandlers, (key) => this.props[key]);
|
|
331
|
+
// check if we should monitor editor changes
|
|
332
|
+
const isValueControlled = (p) => p.onEditorChange !== undefined || p.value !== undefined;
|
|
333
|
+
const wasControlled = isValueControlled(prevProps);
|
|
334
|
+
const nowControlled = isValueControlled(this.props);
|
|
335
|
+
if (!wasControlled && nowControlled) {
|
|
336
|
+
this.editor.on(changeEvents, this.handleEditorChange);
|
|
337
|
+
this.editor.on(this.beforeInputEvent(), this.handleBeforeInput);
|
|
338
|
+
this.editor.on('keydown', this.handleBeforeInputSpecial);
|
|
339
|
+
this.editor.on('keyup', this.handleEditorChangeSpecial);
|
|
340
|
+
this.editor.on('NewBlock', this.handleEditorChange);
|
|
341
|
+
}
|
|
342
|
+
else if (wasControlled && !nowControlled) {
|
|
343
|
+
this.editor.off(changeEvents, this.handleEditorChange);
|
|
344
|
+
this.editor.off(this.beforeInputEvent(), this.handleBeforeInput);
|
|
345
|
+
this.editor.off('keydown', this.handleBeforeInputSpecial);
|
|
346
|
+
this.editor.off('keyup', this.handleEditorChangeSpecial);
|
|
347
|
+
this.editor.off('NewBlock', this.handleEditorChange);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
Editor.defaultProps = {
|
|
353
|
+
cdnVersion: '1',
|
|
354
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "truerte-react",
|
|
3
|
+
"description": "TrueRTE React Component",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "git+https://github.com/TrueRTE/truerte-react.git"
|
|
7
|
+
},
|
|
8
|
+
"bugs": {
|
|
9
|
+
"url": "https://github.com/TrueRTE/truerte-react/issues"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"lib",
|
|
13
|
+
"README.md",
|
|
14
|
+
"CHANGELOG.md",
|
|
15
|
+
"LICENSE.txt"
|
|
16
|
+
],
|
|
17
|
+
"main": "lib/cjs/main/ts/index.js",
|
|
18
|
+
"module": "lib/es2015/main/ts/index.js",
|
|
19
|
+
"scripts": {
|
|
20
|
+
"lint": "eslint 'src/**/*.ts?(x)'",
|
|
21
|
+
"clean": "rimraf lib",
|
|
22
|
+
"test": "bedrock-auto -b chrome-headless -f src/test/ts/**/*Test.ts",
|
|
23
|
+
"test-manual": "bedrock -f src/test/ts/**/*Test.ts",
|
|
24
|
+
"build": "npm run clean && tsc -p ./tsconfig.es2015.json && tsc -p ./tsconfig.cjs.json",
|
|
25
|
+
"watch": "tsc -w -p ./tsconfig.es2015.json",
|
|
26
|
+
"prepublishOnly": "npm run build"
|
|
27
|
+
},
|
|
28
|
+
"keywords": [
|
|
29
|
+
"truerte",
|
|
30
|
+
"react",
|
|
31
|
+
"editor"
|
|
32
|
+
],
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"truerte": "^1.0.0",
|
|
36
|
+
"react": "^19.0.0 || ^18.0.0 || ^17.0.1 || ^16.7.0",
|
|
37
|
+
"react-dom": "^19.0.0 || ^18.0.0 || ^17.0.1 || ^16.7.0"
|
|
38
|
+
},
|
|
39
|
+
"peerDependenciesMeta": {
|
|
40
|
+
"truerte": {
|
|
41
|
+
"optional": true
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@ephox/agar": "8.0.1",
|
|
46
|
+
"@ephox/bedrock-client": "^15.0.0",
|
|
47
|
+
"@ephox/bedrock-server": "^15.0.3-alpha.0",
|
|
48
|
+
"@ephox/mcagar": "^9.0.1",
|
|
49
|
+
"@tinymce/eslint-plugin": "^3.0.0",
|
|
50
|
+
"@types/node": "^22.17.2",
|
|
51
|
+
"@types/react": "^19.1.10",
|
|
52
|
+
"@types/react-dom": "^19.1.7",
|
|
53
|
+
"truerte": "file:../truerte/modules/truerte",
|
|
54
|
+
"truerte-1": "file:../truerte/modules/truerte",
|
|
55
|
+
"react": "^19.1.1",
|
|
56
|
+
"react-dom": "^19.1.1",
|
|
57
|
+
"rimraf": "^6.0.1",
|
|
58
|
+
"typescript": "~5.8.3",
|
|
59
|
+
"vite": "^6.3.5"
|
|
60
|
+
},
|
|
61
|
+
"version": "0.0.3",
|
|
62
|
+
"dependencies": {}
|
|
63
|
+
}
|