truerte-react 0.0.5 → 0.0.6
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/README.md +4 -2
- package/lib/cjs/main/ts/BundledTrueRTE.d.ts +10 -0
- package/lib/cjs/main/ts/BundledTrueRTE.js +140 -0
- package/lib/cjs/main/ts/components/Editor.d.ts +12 -3
- package/lib/cjs/main/ts/components/Editor.js +85 -31
- package/lib/es2015/main/ts/BundledTrueRTE.d.ts +10 -0
- package/lib/es2015/main/ts/BundledTrueRTE.js +135 -0
- package/lib/es2015/main/ts/components/Editor.d.ts +12 -3
- package/lib/es2015/main/ts/components/Editor.js +85 -31
- package/package.json +5 -10
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ This package is a thin wrapper around [TrueRTE](https://github.com/TrueRTE/truer
|
|
|
12
12
|
## Installation
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
-
npm install truerte
|
|
15
|
+
npm install truerte-react
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
## Quick Example
|
|
@@ -23,7 +23,6 @@ import { Editor } from "truerte-react";
|
|
|
23
23
|
export default function App() {
|
|
24
24
|
return (
|
|
25
25
|
<Editor
|
|
26
|
-
truerteScriptSrc="/truerte/truerte.min.js"
|
|
27
26
|
useLucideIcons={true}
|
|
28
27
|
init={{
|
|
29
28
|
height: 500,
|
|
@@ -35,6 +34,9 @@ export default function App() {
|
|
|
35
34
|
}
|
|
36
35
|
```
|
|
37
36
|
|
|
37
|
+
`truerte-react` now loads bundled TrueRTE core assets from the installed package by default.
|
|
38
|
+
If you need script URL loading, provide `truerteScriptSrc` (or set `bundleCoreEditor={false}` to use the CDN fallback).
|
|
39
|
+
|
|
38
40
|
## Issues
|
|
39
41
|
|
|
40
42
|
Have you found an issue with `truerte-react` or do you have a feature request?
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const parsePluginNames: (plugins: unknown) => string[];
|
|
2
|
+
export interface BundledTrueRTELoadOptions {
|
|
3
|
+
plugins: unknown;
|
|
4
|
+
icons?: unknown;
|
|
5
|
+
model?: unknown;
|
|
6
|
+
theme?: unknown;
|
|
7
|
+
skin?: unknown;
|
|
8
|
+
contentCss?: unknown;
|
|
9
|
+
}
|
|
10
|
+
export declare const loadBundledTrueRTE: (options: BundledTrueRTELoadOptions) => Promise<void>;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.loadBundledTrueRTE = exports.parsePluginNames = void 0;
|
|
13
|
+
const toTokens = (value) => value
|
|
14
|
+
.split(/[\s,]+/)
|
|
15
|
+
.map((token) => token.trim())
|
|
16
|
+
.filter((token) => token.length > 0);
|
|
17
|
+
const unique = (items) => Array.from(new Set(items));
|
|
18
|
+
const parsePluginNames = (plugins) => {
|
|
19
|
+
if (typeof plugins === 'string') {
|
|
20
|
+
return unique(toTokens(plugins));
|
|
21
|
+
}
|
|
22
|
+
if (Array.isArray(plugins)) {
|
|
23
|
+
return unique(plugins.flatMap((item) => typeof item === 'string' ? toTokens(item) : []));
|
|
24
|
+
}
|
|
25
|
+
return [];
|
|
26
|
+
};
|
|
27
|
+
exports.parsePluginNames = parsePluginNames;
|
|
28
|
+
const parseContentCssNames = (contentCss) => {
|
|
29
|
+
if (typeof contentCss === 'string') {
|
|
30
|
+
return unique(toTokens(contentCss));
|
|
31
|
+
}
|
|
32
|
+
if (Array.isArray(contentCss)) {
|
|
33
|
+
return unique(contentCss.flatMap((item) => typeof item === 'string' ? toTokens(item) : []));
|
|
34
|
+
}
|
|
35
|
+
return [];
|
|
36
|
+
};
|
|
37
|
+
const MODEL_LOADERS = {
|
|
38
|
+
dom: () => Promise.resolve().then(() => require('truerte/js/truerte/models/dom/model.js'))
|
|
39
|
+
};
|
|
40
|
+
const THEME_LOADERS = {
|
|
41
|
+
silver: () => Promise.resolve().then(() => require('truerte/js/truerte/themes/silver/theme.js'))
|
|
42
|
+
};
|
|
43
|
+
const ICON_LOADERS = {
|
|
44
|
+
default: () => Promise.resolve().then(() => require('truerte/js/truerte/icons/default/icons.js')),
|
|
45
|
+
'truerte-lucide': () => Promise.resolve().then(() => require('truerte/js/truerte/icons/truerte-lucide/icons.js'))
|
|
46
|
+
};
|
|
47
|
+
const SKIN_LOADERS = {
|
|
48
|
+
oxide: () => Promise.resolve().then(() => require('truerte/js/truerte/skins/ui/oxide/skin.js')),
|
|
49
|
+
'oxide-dark': () => Promise.resolve().then(() => require('truerte/js/truerte/skins/ui/oxide-dark/skin.js')),
|
|
50
|
+
'truerte-5': () => Promise.resolve().then(() => require('truerte/js/truerte/skins/ui/truerte-5/skin.js')),
|
|
51
|
+
'truerte-5-dark': () => Promise.resolve().then(() => require('truerte/js/truerte/skins/ui/truerte-5-dark/skin.js'))
|
|
52
|
+
};
|
|
53
|
+
const CONTENT_CSS_LOADERS = {
|
|
54
|
+
default: () => Promise.resolve().then(() => require('truerte/js/truerte/skins/content/default/content.js')),
|
|
55
|
+
dark: () => Promise.resolve().then(() => require('truerte/js/truerte/skins/content/dark/content.js')),
|
|
56
|
+
document: () => Promise.resolve().then(() => require('truerte/js/truerte/skins/content/document/content.js')),
|
|
57
|
+
writer: () => Promise.resolve().then(() => require('truerte/js/truerte/skins/content/writer/content.js')),
|
|
58
|
+
'truerte-5': () => Promise.resolve().then(() => require('truerte/js/truerte/skins/content/truerte-5/content.js')),
|
|
59
|
+
'truerte-5-dark': () => Promise.resolve().then(() => require('truerte/js/truerte/skins/content/truerte-5-dark/content.js'))
|
|
60
|
+
};
|
|
61
|
+
const PLUGIN_LOADERS = {
|
|
62
|
+
accordion: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/accordion/plugin.js')),
|
|
63
|
+
advlist: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/advlist/plugin.js')),
|
|
64
|
+
anchor: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/anchor/plugin.js')),
|
|
65
|
+
autolink: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/autolink/plugin.js')),
|
|
66
|
+
autoresize: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/autoresize/plugin.js')),
|
|
67
|
+
autosave: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/autosave/plugin.js')),
|
|
68
|
+
casechange: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/casechange/plugin.js')),
|
|
69
|
+
charmap: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/charmap/plugin.js')),
|
|
70
|
+
code: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/code/plugin.js')),
|
|
71
|
+
codesample: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/codesample/plugin.js')),
|
|
72
|
+
directionality: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/directionality/plugin.js')),
|
|
73
|
+
emoticons: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/emoticons/plugin.js')),
|
|
74
|
+
fullscreen: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/fullscreen/plugin.js')),
|
|
75
|
+
help: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/help/plugin.js')),
|
|
76
|
+
image: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/image/plugin.js')),
|
|
77
|
+
importcss: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/importcss/plugin.js')),
|
|
78
|
+
insertdatetime: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/insertdatetime/plugin.js')),
|
|
79
|
+
letterspacing: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/letterspacing/plugin.js')),
|
|
80
|
+
link: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/link/plugin.js')),
|
|
81
|
+
lists: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/lists/plugin.js')),
|
|
82
|
+
lucideicons: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/lucideicons/plugin.js')),
|
|
83
|
+
media: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/media/plugin.js')),
|
|
84
|
+
nonbreaking: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/nonbreaking/plugin.js')),
|
|
85
|
+
pagebreak: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/pagebreak/plugin.js')),
|
|
86
|
+
paragraphspacing: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/paragraphspacing/plugin.js')),
|
|
87
|
+
preview: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/preview/plugin.js')),
|
|
88
|
+
quickbars: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/quickbars/plugin.js')),
|
|
89
|
+
save: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/save/plugin.js')),
|
|
90
|
+
searchreplace: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/searchreplace/plugin.js')),
|
|
91
|
+
table: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/table/plugin.js')),
|
|
92
|
+
template: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/template/plugin.js')),
|
|
93
|
+
visualblocks: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/visualblocks/plugin.js')),
|
|
94
|
+
visualchars: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/visualchars/plugin.js')),
|
|
95
|
+
wordcount: () => Promise.resolve().then(() => require('truerte/js/truerte/plugins/wordcount/plugin.js'))
|
|
96
|
+
};
|
|
97
|
+
const loadedModels = new Set();
|
|
98
|
+
const loadedThemes = new Set();
|
|
99
|
+
const loadedIcons = new Set();
|
|
100
|
+
const loadedSkins = new Set();
|
|
101
|
+
const loadedContentCss = new Set();
|
|
102
|
+
const loadedPlugins = new Set();
|
|
103
|
+
let corePromise;
|
|
104
|
+
const loadCore = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
105
|
+
corePromise !== null && corePromise !== void 0 ? corePromise : (corePromise = Promise.resolve().then(() => require('truerte/js/truerte/truerte.js')).then(() => undefined));
|
|
106
|
+
yield corePromise;
|
|
107
|
+
});
|
|
108
|
+
const loadCachedResource = (cache, name, loaders) => __awaiter(void 0, void 0, void 0, function* () {
|
|
109
|
+
if (cache.has(name)) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const loader = loaders[name];
|
|
113
|
+
if (!loader) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
yield loader();
|
|
117
|
+
cache.add(name);
|
|
118
|
+
});
|
|
119
|
+
const loadBundledTrueRTE = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
120
|
+
yield loadCore();
|
|
121
|
+
const model = typeof options.model === 'string' ? options.model : 'dom';
|
|
122
|
+
const theme = typeof options.theme === 'string' ? options.theme : 'silver';
|
|
123
|
+
const iconPack = typeof options.icons === 'string' ? options.icons : 'default';
|
|
124
|
+
const skin = options.skin === false ? false : (typeof options.skin === 'string' ? options.skin : 'oxide');
|
|
125
|
+
const contentCss = options.contentCss === false
|
|
126
|
+
? []
|
|
127
|
+
: options.contentCss === undefined
|
|
128
|
+
? ['default']
|
|
129
|
+
: parseContentCssNames(options.contentCss);
|
|
130
|
+
const plugins = (0, exports.parsePluginNames)(options.plugins);
|
|
131
|
+
yield Promise.all([
|
|
132
|
+
loadCachedResource(loadedModels, model, MODEL_LOADERS),
|
|
133
|
+
loadCachedResource(loadedThemes, theme, THEME_LOADERS),
|
|
134
|
+
loadCachedResource(loadedIcons, iconPack, ICON_LOADERS),
|
|
135
|
+
...(skin ? [loadCachedResource(loadedSkins, skin, SKIN_LOADERS)] : []),
|
|
136
|
+
...contentCss.map((name) => loadCachedResource(loadedContentCss, name, CONTENT_CSS_LOADERS)),
|
|
137
|
+
]);
|
|
138
|
+
yield Promise.all(plugins.map((plugin) => loadCachedResource(loadedPlugins, plugin, PLUGIN_LOADERS)));
|
|
139
|
+
});
|
|
140
|
+
exports.loadBundledTrueRTE = loadBundledTrueRTE;
|
|
@@ -71,11 +71,17 @@ export interface IProps {
|
|
|
71
71
|
*/
|
|
72
72
|
tabIndex: number;
|
|
73
73
|
/**
|
|
74
|
-
* @description The TrueRTE version to use when loading from jsDelivr CDN.
|
|
74
|
+
* @description The TrueRTE version to use when loading from jsDelivr CDN. This is only used when
|
|
75
|
+
* `bundleCoreEditor` is `false` and `truerteScriptSrc` is not specified. By default, version 1
|
|
75
76
|
* (that is, the latest minor and patch release of the major version 1) will be used.
|
|
76
77
|
* For more info about the possible version formats, see the {@link https://www.jsdelivr.com/documentation#id-npm jsDelivr documentation}.
|
|
77
78
|
*/
|
|
78
79
|
cdnVersion: Version;
|
|
80
|
+
/**
|
|
81
|
+
* @description When true (default), load bundled TrueRTE core/assets from the installed `truerte` package
|
|
82
|
+
* instead of injecting a script tag. Set to false to use script URL loading fallback behavior.
|
|
83
|
+
*/
|
|
84
|
+
bundleCoreEditor: boolean;
|
|
79
85
|
/**
|
|
80
86
|
* @see {@link https://www.truerte.org/docs/truerte/1/react-ref/#plugins React Tech Ref - plugins}
|
|
81
87
|
* @description The plugins to load into the editor. Equivalent to the `plugins` option in TrueRTE.
|
|
@@ -102,9 +108,9 @@ export interface IProps {
|
|
|
102
108
|
*/
|
|
103
109
|
editorRef: EditorInstanceRef;
|
|
104
110
|
/**
|
|
105
|
-
* @description
|
|
111
|
+
* @description URL(s) of TrueRTE script files to lazy load at runtime.
|
|
106
112
|
*/
|
|
107
|
-
truerteScriptSrc: string;
|
|
113
|
+
truerteScriptSrc: string | string[];
|
|
108
114
|
/**
|
|
109
115
|
* @description When true, automatically configures `icons: 'truerte-lucide'`
|
|
110
116
|
* unless you explicitly provide `init.icons` or `init.icons_url`.
|
|
@@ -147,6 +153,7 @@ export declare class Editor extends React.Component<IAllProps> {
|
|
|
147
153
|
private get view();
|
|
148
154
|
componentDidUpdate(prevProps: Partial<IAllProps>): void;
|
|
149
155
|
componentDidMount(): void;
|
|
156
|
+
private bootstrapEditor;
|
|
150
157
|
componentWillUnmount(): void;
|
|
151
158
|
render(): React.ReactElement<{
|
|
152
159
|
ref: React.RefObject<HTMLElement | null>;
|
|
@@ -167,5 +174,7 @@ export declare class Editor extends React.Component<IAllProps> {
|
|
|
167
174
|
private handleEditorChangeSpecial;
|
|
168
175
|
private assignEditorRef;
|
|
169
176
|
private initialise;
|
|
177
|
+
private resolvePlugins;
|
|
178
|
+
private resolveIconPack;
|
|
170
179
|
}
|
|
171
180
|
export {};
|
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
2
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
12
|
exports.Editor = void 0;
|
|
4
13
|
/**
|
|
@@ -8,6 +17,7 @@ exports.Editor = void 0;
|
|
|
8
17
|
* Licensed under the MIT license (https://github.com/truerte/truerte-react/blob/main/LICENSE.TXT)
|
|
9
18
|
*/
|
|
10
19
|
const React = require("react");
|
|
20
|
+
const BundledTrueRTE_1 = require("../BundledTrueRTE");
|
|
11
21
|
const ScriptLoader2_1 = require("../ScriptLoader2");
|
|
12
22
|
const TrueRTE_1 = require("../TrueRTE");
|
|
13
23
|
const Utils_1 = require("../Utils");
|
|
@@ -22,6 +32,53 @@ class Editor extends React.Component {
|
|
|
22
32
|
super(props);
|
|
23
33
|
this.rollbackTimer = undefined;
|
|
24
34
|
this.valueCursor = undefined;
|
|
35
|
+
this.bootstrapEditor = () => __awaiter(this, void 0, void 0, function* () {
|
|
36
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
37
|
+
if ((0, TrueRTE_1.getTrueRTE)(this.view) !== null) {
|
|
38
|
+
this.initialise();
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (!((_a = this.elementRef.current) === null || _a === void 0 ? void 0 : _a.ownerDocument)) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const scriptSources = this.getScriptSources();
|
|
45
|
+
if (scriptSources.length > 0) {
|
|
46
|
+
const successHandler = () => {
|
|
47
|
+
var _a, _b;
|
|
48
|
+
(_b = (_a = this.props).onScriptsLoad) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
49
|
+
this.initialise();
|
|
50
|
+
};
|
|
51
|
+
const errorHandler = (err) => {
|
|
52
|
+
var _a, _b;
|
|
53
|
+
(_b = (_a = this.props).onScriptsLoadError) === null || _b === void 0 ? void 0 : _b.call(_a, err);
|
|
54
|
+
};
|
|
55
|
+
ScriptLoader2_1.ScriptLoader.loadList(this.elementRef.current.ownerDocument, scriptSources, (_c = (_b = this.props.scriptLoading) === null || _b === void 0 ? void 0 : _b.delay) !== null && _c !== void 0 ? _c : 0, successHandler, errorHandler);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (Array.isArray(this.props.truerteScriptSrc) && this.props.truerteScriptSrc.length === 0) {
|
|
59
|
+
(_e = (_d = this.props).onScriptsLoadError) === null || _e === void 0 ? void 0 : _e.call(_d, new Error('No `truerte` global is present but the `truerteScriptSrc` prop was an empty array.'));
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
const delay = (_g = (_f = this.props.scriptLoading) === null || _f === void 0 ? void 0 : _f.delay) !== null && _g !== void 0 ? _g : 0;
|
|
64
|
+
if (delay > 0) {
|
|
65
|
+
yield new Promise((resolve) => setTimeout(resolve, delay));
|
|
66
|
+
}
|
|
67
|
+
yield (0, BundledTrueRTE_1.loadBundledTrueRTE)({
|
|
68
|
+
plugins: this.resolvePlugins(),
|
|
69
|
+
icons: this.resolveIconPack(),
|
|
70
|
+
model: (_h = this.props.init) === null || _h === void 0 ? void 0 : _h.model,
|
|
71
|
+
theme: (_j = this.props.init) === null || _j === void 0 ? void 0 : _j.theme,
|
|
72
|
+
skin: (_k = this.props.init) === null || _k === void 0 ? void 0 : _k.skin,
|
|
73
|
+
contentCss: (_l = this.props.init) === null || _l === void 0 ? void 0 : _l.content_css
|
|
74
|
+
});
|
|
75
|
+
(_o = (_m = this.props).onScriptsLoad) === null || _o === void 0 ? void 0 : _o.call(_m);
|
|
76
|
+
this.initialise();
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
(_q = (_p = this.props).onScriptsLoadError) === null || _q === void 0 ? void 0 : _q.call(_p, err);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
25
82
|
this.rollbackChange = () => {
|
|
26
83
|
const editor = this.editor;
|
|
27
84
|
const value = this.props.value;
|
|
@@ -92,7 +149,7 @@ class Editor extends React.Component {
|
|
|
92
149
|
}
|
|
93
150
|
};
|
|
94
151
|
this.initialise = (attempts = 0) => {
|
|
95
|
-
var _a, _b
|
|
152
|
+
var _a, _b;
|
|
96
153
|
const target = this.elementRef.current;
|
|
97
154
|
if (!target) {
|
|
98
155
|
return; // Editor has been unmounted
|
|
@@ -120,12 +177,9 @@ class Editor extends React.Component {
|
|
|
120
177
|
if (!truerte) {
|
|
121
178
|
throw new Error('truerte should have been loaded into global scope');
|
|
122
179
|
}
|
|
123
|
-
const resolvedPlugins =
|
|
124
|
-
const
|
|
125
|
-
const resolvedIconPack = this.props.
|
|
126
|
-
? 'truerte-lucide'
|
|
127
|
-
: (_d = this.props.init) === null || _d === void 0 ? void 0 : _d.icons;
|
|
128
|
-
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) => {
|
|
180
|
+
const resolvedPlugins = this.resolvePlugins();
|
|
181
|
+
const resolvedIconPack = this.resolveIconPack();
|
|
182
|
+
const finalInit = Object.assign(Object.assign({}, this.props.init), { selector: undefined, target, readonly: this.props.disabled, inline: this.inline, plugins: resolvedPlugins, icons: resolvedIconPack, toolbar: (_a = this.props.toolbar) !== null && _a !== void 0 ? _a : (_b = this.props.init) === null || _b === void 0 ? void 0 : _b.toolbar, setup: (editor) => {
|
|
129
183
|
this.editor = editor;
|
|
130
184
|
this.assignEditorRef(this.props.editorRef, editor);
|
|
131
185
|
this.bindHandlers({});
|
|
@@ -171,6 +225,14 @@ class Editor extends React.Component {
|
|
|
171
225
|
}
|
|
172
226
|
truerte.init(finalInit);
|
|
173
227
|
};
|
|
228
|
+
this.resolvePlugins = () => { var _a; return (0, Utils_1.mergePlugins)((_a = this.props.init) === null || _a === void 0 ? void 0 : _a.plugins, this.props.plugins); };
|
|
229
|
+
this.resolveIconPack = () => {
|
|
230
|
+
var _a, _b, _c;
|
|
231
|
+
const hasExplicitIconConfig = ((_a = this.props.init) === null || _a === void 0 ? void 0 : _a.icons) !== undefined || ((_b = this.props.init) === null || _b === void 0 ? void 0 : _b.icons_url) !== undefined;
|
|
232
|
+
return this.props.useLucideIcons === true && !hasExplicitIconConfig
|
|
233
|
+
? 'truerte-lucide'
|
|
234
|
+
: (_c = this.props.init) === null || _c === void 0 ? void 0 : _c.icons;
|
|
235
|
+
};
|
|
174
236
|
this.id = this.props.id || (0, Uuid_1.uuid)('truerte-react');
|
|
175
237
|
this.elementRef = React.createRef();
|
|
176
238
|
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;
|
|
@@ -239,25 +301,7 @@ class Editor extends React.Component {
|
|
|
239
301
|
}
|
|
240
302
|
}
|
|
241
303
|
componentDidMount() {
|
|
242
|
-
|
|
243
|
-
if ((0, TrueRTE_1.getTrueRTE)(this.view) !== null) {
|
|
244
|
-
this.initialise();
|
|
245
|
-
}
|
|
246
|
-
else if (Array.isArray(this.props.truerteScriptSrc) && this.props.truerteScriptSrc.length === 0) {
|
|
247
|
-
(_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.'));
|
|
248
|
-
}
|
|
249
|
-
else if ((_c = this.elementRef.current) === null || _c === void 0 ? void 0 : _c.ownerDocument) {
|
|
250
|
-
const successHandler = () => {
|
|
251
|
-
var _a, _b;
|
|
252
|
-
(_b = (_a = this.props).onScriptsLoad) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
253
|
-
this.initialise();
|
|
254
|
-
};
|
|
255
|
-
const errorHandler = (err) => {
|
|
256
|
-
var _a, _b;
|
|
257
|
-
(_b = (_a = this.props).onScriptsLoadError) === null || _b === void 0 ? void 0 : _b.call(_a, err);
|
|
258
|
-
};
|
|
259
|
-
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);
|
|
260
|
-
}
|
|
304
|
+
void this.bootstrapEditor();
|
|
261
305
|
}
|
|
262
306
|
componentWillUnmount() {
|
|
263
307
|
const editor = this.editor;
|
|
@@ -306,15 +350,24 @@ class Editor extends React.Component {
|
|
|
306
350
|
var _a, _b;
|
|
307
351
|
const async = (_a = this.props.scriptLoading) === null || _a === void 0 ? void 0 : _a.async;
|
|
308
352
|
const defer = (_b = this.props.scriptLoading) === null || _b === void 0 ? void 0 : _b.defer;
|
|
353
|
+
const toScriptItem = (src) => ({ src, async, defer });
|
|
309
354
|
if (this.props.truerteScriptSrc !== undefined) {
|
|
310
355
|
if (typeof this.props.truerteScriptSrc === 'string') {
|
|
311
|
-
return
|
|
356
|
+
return this.props.truerteScriptSrc.length > 0 ? [toScriptItem(this.props.truerteScriptSrc)] : [];
|
|
357
|
+
}
|
|
358
|
+
if (Array.isArray(this.props.truerteScriptSrc)) {
|
|
359
|
+
return this.props.truerteScriptSrc
|
|
360
|
+
.filter((src) => typeof src === 'string' && src.length > 0)
|
|
361
|
+
.map(toScriptItem);
|
|
312
362
|
}
|
|
313
363
|
}
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
364
|
+
if (this.props.bundleCoreEditor === false) {
|
|
365
|
+
// fallback to jsDelivr CDN when bundled loading is disabled and no explicit script source is provided
|
|
366
|
+
// `cdnVersion` is in `defaultProps`, so it's always defined.
|
|
367
|
+
const cdnLink = `https://cdn.jsdelivr.net/npm/truerte@${this.props.cdnVersion}/truerte.min.js`;
|
|
368
|
+
return [toScriptItem(cdnLink)];
|
|
369
|
+
}
|
|
370
|
+
return [];
|
|
318
371
|
}
|
|
319
372
|
getInitialValue() {
|
|
320
373
|
if (typeof this.props.initialValue === 'string') {
|
|
@@ -355,4 +408,5 @@ class Editor extends React.Component {
|
|
|
355
408
|
exports.Editor = Editor;
|
|
356
409
|
Editor.defaultProps = {
|
|
357
410
|
cdnVersion: '1',
|
|
411
|
+
bundleCoreEditor: true,
|
|
358
412
|
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const parsePluginNames: (plugins: unknown) => string[];
|
|
2
|
+
export interface BundledTrueRTELoadOptions {
|
|
3
|
+
plugins: unknown;
|
|
4
|
+
icons?: unknown;
|
|
5
|
+
model?: unknown;
|
|
6
|
+
theme?: unknown;
|
|
7
|
+
skin?: unknown;
|
|
8
|
+
contentCss?: unknown;
|
|
9
|
+
}
|
|
10
|
+
export declare const loadBundledTrueRTE: (options: BundledTrueRTELoadOptions) => Promise<void>;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
const toTokens = (value) => value
|
|
11
|
+
.split(/[\s,]+/)
|
|
12
|
+
.map((token) => token.trim())
|
|
13
|
+
.filter((token) => token.length > 0);
|
|
14
|
+
const unique = (items) => Array.from(new Set(items));
|
|
15
|
+
export const parsePluginNames = (plugins) => {
|
|
16
|
+
if (typeof plugins === 'string') {
|
|
17
|
+
return unique(toTokens(plugins));
|
|
18
|
+
}
|
|
19
|
+
if (Array.isArray(plugins)) {
|
|
20
|
+
return unique(plugins.flatMap((item) => typeof item === 'string' ? toTokens(item) : []));
|
|
21
|
+
}
|
|
22
|
+
return [];
|
|
23
|
+
};
|
|
24
|
+
const parseContentCssNames = (contentCss) => {
|
|
25
|
+
if (typeof contentCss === 'string') {
|
|
26
|
+
return unique(toTokens(contentCss));
|
|
27
|
+
}
|
|
28
|
+
if (Array.isArray(contentCss)) {
|
|
29
|
+
return unique(contentCss.flatMap((item) => typeof item === 'string' ? toTokens(item) : []));
|
|
30
|
+
}
|
|
31
|
+
return [];
|
|
32
|
+
};
|
|
33
|
+
const MODEL_LOADERS = {
|
|
34
|
+
dom: () => import('truerte/js/truerte/models/dom/model.js')
|
|
35
|
+
};
|
|
36
|
+
const THEME_LOADERS = {
|
|
37
|
+
silver: () => import('truerte/js/truerte/themes/silver/theme.js')
|
|
38
|
+
};
|
|
39
|
+
const ICON_LOADERS = {
|
|
40
|
+
default: () => import('truerte/js/truerte/icons/default/icons.js'),
|
|
41
|
+
'truerte-lucide': () => import('truerte/js/truerte/icons/truerte-lucide/icons.js')
|
|
42
|
+
};
|
|
43
|
+
const SKIN_LOADERS = {
|
|
44
|
+
oxide: () => import('truerte/js/truerte/skins/ui/oxide/skin.js'),
|
|
45
|
+
'oxide-dark': () => import('truerte/js/truerte/skins/ui/oxide-dark/skin.js'),
|
|
46
|
+
'truerte-5': () => import('truerte/js/truerte/skins/ui/truerte-5/skin.js'),
|
|
47
|
+
'truerte-5-dark': () => import('truerte/js/truerte/skins/ui/truerte-5-dark/skin.js')
|
|
48
|
+
};
|
|
49
|
+
const CONTENT_CSS_LOADERS = {
|
|
50
|
+
default: () => import('truerte/js/truerte/skins/content/default/content.js'),
|
|
51
|
+
dark: () => import('truerte/js/truerte/skins/content/dark/content.js'),
|
|
52
|
+
document: () => import('truerte/js/truerte/skins/content/document/content.js'),
|
|
53
|
+
writer: () => import('truerte/js/truerte/skins/content/writer/content.js'),
|
|
54
|
+
'truerte-5': () => import('truerte/js/truerte/skins/content/truerte-5/content.js'),
|
|
55
|
+
'truerte-5-dark': () => import('truerte/js/truerte/skins/content/truerte-5-dark/content.js')
|
|
56
|
+
};
|
|
57
|
+
const PLUGIN_LOADERS = {
|
|
58
|
+
accordion: () => import('truerte/js/truerte/plugins/accordion/plugin.js'),
|
|
59
|
+
advlist: () => import('truerte/js/truerte/plugins/advlist/plugin.js'),
|
|
60
|
+
anchor: () => import('truerte/js/truerte/plugins/anchor/plugin.js'),
|
|
61
|
+
autolink: () => import('truerte/js/truerte/plugins/autolink/plugin.js'),
|
|
62
|
+
autoresize: () => import('truerte/js/truerte/plugins/autoresize/plugin.js'),
|
|
63
|
+
autosave: () => import('truerte/js/truerte/plugins/autosave/plugin.js'),
|
|
64
|
+
casechange: () => import('truerte/js/truerte/plugins/casechange/plugin.js'),
|
|
65
|
+
charmap: () => import('truerte/js/truerte/plugins/charmap/plugin.js'),
|
|
66
|
+
code: () => import('truerte/js/truerte/plugins/code/plugin.js'),
|
|
67
|
+
codesample: () => import('truerte/js/truerte/plugins/codesample/plugin.js'),
|
|
68
|
+
directionality: () => import('truerte/js/truerte/plugins/directionality/plugin.js'),
|
|
69
|
+
emoticons: () => import('truerte/js/truerte/plugins/emoticons/plugin.js'),
|
|
70
|
+
fullscreen: () => import('truerte/js/truerte/plugins/fullscreen/plugin.js'),
|
|
71
|
+
help: () => import('truerte/js/truerte/plugins/help/plugin.js'),
|
|
72
|
+
image: () => import('truerte/js/truerte/plugins/image/plugin.js'),
|
|
73
|
+
importcss: () => import('truerte/js/truerte/plugins/importcss/plugin.js'),
|
|
74
|
+
insertdatetime: () => import('truerte/js/truerte/plugins/insertdatetime/plugin.js'),
|
|
75
|
+
letterspacing: () => import('truerte/js/truerte/plugins/letterspacing/plugin.js'),
|
|
76
|
+
link: () => import('truerte/js/truerte/plugins/link/plugin.js'),
|
|
77
|
+
lists: () => import('truerte/js/truerte/plugins/lists/plugin.js'),
|
|
78
|
+
lucideicons: () => import('truerte/js/truerte/plugins/lucideicons/plugin.js'),
|
|
79
|
+
media: () => import('truerte/js/truerte/plugins/media/plugin.js'),
|
|
80
|
+
nonbreaking: () => import('truerte/js/truerte/plugins/nonbreaking/plugin.js'),
|
|
81
|
+
pagebreak: () => import('truerte/js/truerte/plugins/pagebreak/plugin.js'),
|
|
82
|
+
paragraphspacing: () => import('truerte/js/truerte/plugins/paragraphspacing/plugin.js'),
|
|
83
|
+
preview: () => import('truerte/js/truerte/plugins/preview/plugin.js'),
|
|
84
|
+
quickbars: () => import('truerte/js/truerte/plugins/quickbars/plugin.js'),
|
|
85
|
+
save: () => import('truerte/js/truerte/plugins/save/plugin.js'),
|
|
86
|
+
searchreplace: () => import('truerte/js/truerte/plugins/searchreplace/plugin.js'),
|
|
87
|
+
table: () => import('truerte/js/truerte/plugins/table/plugin.js'),
|
|
88
|
+
template: () => import('truerte/js/truerte/plugins/template/plugin.js'),
|
|
89
|
+
visualblocks: () => import('truerte/js/truerte/plugins/visualblocks/plugin.js'),
|
|
90
|
+
visualchars: () => import('truerte/js/truerte/plugins/visualchars/plugin.js'),
|
|
91
|
+
wordcount: () => import('truerte/js/truerte/plugins/wordcount/plugin.js')
|
|
92
|
+
};
|
|
93
|
+
const loadedModels = new Set();
|
|
94
|
+
const loadedThemes = new Set();
|
|
95
|
+
const loadedIcons = new Set();
|
|
96
|
+
const loadedSkins = new Set();
|
|
97
|
+
const loadedContentCss = new Set();
|
|
98
|
+
const loadedPlugins = new Set();
|
|
99
|
+
let corePromise;
|
|
100
|
+
const loadCore = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
101
|
+
corePromise !== null && corePromise !== void 0 ? corePromise : (corePromise = import('truerte/js/truerte/truerte.js').then(() => undefined));
|
|
102
|
+
yield corePromise;
|
|
103
|
+
});
|
|
104
|
+
const loadCachedResource = (cache, name, loaders) => __awaiter(void 0, void 0, void 0, function* () {
|
|
105
|
+
if (cache.has(name)) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const loader = loaders[name];
|
|
109
|
+
if (!loader) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
yield loader();
|
|
113
|
+
cache.add(name);
|
|
114
|
+
});
|
|
115
|
+
export const loadBundledTrueRTE = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
116
|
+
yield loadCore();
|
|
117
|
+
const model = typeof options.model === 'string' ? options.model : 'dom';
|
|
118
|
+
const theme = typeof options.theme === 'string' ? options.theme : 'silver';
|
|
119
|
+
const iconPack = typeof options.icons === 'string' ? options.icons : 'default';
|
|
120
|
+
const skin = options.skin === false ? false : (typeof options.skin === 'string' ? options.skin : 'oxide');
|
|
121
|
+
const contentCss = options.contentCss === false
|
|
122
|
+
? []
|
|
123
|
+
: options.contentCss === undefined
|
|
124
|
+
? ['default']
|
|
125
|
+
: parseContentCssNames(options.contentCss);
|
|
126
|
+
const plugins = parsePluginNames(options.plugins);
|
|
127
|
+
yield Promise.all([
|
|
128
|
+
loadCachedResource(loadedModels, model, MODEL_LOADERS),
|
|
129
|
+
loadCachedResource(loadedThemes, theme, THEME_LOADERS),
|
|
130
|
+
loadCachedResource(loadedIcons, iconPack, ICON_LOADERS),
|
|
131
|
+
...(skin ? [loadCachedResource(loadedSkins, skin, SKIN_LOADERS)] : []),
|
|
132
|
+
...contentCss.map((name) => loadCachedResource(loadedContentCss, name, CONTENT_CSS_LOADERS)),
|
|
133
|
+
]);
|
|
134
|
+
yield Promise.all(plugins.map((plugin) => loadCachedResource(loadedPlugins, plugin, PLUGIN_LOADERS)));
|
|
135
|
+
});
|
|
@@ -71,11 +71,17 @@ export interface IProps {
|
|
|
71
71
|
*/
|
|
72
72
|
tabIndex: number;
|
|
73
73
|
/**
|
|
74
|
-
* @description The TrueRTE version to use when loading from jsDelivr CDN.
|
|
74
|
+
* @description The TrueRTE version to use when loading from jsDelivr CDN. This is only used when
|
|
75
|
+
* `bundleCoreEditor` is `false` and `truerteScriptSrc` is not specified. By default, version 1
|
|
75
76
|
* (that is, the latest minor and patch release of the major version 1) will be used.
|
|
76
77
|
* For more info about the possible version formats, see the {@link https://www.jsdelivr.com/documentation#id-npm jsDelivr documentation}.
|
|
77
78
|
*/
|
|
78
79
|
cdnVersion: Version;
|
|
80
|
+
/**
|
|
81
|
+
* @description When true (default), load bundled TrueRTE core/assets from the installed `truerte` package
|
|
82
|
+
* instead of injecting a script tag. Set to false to use script URL loading fallback behavior.
|
|
83
|
+
*/
|
|
84
|
+
bundleCoreEditor: boolean;
|
|
79
85
|
/**
|
|
80
86
|
* @see {@link https://www.truerte.org/docs/truerte/1/react-ref/#plugins React Tech Ref - plugins}
|
|
81
87
|
* @description The plugins to load into the editor. Equivalent to the `plugins` option in TrueRTE.
|
|
@@ -102,9 +108,9 @@ export interface IProps {
|
|
|
102
108
|
*/
|
|
103
109
|
editorRef: EditorInstanceRef;
|
|
104
110
|
/**
|
|
105
|
-
* @description
|
|
111
|
+
* @description URL(s) of TrueRTE script files to lazy load at runtime.
|
|
106
112
|
*/
|
|
107
|
-
truerteScriptSrc: string;
|
|
113
|
+
truerteScriptSrc: string | string[];
|
|
108
114
|
/**
|
|
109
115
|
* @description When true, automatically configures `icons: 'truerte-lucide'`
|
|
110
116
|
* unless you explicitly provide `init.icons` or `init.icons_url`.
|
|
@@ -147,6 +153,7 @@ export declare class Editor extends React.Component<IAllProps> {
|
|
|
147
153
|
private get view();
|
|
148
154
|
componentDidUpdate(prevProps: Partial<IAllProps>): void;
|
|
149
155
|
componentDidMount(): void;
|
|
156
|
+
private bootstrapEditor;
|
|
150
157
|
componentWillUnmount(): void;
|
|
151
158
|
render(): React.ReactElement<{
|
|
152
159
|
ref: React.RefObject<HTMLElement | null>;
|
|
@@ -167,5 +174,7 @@ export declare class Editor extends React.Component<IAllProps> {
|
|
|
167
174
|
private handleEditorChangeSpecial;
|
|
168
175
|
private assignEditorRef;
|
|
169
176
|
private initialise;
|
|
177
|
+
private resolvePlugins;
|
|
178
|
+
private resolveIconPack;
|
|
170
179
|
}
|
|
171
180
|
export {};
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
1
10
|
/**
|
|
2
11
|
* Official TrueRTE React component
|
|
3
12
|
* Copyright (c) 2022 Ephox Corporation DBA Tiny Technologies, Inc.
|
|
@@ -5,6 +14,7 @@
|
|
|
5
14
|
* Licensed under the MIT license (https://github.com/truerte/truerte-react/blob/main/LICENSE.TXT)
|
|
6
15
|
*/
|
|
7
16
|
import * as React from 'react';
|
|
17
|
+
import { loadBundledTrueRTE } from '../BundledTrueRTE';
|
|
8
18
|
import { ScriptLoader } from '../ScriptLoader2';
|
|
9
19
|
import { getTrueRTE } from '../TrueRTE';
|
|
10
20
|
import { isFunction, isTextareaOrInput, mergePlugins, configHandlers, isBeforeInputEventAvailable, setMode } from '../Utils';
|
|
@@ -19,6 +29,53 @@ export class Editor extends React.Component {
|
|
|
19
29
|
super(props);
|
|
20
30
|
this.rollbackTimer = undefined;
|
|
21
31
|
this.valueCursor = undefined;
|
|
32
|
+
this.bootstrapEditor = () => __awaiter(this, void 0, void 0, function* () {
|
|
33
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
34
|
+
if (getTrueRTE(this.view) !== null) {
|
|
35
|
+
this.initialise();
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (!((_a = this.elementRef.current) === null || _a === void 0 ? void 0 : _a.ownerDocument)) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const scriptSources = this.getScriptSources();
|
|
42
|
+
if (scriptSources.length > 0) {
|
|
43
|
+
const successHandler = () => {
|
|
44
|
+
var _a, _b;
|
|
45
|
+
(_b = (_a = this.props).onScriptsLoad) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
46
|
+
this.initialise();
|
|
47
|
+
};
|
|
48
|
+
const errorHandler = (err) => {
|
|
49
|
+
var _a, _b;
|
|
50
|
+
(_b = (_a = this.props).onScriptsLoadError) === null || _b === void 0 ? void 0 : _b.call(_a, err);
|
|
51
|
+
};
|
|
52
|
+
ScriptLoader.loadList(this.elementRef.current.ownerDocument, scriptSources, (_c = (_b = this.props.scriptLoading) === null || _b === void 0 ? void 0 : _b.delay) !== null && _c !== void 0 ? _c : 0, successHandler, errorHandler);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (Array.isArray(this.props.truerteScriptSrc) && this.props.truerteScriptSrc.length === 0) {
|
|
56
|
+
(_e = (_d = this.props).onScriptsLoadError) === null || _e === void 0 ? void 0 : _e.call(_d, new Error('No `truerte` global is present but the `truerteScriptSrc` prop was an empty array.'));
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
const delay = (_g = (_f = this.props.scriptLoading) === null || _f === void 0 ? void 0 : _f.delay) !== null && _g !== void 0 ? _g : 0;
|
|
61
|
+
if (delay > 0) {
|
|
62
|
+
yield new Promise((resolve) => setTimeout(resolve, delay));
|
|
63
|
+
}
|
|
64
|
+
yield loadBundledTrueRTE({
|
|
65
|
+
plugins: this.resolvePlugins(),
|
|
66
|
+
icons: this.resolveIconPack(),
|
|
67
|
+
model: (_h = this.props.init) === null || _h === void 0 ? void 0 : _h.model,
|
|
68
|
+
theme: (_j = this.props.init) === null || _j === void 0 ? void 0 : _j.theme,
|
|
69
|
+
skin: (_k = this.props.init) === null || _k === void 0 ? void 0 : _k.skin,
|
|
70
|
+
contentCss: (_l = this.props.init) === null || _l === void 0 ? void 0 : _l.content_css
|
|
71
|
+
});
|
|
72
|
+
(_o = (_m = this.props).onScriptsLoad) === null || _o === void 0 ? void 0 : _o.call(_m);
|
|
73
|
+
this.initialise();
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
(_q = (_p = this.props).onScriptsLoadError) === null || _q === void 0 ? void 0 : _q.call(_p, err);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
22
79
|
this.rollbackChange = () => {
|
|
23
80
|
const editor = this.editor;
|
|
24
81
|
const value = this.props.value;
|
|
@@ -89,7 +146,7 @@ export class Editor extends React.Component {
|
|
|
89
146
|
}
|
|
90
147
|
};
|
|
91
148
|
this.initialise = (attempts = 0) => {
|
|
92
|
-
var _a, _b
|
|
149
|
+
var _a, _b;
|
|
93
150
|
const target = this.elementRef.current;
|
|
94
151
|
if (!target) {
|
|
95
152
|
return; // Editor has been unmounted
|
|
@@ -117,12 +174,9 @@ export class Editor extends React.Component {
|
|
|
117
174
|
if (!truerte) {
|
|
118
175
|
throw new Error('truerte should have been loaded into global scope');
|
|
119
176
|
}
|
|
120
|
-
const resolvedPlugins =
|
|
121
|
-
const
|
|
122
|
-
const resolvedIconPack = this.props.
|
|
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) => {
|
|
177
|
+
const resolvedPlugins = this.resolvePlugins();
|
|
178
|
+
const resolvedIconPack = this.resolveIconPack();
|
|
179
|
+
const finalInit = Object.assign(Object.assign({}, this.props.init), { selector: undefined, target, readonly: this.props.disabled, inline: this.inline, plugins: resolvedPlugins, icons: resolvedIconPack, toolbar: (_a = this.props.toolbar) !== null && _a !== void 0 ? _a : (_b = this.props.init) === null || _b === void 0 ? void 0 : _b.toolbar, setup: (editor) => {
|
|
126
180
|
this.editor = editor;
|
|
127
181
|
this.assignEditorRef(this.props.editorRef, editor);
|
|
128
182
|
this.bindHandlers({});
|
|
@@ -168,6 +222,14 @@ export class Editor extends React.Component {
|
|
|
168
222
|
}
|
|
169
223
|
truerte.init(finalInit);
|
|
170
224
|
};
|
|
225
|
+
this.resolvePlugins = () => { var _a; return mergePlugins((_a = this.props.init) === null || _a === void 0 ? void 0 : _a.plugins, this.props.plugins); };
|
|
226
|
+
this.resolveIconPack = () => {
|
|
227
|
+
var _a, _b, _c;
|
|
228
|
+
const hasExplicitIconConfig = ((_a = this.props.init) === null || _a === void 0 ? void 0 : _a.icons) !== undefined || ((_b = this.props.init) === null || _b === void 0 ? void 0 : _b.icons_url) !== undefined;
|
|
229
|
+
return this.props.useLucideIcons === true && !hasExplicitIconConfig
|
|
230
|
+
? 'truerte-lucide'
|
|
231
|
+
: (_c = this.props.init) === null || _c === void 0 ? void 0 : _c.icons;
|
|
232
|
+
};
|
|
171
233
|
this.id = this.props.id || uuid('truerte-react');
|
|
172
234
|
this.elementRef = React.createRef();
|
|
173
235
|
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;
|
|
@@ -236,25 +298,7 @@ export class Editor extends React.Component {
|
|
|
236
298
|
}
|
|
237
299
|
}
|
|
238
300
|
componentDidMount() {
|
|
239
|
-
|
|
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
|
-
}
|
|
301
|
+
void this.bootstrapEditor();
|
|
258
302
|
}
|
|
259
303
|
componentWillUnmount() {
|
|
260
304
|
const editor = this.editor;
|
|
@@ -303,15 +347,24 @@ export class Editor extends React.Component {
|
|
|
303
347
|
var _a, _b;
|
|
304
348
|
const async = (_a = this.props.scriptLoading) === null || _a === void 0 ? void 0 : _a.async;
|
|
305
349
|
const defer = (_b = this.props.scriptLoading) === null || _b === void 0 ? void 0 : _b.defer;
|
|
350
|
+
const toScriptItem = (src) => ({ src, async, defer });
|
|
306
351
|
if (this.props.truerteScriptSrc !== undefined) {
|
|
307
352
|
if (typeof this.props.truerteScriptSrc === 'string') {
|
|
308
|
-
return
|
|
353
|
+
return this.props.truerteScriptSrc.length > 0 ? [toScriptItem(this.props.truerteScriptSrc)] : [];
|
|
354
|
+
}
|
|
355
|
+
if (Array.isArray(this.props.truerteScriptSrc)) {
|
|
356
|
+
return this.props.truerteScriptSrc
|
|
357
|
+
.filter((src) => typeof src === 'string' && src.length > 0)
|
|
358
|
+
.map(toScriptItem);
|
|
309
359
|
}
|
|
310
360
|
}
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
361
|
+
if (this.props.bundleCoreEditor === false) {
|
|
362
|
+
// fallback to jsDelivr CDN when bundled loading is disabled and no explicit script source is provided
|
|
363
|
+
// `cdnVersion` is in `defaultProps`, so it's always defined.
|
|
364
|
+
const cdnLink = `https://cdn.jsdelivr.net/npm/truerte@${this.props.cdnVersion}/truerte.min.js`;
|
|
365
|
+
return [toScriptItem(cdnLink)];
|
|
366
|
+
}
|
|
367
|
+
return [];
|
|
315
368
|
}
|
|
316
369
|
getInitialValue() {
|
|
317
370
|
if (typeof this.props.initialValue === 'string') {
|
|
@@ -351,4 +404,5 @@ export class Editor extends React.Component {
|
|
|
351
404
|
}
|
|
352
405
|
Editor.defaultProps = {
|
|
353
406
|
cdnVersion: '1',
|
|
407
|
+
bundleCoreEditor: true,
|
|
354
408
|
};
|
package/package.json
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "truerte-react",
|
|
3
|
+
"version": "0.0.6",
|
|
3
4
|
"description": "TrueRTE React Component",
|
|
4
5
|
"repository": {
|
|
5
6
|
"type": "git",
|
|
@@ -32,15 +33,9 @@
|
|
|
32
33
|
],
|
|
33
34
|
"license": "MIT",
|
|
34
35
|
"peerDependencies": {
|
|
35
|
-
"truerte": "^0.0.3",
|
|
36
36
|
"react": "^19.0.0 || ^18.0.0 || ^17.0.1 || ^16.7.0",
|
|
37
37
|
"react-dom": "^19.0.0 || ^18.0.0 || ^17.0.1 || ^16.7.0"
|
|
38
38
|
},
|
|
39
|
-
"peerDependenciesMeta": {
|
|
40
|
-
"truerte": {
|
|
41
|
-
"optional": true
|
|
42
|
-
}
|
|
43
|
-
},
|
|
44
39
|
"devDependencies": {
|
|
45
40
|
"@ephox/agar": "8.0.1",
|
|
46
41
|
"@ephox/bedrock-client": "^15.0.0",
|
|
@@ -50,14 +45,14 @@
|
|
|
50
45
|
"@types/node": "^22.17.2",
|
|
51
46
|
"@types/react": "^19.1.10",
|
|
52
47
|
"@types/react-dom": "^19.1.7",
|
|
53
|
-
"truerte": "file:../truerte/modules/truerte",
|
|
54
|
-
"truerte-1": "file:../truerte/modules/truerte",
|
|
55
48
|
"react": "^19.1.1",
|
|
56
49
|
"react-dom": "^19.1.1",
|
|
57
50
|
"rimraf": "^6.0.1",
|
|
51
|
+
"truerte-1": "file:../truerte/modules/truerte",
|
|
58
52
|
"typescript": "~5.8.3",
|
|
59
53
|
"vite": "^6.3.5"
|
|
60
54
|
},
|
|
61
|
-
"
|
|
62
|
-
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"truerte": "^0.0.3 || ^1.0.0"
|
|
57
|
+
}
|
|
63
58
|
}
|