@kungal/editor-core 0.36.0 → 0.38.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,52 @@
1
1
  # @kungal/editor-core
2
2
 
3
+ ## 0.38.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 0f3ceab: 隐藏文本:编辑时看得出被隐藏,光标锚点不再进入存库的 markdown
8
+
9
+ - **剧透块的底色不再依赖宿主 token。** 原来是 `background: var(--color-default-500)`,
10
+ 没有 fallback —— 宿主没定义这个调色板变量时整条声明作废,实测算出来是
11
+ `rgba(0, 0, 0, 0)`:编辑时剧透块和正文长得一模一样。而「零 CSS 的 headless 编辑器」
12
+ 正是这样的宿主。现在自带一份不依赖任何设计 token 的默认底色(由 `currentColor`
13
+ 混出,明暗主题都成立),并留出 `--kun-spoiler-bg` 这个换肤钩子 —— 内联样式压得过
14
+ 任何选择器,但压不过自定义属性,所以这是宿主唯一能用纯 CSS 改它的入口。
15
+ `@kungal/editor-nuxt/editor.css` 把它映射成 `--color-default-200`,KunUI 宿主观感不变。
16
+ - **光标锚点(`U+200B`)只留在编辑器文档里,不再写进 markdown。** 锚点是编辑器的
17
+ 内部装置(光标必须落在某个 text 节点上),但它一直跟着正文一起被序列化出去,存库的
18
+ 文本会变成 `鲲 ||Galgame||<U+200B> 论坛` —— 数据库、diff、以及每一个不认识本编辑器的
19
+ 下游都得吃下这个看不见的字符。现在在 **serializer** 这一层统一剥掉:`getMarkdown()`、
20
+ `v-model`、源码视图、宿主自己的 action 都读同一个 slice,所以一处收口全部干净;
21
+ 从旧内容或粘贴带进来的锚点也一并清掉 —— **旧帖打开再保存一次就自愈**。
22
+ 解析时反过来给每个 `||…||` 补回锚点,所以「点在段尾的剧透块后面接着打字,字落在
23
+ 块外面」这件事和以前一样成立。
24
+
25
+ 对下游没有破坏性改动:markdown 少了一个不可见字符,DOM 结构与命令行为不变。
26
+
27
+ ## 0.37.0
28
+
29
+ ### Minor Changes
30
+
31
+ - a473708: 隐藏文本:选区里的换行不再写出读不回来的 markdown,选区气泡里也有了这颗按钮
32
+
33
+ - **`insertKunSpoilerCommand` 把选区里的换行折成空格。** `||…||` 在每一个读它的地方
34
+ 都只在同一行内配对(这里的 remark 转换、共用同一语法的服务端渲染器),而 commonmark 的
35
+ hardbreak 声明了 `leafText: () => '\n'` —— 所以选中跨行的文字点「隐藏文本」,按钮会写出
36
+ `||第一行\n第二行||`:一段它自己都读不回来、渲染出来是两条光秃秃竖线的 markdown。现在
37
+ `textBetween` 的**两个**分隔符都给 `' '`(块级的本来就是),跨行选区并成一个单行 spoiler。
38
+ - **选区里一个字都没有时返回 `false`**,而不是把选中的东西替换掉 —— 单独选中一张图片点
39
+ 「隐藏文本」不再删图。(选中的是节点、或在代码块里,原本就已经返回 `false`。)
40
+ - **选区气泡工具栏加入 `spoiler`**:`KunSelectionItem` 多一个成员,默认那一排变成
41
+ `bold / italic / strike / code / spoiler / link`。按下态走已有的 `activeMarks.spoiler`,
42
+ 光标在 spoiler 里时按钮点亮、点一下揭示,和固定工具栏完全一致。
43
+ - 顺手把气泡默认按钮表收成**一份** `DEFAULT_SELECTION_ITEMS`(`context.ts`)。原本
44
+ `<KunEditor>` 和气泡各存一份,只改气泡那份等于没改 —— 真实编辑器读的是 context 那份。
45
+
46
+ **跨行剧透不在此列**:`||…||` 是行内语法(schema `inline: true`,mdast 里开闭两个 `||`
47
+ 根本落在不同的 text 节点上),要藏整段多行内容需要的是一个块级容器语法,得全生态(渲染器
48
+ 先行)另行约定,不是把 `||…||` 拉长。
49
+
3
50
  ## 0.36.0
4
51
 
5
52
  ### Minor Changes
@@ -7,13 +7,13 @@ var listener = require('@milkdown/kit/plugin/listener');
7
7
  var clipboard = require('@milkdown/kit/plugin/clipboard');
8
8
  var indent = require('@milkdown/kit/plugin/indent');
9
9
  var trailing = require('@milkdown/kit/plugin/trailing');
10
+ var core = require('@milkdown/kit/core');
10
11
  var model = require('@milkdown/kit/prose/model');
11
12
  var exception = require('@milkdown/kit/exception');
12
13
  var inputrules = require('@milkdown/kit/prose/inputrules');
13
14
  var state = require('@milkdown/kit/prose/state');
14
15
  var utils = require('@milkdown/kit/utils');
15
16
  var unistUtilVisit = require('unist-util-visit');
16
- var core = require('@milkdown/kit/core');
17
17
  var commands = require('@milkdown/kit/prose/commands');
18
18
  var prose = require('@milkdown/kit/prose');
19
19
  var katex = require('katex');
@@ -37,10 +37,17 @@ var remarkMath__default = /*#__PURE__*/_interopDefault(remarkMath);
37
37
  var spoilerAttr = utils.$nodeAttr("kun-spoiler", () => ({
38
38
  container: {
39
39
  class: "kun-spoiler",
40
- style: "background: var(--color-default-500); border-radius: var(--radius-sm); padding: 0 4px; cursor: pointer;"
40
+ style: "background: rgba(127, 127, 127, 0.3); background: var(--kun-spoiler-bg, color-mix(in oklab, currentColor 22%, transparent)); border-radius: var(--radius-sm, 0.25rem); padding: 0 4px; cursor: pointer;"
41
41
  }
42
42
  }));
43
43
  var CARET_ANCHOR = "\u200B";
44
+ var stripCaretAnchors = (ctx) => async () => {
45
+ await ctx.wait(core.SerializerReady);
46
+ ctx.update(
47
+ core.serializerCtx,
48
+ (serialize) => (doc) => serialize(doc).replaceAll(CARET_ANCHOR, "")
49
+ );
50
+ };
44
51
  var withoutAnchors = (content) => {
45
52
  const kept = [];
46
53
  content.forEach((child) => {
@@ -151,10 +158,13 @@ var insertKunSpoilerCommand = utils.$command(
151
158
  if ($from.parent.isTextblock && !$from.parent.canReplaceWith($from.index(), $from.index(), type)) {
152
159
  return false;
153
160
  }
161
+ const text = state$1.doc.textBetween(from, to, " ", " ").replaceAll(CARET_ANCHOR, "");
162
+ if (!empty && !text.trim()) {
163
+ return false;
164
+ }
154
165
  if (!dispatch) {
155
166
  return true;
156
167
  }
157
- const text = state$1.doc.textBetween(from, to, " ").replaceAll(CARET_ANCHOR, "");
158
168
  const node = type.create(null, state$1.schema.text(text || CARET_ANCHOR));
159
169
  const tr = state$1.tr.replaceSelectionWith(node, false);
160
170
  const after = tr.selection.to;
@@ -198,16 +208,17 @@ var remarkSpoilerPlugin = utils.$remark("remarkSpoiler", () => () => {
198
208
  if (!node.value.includes("||")) {
199
209
  return;
200
210
  }
211
+ const value = node.value.replaceAll(CARET_ANCHOR, "");
201
212
  const regex = /\|\|(.*?)\|\|/g;
202
213
  const newNodes = [];
203
214
  let lastIndex = 0;
204
- for (const match of node.value.matchAll(regex)) {
215
+ for (const match of value.matchAll(regex)) {
205
216
  const [full, content] = match;
206
217
  const matchIndex = match.index ?? 0;
207
218
  if (matchIndex > lastIndex) {
208
219
  newNodes.push({
209
220
  type: "text",
210
- value: node.value.slice(lastIndex, matchIndex)
221
+ value: value.slice(lastIndex, matchIndex)
211
222
  });
212
223
  }
213
224
  if (content) {
@@ -215,11 +226,12 @@ var remarkSpoilerPlugin = utils.$remark("remarkSpoiler", () => () => {
215
226
  type: "kun-spoiler",
216
227
  children: [{ type: "text", value: content }]
217
228
  });
229
+ newNodes.push({ type: "text", value: CARET_ANCHOR });
218
230
  }
219
231
  lastIndex = matchIndex + full.length;
220
232
  }
221
- if (lastIndex < node.value.length) {
222
- newNodes.push({ type: "text", value: node.value.slice(lastIndex) });
233
+ if (lastIndex < value.length) {
234
+ newNodes.push({ type: "text", value: value.slice(lastIndex) });
223
235
  }
224
236
  if (newNodes.length > 0 && typeof index === "number") {
225
237
  parent.children?.splice(index, 1, ...newNodes);
@@ -233,7 +245,8 @@ var createSpoilerPlugin = () => [
233
245
  spoilerSchema,
234
246
  insertSpoilerInputRule,
235
247
  insertKunSpoilerCommand,
236
- remarkSpoilerPlugin
248
+ remarkSpoilerPlugin,
249
+ stripCaretAnchors
237
250
  ].flat();
238
251
  var hasMark = (state, type) => {
239
252
  if (!type) {