@jenkin-a/jeditor 1.0.0 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Demo/cdn.html +24 -0
- package/Demo/img.png +0 -0
- package/README.en.md +388 -0
- package/README.md +390 -0
- package/dist/jeditor.css +1 -1
- package/dist/jeditor.es.js +7851 -366
- package/dist/jeditor.iife.js +366 -0
- package/dist/jeditor.umd.js +366 -5
- package/package.json +25 -9
package/Demo/cdn.html
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>JEditor CDN Demo</title>
|
|
7
|
+
<link rel="stylesheet" href="../dist/jeditor.css">
|
|
8
|
+
<script src="https://unpkg.com/feather-icons"></script>
|
|
9
|
+
</head>
|
|
10
|
+
<body style="margin:0;background:#f2f2f2;font-family:Arial,sans-serif;">
|
|
11
|
+
<div style="max-width:1200px;margin:40px auto;padding:0 16px;">
|
|
12
|
+
<div id="cdn-editor">
|
|
13
|
+
<h2>CDN bootstrap</h2>
|
|
14
|
+
<p>This block is parsed from native HTML without Vite.</p>
|
|
15
|
+
<p>After building, open this file and load <code>../dist/jeditor.iife.js</code>.</p>
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
<script src="../dist/jeditor.iife.js"></script>
|
|
20
|
+
<script>
|
|
21
|
+
window.editor = window.JEditor.create('#cdn-editor')
|
|
22
|
+
</script>
|
|
23
|
+
</body>
|
|
24
|
+
</html>
|
package/Demo/img.png
ADDED
|
Binary file
|
package/README.en.md
ADDED
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
# JEditor
|
|
2
|
+
|
|
3
|
+
Language: English | [中文](README.md)
|
|
4
|
+
|
|
5
|
+
Current version: `v1.0.2`
|
|
6
|
+
|
|
7
|
+
JEditor is a web rich text editor for document writing, static fragment authoring, and Source HTML editing. It started as a Tiptap-based editor, but the current version is already more than a simple “toolbar + Tiptap wrapper”. It is evolving into a hybrid editing architecture that supports:
|
|
8
|
+
|
|
9
|
+
- visual document editing
|
|
10
|
+
- Source HTML editing
|
|
11
|
+
- HTML preservation and restoration
|
|
12
|
+
- direct CDN usage in the browser
|
|
13
|
+
|
|
14
|
+

|
|
15
|
+
|
|
16
|
+
## Goals
|
|
17
|
+
|
|
18
|
+
JEditor is not only trying to replicate a traditional rich text editor. Its core goal is harder:
|
|
19
|
+
|
|
20
|
+
`Let users edit content like a document while preserving raw HTML as much as possible.`
|
|
21
|
+
|
|
22
|
+
That is the main difference between JEditor and conventional editors:
|
|
23
|
+
|
|
24
|
+
- most editors focus on structured content only
|
|
25
|
+
- JEditor cares about both structured editing and HTML survivability
|
|
26
|
+
|
|
27
|
+
## Current capabilities
|
|
28
|
+
|
|
29
|
+
The current version already includes:
|
|
30
|
+
|
|
31
|
+
- dual-toolbar editing UI
|
|
32
|
+
- native HTML bootstrap from a container
|
|
33
|
+
- `textarea` bootstrap with automatic sync
|
|
34
|
+
- ESM / UMD / IIFE builds
|
|
35
|
+
- direct CDN integration without npm
|
|
36
|
+
- Source toggle button
|
|
37
|
+
- source editor on the left and high-fidelity preview on the right
|
|
38
|
+
- full HTML document preservation
|
|
39
|
+
- fragment HTML preprocess and restore flow
|
|
40
|
+
- Raw HTML Block placeholders
|
|
41
|
+
- core editing features:
|
|
42
|
+
- undo / redo
|
|
43
|
+
- format painter
|
|
44
|
+
- clear format
|
|
45
|
+
- heading / paragraph
|
|
46
|
+
- font family / font size
|
|
47
|
+
- bold / italic / underline / strike
|
|
48
|
+
- color
|
|
49
|
+
- blockquote
|
|
50
|
+
- inline code
|
|
51
|
+
- code block
|
|
52
|
+
- lists
|
|
53
|
+
- link
|
|
54
|
+
- table
|
|
55
|
+
- image
|
|
56
|
+
- callout
|
|
57
|
+
- fullscreen
|
|
58
|
+
|
|
59
|
+
## Architecture overview
|
|
60
|
+
|
|
61
|
+
JEditor now follows a hybrid architecture centered around “Source HTML as the single source of truth”:
|
|
62
|
+
|
|
63
|
+
```text
|
|
64
|
+
Source HTML
|
|
65
|
+
↓
|
|
66
|
+
Parser / Preprocess
|
|
67
|
+
↓
|
|
68
|
+
Projection
|
|
69
|
+
↓
|
|
70
|
+
Visual Editor (Tiptap)
|
|
71
|
+
↓
|
|
72
|
+
restoreRawHTML()
|
|
73
|
+
↓
|
|
74
|
+
Output HTML
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
You can think of it as three layers:
|
|
78
|
+
|
|
79
|
+
1. Source Layer
|
|
80
|
+
- stores the original HTML
|
|
81
|
+
- keeps full documents source-authoritative
|
|
82
|
+
- powers the high-fidelity preview
|
|
83
|
+
|
|
84
|
+
2. Projection Layer
|
|
85
|
+
- preprocesses HTML before `setContent`
|
|
86
|
+
- sends supported nodes into the schema
|
|
87
|
+
- wraps unknown nodes as `RawHtmlIsland`
|
|
88
|
+
|
|
89
|
+
3. Visual Layer
|
|
90
|
+
- uses Tiptap for structured editing
|
|
91
|
+
- all toolbar, plugin, command, and selection logic lives here
|
|
92
|
+
|
|
93
|
+
## Three editing states
|
|
94
|
+
|
|
95
|
+
### 1. Visual Mode
|
|
96
|
+
|
|
97
|
+
This is the default mode. It is used for structured editing such as writing paragraphs, formatting text, inserting tables, callouts, images, and code blocks.
|
|
98
|
+
|
|
99
|
+
This layer mainly depends on Tiptap for:
|
|
100
|
+
|
|
101
|
+
- selection handling
|
|
102
|
+
- command chains
|
|
103
|
+
- schema
|
|
104
|
+
- history
|
|
105
|
+
- node and mark extensions
|
|
106
|
+
|
|
107
|
+
### 2. Source Mode
|
|
108
|
+
|
|
109
|
+
Enter it by clicking the `Source` button on the right side of the second toolbar row.
|
|
110
|
+
|
|
111
|
+
The current implementation is:
|
|
112
|
+
|
|
113
|
+
- left: source editor `textarea`
|
|
114
|
+
- right: high-fidelity iframe preview
|
|
115
|
+
|
|
116
|
+
When the content is a full HTML document, JEditor does not force it back through the visual editor. This avoids losing or normalizing:
|
|
117
|
+
|
|
118
|
+
- `<!DOCTYPE html>`
|
|
119
|
+
- `<head>`
|
|
120
|
+
- `<style>`
|
|
121
|
+
- `<script>`
|
|
122
|
+
- the original document structure
|
|
123
|
+
|
|
124
|
+
### 3. Hybrid / Preservation Flow
|
|
125
|
+
|
|
126
|
+
This is currently the most important layer in JEditor.
|
|
127
|
+
|
|
128
|
+
For fragment HTML, JEditor preprocesses content before `setContent()`:
|
|
129
|
+
|
|
130
|
+
- supported nodes are parsed normally
|
|
131
|
+
- unsupported nodes are wrapped as `raw-html` placeholders
|
|
132
|
+
|
|
133
|
+
When exporting, `restoreRawHTML()` turns them back into their original HTML.
|
|
134
|
+
|
|
135
|
+
The goal is simple:
|
|
136
|
+
|
|
137
|
+
`Unknown HTML may not be editable, but it must not be deleted.`
|
|
138
|
+
|
|
139
|
+
## Project structure
|
|
140
|
+
|
|
141
|
+
Core source lives under `src`:
|
|
142
|
+
|
|
143
|
+
- `src/jeditor.js`
|
|
144
|
+
- main editor entry
|
|
145
|
+
- controls mode switching, Source flow, HTML sync, and initialization
|
|
146
|
+
|
|
147
|
+
- `src/editor/index.js`
|
|
148
|
+
- creates the Tiptap editor instance
|
|
149
|
+
|
|
150
|
+
- `src/core/plugin-manager.js`
|
|
151
|
+
- central plugin registry and lifecycle manager
|
|
152
|
+
|
|
153
|
+
- `src/core/config.js`
|
|
154
|
+
- default config and user config merging
|
|
155
|
+
|
|
156
|
+
- `src/core/html-preservation.js`
|
|
157
|
+
- `preprocessHTML`
|
|
158
|
+
- `restoreRawHTML`
|
|
159
|
+
- HTML preservation pipeline
|
|
160
|
+
|
|
161
|
+
- `src/toolbar/ui.js`
|
|
162
|
+
- toolbar DOM, popovers, state sync
|
|
163
|
+
|
|
164
|
+
- `src/plugins`
|
|
165
|
+
- all toolbar behaviors and commands
|
|
166
|
+
|
|
167
|
+
- `src/extensions`
|
|
168
|
+
- custom schema / mark / node extensions
|
|
169
|
+
|
|
170
|
+
- `src/styles/editor.css`
|
|
171
|
+
- built-in editor styles
|
|
172
|
+
|
|
173
|
+
## HTML preservation
|
|
174
|
+
|
|
175
|
+
This is the most important architectural capability in the current version.
|
|
176
|
+
|
|
177
|
+
### 1. preprocessHTML
|
|
178
|
+
|
|
179
|
+
Runs before `setContent()`.
|
|
180
|
+
|
|
181
|
+
Responsibilities:
|
|
182
|
+
|
|
183
|
+
- walk through input HTML
|
|
184
|
+
- decide whether a node is supported by the current schema
|
|
185
|
+
- convert unsupported nodes into placeholders
|
|
186
|
+
|
|
187
|
+
For example:
|
|
188
|
+
|
|
189
|
+
```html
|
|
190
|
+
<section style="display:flex">
|
|
191
|
+
<article>...</article>
|
|
192
|
+
</section>
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
If the current schema cannot fully represent it, JEditor does not drop it. Instead, it converts it into:
|
|
196
|
+
|
|
197
|
+
```html
|
|
198
|
+
<raw-html data-raw-html="...encoded html..."></raw-html>
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### 2. RawHtmlIsland
|
|
202
|
+
|
|
203
|
+
`RawHtmlIsland` is an indivisible block node.
|
|
204
|
+
|
|
205
|
+
Its job is not to edit arbitrary HTML. Its job is to preserve it.
|
|
206
|
+
|
|
207
|
+
Visually, it is rendered as a visible block instead of an empty node, for example:
|
|
208
|
+
|
|
209
|
+
- Raw HTML Block
|
|
210
|
+
- HTML preserved
|
|
211
|
+
|
|
212
|
+
It currently supports:
|
|
213
|
+
|
|
214
|
+
- double click to jump back to Source
|
|
215
|
+
- copy raw HTML
|
|
216
|
+
- delete block
|
|
217
|
+
|
|
218
|
+
Implementation:
|
|
219
|
+
|
|
220
|
+
- `src/extensions/raw-html-island.js`
|
|
221
|
+
|
|
222
|
+
### 3. restoreRawHTML
|
|
223
|
+
|
|
224
|
+
Runs during `getHTML()`.
|
|
225
|
+
|
|
226
|
+
Responsibilities:
|
|
227
|
+
|
|
228
|
+
- scan editor output
|
|
229
|
+
- find `raw-html[data-raw-html]`
|
|
230
|
+
- restore the original saved `outerHTML`
|
|
231
|
+
|
|
232
|
+
That means even if some nodes cannot be edited visually, they can still be exported back as their original HTML.
|
|
233
|
+
|
|
234
|
+
## Schema extension direction
|
|
235
|
+
|
|
236
|
+
The first stage of schema extension has already begun:
|
|
237
|
+
|
|
238
|
+
- `GenericDiv`
|
|
239
|
+
- `GlobalStyle`
|
|
240
|
+
- `RawHtmlIsland`
|
|
241
|
+
|
|
242
|
+
The goal is to gradually support more permissive HTML instead of letting it be removed by a strict schema too early.
|
|
243
|
+
|
|
244
|
+
Next steps will include:
|
|
245
|
+
|
|
246
|
+
- `GenericSpan`
|
|
247
|
+
- finer inline fallback
|
|
248
|
+
- broader unknown-tag preservation
|
|
249
|
+
|
|
250
|
+
## Plugin system
|
|
251
|
+
|
|
252
|
+
JEditor uses a plugin-driven toolbar and command architecture.
|
|
253
|
+
|
|
254
|
+
A plugin usually contains:
|
|
255
|
+
|
|
256
|
+
- `name`
|
|
257
|
+
- `toolbar`
|
|
258
|
+
- `tiptapExtension`
|
|
259
|
+
- `command`
|
|
260
|
+
- `isActive`
|
|
261
|
+
- `renderPopover`
|
|
262
|
+
- `init / destroy`
|
|
263
|
+
|
|
264
|
+
This gives JEditor a few advantages:
|
|
265
|
+
|
|
266
|
+
- UI and commands stay decoupled
|
|
267
|
+
- toolbar items can be composed by configuration
|
|
268
|
+
- new tools can be added without rewriting the core editor
|
|
269
|
+
|
|
270
|
+
Built-in plugin entry:
|
|
271
|
+
|
|
272
|
+
- `src/plugins/index.js`
|
|
273
|
+
|
|
274
|
+
Plugin manager:
|
|
275
|
+
|
|
276
|
+
- `src/core/plugin-manager.js`
|
|
277
|
+
|
|
278
|
+
## Install and development
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
npm install
|
|
282
|
+
npm run dev
|
|
283
|
+
npm run build
|
|
284
|
+
npm run preview
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
Build outputs:
|
|
288
|
+
|
|
289
|
+
- `dist/jeditor.es.js`
|
|
290
|
+
- `dist/jeditor.umd.js`
|
|
291
|
+
- `dist/jeditor.iife.js`
|
|
292
|
+
- `dist/jeditor.css`
|
|
293
|
+
|
|
294
|
+
## ESM usage
|
|
295
|
+
|
|
296
|
+
```js
|
|
297
|
+
import '@jenkin-a/jeditor/dist/jeditor.css'
|
|
298
|
+
import { JEditor } from '@jenkin-a/jeditor'
|
|
299
|
+
|
|
300
|
+
const editor = JEditor.create('#editor', {
|
|
301
|
+
placeholder: 'Start writing...',
|
|
302
|
+
})
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
You can also create from an HTML string:
|
|
306
|
+
|
|
307
|
+
```js
|
|
308
|
+
const editor = JEditor.fromHTML('#editor', '<h2>Hello</h2><p>World</p>')
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
## CDN / no-npm usage
|
|
312
|
+
|
|
313
|
+
```html
|
|
314
|
+
<link rel="stylesheet" href="https://unpkg.com/@jenkin-a/jeditor/dist/jeditor.css">
|
|
315
|
+
<script src="https://unpkg.com/feather-icons"></script>
|
|
316
|
+
<script src="https://unpkg.com/@jenkin-a/jeditor/dist/jeditor.iife.js"></script>
|
|
317
|
+
|
|
318
|
+
<div id="editor">
|
|
319
|
+
<h2>Hello, JEditor</h2>
|
|
320
|
+
<p>The native HTML inside this container will be parsed on startup.</p>
|
|
321
|
+
</div>
|
|
322
|
+
|
|
323
|
+
<script>
|
|
324
|
+
const editor = window.JEditor.create('#editor', {
|
|
325
|
+
placeholder: 'Start writing...',
|
|
326
|
+
})
|
|
327
|
+
</script>
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
To pin a version:
|
|
331
|
+
|
|
332
|
+
```html
|
|
333
|
+
<script src="https://unpkg.com/@jenkin-a/jeditor@1.0.2/dist/jeditor.iife.js"></script>
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
## API
|
|
337
|
+
|
|
338
|
+
```js
|
|
339
|
+
editor.getHTML()
|
|
340
|
+
editor.getJSON()
|
|
341
|
+
editor.getText()
|
|
342
|
+
editor.setContent('<p>Hello</p>')
|
|
343
|
+
editor.importHTML('<p>Hello</p>')
|
|
344
|
+
editor.focus()
|
|
345
|
+
editor.destroy()
|
|
346
|
+
editor.toggleSourceMode()
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
## Good fit for
|
|
350
|
+
|
|
351
|
+
JEditor is a good fit for:
|
|
352
|
+
|
|
353
|
+
- enterprise knowledge-base editors
|
|
354
|
+
- SOP / notice / documentation workbenches
|
|
355
|
+
- CMS editors that need Source HTML support
|
|
356
|
+
- admin systems that need both visual editing and HTML editing
|
|
357
|
+
- lightweight browser integrations via CDN
|
|
358
|
+
|
|
359
|
+
## Current boundaries
|
|
360
|
+
|
|
361
|
+
The current version is already strong, but it is still evolving.
|
|
362
|
+
|
|
363
|
+
Some current boundaries:
|
|
364
|
+
|
|
365
|
+
- some UI details still need polishing
|
|
366
|
+
- a few toolbar interactions can be refined further
|
|
367
|
+
- complex unknown inline HTML preservation is not final yet
|
|
368
|
+
- Source Mode and Hybrid Mode will continue to evolve
|
|
369
|
+
|
|
370
|
+
## Next direction
|
|
371
|
+
|
|
372
|
+
The next development direction is clear:
|
|
373
|
+
|
|
374
|
+
1. expand the schema
|
|
375
|
+
- `GenericSpan`
|
|
376
|
+
- broader style / attr preservation
|
|
377
|
+
|
|
378
|
+
2. improve Raw HTML preservation
|
|
379
|
+
- finer fallback behavior
|
|
380
|
+
- better import / export restoration
|
|
381
|
+
|
|
382
|
+
3. strengthen Source / Visual collaboration
|
|
383
|
+
- more stable mode switching
|
|
384
|
+
- deeper Hybrid editing experience
|
|
385
|
+
|
|
386
|
+
## License
|
|
387
|
+
|
|
388
|
+
MIT
|