@kungal/editor-nuxt 0.38.0 → 0.38.2
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/CHANGELOG.md +75 -0
- package/README.md +6 -0
- package/editor.css +24 -2
- package/package.json +4 -3
- package/runtime/KunEditorToolbar.vue +10 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,80 @@
|
|
|
1
1
|
# @kungal/editor-nuxt
|
|
2
2
|
|
|
3
|
+
## 0.38.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 4dbe38b: 删 @提及 / #楼层 引用块时光标不再跳行,手机键盘不再收起又弹出
|
|
8
|
+
|
|
9
|
+
下游报的问题:回复里 `@anjila #3 ` 这样的引用标记,按退格时光标先掉到下一行、再回来,
|
|
10
|
+
删两个块要抖两次;手机端每抖一次,键盘就收起再弹出一次。原因此前一直没查明。
|
|
11
|
+
|
|
12
|
+
根因有两层,都在「段落以一个不可编辑的行内原子节点结尾」这一刻:
|
|
13
|
+
|
|
14
|
+
1. **视觉跳行(桌面 + 手机都有)。** 尾随空格删掉后,段落最后一个节点是
|
|
15
|
+
`contenteditable="false"` 的芯片。ProseMirror 为了让 Chrome / Safari 能在芯片后面画光标,
|
|
16
|
+
会补一个 `<img class="ProseMirror-separator">` 和一个尾随 `<br>`。这个 img 本该是 0×0 的
|
|
17
|
+
行内空元素,但宿主的通用 `img` 规则(Tailwind preflight 让所有 img `display:block`,
|
|
18
|
+
论坛的 `.milkdown img` 又加了 `my-8` 外边距和边框)把它变成了块级盒子 —— `<br>` 连同光标
|
|
19
|
+
被挤到下一行,段落高度翻倍(实测 24px → 48px),下一次退格删掉芯片后又缩回去,这就是抖动。
|
|
20
|
+
ProseMirror 自己的样式表里有一条 "Protect against generic img rules" 的守卫,Milkdown
|
|
21
|
+
不带那份样式表,`editor.css` 也一直没补 —— 现在补上了,`!important`,压过宿主的 prose 层。
|
|
22
|
+
2. **键盘闪烁(Android)。** 光标紧挨芯片时,基础 keymap 的退格命令全都不适用,ProseMirror 交给
|
|
23
|
+
浏览器原生删;桌面上真实的 keydown 会触发 prosemirror-view 自己的兜底(`captureKeyDown`)
|
|
24
|
+
用事务删掉节点,但虚拟键盘发的是 keyCode 229,兜底不会跑,浏览器原生删不可编辑元素
|
|
25
|
+
「有时会失败」(prosemirror-view 原话),它对这种情况的回退是 **`view.dom.blur(); view.focus()`**
|
|
26
|
+
再粗暴删一格 —— 那一对 blur/focus 就是键盘收起又弹出。
|
|
27
|
+
|
|
28
|
+
修法:
|
|
29
|
+
|
|
30
|
+
- `@kungal/editor-nuxt/editor.css` 新增结构性规则 `.kun-editor__wysiwyg img.ProseMirror-separator`
|
|
31
|
+
(display:inline、0×0、无外边距无边框)。写自己样式表的宿主请把它一并带上 —— 文档「样式」页
|
|
32
|
+
的结构性规则清单已加入。
|
|
33
|
+
- `@kungal/editor-core` 新增 `createInlineAtomPlugin()`(预设默认启用,纯逻辑):在 `beforeinput`
|
|
34
|
+
的 `deleteContentBackward` / `deleteContentForward` 上,只要光标紧挨(或选中的就是)一个行内原子
|
|
35
|
+
节点,就 `preventDefault` 并用**一个事务**删掉它 —— 硬件键盘、IME、虚拟键盘、右键菜单删除走的
|
|
36
|
+
都是这一个事件,浏览器再也碰不到那个 `contenteditable=false` 元素,prosemirror-view 的
|
|
37
|
+
blur/focus 回退没有机会触发。任何 `atom: true` 的行内节点(提及、引用、行内公式、以后的自定义
|
|
38
|
+
芯片)自动享有;块级原子节点仍交给基础 keymap 的 `selectNodeBackward`。输入规则刚触发时的退格
|
|
39
|
+
照旧先撤销规则(与基础 keymap 的顺序一致);IME 组合中不介入。
|
|
40
|
+
|
|
41
|
+
行为:`@anjila #3 ` 仍是 4 次退格(空格、芯片、空格、芯片 —— 空格是真实字符,与 Slack / Notion /
|
|
42
|
+
Google Docs 一致),但每一次都精确删一个单位,光标全程留在同一行。无破坏性变更。
|
|
43
|
+
|
|
44
|
+
- Updated dependencies [4dbe38b]
|
|
45
|
+
- @kungal/editor-core@0.38.2
|
|
46
|
+
- @kungal/editor-vue@0.38.2
|
|
47
|
+
|
|
48
|
+
## 0.38.1
|
|
49
|
+
|
|
50
|
+
### Patch Changes
|
|
51
|
+
|
|
52
|
+
- f078b5b: KunUI 工具栏的链接面板不再抢着聚焦,页面不会被弹到顶部
|
|
53
|
+
|
|
54
|
+
下游报的两个 bug:① 滚到页面中部点「链接」,整页跳回顶部;② 编辑器放进 `KunModal` /
|
|
55
|
+
`KunDrawer` 时,链接面板里的输入框一个字都打不进去。
|
|
56
|
+
|
|
57
|
+
两个都属实,但根因都在 KunUI 侧,且 `@kungal/ui-vue` **2.26.0 已经全部修好**(库里每一处
|
|
58
|
+
主动 `focus()` 都带 `preventScroll`;浮层面板会登记进开它的那个弹窗的焦点陷阱)。
|
|
59
|
+
|
|
60
|
+
这里只做一件事:**把工具栏链接面板上那个多余的 `:autofocus="true"` 删掉。**
|
|
61
|
+
`KunPopover` 打开时本来就会带着 `preventScroll` 聚焦面板里第一个可聚焦元素 ——
|
|
62
|
+
输入框自己的挂载聚焦比它早一拍,发生在 floating-ui 量出位置**之前**,此时 teleport 到
|
|
63
|
+
`<body>` 的面板还停在文档原点(实测 `getBoundingClientRect().top === -1440`),
|
|
64
|
+
浏览器「滚动到该元素」就把整页拉回了顶部。这个 prop 从来没做过 popover 没做对的事,
|
|
65
|
+
删掉之后即使宿主的 KunUI 还没升到 2.26.0,也不会再跳顶。
|
|
66
|
+
|
|
67
|
+
第二个问题(弹窗里的焦点陷阱)编辑器这一侧无解 —— 面板是 KunUI teleport 的,陷阱也是
|
|
68
|
+
KunUI 建的。**编辑器放进 `KunModal` / `KunDrawer`,请把 `@kungal/ui-vue` 升到 2.26.0 及以上**,
|
|
69
|
+
这一点已写进 `@kungal/editor-nuxt` 的 README 与文档的「Nuxt 接入」页(那页还加了一个
|
|
70
|
+
「弹窗里的编辑器」实测 demo)。
|
|
71
|
+
|
|
72
|
+
无破坏性变更:面板照样自动聚焦,行为不变。
|
|
73
|
+
|
|
74
|
+
- Updated dependencies [f078b5b]
|
|
75
|
+
- @kungal/editor-core@0.38.1
|
|
76
|
+
- @kungal/editor-vue@0.38.1
|
|
77
|
+
|
|
3
78
|
## 0.38.0
|
|
4
79
|
|
|
5
80
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -30,6 +30,12 @@ Then, anywhere in a template:
|
|
|
30
30
|
`@kungal/ui-tokens` + `@kungal/ui-vue` setup. This layer intentionally owns no
|
|
31
31
|
Tailwind entry — the `@source` scan path is node_modules-layout-specific, so
|
|
32
32
|
only the app can write it correctly.
|
|
33
|
+
- **Rendering the editor inside a `KunModal` / `KunDrawer` needs
|
|
34
|
+
`@kungal/ui-vue` >= 2.26.0.** The toolbar's link and sticker panels are
|
|
35
|
+
`KunPopover`s, which teleport to `<body>`; before 2.26.0 an overlay's focus
|
|
36
|
+
trap did not know about them and pulled focus straight back to the trigger, so
|
|
37
|
+
those panels could not be typed into. 2.26.0 registers a popover with the
|
|
38
|
+
overlay that opened it. Nothing to configure on the editor side.
|
|
33
39
|
|
|
34
40
|
## Status
|
|
35
41
|
|
package/editor.css
CHANGED
|
@@ -11,8 +11,9 @@
|
|
|
11
11
|
* Import it (fixes then arrive with a version bump) or copy it into your app and
|
|
12
12
|
* edit freely — it's plain CSS with no build step.
|
|
13
13
|
*
|
|
14
|
-
* It also carries the
|
|
15
|
-
*
|
|
14
|
+
* It also carries the structural rules the editor genuinely needs to function:
|
|
15
|
+
* ProseMirror's `white-space`, the guard on ProseMirror's caret hack nodes, and
|
|
16
|
+
* the popover positioning / show-hide.
|
|
16
17
|
*/
|
|
17
18
|
|
|
18
19
|
/* The surface every floating panel sits on (selection bubble, @mention dropdown,
|
|
@@ -105,6 +106,27 @@
|
|
|
105
106
|
word-wrap: break-word;
|
|
106
107
|
}
|
|
107
108
|
|
|
109
|
+
/* ProseMirror's caret hack node. When a textblock ENDS in a `contenteditable=false`
|
|
110
|
+
* node — an @mention or #floor chip, inline math, any inline atom — prosemirror-view
|
|
111
|
+
* appends `<img class="ProseMirror-separator">` + `<br class="ProseMirror-trailingBreak">`
|
|
112
|
+
* so Chrome / Safari can draw a caret after it. The img is meant to be a 0×0
|
|
113
|
+
* inline nothing, but a host's generic `img` rule (Tailwind's preflight makes
|
|
114
|
+
* every img display:block; the forum adds my-8 margins and a border) turns it
|
|
115
|
+
* into a block box: the trailing <br>, and the caret with it, drop onto a new
|
|
116
|
+
* line, the paragraph doubles in height, and every Backspace past a chip looks
|
|
117
|
+
* like a jump. prosemirror-view's own stylesheet ships this guard ("Protect
|
|
118
|
+
* against generic img rules"); Milkdown doesn't include that sheet, so it lives
|
|
119
|
+
* here. `!important` on purpose — it has to beat whatever the host's prose
|
|
120
|
+
* layer says about images. */
|
|
121
|
+
.kun-editor__wysiwyg img.ProseMirror-separator {
|
|
122
|
+
display: inline !important;
|
|
123
|
+
width: 0 !important;
|
|
124
|
+
height: 0 !important;
|
|
125
|
+
margin: 0 !important;
|
|
126
|
+
padding: 0 !important;
|
|
127
|
+
border: none !important;
|
|
128
|
+
}
|
|
129
|
+
|
|
108
130
|
/* The spoiler chip while you EDIT it (`||hidden||`). @kungal/editor-core paints
|
|
109
131
|
* a `currentColor`-derived tint on its own — it must look hidden in a host with
|
|
110
132
|
* no design tokens at all — and reads `--kun-spoiler-bg` first, which is this
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kungal/editor-nuxt",
|
|
3
|
-
"version": "0.38.
|
|
3
|
+
"version": "0.38.2",
|
|
4
4
|
"description": "KunEditor Nuxt Layer — wraps @kungal/editor-vue and auto-imports <KunEditor> so an existing Nuxt app keeps its exact DX (no import needed).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
"nuxt.config.ts"
|
|
33
33
|
],
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@kungal/editor-
|
|
36
|
-
"@kungal/editor-
|
|
35
|
+
"@kungal/editor-core": "0.38.2",
|
|
36
|
+
"@kungal/editor-vue": "0.38.2"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"@kungal/ui-vue": "^2.7.0",
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
"vue": "^3.5.0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
+
"@kungal/ui-vue": "^2.26.0",
|
|
45
46
|
"@nuxt/kit": "^4.4.7"
|
|
46
47
|
},
|
|
47
48
|
"scripts": {
|
|
@@ -321,7 +321,16 @@ const insertSticker = (src: string, name: string) =>
|
|
|
321
321
|
</template>
|
|
322
322
|
<!-- `type="text"` + `inputmode="url"`, never `type="url"`: this IS a
|
|
323
323
|
form, so native URL validation would block submit on a schemeless
|
|
324
|
-
`www.a.com/x` — the very input insertLinkCommand normalizes.
|
|
324
|
+
`www.a.com/x` — the very input insertLinkCommand normalizes.
|
|
325
|
+
|
|
326
|
+
NO `autofocus`: KunPopover already focuses the first focusable
|
|
327
|
+
element in its panel when it opens, and does it with
|
|
328
|
+
`preventScroll`. The input's own mount-time focus ran a tick
|
|
329
|
+
EARLIER — while the panel, teleported to <body>, was still sitting
|
|
330
|
+
at the document origin because floating-ui had not measured yet —
|
|
331
|
+
so "scroll the focused element into view" yanked the whole page to
|
|
332
|
+
the top. KunUI ≥ 2.26.0 passes preventScroll there too, but this
|
|
333
|
+
prop was doing nothing the popover wasn't already doing right. -->
|
|
325
334
|
<form class="flex items-center gap-1" @submit.prevent="applyLink">
|
|
326
335
|
<KunInput
|
|
327
336
|
v-model="linkUrl"
|
|
@@ -329,7 +338,6 @@ const insertSticker = (src: string, name: string) =>
|
|
|
329
338
|
inputmode="url"
|
|
330
339
|
size="sm"
|
|
331
340
|
:placeholder="t.linkPlaceholder"
|
|
332
|
-
:autofocus="true"
|
|
333
341
|
class="flex-1"
|
|
334
342
|
/>
|
|
335
343
|
<KunButton type="submit" variant="flat" color="primary" size="sm">
|