@jenkin-a/jeditor 1.0.4 → 1.0.8
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.en.md +36 -156
- package/README.md +39 -161
- package/dist/jeditor.css +1 -1
- package/dist/jeditor.es.js +824 -695
- package/dist/jeditor.iife.js +57 -57
- package/dist/jeditor.umd.js +57 -57
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -2,24 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
Language: English | [中文](README.md)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Open source repository: [https://github.com/JenkinAAA/JEditor](https://github.com/JenkinAAA/JEditor)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Current version: `v1.0.8`
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
- Source HTML editing
|
|
11
|
-
- HTML preservation and restoration
|
|
12
|
-
- direct CDN usage in the browser
|
|
9
|
+
JEditor is a web rich text editor for document authoring, static HTML fragment editing, and Source HTML editing. It is built on top of Tiptap, but the current version is no longer just a toolbar wrapper. It is evolving into a hybrid editor that supports visual editing, source editing, HTML preservation, and direct CDN usage.
|
|
13
10
|
|
|
14
11
|

|
|
15
12
|
|
|
16
13
|
## Goals
|
|
17
14
|
|
|
18
|
-
JEditor is not
|
|
15
|
+
JEditor is not trying to simply clone a traditional rich text editor. Its core goal is harder:
|
|
19
16
|
|
|
20
17
|
`Let users edit content like a document while preserving raw HTML as much as possible.`
|
|
21
18
|
|
|
22
|
-
That is the
|
|
19
|
+
That is the key difference between JEditor and conventional editors:
|
|
23
20
|
|
|
24
21
|
- most editors focus on structured content only
|
|
25
22
|
- JEditor cares about both structured editing and HTML survivability
|
|
@@ -56,22 +53,27 @@ The current version already includes:
|
|
|
56
53
|
- callout
|
|
57
54
|
- fullscreen
|
|
58
55
|
|
|
56
|
+
## Current severe bugs
|
|
57
|
+
|
|
58
|
+
These are planned to be addressed in the next version, targeted before `2026.06`.
|
|
59
|
+
|
|
60
|
+
- Table styling still has readability and editing issues in real document scenarios
|
|
61
|
+
- Table interaction logic is still unstable, especially handles, resizing, and dragging
|
|
62
|
+
- Callout focus handling and interaction logic still have defects that affect usability
|
|
63
|
+
|
|
64
|
+
For other bugs, please open an [Issue](https://github.com/JenkinAAA/JEditor/issues).
|
|
65
|
+
|
|
59
66
|
## Architecture overview
|
|
60
67
|
|
|
61
|
-
JEditor
|
|
68
|
+
JEditor follows a hybrid architecture centered around “Source HTML as the single source of truth”:
|
|
62
69
|
|
|
63
70
|
```text
|
|
64
71
|
Source HTML
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
Visual Editor (Tiptap)
|
|
71
|
-
↓
|
|
72
|
-
restoreRawHTML()
|
|
73
|
-
↓
|
|
74
|
-
Output HTML
|
|
72
|
+
-> Parser / Preprocess
|
|
73
|
+
-> Projection
|
|
74
|
+
-> Visual Editor (Tiptap)
|
|
75
|
+
-> restoreRawHTML()
|
|
76
|
+
-> Output HTML
|
|
75
77
|
```
|
|
76
78
|
|
|
77
79
|
You can think of it as three layers:
|
|
@@ -106,7 +108,7 @@ This layer mainly depends on Tiptap for:
|
|
|
106
108
|
|
|
107
109
|
### 2. Source Mode
|
|
108
110
|
|
|
109
|
-
Enter it by clicking the `Source` button
|
|
111
|
+
Enter it by clicking the `Source` button.
|
|
110
112
|
|
|
111
113
|
The current implementation is:
|
|
112
114
|
|
|
@@ -136,116 +138,24 @@ The goal is simple:
|
|
|
136
138
|
|
|
137
139
|
`Unknown HTML may not be editable, but it must not be deleted.`
|
|
138
140
|
|
|
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
141
|
## HTML preservation
|
|
174
142
|
|
|
175
|
-
|
|
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
|
|
143
|
+
The current HTML preservation flow can be understood in three simple steps:
|
|
202
144
|
|
|
203
|
-
`
|
|
145
|
+
1. `preprocessHTML`
|
|
146
|
+
- runs before `setContent()`
|
|
147
|
+
- supported nodes go into the visual editor
|
|
148
|
+
- unsupported nodes are converted into `raw-html`
|
|
204
149
|
|
|
205
|
-
|
|
150
|
+
2. `RawHtmlIsland`
|
|
151
|
+
- acts as an indivisible block node
|
|
152
|
+
- preserves original HTML instead of forcing it into a structured schema
|
|
206
153
|
|
|
207
|
-
|
|
154
|
+
3. `restoreRawHTML`
|
|
155
|
+
- runs during `getHTML()`
|
|
156
|
+
- restores `raw-html` placeholders back to their original `outerHTML`
|
|
208
157
|
|
|
209
|
-
|
|
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
|
|
158
|
+
This means that even if some HTML cannot be edited visually, it can still survive export as intact HTML.
|
|
249
159
|
|
|
250
160
|
## Plugin system
|
|
251
161
|
|
|
@@ -267,14 +177,6 @@ This gives JEditor a few advantages:
|
|
|
267
177
|
- toolbar items can be composed by configuration
|
|
268
178
|
- new tools can be added without rewriting the core editor
|
|
269
179
|
|
|
270
|
-
Built-in plugin entry:
|
|
271
|
-
|
|
272
|
-
- `src/plugins/index.js`
|
|
273
|
-
|
|
274
|
-
Plugin manager:
|
|
275
|
-
|
|
276
|
-
- `src/core/plugin-manager.js`
|
|
277
|
-
|
|
278
180
|
## Install and development
|
|
279
181
|
|
|
280
182
|
```bash
|
|
@@ -311,9 +213,9 @@ const editor = JEditor.fromHTML('#editor', '<h2>Hello</h2><p>World</p>')
|
|
|
311
213
|
## CDN / no-npm usage
|
|
312
214
|
|
|
313
215
|
```html
|
|
314
|
-
<link rel="stylesheet" href="https://unpkg.com/@jenkin-a/jeditor/dist/jeditor.css">
|
|
216
|
+
<link rel="stylesheet" href="https://unpkg.com/@jenkin-a/jeditor@1.0.8/dist/jeditor.css">
|
|
315
217
|
<script src="https://unpkg.com/feather-icons"></script>
|
|
316
|
-
<script src="https://unpkg.com/@jenkin-a/jeditor/dist/jeditor.iife.js"></script>
|
|
218
|
+
<script src="https://unpkg.com/@jenkin-a/jeditor@1.0.8/dist/jeditor.iife.js"></script>
|
|
317
219
|
|
|
318
220
|
<div id="editor">
|
|
319
221
|
<h2>Hello, JEditor</h2>
|
|
@@ -327,12 +229,6 @@ const editor = JEditor.fromHTML('#editor', '<h2>Hello</h2><p>World</p>')
|
|
|
327
229
|
</script>
|
|
328
230
|
```
|
|
329
231
|
|
|
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
232
|
## API
|
|
337
233
|
|
|
338
234
|
```js
|
|
@@ -367,22 +263,6 @@ Some current boundaries:
|
|
|
367
263
|
- complex unknown inline HTML preservation is not final yet
|
|
368
264
|
- Source Mode and Hybrid Mode will continue to evolve
|
|
369
265
|
|
|
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
266
|
## License
|
|
387
267
|
|
|
388
268
|
MIT
|
package/README.md
CHANGED
|
@@ -2,16 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
Language: [English](README.en.md) | 中文
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
开源仓库:[https://github.com/JenkinAAA/JEditor](https://github.com/JenkinAAA/JEditor)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
当前版本:`v1.0.8`
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
- Source HTML 编辑
|
|
11
|
-
- HTML 保活与回写
|
|
12
|
-
- 浏览器 CDN 直连
|
|
13
|
-
|
|
14
|
-
的混合编辑架构。
|
|
9
|
+
JEditor 是一个面向文档写作、静态 HTML 片段编辑、Source HTML 编辑的 Web 富文本编辑器。它以 Tiptap 为基础,但当前版本已经不只是简单的工具栏封装,而是在此基础上演进成了一个同时支持可视化编辑、源码编辑、HTML 保活与 CDN 直连的混合编辑器。
|
|
15
10
|
|
|
16
11
|

|
|
17
12
|
|
|
@@ -21,7 +16,7 @@ JEditor 的目标不是单纯复刻一个传统富文本编辑器,而是解决
|
|
|
21
16
|
|
|
22
17
|
`让用户既能像写文档一样编辑内容,又能尽可能保留和操作原始 HTML。`
|
|
23
18
|
|
|
24
|
-
这也是 JEditor
|
|
19
|
+
这也是 JEditor 与常规编辑器的核心差异:
|
|
25
20
|
|
|
26
21
|
- 普通编辑器更强调“结构化内容”
|
|
27
22
|
- JEditor 同时强调“结构化编辑体验”和“HTML 存活能力”
|
|
@@ -32,7 +27,7 @@ JEditor 的目标不是单纯复刻一个传统富文本编辑器,而是解决
|
|
|
32
27
|
|
|
33
28
|
- 双工具栏富文本编辑体验
|
|
34
29
|
- 原生 HTML 容器启动
|
|
35
|
-
- `textarea`
|
|
30
|
+
- `textarea` 启动与自动回填
|
|
36
31
|
- ESM / UMD / IIFE 三种构建产物
|
|
37
32
|
- CDN 直接接入,无需 npm
|
|
38
33
|
- Source 按钮切换源码编辑
|
|
@@ -58,22 +53,27 @@ JEditor 的目标不是单纯复刻一个传统富文本编辑器,而是解决
|
|
|
58
53
|
- Callout
|
|
59
54
|
- 全屏
|
|
60
55
|
|
|
56
|
+
## 当前较为严重的 BUG
|
|
57
|
+
|
|
58
|
+
将在下一个版本进行更新,计划于 `2026.06` 之前完成。
|
|
59
|
+
|
|
60
|
+
- 表格设计样式仍存在缺陷,当前版本不够适合长文档阅读与编辑
|
|
61
|
+
- 表格交互逻辑仍存在缺陷,手柄、缩放、拖拽等相关交互代码还不稳定
|
|
62
|
+
- Callout 的焦点管理与交互逻辑仍存在缺陷,会影响操作体验
|
|
63
|
+
|
|
64
|
+
其它 bug 欢迎通过 [Issues](https://github.com/JenkinAAA/JEditor/issues) 提出。
|
|
65
|
+
|
|
61
66
|
## 架构概览
|
|
62
67
|
|
|
63
68
|
JEditor 当前采用的是一套“Source HTML 为唯一真相”的混合架构:
|
|
64
69
|
|
|
65
70
|
```text
|
|
66
71
|
Source HTML
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
Visual Editor (Tiptap)
|
|
73
|
-
↓
|
|
74
|
-
restoreRawHTML()
|
|
75
|
-
↓
|
|
76
|
-
Output HTML
|
|
72
|
+
-> Parser / Preprocess
|
|
73
|
+
-> Projection
|
|
74
|
+
-> Visual Editor (Tiptap)
|
|
75
|
+
-> restoreRawHTML()
|
|
76
|
+
-> Output HTML
|
|
77
77
|
```
|
|
78
78
|
|
|
79
79
|
可以把它理解为三层:
|
|
@@ -125,7 +125,7 @@ Output HTML
|
|
|
125
125
|
|
|
126
126
|
### 3. Hybrid / Preservation Flow
|
|
127
127
|
|
|
128
|
-
这是 JEditor
|
|
128
|
+
这是 JEditor 当前最关键的一层。
|
|
129
129
|
|
|
130
130
|
对于 fragment HTML,JEditor 会在 `setContent()` 之前先做预处理:
|
|
131
131
|
|
|
@@ -134,126 +134,34 @@ Output HTML
|
|
|
134
134
|
|
|
135
135
|
导出时再通过 `restoreRawHTML()` 还原成原始 HTML。
|
|
136
136
|
|
|
137
|
-
|
|
137
|
+
目标很明确:
|
|
138
138
|
|
|
139
139
|
`未知 HTML 不一定能编辑,但不能被删除。`
|
|
140
140
|
|
|
141
|
-
## 目录结构
|
|
142
|
-
|
|
143
|
-
核心源码主要在 `src`:
|
|
144
|
-
|
|
145
|
-
- `src/jeditor.js`
|
|
146
|
-
- 编辑器总入口
|
|
147
|
-
- 负责模式切换、Source 控制、HTML 同步、初始化
|
|
148
|
-
|
|
149
|
-
- `src/editor/index.js`
|
|
150
|
-
- 创建 Tiptap Editor 实例
|
|
151
|
-
|
|
152
|
-
- `src/core/plugin-manager.js`
|
|
153
|
-
- 统一注册和管理插件
|
|
154
|
-
|
|
155
|
-
- `src/core/config.js`
|
|
156
|
-
- 默认配置与用户配置合并
|
|
157
|
-
|
|
158
|
-
- `src/core/html-preservation.js`
|
|
159
|
-
- `preprocessHTML`
|
|
160
|
-
- `restoreRawHTML`
|
|
161
|
-
- HTML 保活入口
|
|
162
|
-
|
|
163
|
-
- `src/toolbar/ui.js`
|
|
164
|
-
- 工具栏 DOM 生成、下拉菜单、状态同步
|
|
165
|
-
|
|
166
|
-
- `src/plugins`
|
|
167
|
-
- 所有工具栏能力与命令实现
|
|
168
|
-
|
|
169
|
-
- `src/extensions`
|
|
170
|
-
- 自定义 schema / mark / node 扩展
|
|
171
|
-
|
|
172
|
-
- `src/styles/editor.css`
|
|
173
|
-
- 编辑器内置样式
|
|
174
|
-
|
|
175
141
|
## HTML 保活机制
|
|
176
142
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
### 1. preprocessHTML
|
|
180
|
-
|
|
181
|
-
在 `setContent()` 前执行。
|
|
182
|
-
|
|
183
|
-
职责:
|
|
184
|
-
|
|
185
|
-
- 遍历输入 HTML
|
|
186
|
-
- 判断节点是否属于当前 schema 可接受范围
|
|
187
|
-
- 对未知节点生成占位节点
|
|
188
|
-
|
|
189
|
-
例如:
|
|
190
|
-
|
|
191
|
-
```html
|
|
192
|
-
<section style="display:flex">
|
|
193
|
-
<article>...</article>
|
|
194
|
-
</section>
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
如果当前 schema 不能完整表达这类结构,就不会直接丢弃,而是转换为:
|
|
198
|
-
|
|
199
|
-
```html
|
|
200
|
-
<raw-html data-raw-html="...encoded html..."></raw-html>
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
### 2. RawHtmlIsland
|
|
143
|
+
JEditor 的 HTML 保活目前可以简单理解为三步:
|
|
204
144
|
|
|
205
|
-
`
|
|
145
|
+
1. `preprocessHTML`
|
|
146
|
+
- 在 `setContent()` 前执行
|
|
147
|
+
- 可识别节点正常进入编辑器
|
|
148
|
+
- 不可识别节点转成 `raw-html`
|
|
206
149
|
|
|
207
|
-
|
|
150
|
+
2. `RawHtmlIsland`
|
|
151
|
+
- 作为不可拆分的块节点存在
|
|
152
|
+
- 负责保存原始 HTML,而不是强行结构化解析
|
|
208
153
|
|
|
209
|
-
|
|
154
|
+
3. `restoreRawHTML`
|
|
155
|
+
- 在 `getHTML()` 时执行
|
|
156
|
+
- 把 `raw-html` 占位恢复成原始 `outerHTML`
|
|
210
157
|
|
|
211
|
-
|
|
212
|
-
- HTML preserved
|
|
213
|
-
|
|
214
|
-
并支持:
|
|
215
|
-
|
|
216
|
-
- 双击跳转 Source
|
|
217
|
-
- 复制原始 HTML
|
|
218
|
-
- 删除该块
|
|
219
|
-
|
|
220
|
-
对应实现:
|
|
221
|
-
|
|
222
|
-
- `src/extensions/raw-html-island.js`
|
|
223
|
-
|
|
224
|
-
### 3. restoreRawHTML
|
|
225
|
-
|
|
226
|
-
在 `getHTML()` 时执行。
|
|
227
|
-
|
|
228
|
-
职责:
|
|
229
|
-
|
|
230
|
-
- 扫描编辑器输出
|
|
231
|
-
- 找到 `raw-html[data-raw-html]`
|
|
232
|
-
- 将其还原为保存的原始 `outerHTML`
|
|
233
|
-
|
|
234
|
-
因此即便某些节点在可视化层无法编辑,导出时仍然可以完整回到原始 HTML。
|
|
235
|
-
|
|
236
|
-
## Schema 扩展方向
|
|
237
|
-
|
|
238
|
-
当前已经开始接入第一阶段的 schema 扩展:
|
|
239
|
-
|
|
240
|
-
- `GenericDiv`
|
|
241
|
-
- `GlobalStyle`
|
|
242
|
-
- `RawHtmlIsland`
|
|
243
|
-
|
|
244
|
-
目标是逐步让 JEditor 支持更多“宽松但可保留”的 HTML 语法,而不是一开始就被严格 schema 过滤掉。
|
|
245
|
-
|
|
246
|
-
后续会继续推进:
|
|
247
|
-
|
|
248
|
-
- `GenericSpan`
|
|
249
|
-
- 更细粒度的 inline fallback
|
|
250
|
-
- 更完整的未知标签保留策略
|
|
158
|
+
这意味着即使某些 HTML 无法在可视化层直接编辑,导出时仍然可以尽量保持原样。
|
|
251
159
|
|
|
252
160
|
## 插件体系
|
|
253
161
|
|
|
254
162
|
JEditor 使用插件驱动工具栏和命令。
|
|
255
163
|
|
|
256
|
-
|
|
164
|
+
每个插件通常包含:
|
|
257
165
|
|
|
258
166
|
- `name`
|
|
259
167
|
- `toolbar`
|
|
@@ -267,15 +175,7 @@ JEditor 使用插件驱动工具栏和命令。
|
|
|
267
175
|
|
|
268
176
|
- UI 与命令可以解耦
|
|
269
177
|
- 工具栏项可以按配置组合
|
|
270
|
-
-
|
|
271
|
-
|
|
272
|
-
内置插件入口:
|
|
273
|
-
|
|
274
|
-
- `src/plugins/index.js`
|
|
275
|
-
|
|
276
|
-
插件管理器:
|
|
277
|
-
|
|
278
|
-
- `src/core/plugin-manager.js`
|
|
178
|
+
- 扩展新按钮时无需重写编辑器核心
|
|
279
179
|
|
|
280
180
|
## 安装与开发
|
|
281
181
|
|
|
@@ -313,9 +213,9 @@ const editor = JEditor.fromHTML('#editor', '<h2>Hello</h2><p>World</p>')
|
|
|
313
213
|
## CDN / 无 npm 用法
|
|
314
214
|
|
|
315
215
|
```html
|
|
316
|
-
<link rel="stylesheet" href="https://unpkg.com/@jenkin-a/jeditor/dist/jeditor.css">
|
|
216
|
+
<link rel="stylesheet" href="https://unpkg.com/@jenkin-a/jeditor@1.0.8/dist/jeditor.css">
|
|
317
217
|
<script src="https://unpkg.com/feather-icons"></script>
|
|
318
|
-
<script src="https://unpkg.com/@jenkin-a/jeditor/dist/jeditor.iife.js"></script>
|
|
218
|
+
<script src="https://unpkg.com/@jenkin-a/jeditor@1.0.8/dist/jeditor.iife.js"></script>
|
|
319
219
|
|
|
320
220
|
<div id="editor">
|
|
321
221
|
<h2>你好,JEditor</h2>
|
|
@@ -329,12 +229,6 @@ const editor = JEditor.fromHTML('#editor', '<h2>Hello</h2><p>World</p>')
|
|
|
329
229
|
</script>
|
|
330
230
|
```
|
|
331
231
|
|
|
332
|
-
如果需要锁定版本:
|
|
333
|
-
|
|
334
|
-
```html
|
|
335
|
-
<script src="https://unpkg.com/@jenkin-a/jeditor@1.0.2/dist/jeditor.iife.js"></script>
|
|
336
|
-
```
|
|
337
|
-
|
|
338
232
|
## API
|
|
339
233
|
|
|
340
234
|
```js
|
|
@@ -360,7 +254,7 @@ JEditor 适合以下场景:
|
|
|
360
254
|
|
|
361
255
|
## 当前边界
|
|
362
256
|
|
|
363
|
-
|
|
257
|
+
虽然当前版本已经非常强,但它仍在持续演进中。
|
|
364
258
|
|
|
365
259
|
目前仍存在一些边界:
|
|
366
260
|
|
|
@@ -369,22 +263,6 @@ JEditor 适合以下场景:
|
|
|
369
263
|
- 复杂未知 inline HTML 的保活能力还不是最终形态
|
|
370
264
|
- Source Mode 与 Hybrid Mode 还会继续深化
|
|
371
265
|
|
|
372
|
-
## 下一阶段方向
|
|
373
|
-
|
|
374
|
-
下一步的重点已经明确:
|
|
375
|
-
|
|
376
|
-
1. 扩展 schema
|
|
377
|
-
- `GenericSpan`
|
|
378
|
-
- 更宽松的 style / attr 保留
|
|
379
|
-
|
|
380
|
-
2. 完善 Raw HTML 保活
|
|
381
|
-
- 更细粒度 fallback
|
|
382
|
-
- 更好的导入 / 导出还原
|
|
383
|
-
|
|
384
|
-
3. 强化 Source / Visual 协同
|
|
385
|
-
- 更稳定的双向切换
|
|
386
|
-
- 更完整的 Hybrid 编辑体验
|
|
387
|
-
|
|
388
266
|
## License
|
|
389
267
|
|
|
390
268
|
MIT
|
package/dist/jeditor.css
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
:root{--je-blue:#0052d9;--je-blue-active:#e6f0ff;--je-divider:#e0e0e0;--je-hover:#eee;--je-radius:4px}.je-container{-webkit-font-smoothing:antialiased;background:#fff;border:1px solid #e6e6e6;border-radius:4px;flex-direction:column;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,PingFang SC,Microsoft YaHei,sans-serif;display:flex;overflow:visible}.je-toolbar-row{z-index:40;flex-shrink:0;align-items:center;gap:1px;padding:0 12px;display:flex;position:sticky}.je-toolbar-row--primary{background:#fff;height:44px;top:0}.je-toolbar-row--secondary{background:#f3f4f6;border-radius:6px;height:42px;margin:0 8px 4px;position:sticky;top:44px}.je-toolbar-row--secondary:after{content:"";pointer-events:none;opacity:0;background:#eef0f2;height:1px;transition:opacity .12s;position:absolute;bottom:-5px;left:-8px;right:-8px}.je-container.is-scrolled .je-toolbar-row--secondary:after{opacity:1}.je-spacer{flex:1}.v-divider{background-color:var(--je-divider);flex-shrink:0;width:1px;height:16px;margin:0 6px}.tool-btn,.tool-btn-text,.tool-btn-arrow-down{border-radius:var(--je-radius);color:#444;cursor:pointer;background:0 0;border:none;flex-shrink:0;justify-content:center;align-items:center;gap:2px;line-height:1;transition:background-color .1s;display:inline-flex}.tool-btn{width:28px;height:28px;padding:0;font-size:13px}.tool-btn:hover{background-color:var(--je-hover)}.tool-btn.is-muted,.tool-btn-text.is-muted,.je-color-group.is-muted{color:#9ca3af;opacity:1;pointer-events:none}.tool-btn-text{white-space:nowrap;height:28px;padding:0 6px;font-size:13px}.tool-btn-text:hover{background-color:var(--je-hover)}.tool-btn-text--icon{gap:4px}.tool-btn-arrow-down{color:#999;width:16px;height:28px;padding:0}.tool-btn-arrow-down:hover{background-color:var(--je-hover)}.tool-btn svg,.tool-btn-text svg,.tool-btn-arrow-down svg{flex-shrink:0;width:20px;height:20px}.tool-btn-text svg,.tool-btn-arrow-down svg{width:14px;height:14px}.je-color-group{flex-shrink:0;align-items:center;display:inline-flex}.je-color-inner{justify-content:center;align-items:center;line-height:1;display:flex}.je-color-chip{background:0 0;border-radius:6px;justify-content:center;align-items:center;width:20px;height:20px;padding:0;display:inline-flex}.je-color-char{color:currentColor;font-size:14px;font-weight:600}.tool-btn.is-active,.tool-btn-text.is-active,.je-color-group.is-active{background-color:var(--je-blue-active);color:var(--je-blue)}.tool-btn.is-disabled,.tool-btn-text.is-disabled,.je-color-group.is-disabled{opacity:.35;pointer-events:none;cursor:default}.je-container.is-source-mode .je-toolbar-row .is-disabled{opacity:.35}.tool-btn.is-muted:hover,.tool-btn-text.is-muted:hover{background:0 0}.is-overflow-hidden{display:none!important}.je-editor-area,.je-editor-visual{flex-direction:column;flex:1;display:flex}.je-document-preview{background:#fff;border:none;width:100%;min-height:700px;display:none}.je-document-preview.is-active{display:block}.je-source-pane{box-sizing:border-box;background:linear-gradient(#f8fafc 0%,#fff 100%);flex:1;grid-template-columns:minmax(320px,1fr) minmax(320px,1fr);gap:16px;min-height:700px;padding:20px 24px 24px;display:none}.je-source-pane.is-active{display:grid}.je-source-textarea{color:#0f172a;resize:none;box-sizing:border-box;white-space:pre;background:#fff;border:1px solid #e5e7eb;border-radius:14px;outline:none;width:100%;min-height:100%;padding:18px 20px;font:13px/1.7 JetBrains Mono,SFMono-Regular,Consolas,monospace}.je-source-textarea:focus{border-color:#bfdbfe;box-shadow:0 0 0 4px #bfdbfe59}.je-source-preview{box-sizing:border-box;background:#fff;border:1px solid #e5e7eb;border-radius:14px;width:100%;min-height:100%}.je-editor-area .tiptap{cursor:text;color:#333;overflow-wrap:anywhere;word-break:break-word;outline:none;flex:1;max-width:100%;min-height:700px;padding:32px 60px;font-size:14px;line-height:1.7}.je-editor-area .tiptap h1{margin-bottom:.5em;font-size:2em;font-weight:700}.je-editor-area .tiptap h2{margin-bottom:.5em;font-size:1.5em;font-weight:700}.je-editor-area .tiptap h3{margin-bottom:.5em;font-size:1.25em;font-weight:700}.je-editor-area .tiptap p{margin-bottom:.8em;line-height:1.7}.je-editor-area .tiptap blockquote{color:#111827;background:#f3f4f6;border-left:3px solid #374151;margin:.8em 0;padding:8px 16px 8px 18px}.je-editor-area .tiptap ul{margin-bottom:.8em;padding-left:1.7em;list-style-type:disc}.je-editor-area .tiptap ul li::marker{color:#1c81d9}.je-editor-area .tiptap ol{counter-reset:je-ol;margin-bottom:.8em;padding-left:3.2em;list-style-type:none}.je-editor-area .tiptap ol>li{counter-increment:je-ol;position:relative}.je-editor-area .tiptap ol>li:before{content:counter(je-ol) ".";color:#1c81d9;white-space:nowrap;text-align:right;font-variant-numeric:tabular-nums;width:2.6em;position:absolute;left:-3.2em}.je-editor-area .tiptap ol ol{counter-reset:je-sub-ol;padding-left:3.8em}.je-editor-area .tiptap ol ol>li{counter-increment:je-sub-ol}.je-editor-area .tiptap ol ol>li:before{content:counter(je-ol) "." counter(je-sub-ol);width:3.2em;left:-3.8em}.je-editor-area .tiptap ol ol ol{counter-reset:je-sub-sub-ol;padding-left:4.8em}.je-editor-area .tiptap ol ol ol>li{counter-increment:je-sub-sub-ol}.je-editor-area .tiptap ol ol ol>li:before{content:counter(je-ol) "." counter(je-sub-ol) "." counter(je-sub-sub-ol);width:4.2em;left:-4.8em}.je-editor-area .tiptap li>p{margin-bottom:.35em}.je-editor-area .tiptap h1,.je-editor-area .tiptap h2,.je-editor-area .tiptap h3,.je-editor-area .tiptap h4,.je-editor-area .tiptap h5,.je-editor-area .tiptap h6,.je-editor-area .tiptap p,.je-editor-area .tiptap li,.je-editor-area .tiptap blockquote{overflow-wrap:anywhere;word-break:break-word;max-width:100%}.je-editor-area .tiptap hr{background:#e5e7eb;border:none;height:1px;margin:1.1em 0}.je-editor-area .tiptap code{color:#c2410c;background:#f7f9fc;border:1px solid #e8edf3;border-radius:6px;padding:.14em .42em;font-family:JetBrains Mono,SFMono-Regular,Consolas,monospace;font-size:.92em;font-weight:700}.je-editor-area .tiptap a{color:#2563eb;text-underline-offset:2px;text-decoration:underline;text-decoration-thickness:1px}.je-editor-area .tiptap .tableWrapper{width:fit-content;max-width:100%;margin:1em 0;position:relative}.je-editor-area .tiptap table{border-collapse:collapse;table-layout:fixed;background:#fff;width:auto;margin:1em 0}.je-editor-area .tiptap th,.je-editor-area .tiptap td{vertical-align:top;border:1px solid #e5e7eb;width:8px;min-width:8px;height:4px;padding:4px 8px}.je-editor-area .tiptap th{color:#374151;background:#f8fafc;font-weight:600}.je-modal-overlay{z-index:1400;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);background:#0f172a2e;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.je-modal{background:#fff;border:1px solid #e8edf3;border-radius:14px;width:min(430px,100vw - 32px);padding:22px 24px 20px;box-shadow:0 24px 60px #0f172a29}.je-modal-title{color:#111827;margin-bottom:18px;font-size:18px;font-weight:700}.je-modal-field{grid-template-columns:44px 1fr;align-items:center;gap:10px;margin-bottom:14px;display:grid}.je-modal-label{color:#374151;font-size:14px}.je-modal-input{color:#111827;background:#f9fbfd;border:1px solid #dbe3ec;border-radius:8px;outline:none;height:36px;padding:0 12px;font-size:14px}.je-modal-input::placeholder{color:#9ca3af}.je-modal-input:focus{background:#fff;border-color:#9ec5fe;box-shadow:0 0 0 3px #93c5fd2e}.je-modal-actions{justify-content:flex-end;gap:10px;margin-top:24px;display:flex}.je-modal-btn{color:#374151;cursor:pointer;background:#fff;border:1px solid #e3e8ef;border-radius:8px;min-width:70px;height:34px;padding:0 14px;font-size:14px;transition:background-color .12s,border-color .12s,color .12s}.je-modal-btn:hover{background:#f8fafc;border-color:#d4dde8}.je-modal-btn.is-primary{color:#3b82f6;background:#ddebff;border-color:#cfe1f8}.je-modal-btn.is-primary:hover{background:#d3e6ff;border-color:#bfd6f6}::-webkit-scrollbar{width:6px}::-webkit-scrollbar-thumb{background:#ddd;border-radius:10px}.image-node-wrapper{cursor:default;-webkit-user-select:none;user-select:none;line-height:0;display:inline-block;position:relative}.image-node-wrapper img{border:2px solid #0000;border-radius:2px;max-width:100%;transition:border-color .15s;display:block}.image-node-wrapper.is-selected img{border-color:var(--je-blue)}.image-resize-handle{background:var(--je-blue);z-index:10;border-radius:50%;width:10px;height:10px;display:none;position:absolute}.image-node-wrapper.is-selected .image-resize-handle{display:block}.image-resize-handle[data-corner=tl]{cursor:nwse-resize;top:-5px;left:-5px}.image-resize-handle[data-corner=tr]{cursor:nesw-resize;top:-5px;right:-5px}.image-resize-handle[data-corner=bl]{cursor:nesw-resize;bottom:-5px;left:-5px}.image-resize-handle[data-corner=br]{cursor:nwse-resize;bottom:-5px;right:-5px}.je-code-button{color:#1d4ed8;font-family:Courier New,monospace;font-weight:700}.je-popover{z-index:1000;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);background:#fffffff5;border:1px solid #e5e7eb;border-radius:14px;min-width:180px;padding:10px;position:absolute;box-shadow:0 10px 28px #0f172a1a}.je-popover-list{flex-direction:column;gap:4px;display:flex}.je-popover-list--scroll{max-height:260px;overflow-y:auto}.je-popover-list--font-family{max-height:312px}.je-popover--font-family{min-width:144px;max-width:180px}.je-popover--font-size{min-width:126px;max-width:150px}.je-popover-item{color:#374151;cursor:pointer;text-align:left;background:0 0;border:none;border-radius:10px;align-items:center;gap:8px;width:100%;padding:8px 10px;font-size:13px;display:flex}.je-popover-item svg{flex-shrink:0;width:16px;height:16px}.je-popover-item:hover{background:#f3f4f6}.je-popover-color{width:fit-content;min-width:unset;max-width:calc(100vw - 32px)}.je-color-section+.je-color-section{margin-top:10px}.je-color-section-title{color:#9ca3af;margin-bottom:8px;font-size:12px;font-weight:500}.je-color-grid{grid-template-columns:repeat(6,30px);justify-content:start;gap:6px;display:grid}.je-color-grid--recent{grid-template-columns:repeat(6,30px)}.je-color-swatch{cursor:pointer;color:#6b7280;background:#fff;border:1px solid #d1d5db;border-radius:8px;justify-content:center;align-items:center;width:30px;height:30px;transition:transform .12s,border-color .12s,box-shadow .12s;display:inline-flex}.je-color-swatch:hover{border-color:#93c5fd;transform:translateY(-1px);box-shadow:0 0 0 3px #3b82f624}.je-color-swatch.is-empty{opacity:.28;cursor:default}.je-color-swatch--filled{border-color:#d1d5db}.je-color-swatch--text{background:#fff;padding:0}.je-color-swatch--custom,.je-color-swatch--clear,.je-color-swatch--combo{background:#fff}.je-color-swatch--custom{position:relative;overflow:hidden}.je-style-preview{background:0 0;border-radius:5px;justify-content:center;align-items:center;width:18px;height:18px;font-size:15px;font-weight:700;display:inline-flex}.je-style-preview.is-empty{opacity:.45;box-shadow:inset 0 0 0 1px #d1d5dbe6}.je-style-preview.is-clear{color:#9ca3af}.je-color-custom-panel{background:#fafbfc;border:1px solid #eef2f7;border-radius:10px;flex-direction:column;gap:8px;margin-top:10px;padding:10px;display:flex}.je-color-custom-panel.is-hidden{display:none}.je-color-custom-title{color:#9ca3af;font-size:12px;font-weight:500}.je-color-picker{cursor:pointer;background:#fff;border:1px solid #edf2f7;border-radius:8px;width:100%;height:34px;padding:2px}.je-color-actions{gap:6px;display:flex}.je-action-btn{color:#667085;cursor:pointer;background:#fff;border:1px solid #e8edf3;border-radius:8px;flex:1;height:30px;padding:0 10px;font-size:12px;transition:background-color .12s,border-color .12s,color .12s}.je-action-btn:hover{background:#f8fafc;border-color:#dde5ee}.je-action-btn.is-primary{color:#4b5563;background:#eef3f8;border-color:#dbe5f0}.je-action-btn.is-primary:hover{background:#e4ebf3;border-color:#ced8e4}.je-callout-item{color:#374151;cursor:pointer;text-align:left;background:0 0;border:none;border-radius:10px;grid-template-columns:30px 1fr;align-items:center;gap:10px;width:100%;padding:8px 10px;display:grid}.je-callout-item:hover{background:#f3f4f6}.je-callout-badge{border-radius:8px;justify-content:center;align-items:center;width:30px;height:30px;font-size:14px;font-weight:700;display:inline-flex}.je-callout-content{flex-direction:column;gap:2px;display:flex}.je-callout-label{color:#111827;font-size:13px;font-weight:600}.je-callout-short{color:#9ca3af;font-size:12px}.je-editor-area .tiptap .je-callout-wrapper{box-sizing:border-box;width:auto;margin:12px 0;position:relative}.je-editor-area .tiptap .je-callout{background:var(--je-callout-bg,#faf8ff);width:auto;color:var(--je-callout-color,#9333ea);box-sizing:border-box;border:1px solid #0000;border-radius:14px;margin:0;padding:14px 16px;position:relative}.je-editor-area .tiptap .je-callout-header{-webkit-user-select:none;user-select:none;align-items:center;gap:10px;margin-bottom:10px;display:flex}.je-editor-area .tiptap .je-callout-drag-handle{width:24px;height:24px;color:inherit;cursor:grab;opacity:0;pointer-events:none;background:0 0;border:none;border-radius:8px;flex-shrink:0;justify-content:center;align-items:center;transition:opacity .18s,background-color .12s;display:inline-flex}.je-editor-area .tiptap .je-callout-wrapper:hover .je-callout-drag-handle,.je-editor-area .tiptap .je-callout-wrapper.is-handle-visible .je-callout-drag-handle,.je-editor-area .tiptap .je-callout-wrapper.ProseMirror-selectednode .je-callout-drag-handle,.je-editor-area .tiptap .je-callout-drag-handle:focus-visible{opacity:1;pointer-events:auto}.je-editor-area .tiptap .je-callout-drag-handle:hover,.je-editor-area .tiptap .je-callout-drag-handle:focus-visible{background:#ffffff80;outline:none}.je-editor-area .tiptap .je-callout-drag-handle svg{width:14px;height:14px}.je-editor-area .tiptap .je-callout-wrapper.ProseMirror-selectednode .je-callout{border-color:var(--je-callout-color,#9333ea);box-shadow:0 0 0 2px color-mix(in srgb, var(--je-callout-color,#9333ea) 12%, transparent)}.je-editor-area .tiptap .je-callout-title-btn{color:inherit;cursor:pointer;background:0 0;border:none;align-items:center;gap:8px;padding:0;font-size:14px;font-weight:700;display:inline-flex}.je-editor-area .tiptap .je-callout-title-btn svg,.je-editor-area .tiptap .je-callout-icon svg{width:18px;height:18px}.je-editor-area .tiptap .je-callout-body>:last-child{margin-bottom:0}.je-editor-area .tiptap .je-callout-body{color:inherit;min-height:24px}.je-callout-type-popover{z-index:1001;min-width:220px;position:absolute}.je-insert-popover{min-width:160px;padding:8px}.je-insert-item{color:#374151;cursor:pointer;text-align:left;background:0 0;border:none;border-radius:10px;justify-content:space-between;align-items:center;width:100%;min-height:34px;padding:0 10px;display:flex}.je-insert-item:hover{background:#f3f6fa}.je-insert-item-main{align-items:center;gap:8px;display:inline-flex}.je-insert-item-icon,.je-insert-item-arrow{color:#6b7280;justify-content:center;align-items:center;display:inline-flex}.je-insert-item-icon svg{width:16px;height:16px}.je-insert-table-panel{flex-direction:column;align-items:center;width:fit-content;min-width:216px;padding:10px;display:flex}.je-insert-table-title{color:#6b7280;width:196px;margin-bottom:10px;font-size:13px}.je-insert-table-grid{grid-template-columns:repeat(10,16px);gap:4px;width:196px;display:grid}.je-insert-table-cell{cursor:pointer;background:#f8fafc;border:1px solid #dbe3ec;width:16px;height:16px}.je-insert-table-cell.is-active{background:#dbeafe;border-color:#93c5fd}.je-insert-table-info{color:#6b7280;width:196px;margin-top:10px;font-size:13px}.je-insert-table-custom{border-top:1px solid #eef2f7;grid-template-columns:minmax(0,1fr) minmax(0,1fr) 48px;gap:6px;width:196px;margin-top:12px;padding-top:10px;display:grid}.je-insert-table-custom-field{color:#6b7280;flex-direction:column;gap:4px;font-size:12px;display:flex}.je-insert-table-number{box-sizing:border-box;background:#fff;border:1px solid #dbe3ec;border-radius:8px;outline:none;width:100%;height:30px;padding:0 8px}.je-insert-table-confirm{color:#4b5563;cursor:pointer;box-sizing:border-box;background:#eef3f8;border:1px solid #dbe5f0;border-radius:8px;align-self:end;width:100%;height:30px;padding:0}.je-table-wrap{width:fit-content;max-width:100%;position:relative}.je-table-move-handle,.je-table-resize-handle{z-index:3;opacity:0;transition:opacity .12s,background-color .12s;position:absolute}.je-table-wrap:hover .je-table-move-handle,.je-table-wrap:hover .je-table-resize-handle,.je-table-wrap.ProseMirror-selectednode .je-table-move-handle,.je-table-wrap.ProseMirror-selectednode .je-table-resize-handle{opacity:1}.je-table-move-handle{color:#6b7280;cursor:grab;background:#fff;border:1px solid #dbe3ec;border-radius:6px;justify-content:center;align-items:center;width:20px;height:20px;display:inline-flex;top:-10px;left:-10px}.je-table-move-handle svg{width:12px;height:12px}.je-table-resize-handle{cursor:nwse-resize;background:#cbd5e1;border-radius:4px;width:14px;height:14px;bottom:-8px;right:-8px}.je-code-block-wrap{background:#fff;border:1px solid #d0d7de;border-radius:12px;width:100%;margin:1em 0;position:relative;overflow:hidden}.je-code-block-header{background:#f6f8fa;align-items:center;gap:8px;min-height:34px;padding:0 12px;display:flex}.je-code-block-select{color:#6b7280;appearance:none;background:0 0;border:none;border-radius:0;outline:none;height:24px;padding:0 18px 0 0;font-size:12px}.je-code-block-select option{color:#111827}.je-code-block-header:after{content:"";pointer-events:none;border-bottom:1.5px solid #9ca3af;border-right:1.5px solid #9ca3af;width:10px;height:10px;margin-left:-12px;transform:rotate(45deg)scale(.6)}.je-code-block-spacer{flex:1}.je-code-block-copy{color:#6b7280;opacity:0;pointer-events:none;cursor:pointer;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;width:20px;height:20px;padding:0;transition:opacity .12s,background-color .12s,color .12s;display:inline-flex}.je-code-block-copy:hover{color:#374151;background:#eaeef2}.je-code-block-copy.is-copied{color:#1d4ed8}.je-code-block-copy svg{width:14px;height:14px}.je-code-block-wrap:hover .je-code-block-copy,.je-code-block-wrap:focus-within .je-code-block-copy{opacity:1;pointer-events:auto}.je-code-block-wrap pre{background:0 0;margin:0;padding:12px 16px 16px;overflow-x:auto}.je-code-block-wrap pre code{color:#24292e;box-shadow:none;background:0 0;border:none;padding:0;font-size:13px;font-weight:400;display:block}.je-code-block-wrap pre code.je-code-block{box-shadow:none;background:0 0;border:none}.je-code-block-wrap .hljs-comment,.je-code-block-wrap .hljs-quote{color:#6a737d;font-style:italic}.je-code-block-wrap .hljs-keyword,.je-code-block-wrap .hljs-doctag,.je-code-block-wrap .hljs-selector-tag,.je-code-block-wrap .hljs-literal,.je-code-block-wrap .hljs-type{color:#d73a49}.je-code-block-wrap .hljs-string,.je-code-block-wrap .hljs-attr,.je-code-block-wrap .hljs-template-tag{color:#032f62}.je-code-block-wrap .hljs-number,.je-code-block-wrap .hljs-built_in,.je-code-block-wrap .hljs-title.class_,.je-code-block-wrap .hljs-symbol{color:#005cc5}.je-code-block-wrap .hljs-function,.je-code-block-wrap .hljs-title.function_{color:#6f42c1}.je-link-popover{z-index:1100;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);background:#fffffffa;border:1px solid #e5e7eb;border-radius:10px;grid-template-columns:1fr auto;align-items:center;width:268px;min-height:36px;padding:0 8px;display:grid;position:absolute;box-shadow:0 10px 28px #0f172a1f}.je-link-popover__main{color:#2563eb;white-space:nowrap;text-overflow:ellipsis;align-items:center;font-size:13px;text-decoration:none;display:inline-flex;overflow:hidden}.je-link-popover__actions{align-items:center;gap:4px;margin-left:8px;display:inline-flex}.je-link-popover__action{color:#6b7280;cursor:pointer;background:#fff;border:1px solid #e5e7eb;border-radius:8px;width:28px;height:28px}.je-link-popover__action:hover{color:#374151;background:#f8fafc}.raw-html-island{background:linear-gradient(#f8fafc 0%,#fff 100%);border:1px solid #e5e7eb;border-radius:14px;margin:12px 0;overflow:hidden}.raw-html-island__header{color:#475569;letter-spacing:.02em;text-transform:uppercase;border-bottom:1px solid #eef2f7;justify-content:space-between;align-items:center;gap:12px;padding:10px 14px;font-size:12px;font-weight:700;display:flex}.raw-html-island__actions{align-items:center;gap:6px;display:inline-flex}.raw-html-island__action{color:#64748b;cursor:pointer;background:#fff;border:1px solid #e6ebf1;border-radius:8px;height:28px;padding:0 10px;font-size:12px;transition:background-color .12s,border-color .12s,color .12s}.raw-html-island__action:hover{color:#475569;background:#f8fafc;border-color:#d6dee8}.raw-html-island__action.is-danger{color:#b91c1c}.raw-html-island__body{color:#0f172a;white-space:pre-wrap;word-break:break-word;margin:0;padding:14px;font:12px/1.7 JetBrains Mono,SFMono-Regular,Consolas,monospace}.raw-html-island.is-editing .raw-html-island__body{display:none}.raw-html-island__editor{background:#fff;border-top:1px solid #eef2f7;padding:14px}.raw-html-island__editor.is-hidden{display:none}.raw-html-island__textarea{color:#0f172a;resize:vertical;box-sizing:border-box;white-space:pre;background:#f8fafc;border:1px solid #e5e7eb;border-radius:12px;outline:none;width:100%;min-height:220px;padding:12px 14px;font:12px/1.7 JetBrains Mono,SFMono-Regular,Consolas,monospace}.raw-html-island__textarea:focus{background:#fff;border-color:#bfdbfe;box-shadow:0 0 0 4px #bfdbfe47}.raw-html-island__editor-actions{justify-content:flex-end;gap:8px;margin-top:10px;display:flex}.raw-html-island__action.is-primary{color:#4b5563;background:#eef3f8;border-color:#dbe5f0}.raw-html-island__action.is-primary:hover{background:#e4ebf3;border-color:#ced8e4}@media (width<=980px){.je-source-pane.is-active{grid-template-columns:1fr;min-height:auto}.je-source-textarea,.je-source-preview{min-height:360px}}pre code.hljs{padding:1em;display:block;overflow-x:auto}code.hljs{padding:3px 5px}.hljs{color:#24292e;background:#fff}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#d73a49}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#6f42c1}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-variable,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id{color:#005cc5}.hljs-regexp,.hljs-string,.hljs-meta .hljs-string{color:#032f62}.hljs-built_in,.hljs-symbol{color:#e36209}.hljs-comment,.hljs-code,.hljs-formula{color:#6a737d}.hljs-name,.hljs-quote,.hljs-selector-tag,.hljs-selector-pseudo{color:#22863a}.hljs-subst{color:#24292e}.hljs-section{color:#005cc5;font-weight:700}.hljs-bullet{color:#735c0f}.hljs-emphasis{color:#24292e;font-style:italic}.hljs-strong{color:#24292e;font-weight:700}.hljs-addition{color:#22863a;background-color:#f0fff4}.hljs-deletion{color:#b31d28;background-color:#ffeef0}
|
|
1
|
+
:root{--je-blue:#0052d9;--je-blue-active:#e6f0ff;--je-divider:#e0e0e0;--je-hover:#eee;--je-radius:4px}.je-container{-webkit-font-smoothing:antialiased;background:#fff;border:1px solid #e6e6e6;border-radius:4px;flex-direction:column;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,PingFang SC,Microsoft YaHei,sans-serif;display:flex;overflow:visible}.je-toolbar-shell{z-index:40;background:#fff;flex-direction:column;display:flex;position:sticky;top:0}:is(.je-container:fullscreen,.je-container.je-is-fullscreen){border:none;border-radius:0;width:100vw;max-width:none;height:100vh;max-height:none;overflow:hidden auto}:is(.je-container:fullscreen .je-editor-area,.je-container.je-is-fullscreen .je-editor-area,.je-container:fullscreen .je-editor-visual,.je-container.je-is-fullscreen .je-editor-visual){flex:auto;min-height:0}:is(.je-container:fullscreen .je-document-preview,.je-container.je-is-fullscreen .je-document-preview,.je-container:fullscreen .je-source-pane,.je-container.je-is-fullscreen .je-source-pane){min-height:0}.je-toolbar-row{z-index:1;flex-shrink:0;align-items:center;gap:1px;padding:0 12px;display:flex;position:relative}.je-toolbar-row--primary{background:#fff;height:44px}.je-toolbar-row--secondary{background:#f3f4f6;border-radius:6px;height:42px;margin:0 8px 4px}.je-toolbar-row--secondary:after{content:"";pointer-events:none;opacity:0;background:#eef0f2;height:1px;transition:opacity .12s;position:absolute;bottom:-5px;left:-8px;right:-8px}.je-container.is-scrolled .je-toolbar-row--secondary:after{opacity:1}.je-spacer{flex:1}.v-divider{background-color:var(--je-divider);flex-shrink:0;width:1px;height:16px;margin:0 6px}.tool-btn,.tool-btn-text,.tool-btn-arrow-down{border-radius:var(--je-radius);color:#444;cursor:pointer;background:0 0;border:none;flex-shrink:0;justify-content:center;align-items:center;gap:2px;line-height:1;transition:background-color .1s;display:inline-flex}.tool-btn{width:28px;height:28px;padding:0;font-size:13px}.tool-btn:hover{background-color:var(--je-hover)}.tool-btn.is-muted,.tool-btn-text.is-muted,.je-color-group.is-muted{color:#9ca3af;opacity:1;pointer-events:none}.tool-btn-text{white-space:nowrap;height:28px;padding:0 6px;font-size:13px}.tool-btn-text:hover{background-color:var(--je-hover)}.tool-btn-text--icon{gap:4px}.tool-btn-arrow-down{color:#999;width:16px;height:28px;padding:0}.tool-btn-arrow-down:hover{background-color:var(--je-hover)}.tool-btn svg,.tool-btn-text svg,.tool-btn-arrow-down svg{flex-shrink:0;width:20px;height:20px}.tool-btn-text svg,.tool-btn-arrow-down svg{width:14px;height:14px}.je-color-group{flex-shrink:0;align-items:center;display:inline-flex}.je-color-inner{justify-content:center;align-items:center;line-height:1;display:flex}.je-color-chip{background:0 0;border-radius:6px;justify-content:center;align-items:center;width:20px;height:20px;padding:0;display:inline-flex}.je-color-char{color:currentColor;font-size:14px;font-weight:600}.tool-btn.is-active,.tool-btn-text.is-active,.je-color-group.is-active{background-color:var(--je-blue-active);color:var(--je-blue)}.tool-btn.is-disabled,.tool-btn-text.is-disabled,.je-color-group.is-disabled{opacity:.35;pointer-events:none;cursor:default}.je-container.is-source-mode .je-toolbar-row .is-disabled{opacity:.35}.tool-btn.is-muted:hover,.tool-btn-text.is-muted:hover{background:0 0}.is-overflow-hidden{display:none!important}.je-editor-area,.je-editor-visual{flex-direction:column;flex:1;display:flex}.je-document-preview{background:#fff;border:none;width:100%;min-height:700px;display:none}.je-document-preview.is-active{display:block}.je-source-pane{box-sizing:border-box;background:linear-gradient(#f8fafc 0%,#fff 100%);flex:1;grid-template-columns:minmax(320px,1fr) minmax(320px,1fr);gap:16px;min-height:700px;padding:20px 24px 24px;display:none}.je-source-pane.is-active{display:grid}.je-source-textarea{color:#0f172a;resize:none;box-sizing:border-box;white-space:pre;background:#fff;border:1px solid #e5e7eb;border-radius:14px;outline:none;width:100%;min-height:100%;padding:18px 20px;font:13px/1.7 JetBrains Mono,SFMono-Regular,Consolas,monospace}.je-source-textarea:focus{border-color:#bfdbfe;box-shadow:0 0 0 4px #bfdbfe59}.je-source-preview{box-sizing:border-box;background:#fff;border:1px solid #e5e7eb;border-radius:14px;width:100%;min-height:100%}.je-editor-area .tiptap{cursor:text;color:#333;overflow-wrap:anywhere;word-break:break-word;outline:none;flex:1;max-width:100%;min-height:700px;padding:32px 60px;font-size:14px;line-height:1.7}.je-editor-area .tiptap h1{margin-bottom:.5em;font-size:2em;font-weight:700}.je-editor-area .tiptap h2{margin-bottom:.5em;font-size:1.5em;font-weight:700}.je-editor-area .tiptap h3{margin-bottom:.5em;font-size:1.25em;font-weight:700}.je-editor-area .tiptap p{margin-bottom:.8em;line-height:1.7}.je-editor-area .tiptap blockquote{color:#111827;background:#f3f4f6;border-left:3px solid #374151;margin:.8em 0;padding:8px 16px 8px 18px}.je-editor-area .tiptap ul{margin-bottom:.8em;padding-left:1.7em;list-style-type:disc}.je-editor-area .tiptap ul li::marker{color:#1c81d9}.je-editor-area .tiptap ol{counter-reset:je-ol;margin-bottom:.8em;padding-left:3.2em;list-style-type:none}.je-editor-area .tiptap ol>li{counter-increment:je-ol;position:relative}.je-editor-area .tiptap ol>li:before{content:counter(je-ol) ".";color:#1c81d9;white-space:nowrap;text-align:right;font-variant-numeric:tabular-nums;width:2.6em;position:absolute;left:-3.2em}.je-editor-area .tiptap ol ol{counter-reset:je-sub-ol;padding-left:3.8em}.je-editor-area .tiptap ol ol>li{counter-increment:je-sub-ol}.je-editor-area .tiptap ol ol>li:before{content:counter(je-ol) "." counter(je-sub-ol);width:3.2em;left:-3.8em}.je-editor-area .tiptap ol ol ol{counter-reset:je-sub-sub-ol;padding-left:4.8em}.je-editor-area .tiptap ol ol ol>li{counter-increment:je-sub-sub-ol}.je-editor-area .tiptap ol ol ol>li:before{content:counter(je-ol) "." counter(je-sub-ol) "." counter(je-sub-sub-ol);width:4.2em;left:-4.8em}.je-editor-area .tiptap li>p{margin-bottom:.35em}.je-editor-area .tiptap h1,.je-editor-area .tiptap h2,.je-editor-area .tiptap h3,.je-editor-area .tiptap h4,.je-editor-area .tiptap h5,.je-editor-area .tiptap h6,.je-editor-area .tiptap p,.je-editor-area .tiptap li,.je-editor-area .tiptap blockquote{overflow-wrap:anywhere;word-break:break-word;max-width:100%}.je-editor-area .tiptap hr{background:#e5e7eb;border:none;height:1px;margin:1.1em 0}.je-editor-area .tiptap code{color:#c2410c;background:#f7f9fc;border:1px solid #e8edf3;border-radius:6px;padding:.14em .42em;font-family:JetBrains Mono,SFMono-Regular,Consolas,monospace;font-size:.92em;font-weight:700}.je-editor-area .tiptap a{color:#2563eb;text-underline-offset:2px;text-decoration:underline;text-decoration-thickness:1px}.je-editor-area .tiptap .tableWrapper{width:100%;max-width:100%;margin:1em 0;padding:8px 10px 10px 22px;position:relative;overflow:visible!important}.je-editor-area .tiptap table{border-collapse:collapse;table-layout:fixed;background:#fff;width:100%;margin:0}.je-editor-area .tiptap th,.je-editor-area .tiptap td{vertical-align:top;cursor:text;-webkit-user-select:text;user-select:text;border:none;border-bottom:1px solid #e5e7eb;min-width:80px;height:auto;padding:8px 10px;line-height:1.5}.je-editor-area .tiptap th{color:#374151;background:#f8fafc;border-top:1px solid #cbd5e1;border-bottom-color:#dbe3ec;font-weight:600}.je-editor-area .tiptap tr:last-child td{border-bottom:1px solid #cbd5e1}.je-editor-area .tiptap th>p,.je-editor-area .tiptap td>p{margin:0;line-height:1.5}.je-modal-overlay{z-index:1400;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);background:#0f172a2e;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.je-modal{background:#fff;border:1px solid #e8edf3;border-radius:14px;width:min(430px,100vw - 32px);padding:22px 24px 20px;box-shadow:0 24px 60px #0f172a29}.je-modal-title{color:#111827;margin-bottom:18px;font-size:18px;font-weight:700}.je-modal-field{grid-template-columns:44px 1fr;align-items:center;gap:10px;margin-bottom:14px;display:grid}.je-modal-label{color:#374151;font-size:14px}.je-modal-input{color:#111827;background:#f9fbfd;border:1px solid #dbe3ec;border-radius:8px;outline:none;height:36px;padding:0 12px;font-size:14px}.je-modal-input::placeholder{color:#9ca3af}.je-modal-input:focus{background:#fff;border-color:#9ec5fe;box-shadow:0 0 0 3px #93c5fd2e}.je-modal-actions{justify-content:flex-end;gap:10px;margin-top:24px;display:flex}.je-modal-btn{color:#374151;cursor:pointer;background:#fff;border:1px solid #e3e8ef;border-radius:8px;min-width:70px;height:34px;padding:0 14px;font-size:14px;transition:background-color .12s,border-color .12s,color .12s}.je-modal-btn:hover{background:#f8fafc;border-color:#d4dde8}.je-modal-btn.is-primary{color:#3b82f6;background:#ddebff;border-color:#cfe1f8}.je-modal-btn.is-primary:hover{background:#d3e6ff;border-color:#bfd6f6}::-webkit-scrollbar{width:6px}::-webkit-scrollbar-thumb{background:#ddd;border-radius:10px}.image-node-wrapper{cursor:default;-webkit-user-select:none;user-select:none;line-height:0;display:inline-block;position:relative}.image-node-wrapper img{border:2px solid #0000;border-radius:2px;max-width:100%;transition:border-color .15s;display:block}.image-node-wrapper.is-selected img{border-color:var(--je-blue)}.image-resize-handle{background:var(--je-blue);z-index:10;border-radius:50%;width:10px;height:10px;display:none;position:absolute}.image-node-wrapper.is-selected .image-resize-handle{display:block}.image-resize-handle[data-corner=tl]{cursor:nwse-resize;top:-5px;left:-5px}.image-resize-handle[data-corner=tr]{cursor:nesw-resize;top:-5px;right:-5px}.image-resize-handle[data-corner=bl]{cursor:nesw-resize;bottom:-5px;left:-5px}.image-resize-handle[data-corner=br]{cursor:nwse-resize;bottom:-5px;right:-5px}.je-code-button{color:#1d4ed8;font-family:Courier New,monospace;font-weight:700}.je-popover{z-index:1000;-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);background:#fffffff5;border:1px solid #e5e7eb;border-radius:14px;min-width:180px;padding:10px;position:absolute;box-shadow:0 10px 28px #0f172a1a}.je-popover-list{flex-direction:column;gap:4px;display:flex}.je-popover-list--scroll{max-height:260px;overflow-y:auto}.je-popover-list--font-family{max-height:312px}.je-popover--font-family{min-width:144px;max-width:180px}.je-popover--font-size{min-width:126px;max-width:150px}.je-popover-item{color:#374151;cursor:pointer;text-align:left;background:0 0;border:none;border-radius:10px;align-items:center;gap:8px;width:100%;padding:8px 10px;font-size:13px;display:flex}.je-popover-item svg{flex-shrink:0;width:16px;height:16px}.je-popover-item:hover{background:#f3f4f6}.je-popover-color{width:fit-content;min-width:unset;max-width:calc(100vw - 32px)}.je-color-section+.je-color-section{margin-top:10px}.je-color-section-title{color:#9ca3af;margin-bottom:8px;font-size:12px;font-weight:500}.je-color-grid{grid-template-columns:repeat(6,30px);justify-content:start;gap:6px;display:grid}.je-color-grid--recent{grid-template-columns:repeat(6,30px)}.je-color-swatch{cursor:pointer;color:#6b7280;background:#fff;border:1px solid #d1d5db;border-radius:8px;justify-content:center;align-items:center;width:30px;height:30px;transition:transform .12s,border-color .12s,box-shadow .12s;display:inline-flex}.je-color-swatch:hover{border-color:#93c5fd;transform:translateY(-1px);box-shadow:0 0 0 3px #3b82f624}.je-color-swatch.is-empty{opacity:.28;cursor:default}.je-color-swatch--filled{border-color:#d1d5db}.je-color-swatch--text{background:#fff;padding:0}.je-color-swatch--custom,.je-color-swatch--clear,.je-color-swatch--combo{background:#fff}.je-color-swatch--custom{position:relative;overflow:hidden}.je-style-preview{background:0 0;border-radius:5px;justify-content:center;align-items:center;width:18px;height:18px;font-size:15px;font-weight:700;display:inline-flex}.je-style-preview.is-empty{opacity:.45;box-shadow:inset 0 0 0 1px #d1d5dbe6}.je-style-preview.is-clear{color:#9ca3af}.je-color-custom-panel{background:#fafbfc;border:1px solid #eef2f7;border-radius:10px;flex-direction:column;gap:8px;margin-top:10px;padding:10px;display:flex}.je-color-custom-panel.is-hidden{display:none}.je-color-custom-title{color:#9ca3af;font-size:12px;font-weight:500}.je-color-picker{cursor:pointer;background:#fff;border:1px solid #edf2f7;border-radius:8px;width:100%;height:34px;padding:2px}.je-color-actions{gap:6px;display:flex}.je-action-btn{color:#667085;cursor:pointer;background:#fff;border:1px solid #e8edf3;border-radius:8px;flex:1;height:30px;padding:0 10px;font-size:12px;transition:background-color .12s,border-color .12s,color .12s}.je-action-btn:hover{background:#f8fafc;border-color:#dde5ee}.je-action-btn.is-primary{color:#4b5563;background:#eef3f8;border-color:#dbe5f0}.je-action-btn.is-primary:hover{background:#e4ebf3;border-color:#ced8e4}.je-callout-item{color:#374151;cursor:pointer;text-align:left;background:0 0;border:none;border-radius:10px;grid-template-columns:30px 1fr;align-items:center;gap:10px;width:100%;padding:8px 10px;display:grid}.je-callout-item:hover{background:#f3f4f6}.je-callout-badge{border-radius:8px;justify-content:center;align-items:center;width:30px;height:30px;font-size:14px;font-weight:700;display:inline-flex}.je-callout-content{flex-direction:column;gap:2px;display:flex}.je-callout-label{color:#111827;font-size:13px;font-weight:600}.je-callout-short{color:#9ca3af;font-size:12px}.je-editor-area .tiptap .je-callout-wrapper{box-sizing:border-box;width:auto;margin:12px 0;position:relative}.je-editor-area .tiptap .je-callout{background:var(--je-callout-bg,#faf8ff);width:auto;color:var(--je-callout-color,#9333ea);box-sizing:border-box;border:1px solid #0000;border-radius:14px;margin:0;padding:14px 16px;position:relative}.je-editor-area .tiptap .je-callout-header{-webkit-user-select:none;user-select:none;align-items:center;gap:10px;margin-bottom:10px;display:flex}.je-editor-area .tiptap .je-callout-drag-handle{width:24px;height:24px;color:inherit;cursor:grab;opacity:0;pointer-events:none;background:0 0;border:none;border-radius:8px;flex-shrink:0;justify-content:center;align-items:center;transition:opacity .18s,background-color .12s;display:inline-flex}.je-editor-area .tiptap .je-callout-wrapper:hover .je-callout-drag-handle,.je-editor-area .tiptap .je-callout-wrapper.is-handle-visible .je-callout-drag-handle,.je-editor-area .tiptap .je-callout-wrapper.ProseMirror-selectednode .je-callout-drag-handle,.je-editor-area .tiptap .je-callout-drag-handle:focus-visible{opacity:1;pointer-events:auto}.je-editor-area .tiptap .je-callout-drag-handle:hover,.je-editor-area .tiptap .je-callout-drag-handle:focus-visible{background:#ffffff80;outline:none}.je-editor-area .tiptap .je-callout-drag-handle svg{width:14px;height:14px}.je-editor-area .tiptap .je-callout-wrapper.ProseMirror-selectednode .je-callout{border-color:var(--je-callout-color,#9333ea);box-shadow:0 0 0 2px color-mix(in srgb, var(--je-callout-color,#9333ea) 12%, transparent)}.je-editor-area .tiptap .je-callout-title-btn{color:inherit;cursor:pointer;background:0 0;border:none;align-items:center;gap:8px;padding:0;font-size:14px;font-weight:700;display:inline-flex}.je-editor-area .tiptap .je-callout-title-btn svg,.je-editor-area .tiptap .je-callout-icon svg{width:18px;height:18px}.je-editor-area .tiptap .je-callout-body>:last-child{margin-bottom:0}.je-editor-area .tiptap .je-callout-body{color:inherit;min-height:24px}.je-callout-type-popover{z-index:1001;min-width:220px;position:absolute}.je-insert-popover{min-width:160px;padding:8px}.je-insert-item{color:#374151;cursor:pointer;text-align:left;background:0 0;border:none;border-radius:10px;justify-content:space-between;align-items:center;width:100%;min-height:34px;padding:0 10px;display:flex}.je-insert-item:hover{background:#f3f6fa}.je-insert-item-main{align-items:center;gap:8px;display:inline-flex}.je-insert-item-icon,.je-insert-item-arrow{color:#6b7280;justify-content:center;align-items:center;display:inline-flex}.je-insert-item-icon svg{width:16px;height:16px}.je-insert-table-panel{flex-direction:column;align-items:center;width:fit-content;min-width:216px;padding:10px;display:flex}.je-insert-table-title{color:#6b7280;width:196px;margin-bottom:10px;font-size:13px}.je-insert-table-grid{grid-template-columns:repeat(10,16px);gap:4px;width:196px;display:grid}.je-insert-table-cell{cursor:pointer;background:#f8fafc;border:1px solid #dbe3ec;width:16px;height:16px}.je-insert-table-cell.is-active{background:#dbeafe;border-color:#93c5fd}.je-insert-table-info{color:#6b7280;width:196px;margin-top:10px;font-size:13px}.je-insert-table-custom{border-top:1px solid #eef2f7;grid-template-columns:minmax(0,1fr) minmax(0,1fr) 48px;gap:6px;width:196px;margin-top:12px;padding-top:10px;display:grid}.je-insert-table-custom-field{color:#6b7280;flex-direction:column;gap:4px;font-size:12px;display:flex}.je-insert-table-number{box-sizing:border-box;background:#fff;border:1px solid #dbe3ec;border-radius:8px;outline:none;width:100%;height:30px;padding:0 8px}.je-insert-table-confirm{color:#4b5563;cursor:pointer;box-sizing:border-box;background:#eef3f8;border:1px solid #dbe5f0;border-radius:8px;align-self:end;width:100%;height:30px;padding:0}.je-table-wrap{width:100%;max-width:100%;position:relative;overflow:visible}.je-table-overlay{pointer-events:none;z-index:10;position:absolute;inset:0}.je-table-move-handle,.je-table-resize-handle,.je-table-col-handle,.je-table-row-handle,.je-table-add-control{z-index:3;opacity:0;pointer-events:auto;transition:opacity .12s,background-color .12s,border-color .12s;position:absolute}.je-table-wrap:hover .je-table-move-handle,.je-table-wrap:hover .je-table-resize-handle,.je-table-wrap:hover .je-table-col-handle,.je-table-wrap:hover .je-table-row-handle,.je-table-wrap:hover .je-table-add-control,.je-table-wrap.ProseMirror-selectednode .je-table-move-handle,.je-table-wrap.ProseMirror-selectednode .je-table-resize-handle,.je-table-wrap.ProseMirror-selectednode .je-table-col-handle,.je-table-wrap.ProseMirror-selectednode .je-table-row-handle,.je-table-wrap.ProseMirror-selectednode .je-table-add-control{opacity:1;pointer-events:auto}.je-table-move-handle{color:#6b7280;cursor:grab;background:#fff;border:1px solid #dbe3ec;border-radius:6px;justify-content:center;align-items:center;width:20px;height:20px;display:inline-flex}.je-table-move-handle svg{width:12px;height:12px}.je-table-resize-handle{cursor:nwse-resize;background:#cbd5e1;border-radius:4px;width:14px;height:14px}.je-table-col-handle{cursor:col-resize;background:0 0;border-radius:999px;width:4px;margin-left:-2px;position:absolute}.je-table-col-handle:hover{background:#1c81d9}.je-table-row-handle{cursor:row-resize;background:0 0;border-radius:999px;height:4px;margin-top:-2px}.je-table-row-handle:hover{background:#1c81d9}.je-table-add-control{color:#fff;cursor:pointer;background:#1c81d9;border:none;border-radius:999px;justify-content:center;align-items:center;width:16px;height:16px;padding:0;font-size:12px;font-weight:700;line-height:1;display:inline-flex;box-shadow:0 2px 8px #1c81d93d}.je-table-add-control:hover{background:#166fbf}.je-code-block-wrap{background:#fff;border:1px solid #d0d7de;border-radius:12px;width:100%;margin:1em 0;position:relative;overflow:hidden}.je-code-block-header{background:#f6f8fa;align-items:center;gap:8px;min-height:34px;padding:0 12px;display:flex}.je-code-block-select{color:#6b7280;appearance:none;background:0 0;border:none;border-radius:0;outline:none;height:24px;padding:0 18px 0 0;font-size:12px}.je-code-block-select option{color:#111827}.je-code-block-header:after{content:"";pointer-events:none;border-bottom:1.5px solid #9ca3af;border-right:1.5px solid #9ca3af;width:10px;height:10px;margin-left:-12px;transform:rotate(45deg)scale(.6)}.je-code-block-spacer{flex:1}.je-code-block-copy{color:#6b7280;opacity:0;pointer-events:none;cursor:pointer;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;width:20px;height:20px;padding:0;transition:opacity .12s,background-color .12s,color .12s;display:inline-flex}.je-code-block-copy:hover{color:#374151;background:#eaeef2}.je-code-block-copy.is-copied{color:#1d4ed8}.je-code-block-copy svg{width:14px;height:14px}.je-code-block-wrap:hover .je-code-block-copy,.je-code-block-wrap:focus-within .je-code-block-copy{opacity:1;pointer-events:auto}.je-code-block-wrap pre{background:0 0;margin:0;padding:12px 16px 16px;overflow-x:auto}.je-code-block-wrap pre code{color:#24292e;box-shadow:none;background:0 0;border:none;padding:0;font-size:13px;font-weight:400;display:block}.je-code-block-wrap pre code.je-code-block{box-shadow:none;background:0 0;border:none}.je-code-block-wrap .hljs-comment,.je-code-block-wrap .hljs-quote{color:#6a737d;font-style:italic}.je-code-block-wrap .hljs-keyword,.je-code-block-wrap .hljs-doctag,.je-code-block-wrap .hljs-selector-tag,.je-code-block-wrap .hljs-literal,.je-code-block-wrap .hljs-type{color:#d73a49}.je-code-block-wrap .hljs-string,.je-code-block-wrap .hljs-attr,.je-code-block-wrap .hljs-template-tag{color:#032f62}.je-code-block-wrap .hljs-number,.je-code-block-wrap .hljs-built_in,.je-code-block-wrap .hljs-title.class_,.je-code-block-wrap .hljs-symbol{color:#005cc5}.je-code-block-wrap .hljs-function,.je-code-block-wrap .hljs-title.function_{color:#6f42c1}.je-link-popover{z-index:1100;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);background:#fffffffa;border:1px solid #e5e7eb;border-radius:10px;grid-template-columns:1fr auto;align-items:center;width:268px;min-height:36px;padding:0 8px;display:grid;position:absolute;box-shadow:0 10px 28px #0f172a1f}.je-link-popover__main{color:#2563eb;white-space:nowrap;text-overflow:ellipsis;align-items:center;font-size:13px;text-decoration:none;display:inline-flex;overflow:hidden}.je-link-popover__actions{align-items:center;gap:4px;margin-left:8px;display:inline-flex}.je-link-popover__action{color:#6b7280;cursor:pointer;background:#fff;border:1px solid #e5e7eb;border-radius:8px;width:28px;height:28px}.je-link-popover__action:hover{color:#374151;background:#f8fafc}.raw-html-island{background:linear-gradient(#f8fafc 0%,#fff 100%);border:1px solid #e5e7eb;border-radius:14px;margin:12px 0;overflow:hidden}.raw-html-island__header{color:#475569;letter-spacing:.02em;text-transform:uppercase;border-bottom:1px solid #eef2f7;justify-content:space-between;align-items:center;gap:12px;padding:10px 14px;font-size:12px;font-weight:700;display:flex}.raw-html-island__actions{align-items:center;gap:6px;display:inline-flex}.raw-html-island__action{color:#64748b;cursor:pointer;background:#fff;border:1px solid #e6ebf1;border-radius:8px;height:28px;padding:0 10px;font-size:12px;transition:background-color .12s,border-color .12s,color .12s}.raw-html-island__action:hover{color:#475569;background:#f8fafc;border-color:#d6dee8}.raw-html-island__action.is-danger{color:#b91c1c}.raw-html-island__body{color:#0f172a;white-space:pre-wrap;word-break:break-word;margin:0;padding:14px;font:12px/1.7 JetBrains Mono,SFMono-Regular,Consolas,monospace}.raw-html-island.is-editing .raw-html-island__body{display:none}.raw-html-island__editor{background:#fff;border-top:1px solid #eef2f7;padding:14px}.raw-html-island__editor.is-hidden{display:none}.raw-html-island__textarea{color:#0f172a;resize:vertical;box-sizing:border-box;white-space:pre;background:#f8fafc;border:1px solid #e5e7eb;border-radius:12px;outline:none;width:100%;min-height:220px;padding:12px 14px;font:12px/1.7 JetBrains Mono,SFMono-Regular,Consolas,monospace}.raw-html-island__textarea:focus{background:#fff;border-color:#bfdbfe;box-shadow:0 0 0 4px #bfdbfe47}.raw-html-island__editor-actions{justify-content:flex-end;gap:8px;margin-top:10px;display:flex}.raw-html-island__action.is-primary{color:#4b5563;background:#eef3f8;border-color:#dbe5f0}.raw-html-island__action.is-primary:hover{background:#e4ebf3;border-color:#ced8e4}@media (width<=980px){.je-source-pane.is-active{grid-template-columns:1fr;min-height:auto}.je-source-textarea,.je-source-preview{min-height:360px}}pre code.hljs{padding:1em;display:block;overflow-x:auto}code.hljs{padding:3px 5px}.hljs{color:#24292e;background:#fff}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#d73a49}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#6f42c1}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-variable,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id{color:#005cc5}.hljs-regexp,.hljs-string,.hljs-meta .hljs-string{color:#032f62}.hljs-built_in,.hljs-symbol{color:#e36209}.hljs-comment,.hljs-code,.hljs-formula{color:#6a737d}.hljs-name,.hljs-quote,.hljs-selector-tag,.hljs-selector-pseudo{color:#22863a}.hljs-subst{color:#24292e}.hljs-section{color:#005cc5;font-weight:700}.hljs-bullet{color:#735c0f}.hljs-emphasis{color:#24292e;font-style:italic}.hljs-strong{color:#24292e;font-weight:700}.hljs-addition{color:#22863a;background-color:#f0fff4}.hljs-deletion{color:#b31d28;background-color:#ffeef0}
|
|
2
2
|
/*$vite$:1*/
|