argous 1.2.204 → 1.2.206
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/dist/components/Editor/Events.d.ts +7 -9
- package/dist/components/Editor/Events.js +7 -0
- package/dist/components/Editor/TinyMCE.d.ts +8 -1
- package/dist/components/Editor/TinyMCE.js +10 -2
- package/dist/components/Editor/Utils.d.ts +7 -2
- package/dist/components/Editor/Utils.js +9 -29
- package/dist/components/Editor/components/Editor.d.ts +16 -17
- package/dist/components/Editor/components/Editor.js +49 -92
- package/dist/components/Editor/components/EditorPropTypes.d.ts +8 -1
- package/dist/components/Editor/components/EditorPropTypes.js +9 -19
- package/dist/components/Editor/index.d.ts +9 -2
- package/dist/components/Editor/index.js +7 -0
- package/lib/components/Editor/Events.ts +8 -9
- package/lib/components/Editor/ScriptLoader.ts +96 -0
- package/lib/components/Editor/TinyMCE.ts +12 -2
- package/lib/components/Editor/Utils.ts +8 -25
- package/lib/components/Editor/components/Editor.tsx +78 -100
- package/lib/components/Editor/components/EditorPropTypes.ts +12 -21
- package/lib/components/Editor/index.tsx +10 -2
- package/package.json +1 -1
- package/lib/components/Editor/ScriptLoader2.ts +0 -161
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2017-present, Ephox, Inc.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache 2 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { uuid } from './Utils';
|
|
10
|
+
|
|
11
|
+
export type callbackFn = () => void;
|
|
12
|
+
export interface IStateObj {
|
|
13
|
+
listeners: callbackFn[];
|
|
14
|
+
scriptId: string;
|
|
15
|
+
scriptLoading: boolean;
|
|
16
|
+
scriptLoaded: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const createState = (): IStateObj => ({
|
|
20
|
+
listeners: [],
|
|
21
|
+
scriptId: uuid('tiny-script'),
|
|
22
|
+
scriptLoading: false,
|
|
23
|
+
scriptLoaded: false
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
interface ScriptLoaderInterface {
|
|
27
|
+
load: (doc: Document, url: string, async: boolean, defer: boolean, delay: number, callback: callbackFn) => void;
|
|
28
|
+
reinitialize: () => void;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const CreateScriptLoader = (): ScriptLoaderInterface => {
|
|
32
|
+
let state: IStateObj = createState();
|
|
33
|
+
|
|
34
|
+
const injectScriptTag = (scriptId: string, doc: Document, url: string, async: boolean, defer: boolean, callback: callbackFn) => {
|
|
35
|
+
const scriptTag = doc.createElement('script');
|
|
36
|
+
scriptTag.referrerPolicy = 'origin';
|
|
37
|
+
scriptTag.type = 'application/javascript';
|
|
38
|
+
scriptTag.id = scriptId;
|
|
39
|
+
scriptTag.src = url;
|
|
40
|
+
scriptTag.async = async;
|
|
41
|
+
scriptTag.defer = defer;
|
|
42
|
+
|
|
43
|
+
// scriptTag.appendChild(document.createTextNode(url));
|
|
44
|
+
|
|
45
|
+
const handler = () => {
|
|
46
|
+
scriptTag.removeEventListener('load', handler);
|
|
47
|
+
callback();
|
|
48
|
+
};
|
|
49
|
+
scriptTag.addEventListener('load', handler);
|
|
50
|
+
if (doc.head) {
|
|
51
|
+
doc.head.appendChild(scriptTag);
|
|
52
|
+
}
|
|
53
|
+
// document.body.appendChild(scriptTag);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const load = (doc: Document, url: string, async: boolean, defer: boolean, delay: number, callback: callbackFn) => {
|
|
57
|
+
|
|
58
|
+
const scriptTagInjection = () => injectScriptTag(
|
|
59
|
+
state.scriptId, doc, url, async, defer,
|
|
60
|
+
() => {
|
|
61
|
+
state.listeners.forEach((fn) => fn());
|
|
62
|
+
state.scriptLoaded = true;
|
|
63
|
+
}
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
if (state.scriptLoaded) {
|
|
67
|
+
callback();
|
|
68
|
+
} else {
|
|
69
|
+
state.listeners.push(callback);
|
|
70
|
+
if (!state.scriptLoading) {
|
|
71
|
+
state.scriptLoading = true;
|
|
72
|
+
if (delay > 0) {
|
|
73
|
+
setTimeout(scriptTagInjection, delay);
|
|
74
|
+
} else {
|
|
75
|
+
scriptTagInjection();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
// Only to be used by tests.
|
|
82
|
+
const reinitialize = () => {
|
|
83
|
+
state = createState();
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
return {
|
|
87
|
+
load,
|
|
88
|
+
reinitialize
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const ScriptLoader = CreateScriptLoader();
|
|
93
|
+
|
|
94
|
+
export {
|
|
95
|
+
ScriptLoader
|
|
96
|
+
};
|
|
@@ -1,7 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2017-present, Ephox, Inc.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache 2 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
|
|
1
9
|
import { TinyMCE as TinyMCEGlobal } from './tinymce/tinymce';
|
|
2
10
|
|
|
3
|
-
const
|
|
4
|
-
|
|
11
|
+
const getGlobal = (): any => (typeof window !== 'undefined' ? window : global);
|
|
12
|
+
|
|
13
|
+
const getTinymce = (): TinyMCEGlobal | null => {
|
|
14
|
+
const global = getGlobal();
|
|
5
15
|
|
|
6
16
|
return global && global.tinymce ? global.tinymce : null;
|
|
7
17
|
};
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2017-present, Ephox, Inc.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache 2 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
|
|
1
9
|
import { IAllProps } from './components/Editor';
|
|
2
10
|
import { eventPropTypes, IEventPropTypes } from './components/EditorPropTypes';
|
|
3
11
|
import { Editor as TinyMCEEditor, EditorEvent } from './tinymce/tinymce';
|
|
@@ -52,7 +60,6 @@ export const configHandlers = (
|
|
|
52
60
|
lookup,
|
|
53
61
|
editor.on.bind(editor),
|
|
54
62
|
editor.off.bind(editor),
|
|
55
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
56
63
|
(handlerLookup, key) => (e) => handlerLookup(key)?.(e, editor),
|
|
57
64
|
prevProps,
|
|
58
65
|
props,
|
|
@@ -86,27 +93,3 @@ export const mergePlugins = (initPlugins: string | string[] | undefined, inputPl
|
|
|
86
93
|
|
|
87
94
|
export const isBeforeInputEventAvailable = () => window.InputEvent && typeof (InputEvent.prototype as any).getTargetRanges === 'function';
|
|
88
95
|
|
|
89
|
-
export const isInDoc = (elem: Node) => {
|
|
90
|
-
if (!('isConnected' in Node.prototype)) {
|
|
91
|
-
// Fallback for IE and old Edge
|
|
92
|
-
let current = elem;
|
|
93
|
-
let parent = elem.parentNode;
|
|
94
|
-
while (parent != null) {
|
|
95
|
-
current = parent;
|
|
96
|
-
parent = current.parentNode;
|
|
97
|
-
}
|
|
98
|
-
return current === elem.ownerDocument;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
return elem.isConnected;
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
export const setMode = (editor: TinyMCEEditor | undefined, mode: 'readonly' | 'design') => {
|
|
105
|
-
if (editor !== undefined) {
|
|
106
|
-
if (editor.mode != null && typeof editor.mode === 'object' && typeof editor.mode.set === 'function') {
|
|
107
|
-
editor.mode.set(mode);
|
|
108
|
-
} else { // support TinyMCE 4
|
|
109
|
-
(editor as any).setMode(mode);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
};
|
|
@@ -1,13 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2017-present, Ephox, Inc.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache 2 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
|
|
1
9
|
import { EditorPropTypes, IEditorPropTypes } from './EditorPropTypes';
|
|
2
10
|
import { IEvents } from '../Events';
|
|
3
|
-
import {
|
|
11
|
+
import { ScriptLoader } from '../ScriptLoader';
|
|
4
12
|
import { getTinymce } from '../TinyMCE';
|
|
5
|
-
import { Bookmark, Editor as TinyMCEEditor, EditorEvent,
|
|
6
|
-
import { isFunction, isTextareaOrInput, mergePlugins, uuid, configHandlers, isBeforeInputEventAvailable
|
|
13
|
+
import { Bookmark, Editor as TinyMCEEditor, EditorEvent, RawEditorOptions } from '../tinymce/tinymce';
|
|
14
|
+
import { isFunction, isTextareaOrInput, mergePlugins, uuid, configHandlers, isBeforeInputEventAvailable } from '../Utils';
|
|
15
|
+
import { useTheme } from '@material-ui/core';
|
|
7
16
|
import * as React from 'react';
|
|
8
17
|
|
|
9
|
-
type EditorOptions = Parameters<TinyMCE['init']>[0];
|
|
10
|
-
|
|
11
18
|
export interface IProps {
|
|
12
19
|
apiKey: string;
|
|
13
20
|
id: string;
|
|
@@ -15,15 +22,16 @@ export interface IProps {
|
|
|
15
22
|
initialValue: string;
|
|
16
23
|
onEditorChange: (a: string, editor: TinyMCEEditor) => void;
|
|
17
24
|
value: string;
|
|
18
|
-
init:
|
|
25
|
+
init: RawEditorOptions & { selector?: undefined; target?: undefined };
|
|
26
|
+
/** @deprecated use `editor.getContent({format: 'text' })` in `onEditorChange` prop instead */
|
|
27
|
+
outputFormat: 'html' | 'text';
|
|
19
28
|
tagName: string;
|
|
20
29
|
cloudChannel: string;
|
|
21
|
-
plugins: NonNullable<
|
|
22
|
-
toolbar: NonNullable<
|
|
30
|
+
plugins: NonNullable<RawEditorOptions['plugins']>;
|
|
31
|
+
toolbar: NonNullable<RawEditorOptions['toolbar']>;
|
|
23
32
|
disabled: boolean;
|
|
24
33
|
textareaName: string;
|
|
25
|
-
tinymceScriptSrc: string
|
|
26
|
-
rollback: number | false;
|
|
34
|
+
tinymceScriptSrc: string;
|
|
27
35
|
scriptLoading: {
|
|
28
36
|
async?: boolean;
|
|
29
37
|
defer?: boolean;
|
|
@@ -33,11 +41,14 @@ export interface IProps {
|
|
|
33
41
|
|
|
34
42
|
export interface IAllProps extends Partial<IProps>, Partial<IEvents> { }
|
|
35
43
|
|
|
44
|
+
const changeEvents = () => getTinymce()?.Env?.browser?.isIE() ? 'change keyup compositionend setcontent' : 'change input compositionend setcontent';
|
|
45
|
+
const beforeInputEvent = () => isBeforeInputEventAvailable() ? 'beforeinput SelectionChange' : 'SelectionChange';
|
|
46
|
+
|
|
36
47
|
export class Editor extends React.Component<IAllProps> {
|
|
37
48
|
public static propTypes: IEditorPropTypes = EditorPropTypes;
|
|
38
49
|
|
|
39
50
|
public static defaultProps: Partial<IAllProps> = {
|
|
40
|
-
cloudChannel: '
|
|
51
|
+
cloudChannel: '5'
|
|
41
52
|
};
|
|
42
53
|
|
|
43
54
|
public editor?: TinyMCEEditor;
|
|
@@ -58,10 +69,6 @@ export class Editor extends React.Component<IAllProps> {
|
|
|
58
69
|
this.boundHandlers = {};
|
|
59
70
|
}
|
|
60
71
|
|
|
61
|
-
private get view() {
|
|
62
|
-
return this.elementRef.current?.ownerDocument.defaultView ?? window;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
72
|
public componentDidUpdate(prevProps: Partial<IAllProps>) {
|
|
66
73
|
if (this.rollbackTimer) {
|
|
67
74
|
clearTimeout(this.rollbackTimer);
|
|
@@ -107,31 +114,23 @@ export class Editor extends React.Component<IAllProps> {
|
|
|
107
114
|
}
|
|
108
115
|
if (this.props.disabled !== prevProps.disabled) {
|
|
109
116
|
const disabled = this.props.disabled ?? false;
|
|
110
|
-
|
|
117
|
+
this.editor.mode.set(disabled ? 'readonly' : 'design');
|
|
111
118
|
}
|
|
112
119
|
}
|
|
113
120
|
}
|
|
114
121
|
}
|
|
115
122
|
|
|
116
123
|
public componentDidMount() {
|
|
117
|
-
if (getTinymce(
|
|
124
|
+
if (getTinymce() !== null) {
|
|
118
125
|
this.initialise();
|
|
119
|
-
} else if (
|
|
120
|
-
|
|
121
|
-
} else if (this.elementRef.current?.ownerDocument) {
|
|
122
|
-
const successHandler = () => {
|
|
123
|
-
this.props.onScriptsLoad?.();
|
|
124
|
-
this.initialise();
|
|
125
|
-
};
|
|
126
|
-
const errorHandler = (err: unknown) => {
|
|
127
|
-
this.props.onScriptsLoadError?.(err);
|
|
128
|
-
};
|
|
129
|
-
ScriptLoader.loadList(
|
|
126
|
+
} else if (this.elementRef.current && this.elementRef.current.ownerDocument) {
|
|
127
|
+
ScriptLoader.load(
|
|
130
128
|
this.elementRef.current.ownerDocument,
|
|
131
|
-
this.
|
|
129
|
+
this.getScriptSrc(),
|
|
130
|
+
this.props.scriptLoading?.async ?? false,
|
|
131
|
+
this.props.scriptLoading?.defer ?? false,
|
|
132
132
|
this.props.scriptLoading?.delay ?? 0,
|
|
133
|
-
|
|
134
|
-
errorHandler
|
|
133
|
+
this.initialise
|
|
135
134
|
);
|
|
136
135
|
}
|
|
137
136
|
}
|
|
@@ -139,8 +138,8 @@ export class Editor extends React.Component<IAllProps> {
|
|
|
139
138
|
public componentWillUnmount() {
|
|
140
139
|
const editor = this.editor;
|
|
141
140
|
if (editor) {
|
|
142
|
-
editor.off(
|
|
143
|
-
editor.off(
|
|
141
|
+
editor.off(changeEvents(), this.handleEditorChange);
|
|
142
|
+
editor.off(beforeInputEvent(), this.handleBeforeInput);
|
|
144
143
|
editor.off('keypress', this.handleEditorChangeSpecial);
|
|
145
144
|
editor.off('keydown', this.handleBeforeInputSpecial);
|
|
146
145
|
editor.off('NewBlock', this.handleEditorChange);
|
|
@@ -154,19 +153,11 @@ export class Editor extends React.Component<IAllProps> {
|
|
|
154
153
|
}
|
|
155
154
|
|
|
156
155
|
public render() {
|
|
157
|
-
return
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
return (isIE
|
|
163
|
-
? 'change keyup compositionend setcontent CommentChange'
|
|
164
|
-
: 'change input compositionend setcontent CommentChange'
|
|
165
|
-
);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
private beforeInputEvent() {
|
|
169
|
-
return isBeforeInputEventAvailable() ? 'beforeinput SelectionChange' : 'SelectionChange';
|
|
156
|
+
return <>
|
|
157
|
+
<Tema>
|
|
158
|
+
{this.inline ? this.renderInline() : this.renderIframe()}
|
|
159
|
+
</Tema>
|
|
160
|
+
</>;
|
|
170
161
|
}
|
|
171
162
|
|
|
172
163
|
private renderInline() {
|
|
@@ -187,29 +178,15 @@ export class Editor extends React.Component<IAllProps> {
|
|
|
187
178
|
});
|
|
188
179
|
}
|
|
189
180
|
|
|
190
|
-
private
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
if (this.props.tinymceScriptSrc !== undefined) {
|
|
194
|
-
if (typeof this.props.tinymceScriptSrc === 'string') {
|
|
195
|
-
return [{ src: this.props.tinymceScriptSrc, async, defer }];
|
|
196
|
-
}
|
|
197
|
-
// multiple scripts can be specified which allows for hybrid mode
|
|
198
|
-
return this.props.tinymceScriptSrc.map((item) => {
|
|
199
|
-
if (typeof item === 'string') {
|
|
200
|
-
// async does not make sense for multiple items unless
|
|
201
|
-
// they are not dependent (which will be unlikely)
|
|
202
|
-
return { src: item, async, defer };
|
|
203
|
-
}
|
|
204
|
-
return item;
|
|
205
|
-
|
|
206
|
-
});
|
|
181
|
+
private getScriptSrc() {
|
|
182
|
+
if (typeof this.props.tinymceScriptSrc === 'string') {
|
|
183
|
+
return this.props.tinymceScriptSrc;
|
|
207
184
|
}
|
|
208
|
-
|
|
185
|
+
|
|
209
186
|
const channel = this.props.cloudChannel;
|
|
210
187
|
const apiKey = this.props.apiKey ? this.props.apiKey : 'no-api-key';
|
|
211
|
-
|
|
212
|
-
return
|
|
188
|
+
|
|
189
|
+
return `https://cdn.tiny.cloud/1/${apiKey}/tinymce/${channel}/tinymce.min.js`;
|
|
213
190
|
}
|
|
214
191
|
|
|
215
192
|
private getInitialValue() {
|
|
@@ -225,20 +202,20 @@ export class Editor extends React.Component<IAllProps> {
|
|
|
225
202
|
private bindHandlers(prevProps: Partial<IAllProps>) {
|
|
226
203
|
if (this.editor !== undefined) {
|
|
227
204
|
// typescript chokes trying to understand the type of the lookup function
|
|
228
|
-
configHandlers(this.editor, prevProps, this.props, this.boundHandlers, (key) => this.props[key] as any);
|
|
205
|
+
configHandlers(this.editor as any, prevProps, this.props, this.boundHandlers, (key) => this.props[key] as any);
|
|
229
206
|
// check if we should monitor editor changes
|
|
230
207
|
const isValueControlled = (p: Partial<IAllProps>) => p.onEditorChange !== undefined || p.value !== undefined;
|
|
231
208
|
const wasControlled = isValueControlled(prevProps);
|
|
232
209
|
const nowControlled = isValueControlled(this.props);
|
|
233
210
|
if (!wasControlled && nowControlled) {
|
|
234
|
-
this.editor.on(
|
|
235
|
-
this.editor.on(
|
|
211
|
+
this.editor.on(changeEvents(), this.handleEditorChange);
|
|
212
|
+
this.editor.on(beforeInputEvent(), this.handleBeforeInput);
|
|
236
213
|
this.editor.on('keydown', this.handleBeforeInputSpecial);
|
|
237
214
|
this.editor.on('keyup', this.handleEditorChangeSpecial);
|
|
238
215
|
this.editor.on('NewBlock', this.handleEditorChange);
|
|
239
216
|
} else if (wasControlled && !nowControlled) {
|
|
240
|
-
this.editor.off(
|
|
241
|
-
this.editor.off(
|
|
217
|
+
this.editor.off(changeEvents(), this.handleEditorChange);
|
|
218
|
+
this.editor.off(beforeInputEvent(), this.handleBeforeInput);
|
|
242
219
|
this.editor.off('keydown', this.handleBeforeInputSpecial);
|
|
243
220
|
this.editor.off('keyup', this.handleEditorChangeSpecial);
|
|
244
221
|
this.editor.off('NewBlock', this.handleEditorChange);
|
|
@@ -286,20 +263,19 @@ export class Editor extends React.Component<IAllProps> {
|
|
|
286
263
|
const editor = this.editor;
|
|
287
264
|
if (editor && editor.initialized) {
|
|
288
265
|
const newContent = editor.getContent();
|
|
289
|
-
if (this.props.value !== undefined && this.props.value !== newContent
|
|
266
|
+
if (this.props.value !== undefined && this.props.value !== newContent) {
|
|
290
267
|
// start a timer and revert to the value if not applied in time
|
|
291
268
|
if (!this.rollbackTimer) {
|
|
292
|
-
this.rollbackTimer = window.setTimeout(
|
|
293
|
-
this.rollbackChange,
|
|
294
|
-
typeof this.props.rollback === 'number' ? this.props.rollback : 200
|
|
295
|
-
);
|
|
269
|
+
this.rollbackTimer = window.setTimeout(this.rollbackChange, 200);
|
|
296
270
|
}
|
|
297
271
|
}
|
|
298
272
|
|
|
299
273
|
if (newContent !== this.currentContent) {
|
|
300
274
|
this.currentContent = newContent;
|
|
301
275
|
if (isFunction(this.props.onEditorChange)) {
|
|
302
|
-
this.props.
|
|
276
|
+
const format = this.props.outputFormat;
|
|
277
|
+
const out = format === 'html' ? newContent : editor.getContent({ format });
|
|
278
|
+
this.props.onEditorChange(out, editor);
|
|
303
279
|
}
|
|
304
280
|
}
|
|
305
281
|
}
|
|
@@ -311,41 +287,25 @@ export class Editor extends React.Component<IAllProps> {
|
|
|
311
287
|
}
|
|
312
288
|
};
|
|
313
289
|
|
|
314
|
-
private initialise = (
|
|
290
|
+
private initialise = () => {
|
|
315
291
|
const target = this.elementRef.current;
|
|
316
292
|
if (!target) {
|
|
317
293
|
return; // Editor has been unmounted
|
|
318
294
|
}
|
|
319
|
-
if (!isInDoc(target)) {
|
|
320
|
-
// this is probably someone trying to help by rendering us offscreen
|
|
321
|
-
// but we can't do that because the editor iframe must be in the document
|
|
322
|
-
// in order to have state
|
|
323
|
-
if (attempts === 0) {
|
|
324
|
-
// we probably just need to wait for the current events to be processed
|
|
325
|
-
setTimeout(() => this.initialise(1), 1);
|
|
326
|
-
} else if (attempts < 100) {
|
|
327
|
-
// wait for ten seconds, polling every tenth of a second
|
|
328
|
-
setTimeout(() => this.initialise(attempts + 1), 100);
|
|
329
|
-
} else {
|
|
330
|
-
// give up, at this point it seems that more polling is unlikely to help
|
|
331
|
-
throw new Error('tinymce can only be initialised when in a document');
|
|
332
|
-
}
|
|
333
|
-
return;
|
|
334
|
-
}
|
|
335
295
|
|
|
336
|
-
const tinymce = getTinymce(
|
|
296
|
+
const tinymce = getTinymce();
|
|
337
297
|
if (!tinymce) {
|
|
338
298
|
throw new Error('tinymce should have been loaded into global scope');
|
|
339
299
|
}
|
|
340
300
|
|
|
341
|
-
const finalInit:
|
|
301
|
+
const finalInit: RawEditorOptions = {
|
|
342
302
|
...this.props.init,
|
|
343
303
|
selector: undefined,
|
|
344
304
|
target,
|
|
345
305
|
readonly: this.props.disabled,
|
|
346
306
|
inline: this.inline,
|
|
347
|
-
plugins: mergePlugins(this.props.init
|
|
348
|
-
toolbar: this.props.toolbar
|
|
307
|
+
plugins: mergePlugins(this.props.init && this.props.init.plugins, this.props.plugins),
|
|
308
|
+
toolbar: this.props.toolbar || (this.props.init && this.props.init.toolbar),
|
|
349
309
|
setup: (editor) => {
|
|
350
310
|
this.editor = editor;
|
|
351
311
|
this.bindHandlers({});
|
|
@@ -379,7 +339,7 @@ export class Editor extends React.Component<IAllProps> {
|
|
|
379
339
|
editor.setDirty(false);
|
|
380
340
|
}
|
|
381
341
|
const disabled = this.props.disabled ?? false;
|
|
382
|
-
|
|
342
|
+
editor.mode.set(disabled ? 'readonly' : 'design');
|
|
383
343
|
// ensure existing init_instance_callback is called
|
|
384
344
|
if (this.props.init && isFunction(this.props.init.init_instance_callback)) {
|
|
385
345
|
this.props.init.init_instance_callback(editor);
|
|
@@ -393,6 +353,24 @@ export class Editor extends React.Component<IAllProps> {
|
|
|
393
353
|
target.value = this.getInitialValue();
|
|
394
354
|
}
|
|
395
355
|
|
|
396
|
-
tinymce.init(finalInit);
|
|
356
|
+
tinymce.init(finalInit as any);
|
|
397
357
|
};
|
|
398
358
|
}
|
|
359
|
+
|
|
360
|
+
const Tema = ({ children }) => {
|
|
361
|
+
|
|
362
|
+
const theme = useTheme().palette.type;
|
|
363
|
+
|
|
364
|
+
return (
|
|
365
|
+
<div>
|
|
366
|
+
{theme === 'dark' ? <>
|
|
367
|
+
<link rel='stylesheet' href='./skins/ui/dark/skin.min.css' />
|
|
368
|
+
<link rel='stylesheet' href='./skins/ui/dark/content.min.css' />
|
|
369
|
+
</> : <>
|
|
370
|
+
<link rel='stylesheet' href='./skins/ui/default/content.min.css' />
|
|
371
|
+
<link rel='stylesheet' href='./skins/ui/default/skin.min.css' />
|
|
372
|
+
</>}
|
|
373
|
+
{children}
|
|
374
|
+
</div>
|
|
375
|
+
);
|
|
376
|
+
};
|
|
@@ -1,8 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2017-present, Ephox, Inc.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache 2 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
|
|
1
9
|
import { IProps } from './Editor';
|
|
2
10
|
import { IEvents } from '../Events';
|
|
3
11
|
import * as PropTypes from 'prop-types';
|
|
4
12
|
|
|
5
|
-
export type CopyProps<T> = { [P in keyof T]: PropTypes.Requireable<unknown> };
|
|
13
|
+
export type CopyProps<T> = { [P in keyof T]: PropTypes.Requireable<P | unknown> };
|
|
6
14
|
|
|
7
15
|
export type IEventPropTypes = CopyProps<IEvents>;
|
|
8
16
|
|
|
@@ -22,7 +30,6 @@ export const eventPropTypes: IEventPropTypes = {
|
|
|
22
30
|
onClearUndos: PropTypes.func,
|
|
23
31
|
onClick: PropTypes.func,
|
|
24
32
|
onContextMenu: PropTypes.func,
|
|
25
|
-
onCommentChange: PropTypes.func,
|
|
26
33
|
onCopy: PropTypes.func,
|
|
27
34
|
onCut: PropTypes.func,
|
|
28
35
|
onDblclick: PropTypes.func,
|
|
@@ -71,15 +78,7 @@ export const eventPropTypes: IEventPropTypes = {
|
|
|
71
78
|
onShow: PropTypes.func,
|
|
72
79
|
onSubmit: PropTypes.func,
|
|
73
80
|
onUndo: PropTypes.func,
|
|
74
|
-
onVisualAid: PropTypes.func
|
|
75
|
-
onSkinLoadError: PropTypes.func,
|
|
76
|
-
onThemeLoadError: PropTypes.func,
|
|
77
|
-
onModelLoadError: PropTypes.func,
|
|
78
|
-
onPluginLoadError: PropTypes.func,
|
|
79
|
-
onIconsLoadError: PropTypes.func,
|
|
80
|
-
onLanguageLoadError: PropTypes.func,
|
|
81
|
-
onScriptsLoad: PropTypes.func,
|
|
82
|
-
onScriptsLoadError: PropTypes.func,
|
|
81
|
+
onVisualAid: PropTypes.func
|
|
83
82
|
};
|
|
84
83
|
|
|
85
84
|
export const EditorPropTypes: IEditorPropTypes = {
|
|
@@ -89,6 +88,7 @@ export const EditorPropTypes: IEditorPropTypes = {
|
|
|
89
88
|
init: PropTypes.object,
|
|
90
89
|
initialValue: PropTypes.string,
|
|
91
90
|
onEditorChange: PropTypes.func,
|
|
91
|
+
outputFormat: PropTypes.oneOf(['html', 'text']),
|
|
92
92
|
value: PropTypes.string,
|
|
93
93
|
tagName: PropTypes.string,
|
|
94
94
|
cloudChannel: PropTypes.string,
|
|
@@ -96,16 +96,7 @@ export const EditorPropTypes: IEditorPropTypes = {
|
|
|
96
96
|
toolbar: PropTypes.oneOfType([PropTypes.string, PropTypes.array]),
|
|
97
97
|
disabled: PropTypes.bool,
|
|
98
98
|
textareaName: PropTypes.string,
|
|
99
|
-
tinymceScriptSrc: PropTypes.
|
|
100
|
-
PropTypes.string,
|
|
101
|
-
PropTypes.arrayOf(PropTypes.string),
|
|
102
|
-
PropTypes.arrayOf(PropTypes.shape({
|
|
103
|
-
src: PropTypes.string,
|
|
104
|
-
async: PropTypes.bool,
|
|
105
|
-
defer: PropTypes.bool
|
|
106
|
-
}))
|
|
107
|
-
]),
|
|
108
|
-
rollback: PropTypes.oneOfType([PropTypes.number, PropTypes.oneOf([false])]),
|
|
99
|
+
tinymceScriptSrc: PropTypes.string,
|
|
109
100
|
scriptLoading: PropTypes.shape({
|
|
110
101
|
async: PropTypes.bool,
|
|
111
102
|
defer: PropTypes.bool,
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2017-present, Ephox, Inc.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache 2 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
2
8
|
|
|
3
|
-
|
|
9
|
+
import { Editor } from './components/Editor';
|
|
10
|
+
|
|
11
|
+
export { Editor };
|