-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathtinymce-config.mts
More file actions
184 lines (172 loc) · 8.64 KB
/
Copy pathtinymce-config.mts
File metadata and controls
184 lines (172 loc) · 8.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
// Copyright (C) 2026 Bryan A. Jones.
//
// This file is part of the CodeChat Editor. The CodeChat Editor is free
// software: you can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation, either
// version 3 of the License, or (at your option) any later version.
//
// The CodeChat Editor is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// the CodeChat Editor. If not, see
// [http://www.gnu.org/licenses](http://www.gnu.org/licenses).
//
// `tinymce-config.ts` -- integrate and configure the TinyMCE editor for use
// with the CodeChat Editor
// =========================================================================
//
// Import TinyMCE.
import { default as tinymce, Editor, RawEditorOptions } from "tinymce";
// This is taken from the
// [TinyMCE example code](https://github.com/tinymce/tinymce/blob/main/modules/tinymce/src/core/demo/ts/demo/TinyMceDemo.ts).
// However, esbuild doesn't accept it. This is the workaround:
export { tinymce };
// Default icons are required for TinyMCE 5.3 or above.
import "tinymce/icons/default/index.js";
// A theme is also required.
import "tinymce/themes/silver/index.js";
// Import the skin to use; we're using an inline editor, so load the inline CSS.
import "tinymce/skins/ui/oxide/skin.css";
import "tinymce/skins/ui/oxide/content.inline.css";
// Without this, TinyMCE produces errors.
import "tinymce/models/dom/index.js";
// Import plugins.
import "tinymce/plugins/advlist/index.js";
import "tinymce/plugins/anchor/index.js";
import "tinymce/plugins/charmap/index.js";
import "tinymce/plugins/directionality/index.js";
// Omit these, since they're large and infrequently used. TODO: dynamically load
// these on first use.
/// import "tinymce/plugins/emoticons/index.js";
/// import "tinymce/plugins/emoticons/js/emojis.js";
/// import "tinymce/plugins/emoticons/js/emojiimages.js";
import "tinymce/plugins/help/index.js";
// TODO: this should be a dynamic import based on the current language.
import "tinymce/plugins/help/js/i18n/keynav/en.js";
import "tinymce/plugins/image/index.js";
import "tinymce/plugins/link/index.js";
import "tinymce/plugins/lists/index.js";
import "tinymce/plugins/media/index.js";
import "tinymce/plugins/quickbars/index.js";
import "tinymce/plugins/searchreplace/index.js";
import "tinymce/plugins/table/index.js";
import "tinymce/plugins/visualblocks/index.js";
import "tinymce/plugins/visualchars/index.js";
// Import premium plugins. NOTE: Download separately and add these to
// `src/plugins`.
/// import './plugins/checklist/plugin';
/// import './plugins/powerpaste/plugin';
/// import './plugins/powerpaste/js/wordimport';
// Initialize TinyMCE.
export const init = async (
// Provide additional editor options; note that the basic setup provided
// below can't be overridden by these options. The only exception is a value
// for `setup`, which will be combined with the setup defined in this
// function.
additionalOptions: RawEditorOptions,
) => {
// Merge the provided options with this basic setup, giving priority to the
// settings below.
const combinedOptions: RawEditorOptions = Object.assign(
{},
additionalOptions,
{
// See the list of
// [plugins](https://www.tiny.cloud/docs/tinymce/latest/plugins/).
// These must be accompanied by the corresponding import above.
plugins:
"advlist anchor charmap directionality help image link lists media quickbars searchreplace table visualblocks visualchars",
// The imports above apply the skins; don't try to dynamically load
// the skin's CSS.
skin: false,
// Enable the
// [browser-supplied spellchecker](https://www.tiny.cloud/docs/tinymce/latest/spelling/#browser_spellcheck),
// since TinyMCE's spellchecker is a premium feature.
browser_spellcheck: true,
// Place the Tiny MCE menu bar at the top of the screen; otherwise,
// it floats in front of text, sometimes obscuring what the user
// wants to edit. See the
// [docs](https://www.tiny.cloud/docs/configure/editor-appearance/#fixed_toolbar_container).
fixed_toolbar_container: "#CodeChat-menu",
inline: true,
// When true, this still prevents hyperlinks to anchors on the
// current page from working correctly. There's an onClick handler
// that prevents links in the current page from working -- need to
// look into this. See also
// [a related GitHub issue](https://github.com/tinymce/tinymce/issues/3836).
//readonly: true // Per the comment above, this is commented out.
// Use relative URLs in hyperlinks.
relative_urls: true,
// Disable the
// [TinyMCE toolbar buttons](https://www.tiny.cloud/blog/tinymce-toolbar/)
// to provide more real estate on the screen.
toolbar: false,
// Don't show the file option on the
// [menu](https://www.tiny.cloud/docs/tinymce/latest/menus-configuration-options/#menubar),
// which is useless.
menubar: "edit insert view format table tools help",
// See
// [License key](https://www.tiny.cloud/docs/tinymce/latest/license-key).
license_key: "gpl",
// Block drag-and-drop of unsupported images and files. See the
// [docs](https://www.tiny.cloud/docs/tinymce/latest/file-image-upload/#block_unsupported_drop).
block_unsupported_drop: true,
// Prevent drag-and-dropping images; this create a mess. See the
// [docs](https://www.tiny.cloud/docs/tinymce/latest/copy-and-paste/#paste_data_images).
paste_data_images: false,
// TinyMCE's "Get all features" promotional link breaks accessibility. It carries `aria-hidden="true"` yet remains in the tab order, which is the
// `aria-hidden-focus` failure: a keyboard user lands on a control their screen
// reader has been told does not exist. Separately, its text fails contrast at
// 4.31:1 (`#086be6` on `#e8f1f8`) against the 4.5:1 requirement.
// Disable it.
promotion: false,
// ### Settings for plugins
//
// [Image](https://www.tiny.cloud/docs/plugins/opensource/image/)
image_caption: true,
image_advtab: true,
image_title: true,
// Quickbar config: disable the insert toolbar (which doesn't seem
// useful, and also has the image insert, which is problematic
// currently).
quickbars_insert_toolbar: false,
// Put more buttons on the
// [quick toolbar](https://www.tiny.cloud/docs/tinymce/latest/quickbars/)
// that appears when text is selected.
quickbars_selection_toolbar:
"bold italic underline codeformat | quicklink h2 h3",
// Needed to allow custom elements.
extended_valid_elements:
"graphviz-graph[scale],wc-mermaid,xref[contenteditable|ref],fragment[contenteditable|following|id]",
// Per the [docs](https://www.tiny.cloud/docs/tinymce/latest/content-filtering/#custom_elements), `~` marks tags as an inline element, not a block element.
custom_elements: "graphviz-graph,wc-mermaid,~xref,~fragment",
},
);
// Merge in additional setup code.
const oldSetup = combinedOptions.setup;
combinedOptions.setup =
// Add a "Format as code" button (generated by Gemini).
(editor: Editor) => {
oldSetup?.(editor);
editor.ui.registry.addToggleButton("codeformat", {
text: "<>",
tooltip: "Format as code",
onAction: () =>
editor.execCommand("mceToggleFormat", false, "code"),
onSetup: (api) => {
const changed = editor.formatter.formatChanged(
"code",
(state) => api.setActive(state),
);
return () => changed.unbind();
},
});
};
// Use these combined options to
// [init](https://www.tiny.cloud/docs/tinymce/latest/apis/tinymce.root/#init)
// TinyMCE.
return await tinymce.init(combinedOptions);
};