tulih-editor 0.1.0

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.
Files changed (122) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +331 -0
  3. package/dist/tulih-editor.css +1 -0
  4. package/dist/tulih-editor.es.js +3051 -0
  5. package/dist/tulih-editor.es.js.map +1 -0
  6. package/dist/tulih-editor.umd.js +8 -0
  7. package/dist/tulih-editor.umd.js.map +1 -0
  8. package/dist/types/core/Editor.d.ts +20 -0
  9. package/dist/types/core/PluginManager.d.ts +22 -0
  10. package/dist/types/core/helpers.d.ts +22 -0
  11. package/dist/types/index.d.ts +5 -0
  12. package/dist/types/plugins/align.d.ts +3 -0
  13. package/dist/types/plugins/autoLinkify.d.ts +3 -0
  14. package/dist/types/plugins/autosave.d.ts +3 -0
  15. package/dist/types/plugins/block.d.ts +3 -0
  16. package/dist/types/plugins/caseTransform.d.ts +3 -0
  17. package/dist/types/plugins/codeBlock.d.ts +3 -0
  18. package/dist/types/plugins/colors.d.ts +3 -0
  19. package/dist/types/plugins/darkMode.d.ts +3 -0
  20. package/dist/types/plugins/direction.d.ts +3 -0
  21. package/dist/types/plugins/dragDrop.d.ts +3 -0
  22. package/dist/types/plugins/emoji.d.ts +3 -0
  23. package/dist/types/plugins/emojiAutocomplete.d.ts +3 -0
  24. package/dist/types/plugins/findReplace.d.ts +3 -0
  25. package/dist/types/plugins/floatingToolbar.d.ts +3 -0
  26. package/dist/types/plugins/fontFamily.d.ts +3 -0
  27. package/dist/types/plugins/fontSize.d.ts +3 -0
  28. package/dist/types/plugins/fullscreen.d.ts +3 -0
  29. package/dist/types/plugins/history.d.ts +3 -0
  30. package/dist/types/plugins/hr.d.ts +3 -0
  31. package/dist/types/plugins/iframe.d.ts +3 -0
  32. package/dist/types/plugins/image.d.ts +3 -0
  33. package/dist/types/plugins/imageProps.d.ts +3 -0
  34. package/dist/types/plugins/imageTools.d.ts +3 -0
  35. package/dist/types/plugins/indent.d.ts +3 -0
  36. package/dist/types/plugins/index.d.ts +2 -0
  37. package/dist/types/plugins/inline.d.ts +3 -0
  38. package/dist/types/plugins/inlineCode.d.ts +3 -0
  39. package/dist/types/plugins/keyboardShortcuts.d.ts +3 -0
  40. package/dist/types/plugins/lineHeight.d.ts +3 -0
  41. package/dist/types/plugins/link.d.ts +3 -0
  42. package/dist/types/plugins/linkTooltip.d.ts +3 -0
  43. package/dist/types/plugins/list.d.ts +3 -0
  44. package/dist/types/plugins/markdown.d.ts +3 -0
  45. package/dist/types/plugins/mediaEmbed.d.ts +3 -0
  46. package/dist/types/plugins/pasteImage.d.ts +3 -0
  47. package/dist/types/plugins/pastePlain.d.ts +3 -0
  48. package/dist/types/plugins/pre.d.ts +3 -0
  49. package/dist/types/plugins/readOnly.d.ts +3 -0
  50. package/dist/types/plugins/shortcutCustomizer.d.ts +3 -0
  51. package/dist/types/plugins/shortcutsHelp.d.ts +3 -0
  52. package/dist/types/plugins/source.d.ts +3 -0
  53. package/dist/types/plugins/specialChars.d.ts +3 -0
  54. package/dist/types/plugins/statusBar.d.ts +3 -0
  55. package/dist/types/plugins/subSuper.d.ts +3 -0
  56. package/dist/types/plugins/table.d.ts +3 -0
  57. package/dist/types/plugins/tableBg.d.ts +3 -0
  58. package/dist/types/plugins/tableTools.d.ts +3 -0
  59. package/dist/types/plugins/toolbarCollapse.d.ts +3 -0
  60. package/dist/types/plugins/unlink.d.ts +3 -0
  61. package/dist/types/plugins/wordCount.d.ts +3 -0
  62. package/dist/types/types.d.ts +226 -0
  63. package/package.json +66 -0
  64. package/src/core/Editor.ts +460 -0
  65. package/src/core/PluginManager.ts +140 -0
  66. package/src/core/helpers.ts +209 -0
  67. package/src/css.d.ts +2 -0
  68. package/src/index.ts +87 -0
  69. package/src/plugins/align.ts +72 -0
  70. package/src/plugins/autoLinkify.ts +34 -0
  71. package/src/plugins/autosave.ts +69 -0
  72. package/src/plugins/block.ts +32 -0
  73. package/src/plugins/caseTransform.ts +54 -0
  74. package/src/plugins/codeBlock.ts +93 -0
  75. package/src/plugins/colors.ts +68 -0
  76. package/src/plugins/darkMode.ts +123 -0
  77. package/src/plugins/direction.ts +30 -0
  78. package/src/plugins/dragDrop.ts +68 -0
  79. package/src/plugins/emoji.ts +188 -0
  80. package/src/plugins/emojiAutocomplete.ts +183 -0
  81. package/src/plugins/findReplace.ts +229 -0
  82. package/src/plugins/floatingToolbar.ts +258 -0
  83. package/src/plugins/fontFamily.ts +41 -0
  84. package/src/plugins/fontSize.ts +32 -0
  85. package/src/plugins/fullscreen.ts +36 -0
  86. package/src/plugins/history.ts +14 -0
  87. package/src/plugins/hr.ts +118 -0
  88. package/src/plugins/iframe.ts +88 -0
  89. package/src/plugins/image.ts +107 -0
  90. package/src/plugins/imageProps.ts +119 -0
  91. package/src/plugins/imageTools.ts +344 -0
  92. package/src/plugins/indent.ts +29 -0
  93. package/src/plugins/index.ts +101 -0
  94. package/src/plugins/inline.ts +17 -0
  95. package/src/plugins/inlineCode.ts +21 -0
  96. package/src/plugins/keyboardShortcuts.ts +92 -0
  97. package/src/plugins/lineHeight.ts +40 -0
  98. package/src/plugins/link.ts +344 -0
  99. package/src/plugins/linkTooltip.ts +63 -0
  100. package/src/plugins/list.ts +141 -0
  101. package/src/plugins/markdown.ts +61 -0
  102. package/src/plugins/mediaEmbed.ts +44 -0
  103. package/src/plugins/pasteImage.ts +61 -0
  104. package/src/plugins/pastePlain.ts +43 -0
  105. package/src/plugins/pre.ts +11 -0
  106. package/src/plugins/readOnly.ts +46 -0
  107. package/src/plugins/shortcutCustomizer.ts +125 -0
  108. package/src/plugins/shortcutsHelp.ts +51 -0
  109. package/src/plugins/source.ts +77 -0
  110. package/src/plugins/specialChars.ts +64 -0
  111. package/src/plugins/statusBar.ts +85 -0
  112. package/src/plugins/subSuper.ts +20 -0
  113. package/src/plugins/table.ts +166 -0
  114. package/src/plugins/tableBg.ts +11 -0
  115. package/src/plugins/tableTools.ts +475 -0
  116. package/src/plugins/toolbarCollapse.ts +14 -0
  117. package/src/plugins/unlink.ts +29 -0
  118. package/src/plugins/wordCount.ts +34 -0
  119. package/src/styles/base.css +258 -0
  120. package/src/styles/editor.css +309 -0
  121. package/src/styles/index.css +6 -0
  122. package/src/types.ts +278 -0
package/src/types.ts ADDED
@@ -0,0 +1,278 @@
1
+ /**
2
+ * Public type definitions for TulihEditor.
3
+ *
4
+ * These types describe the plugin contract, the editor options, and the
5
+ * runtime context (`ctx`) handed to every plugin's `init`/`destroy` hook.
6
+ */
7
+
8
+ /* ------------------------------------------------------------------ *
9
+ * Feature flags
10
+ * ------------------------------------------------------------------ */
11
+
12
+ /**
13
+ * Map of plugin name -> enabled. Every built-in plugin is listed for
14
+ * autocomplete, but any custom plugin name is accepted too.
15
+ */
16
+ export interface Features {
17
+ block?: boolean;
18
+ inline?: boolean;
19
+ pre?: boolean;
20
+ inlineCode?: boolean;
21
+ subSuper?: boolean;
22
+ removeFormat?: boolean;
23
+ keyboardShortcuts?: boolean;
24
+ readOnly?: boolean;
25
+ linkTooltip?: boolean;
26
+ emojiAutocomplete?: boolean;
27
+ statusBar?: boolean;
28
+ codeBlock?: boolean;
29
+ mediaEmbed?: boolean;
30
+ dragDrop?: boolean;
31
+ pastePlain?: boolean;
32
+ findReplace?: boolean;
33
+ indent?: boolean;
34
+ list?: boolean;
35
+ lineHeight?: boolean;
36
+ fontSize?: boolean;
37
+ fontFamily?: boolean;
38
+ specialChars?: boolean;
39
+ colors?: boolean;
40
+ tableBg?: boolean;
41
+ align?: boolean;
42
+ markdown?: boolean;
43
+ link?: boolean;
44
+ image?: boolean;
45
+ imageProps?: boolean;
46
+ imageTools?: boolean;
47
+ iframe?: boolean;
48
+ table?: boolean;
49
+ tableTools?: boolean;
50
+ hr?: boolean;
51
+ unlink?: boolean;
52
+ emoji?: boolean;
53
+ direction?: boolean;
54
+ source?: boolean;
55
+ history?: boolean;
56
+ fullscreen?: boolean;
57
+ toolbarCollapse?: boolean;
58
+ autosave?: boolean;
59
+ autoLinkify?: boolean;
60
+ caseTransform?: boolean;
61
+ shortcutsHelp?: boolean;
62
+ floatingToolbar?: boolean;
63
+ darkMode?: boolean;
64
+ shortcutCustomizer?: boolean;
65
+ minimal?: boolean;
66
+ [name: string]: boolean | undefined;
67
+ }
68
+
69
+ /* ------------------------------------------------------------------ *
70
+ * Options
71
+ * ------------------------------------------------------------------ */
72
+
73
+ export interface SanitizeOptions {
74
+ allowedTags: string[];
75
+ allowedAttributes: string[];
76
+ }
77
+
78
+ /** Options accepted by `TulihEditor.attach(target, options)`. */
79
+ export interface EditorOptions {
80
+ /** Enable/disable individual features (plugins). */
81
+ features?: Features;
82
+ /** Hide the classic toolbar; use the floating toolbar only. */
83
+ minimal?: boolean;
84
+ /** Custom toolbar layout. Each inner array is one button group (divider between groups). */
85
+ toolbar?: string[][];
86
+ /** Editor body height. A number is treated as pixels. */
87
+ height?: number | string;
88
+ /** Custom HTML sanitization rules (merged over the defaults). */
89
+ sanitize?: Partial<SanitizeOptions>;
90
+ /** URL schemes permitted for links. Defaults to http, https, mailto, tel. */
91
+ allowedUrlSchemes?: string[];
92
+ /** URL schemes permitted for images. Defaults to http, https, data. */
93
+ allowedImageSchemes?: string[];
94
+ /** Hostnames permitted for iframe embeds. */
95
+ iframeAllowlist?: string[];
96
+ /** `sandbox` attribute applied to embedded iframes. */
97
+ iframeSandbox?: string;
98
+ /** `allow` attribute applied to embedded iframes. */
99
+ iframeAllow?: string;
100
+ /** Start the editor in read-only mode. */
101
+ readOnly?: boolean;
102
+ }
103
+
104
+ /** Options after merging with defaults, stored on the editor instance. */
105
+ export interface ResolvedOptions {
106
+ sanitize: SanitizeOptions;
107
+ urlSchemes: string[];
108
+ imageSchemes: string[];
109
+ iframeAllowlist: string[];
110
+ iframeSandbox: string;
111
+ iframeAllow: string;
112
+ readOnly: boolean;
113
+ }
114
+
115
+ /* ------------------------------------------------------------------ *
116
+ * Utilities exposed on the context
117
+ * ------------------------------------------------------------------ */
118
+
119
+ export interface EditorUtils {
120
+ sanitizeHTML(html: string, sanOpts?: Partial<SanitizeOptions>): string;
121
+ isSafeUrl(url: string, schemes: string[]): boolean;
122
+ isAllowedIframeUrl(url: string): boolean;
123
+ }
124
+
125
+ /* ------------------------------------------------------------------ *
126
+ * Image handlers
127
+ * ------------------------------------------------------------------ */
128
+
129
+ export type UploadImageHandler = (file: File | Blob, callback: (url: string) => void) => void;
130
+ export type BrowseImageHandler = (context: unknown, callback: (url: string) => void) => void;
131
+
132
+ /* ------------------------------------------------------------------ *
133
+ * Plugin contract
134
+ * ------------------------------------------------------------------ */
135
+
136
+ /** Either a static HTML string or a builder that receives the active features. */
137
+ export type HTMLProvider = string | ((features: Features) => string);
138
+ export type CSSProvider = string | ((features?: Features) => string);
139
+
140
+ /**
141
+ * A TulihEditor plugin. The only required field is `name`; everything else is
142
+ * optional. Plugins contribute toolbar buttons, modals, CSS, and behavior.
143
+ */
144
+ export interface Plugin {
145
+ /** Unique plugin name. Used as the feature flag key. */
146
+ name: string;
147
+ /** Sort order in the toolbar. Plugins are grouped per 10-unit range. */
148
+ order?: number;
149
+ /** Names of plugins that must initialize before this one. */
150
+ deps?: string[];
151
+ /** Toolbar markup injected into the toolbar. */
152
+ toolbarHTML?: HTMLProvider;
153
+ /** Modal markup injected after the editor body. */
154
+ modalHTML?: HTMLProvider;
155
+ /** CSS automatically injected into <head> once, on first load. */
156
+ css?: CSSProvider;
157
+ /** Called once per editor instance after the DOM is built. */
158
+ init?(ctx: PluginContext): void;
159
+ /** Called when an editor instance is destroyed. */
160
+ destroy?(ctx: PluginContext): void;
161
+ }
162
+
163
+ /* ------------------------------------------------------------------ *
164
+ * Runtime context handed to every plugin
165
+ * ------------------------------------------------------------------ */
166
+
167
+ export interface PluginContext {
168
+ /** Wrapper element containing toolbar, editor body and modals. */
169
+ wrapper: HTMLElement;
170
+ /** The contenteditable editor body (`.te-editor`). */
171
+ editor: HTMLElement;
172
+ /** The toolbar element (`.te-toolbar`). */
173
+ toolbar: HTMLElement;
174
+ /** The original textarea the editor is attached to. */
175
+ textarea: HTMLTextAreaElement;
176
+ /** Resolved feature flags for this instance. */
177
+ features: Features;
178
+ /** Resolved options for this instance. */
179
+ options: ResolvedOptions;
180
+ /** Sanitization / URL helpers. */
181
+ utils: EditorUtils;
182
+ /** The global TulihEditor object. */
183
+ TulihEditor: TulihEditorStatic;
184
+ /** Save the current selection range onto the wrapper. */
185
+ saveSel(): void;
186
+ /** Restore a previously saved selection range. */
187
+ restoreSel(): void;
188
+ /** Refresh toolbar active states (bold/italic/lists/undo/redo). */
189
+ updateActiveStates(): void;
190
+ /** Set by the pastePlain plugin to toggle plain-text pasting. */
191
+ _pastePlain?: boolean;
192
+ /** Plugins may stash additional state on the context. */
193
+ [key: string]: unknown;
194
+ }
195
+
196
+ /* ------------------------------------------------------------------ *
197
+ * Public editor instance API
198
+ * ------------------------------------------------------------------ */
199
+
200
+ export interface EditorInstance {
201
+ /** Wrapper element. */
202
+ container: HTMLElement | null;
203
+ /** Contenteditable editor body. */
204
+ editor: HTMLElement | null;
205
+ /** Toolbar element. */
206
+ toolbar: HTMLElement | null;
207
+ /** Original textarea. */
208
+ textarea: HTMLTextAreaElement;
209
+ /** Resolved feature flags. */
210
+ features: Features;
211
+ /** Resolved options. */
212
+ options: ResolvedOptions;
213
+ /** Sanitization / URL helpers. */
214
+ utils: EditorUtils;
215
+
216
+ /** Get the editor HTML content. */
217
+ getContent(): string;
218
+ /** Replace the editor content (sanitized). */
219
+ setContent(html: string): void;
220
+ /** Get the plain text content. */
221
+ getText(): string;
222
+ /** Get the current word count. */
223
+ getWordCount(): number;
224
+ /** Get the current character count. */
225
+ getCharCount(): number;
226
+ /** Toggle read-only mode. */
227
+ setReadOnly(readOnly: boolean): void;
228
+ /** Whether the editor is currently read-only. */
229
+ isReadOnly(): boolean;
230
+ /** Tear down the editor and restore the original textarea. */
231
+ destroy(): void;
232
+ }
233
+
234
+ /* ------------------------------------------------------------------ *
235
+ * Plugin manager
236
+ * ------------------------------------------------------------------ */
237
+
238
+ export interface PluginManagerInstance {
239
+ register(name: string, plugin: Plugin): this;
240
+ unregister(name: string): void;
241
+ get(name: string): Plugin | null;
242
+ has(name: string): boolean;
243
+ getNames(): string[];
244
+ initAll(ctx: PluginContext): void;
245
+ destroyAll(ctx: PluginContext): void;
246
+ getToolbarHTML(features: Features, toolbar?: string[][]): string;
247
+ getModalHTML(features: Features): string;
248
+ injectAllCSS(): void;
249
+ }
250
+
251
+ /* ------------------------------------------------------------------ *
252
+ * Global TulihEditor object
253
+ * ------------------------------------------------------------------ */
254
+
255
+ export interface TulihEditorStatic {
256
+ pluginManager: PluginManagerInstance;
257
+ instances: EditorInstance[];
258
+ onBrowseImage: BrowseImageHandler | null;
259
+ onUploadImage?: UploadImageHandler | null;
260
+ setBrowseImage(handler: BrowseImageHandler): void;
261
+ attach(target: string | Element, options?: EditorOptions): EditorInstance | undefined;
262
+ create(target: string | Element, options?: EditorOptions): EditorInstance | undefined;
263
+ }
264
+
265
+ /* ------------------------------------------------------------------ *
266
+ * Internal element augmentations (expando properties)
267
+ * ------------------------------------------------------------------ */
268
+
269
+ export interface TeHistory {
270
+ undo: string[];
271
+ redo: string[];
272
+ }
273
+
274
+ /** Editor body element with the table-history expando used by history/table plugins. */
275
+ export type TeEditorElement = HTMLElement & { _tableHist?: TeHistory };
276
+
277
+ /** Wrapper element with the saved-selection expando. */
278
+ export type TeWrapperElement = HTMLElement & { __savedRange?: Range | null };