dsh-fonttune 0.2.4 → 0.2.6
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.en.md +98 -111
- package/CHANGELOG.md +98 -111
- package/README.en.md +10 -7
- package/README.md +10 -7
- package/cordis.patch.yml +12 -2
- package/lib/client.js +346 -86
- package/lib/index.js +43 -1
- package/lib/shared.cjs +273 -84
- package/package.json +4 -5
package/CHANGELOG.md
CHANGED
|
@@ -2,179 +2,166 @@
|
|
|
2
2
|
|
|
3
3
|
**dsh-fonttune** 的重要变更都记录在这里。英文版见 [CHANGELOG.en.md](CHANGELOG.en.md)。
|
|
4
4
|
|
|
5
|
-
## [0.2.
|
|
5
|
+
## [0.2.6] - 2026-09-24
|
|
6
|
+
|
|
7
|
+
### 修复
|
|
8
|
+
- **点进「字体增强」还要再点一次才看得到设置**:官方插件页现在把「点进这个条目」本身当作展开的手势,插件卡片里却还留着一层自己的折叠头,于是要连点两次。现在在条目页与包配置页里,卡片一进来就是展开的(那枚箭头照旧可以手动收起)。
|
|
9
|
+
- **界面拖动不再一顿一顿的(侧栏、拖宽对话列表都能感觉到)**:插件注入的样式表让浏览器每次重算样式都要把页面上近两千个元素逐个匹配一遍(约 1.5 万次),而拖动时每一帧都会重算一次,于是侧栏和拖拽明显卡顿。现在每个轴只匹配真正需要的那几个元素(约 1 400 次):实测 50 步拖动期间的重算耗时从 **1.5 秒降到 0.5 秒**,超过 25ms 的帧从 **49 个降到 0–2 个**,帧间隔回到 **17ms**(长任务 0);字体、字号、字重、行高、代码轴(含连字与特性开关)的观感与读数完全不变。
|
|
6
10
|
|
|
7
11
|
### 新增
|
|
8
|
-
-
|
|
9
|
-
- **卡片在两条线的三个座位上都能出现**,由宿主自己决定渲染哪一个:rc 的 `settings.plugin.item`(按设置命名空间认领)、alpha 的 `plugins.item`(插件页的插件条目,`id: fonttune`、标签取字典里的 `card.title`、摘要用 `card.description`、详情页才渲染整张卡——**DSH 自己的 shell / agent-loop / subagent / web-search 也是这么登记的**)、以及给已装 profile 包用的 `plugins.bundle.config`(按 npm 包名 `dsh-fonttune` 认领,落在该包的详情页)。
|
|
10
|
-
- **认领命名空间改成「先等、再按签名认」**:alpha 的 `configForms.describe()` 是异步的,以前抢在它应答前按名字猜候选,猜错就会落在别的命名空间上、每次写入都被宿主拒绝(真机表现:卡片能开、一改就报「设置没有保存成功」)。现在候选为空就返回 `null`,并挂一个「待定作用域」占位(`getSnapshot`/`subscribe`/`set`/`unset` 全套),等 describe 的视图到达后按 **schema 里同时含 `uiFollowsDialog` 与 `stackDialog`** 认出自己那一个再接管(真机日志:`served namespaces []` → `matched by served schema: fonttune`)。
|
|
11
|
-
- **宿主侧拆掉 volatile 引用**:alpha 的 `ctx.fiber.config` 里每个字段都是 cosmokit 的 volatile 引用(`{ get(), [Symbol.for("cosmokit.volatile.write")](v) }`,且被冻结),当普通对象读只会拿到空值——真机表现是**卡片第一次渲染是一整排空控件、注入的样式表 0 字节**。现在统一走 `plainConfigValue()` 深拆,`styleRow()` 拿到的是普通对象(实测样式行 973 B、`Georgia` / `520`)。
|
|
12
|
-
- **`inject` 收窄到两条线都有的服务**(`slots` / `locale`):声明一个某条线上不存在的服务(例如 rc 才有的 `settingsScope`)会把**整包 park 住**(`pending (waiting for service: …)`),Web 直接起不来。设置作用域改为运行时用 `ctx.get()` 免声明查找,找不到就按「没有宿主层」降级。
|
|
13
|
-
- **写设置的结果两种形状都认**:rc 的 `mutate` 即使失败也 resolve `undefined`,alpha 的 `set`/`unset` resolve 布尔(`false` = 宿主拒绝)。`followWrite` 现在把同步 `false`、resolve 成 `false` 的 thenable、以及 rejection 三种都报到预设行右侧那句提示里。
|
|
14
|
-
- **`test/host-line-probe.mjs`:与宿主线无关的真机探针**。只断言两条线都必须成立的事——页面无报错、插件只维护**一份**样式表且已接入文档、设置真的作用到文档(设了 `DFP_EXPECT_FAMILY` / `DFP_EXPECT_WEIGHT` 就顺带断言计算样式)、设置页里能找到并渲染出 `.dfp-card`(哪条线的座位都行)、以及从卡片上改一个值真的写进宿主。已并入 `npm run verify:browser` 的只读组。设 `DFP_PROBE=1` 时插件会往控制台打诊断行(服务了哪些命名空间、认领了哪个、座位当前状态),`DFP_DUMP=1` 时探针额外按分组打印插件页的条目。
|
|
12
|
+
- **支持 DSH 0.1.7-rc.1**:它的设置接口与 0.1.5-rc.x 不同,插件在运行时按宿主实际提供的那一套工作。字体、界面字重、代码轴与配置卡片都在这条线上实测正常(卡片在侧栏「插件」页的「字体增强」条目里,也能从 `dsh-fonttune` 包行进入)。
|
|
15
13
|
|
|
16
14
|
### 变更
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
|
|
15
|
+
- **兼容下限明确为 `0.1.5-rc.3`**(不再声明 rc.1 / rc.2),兼容表补上 `0.1.7-rc.1`。
|
|
16
|
+
- **插件自带的 loader 行 id 改成 `dsh-fonttune`**(与设置命名空间、包名一致):DSH 0.1.7 起设置按这个 id 存档,并在首次启动时按**同名**把旧的 `settings.yaml` 搬过去——id 不一致,已保存的字体与字重就只能留在备份文件里,插件看起来「完全没生效」。改成同名之后,从 0.1.5-rc.x 升到 0.1.7 不需要重新选一遍。(同一个 id 也让插件可以写进 profile 的 `dsh.profile.bundles` 安装:插件管理页会把它显示为运行中,配置页照旧可达。)
|
|
17
|
+
|
|
18
|
+
## [0.2.5] - 2026-09-23
|
|
19
|
+
|
|
20
|
+
### 修复
|
|
21
|
+
- **以「链接到源码目录」的方式安装时,0.1.5-rc.x 上的配置卡片与字体一起消失**:插件会用自己目录里的 schema 库副本,而不是 DSH 自带的那一份;副本的较新版本给配置加了 rc 线宿主处理不了的标记,设置命名空间因此根本没有注册出去——设置页看不到卡片、注入的样式是空的、字体毫无变化。现在插件始终使用 DSH 自带的那一份,链接安装与正常安装在行为上完全一致。
|
|
22
|
+
|
|
23
|
+
## [0.2.4] - 2026-09-23
|
|
24
|
+
|
|
25
|
+
### 新增
|
|
26
|
+
- **同一个安装包同时支持两条宿主线**:DSH **0.1.5-rc.1 – rc.3** 与 **0.1.7-alpha.1 – alpha.2** 上都能直接安装使用,不需要挑版本。插件在运行时按宿主实际提供的那一套设置接口工作(rc 线一套、alpha 线一套),两条都不在时只注入字体、不显示卡片。
|
|
27
|
+
- **alpha 上的配置入口**:在 0.1.7-alpha.x 上,卡片出现在侧栏「插件」页的插件条目「字体增强」里;rc.x 上仍在 设置 → 插件 → 插件配置。
|
|
20
28
|
|
|
21
|
-
###
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
|
|
25
|
-
|
|
29
|
+
### 修复
|
|
30
|
+
- **alpha 上卡片第一次打开是一排空控件**:此前读到的是宿主的内部引用而不是配置值,注入的样式因此为空;现在首帧就是正确的字体与读数。
|
|
31
|
+
- **alpha 上改设置提示「设置没有保存成功」**:插件有几率把改动写到不属于自己的位置;现在只在确认是自己的配置之后才写入。
|
|
32
|
+
|
|
33
|
+
### 变更
|
|
34
|
+
- 兼容声明与中英 README 的兼容表更新到 0.2.4,逐条列出五条实测过的宿主线(0.1.5-rc.1 / rc.2 / rc.3、0.1.7-alpha.1 / alpha.2),并写清两条线各自的设置入口。
|
|
26
35
|
|
|
27
36
|
## [0.2.3] - 2026-09-22
|
|
28
37
|
|
|
29
38
|
### 修复
|
|
30
|
-
-
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
- **逐主题的「对话框内代码字体」规则漏了主题前缀**(休眠缺陷,逐主题当前关闭):`pushScopedCodeFamily` 生成的作用域规则没带 `body[data-ds-dark-theme]`,一旦开启逐主题,深色那一套会用**浅色**的代码字体覆盖深色对话框。现在与其他规则一样带前缀,并加了「每一条逐主题规则都必须以主题属性开头」的用例。
|
|
35
|
-
- **`test/split-verify.mjs` 测的是早已退役的轴**:脚本还在写 `sizeOffset`(0.2.0 起退役的界面字号轴)并期望对话链路跟着动,真机自然红。现在它写 `sizeOffsetDialog` + `sizeOffsetCode`,比值按**实测基准**算(对话轴加在 DSH 自己的字号上、代码轴按 16px 基准缩放,两者不同),并新增一条「退役的界面字号轴什么都不动」的真机断言。
|
|
39
|
+
- **改设置失败不再显得像成功了**:保存被宿主拒绝时,预设行右侧会出现一句「设置没有保存成功:原因」,不再只是把控件弹回旧值让人以为存上了。
|
|
40
|
+
- **没有剪贴板的环境里导出也能拿到完整内容**:优先用剪贴板;远程 HTTP 入口取不到剪贴板时退回旧的复制通道;两条都不行才把完整 JSON 放进一个已全选的只读框,按一次复制快捷键即可。
|
|
41
|
+
- **选字体面板**:内置的等宽 / 中文 / 拉丁 / 通用四组不再因为本机字体枚举成功而消失(本机没装的预设字体也能按名字搜到);同一个字体只列一次;拒绝了字体权限的浏览器不再被永久记住,二十秒后再打开会重试。
|
|
42
|
+
- 每一条按主题生成的规则都带上了主题前缀(逐主题目前还没开放,属提前修掉的隐患)。
|
|
36
43
|
|
|
37
44
|
### 变更
|
|
38
|
-
-
|
|
39
|
-
- **退役的字号/行高轴退出「值表面」**:`sizeOffset` 与 `lineHeight`(界面的字号与行高,0.2.0 起不产生任何规则)仍然留在 schema 与文档字段里(老配置照常解析、`normalizeConfig` 照常带出来),但不再进预设快照、不再参与明暗对比——只在这两个字段上有差别的明暗配置不再生成第二份样式表;卡片上的「全部重置」**仍然会清掉它们**,免得一个永远不显示的值烂在文档里。
|
|
40
|
-
- **清理死代码**:删掉 31 个不再渲染的词典键(中英各 31 个,含退役的界面字号/行高、逐主题编辑器、旧预设按钮组与固定预览的文案)、1 条死 CSS(`.dfp-presetForm`)与 7 个死导出(`MARKER`、`isShorthandToken`、`bodyTokenNames`、`uiLineTokenNames`、`deltaTokenNames`、`codeTokenNames`、`uiShorthandTokens`、`scaleFontShorthand`)。`VALUE_FIELDS` / `RETIRED_FIELDS` / `DURABLE_FIELDS` 三个清单把「值轴」「仍存储但不渲染」「全部持久字段」分开写清楚了。
|
|
41
|
-
- **`npm run verify:browser` 统一入口**(`test/browser-verify.mjs`):默认跑只读的 `browser-probe` / `ui-walk` / `style-verify`,`--writers` 再加会写设置命名空间的四支(各自快照并在退出前还原),`--only a,b` 挑子集,逐支打印耗时与退出码并汇总。两支走查脚本按 0.2.x 的卡片重写:`slider-walk` 先展开分区再拖(卡片默认全部收起),断言「拖动不写、松手才写、每条轴落到自己的字段」;`split-walk` 先写入三档字体栈,断言简单模式两格与剩余提示、模式往返不改动栈、真实面板里选一个西文字体只替换西文槽。**找不到控件现在是失败**(以前打印一句「not found」然后退出 0,等于假绿)。
|
|
45
|
+
- **注入的样式更小、后台更省电**:排除列表的写法收敛后,一份真实配置的样式表从 2735 字节降到 2440 字节;界面字号轴的令牌轮询改为先比三个廉价信号,环境没变就完全不读样式表。
|
|
42
46
|
- 兼容表补 0.2.3。
|
|
43
47
|
|
|
44
|
-
### 测试
|
|
45
|
-
- `test/run.mjs`(86 项):新增面板分组规则(预设四组恒在、同字体不重复、本机分组上限与消毒、拒绝后的重试契约)与轮询闸门的计数用例(含负对照:去掉闸门后该用例红)。
|
|
46
|
-
- `test/render-card.mjs`(21 项):新增「第二次渲染(状态变化后 hook 顺序不变)」「拒绝写入的两种形态都上报」「导出兜底交出完整 JSON 并被选中」「重置清掉退役轴」「退役轴不再是值轴」。
|
|
47
|
-
- 真机(受管实例 + 无头 Edge):WEIGHT OK(17 项)、SPLIT OK(9 项)、SLIDER OK(9 项)、SPLIT WALK OK(14 项)、browser-probe / ui-walk 通过。
|
|
48
48
|
|
|
49
49
|
## [0.2.2] - 2026-09-16
|
|
50
50
|
|
|
51
51
|
### 修复
|
|
52
|
-
-
|
|
53
|
-
-
|
|
54
|
-
-
|
|
55
|
-
- **发布 workflow 从来没跑过测试**:`npm pack` **不会**触发 `prepublishOnly`(只有 `npm publish` 会),所以 tag 触发的发布流程一直在打包未测试的产物。现在加了 `npm install` + `npm run verify` 两步(**放在打包之前、且不先构建**——`test/artifacts.mjs` 要校验的正是「仓库里的 `lib/` 就是当前 `src/` 的产物」,先构建会把这个问题掩盖掉),并补一条「tag 必须等于 `package.json` 版本」。
|
|
56
|
-
- **CHANGELOG 提取的前缀匹配会串版本**:release 正文用 `index(line, "## " pat)` 取章节,`0.2.1` 会命中 `0.2.10`。现在按 `## <版本> ` 精确匹配,并在找不到该版本章节时**直接让 job 失败**(以前会静默退回 GitHub 自动生成的 notes)。
|
|
57
|
-
- **CJK 判定漏了两个常见字体名**:`MS PGothic` / `MS PMincho` 被判成非中文字体(`MS Gothic` / `MS Mincho` 正常),而这会直接影响简单模式的「中文槽」推导,故按名字启发式的方向修成 `ms ?p?(?:gothic|mincho)`。
|
|
58
|
-
- **`shiftTokens` 补上零保护**:偏移为 0 时会写出 `calc((14px) + 0px)` 这种真声明,与 `isDormant` / `sameValueSet` 的语义冲突。当前调用侧都拦着,属于给未来调用者拆雷。
|
|
59
|
-
- **`build.mjs --watch` 盯的是文件而不是目录**:源文件被编辑器改名后,进程还守着已经消失的 inode,永远不再重建。现在监听 `src/` 目录并按文件名过滤,重建成功也会打一行日志。
|
|
52
|
+
- **简单模式下「中文字体」选不了也清不掉**:点中文格子选字体、或点中文 chip 的 ×,会直接报错且改动丢失(西文格正常);现在三个字体分区的中文槽都能正常写入。
|
|
53
|
+
- **`MS PGothic` / `MS PMincho` 也被认作中文字体**:此前会被判成西文,影响简单模式中文槽的推导。
|
|
54
|
+
- **补上「控件没接线」这类漏洞的护栏**:离线检查现在会把卡片上每个控件的回调都真点一遍(滑块、分段控件、字体选择器、预设下拉、文本输入、每个按钮),漏接会立刻失败。
|
|
60
55
|
|
|
61
56
|
### 变更
|
|
62
|
-
-
|
|
63
|
-
-
|
|
57
|
+
- **发布不再可能发出未测试的包**:打标签时先跑一遍完整检查再打包,同时校验打包产物与源码一致、标签与版本号一致。
|
|
58
|
+
- 文档纠错:改完源码必须先构建(浏览器加载的是构建产物);市场条目只是**声明**兼容信息,并不存在安装前的自动预检。
|
|
59
|
+
|
|
64
60
|
|
|
65
61
|
## [0.2.1] - 2026-09-16
|
|
66
62
|
|
|
67
63
|
### 修复
|
|
68
|
-
-
|
|
69
|
-
-
|
|
70
|
-
-
|
|
71
|
-
-
|
|
72
|
-
-
|
|
73
|
-
|
|
64
|
+
- **关掉「界面跟随对话」后界面字重不回落、重置也没用**:页面里此前同时存在两份注入样式,随首页下发的那份只在下次刷新时重建,所以「删掉一条规则」这类改动永远不生效;现在页面里始终只有一份,关掉跟随或重置都会立刻生效。
|
|
65
|
+
- **从跟随切到不跟随,界面不再跳回旧值**:关闭的那一刻把界面当时正在显示的值存成它自己的值,视觉上零变化、滑块也从当前位置继续调;对话没设的那一项保持 DSH 原样。
|
|
66
|
+
- **界面字重回来了,而且真的碰不到对话**:把对话正文与代码整棵子树从界面字重规则里排除掉,实测界面文字全部生效、对话一个字都没被带动。
|
|
67
|
+
- **对话分区里「未设置时跟随界面」的说明全部改成如实描述**(跟随关系一直是单向的:界面跟随对话)。
|
|
68
|
+
- 卡片中的预览不再被界面字重波及:对话、代码、界面三块预览各自对应真实效果。
|
|
69
|
+
|
|
70
|
+
### 变更
|
|
71
|
+
- **「跟随对话」开关现在同时管字体与字重**:开启时界面沿用对话的字体与字重(界面自己的两个控件隐藏),关闭后界面用自己的两项,两边互不影响。
|
|
72
|
+
|
|
74
73
|
|
|
75
74
|
## [0.2.0] - 2026-09-16
|
|
76
75
|
|
|
77
76
|
### 新增
|
|
78
|
-
-
|
|
79
|
-
-
|
|
80
|
-
-
|
|
81
|
-
-
|
|
82
|
-
-
|
|
83
|
-
-
|
|
84
|
-
-
|
|
85
|
-
- **卡片信息架构重构**:卡片展开后自上而下是编辑模式行 + **预设条** + **对话 → 界面 → 代码**三个**手风琴分区**(对话排在最前,因为它拥有全部轴),默认全部收起,标题行显示当前值摘要、箭头固定在最右,同一时刻最多展开一个;「拒绝合成样式」只有一两个开关,**不再单独占一个手风琴分区**,直接放在三个分区下面。分区展开后各自在分区末尾出现一个**独立预览框**(只渲染该分区的部分;曾试过悬浮式,真机体验不佳后改回内联)。**行格式与 dsh-quick-toc 对齐**:每项设置是 14px 上下内边距的字段行(原为 16px),开启/关闭一律用「大框切两半」的联合分段控件(28px 高,原为 22px 的胶囊开关),标签在左、控件在同行的右侧(`.dfp-inline` 与 quick-toc 的 `.dqt-pinline` 同构),因此两张卡片的行高与控件对齐一致。
|
|
86
|
-
- **界面的字号 / 行高 / 字重三轴退役(实测结论)**:DSH **没有界面尺寸接口**——设置页、左右侧栏与工作区的文字尺寸是上游 CSS 里的字面量(settings-plugins 22 处、workspace 18 处、sidebar 6 处 `font-size`,**0 处**使用界面阶梯 token),而界面阶梯 token(`--dsw-font-xs-13` / `--dsw-font-s-14` 等)只被会话区的 6 个组件(tool / trajectory / attachment / chat / conversation / cordis)消费;唯一的官方字号接口是「对话字号」。此前用界面阶梯去缩放,既够不到设置页与侧栏,又会顺着 `--dsh-content-font-size` 把**对话**改了;字重更棘手——它只能表达为 `body, body *` 全页规则,无法不波及对话(收窄到 markdown 之外又会连 DSH 给标题的字重一起剥掉)。结论:**字号、行高、字重全部归对话独占**,界面只保留实测生效的字体(`body` 全页 + 主题变量)。`sizeOffset` / `lineHeight` / `weight` 字段保留在 schema 里(旧文档与预设继续解析),但**不再下发任何规则**。
|
|
87
|
-
- **分主题数值移出本版**:深浅色在本版共用同一套数值——顶栏的分主题开关与浅/深编辑切换整体移除(宿主 schema 里的深色字段保留但休眠,渲染层强制忽略),功能留到下个版本再评估。
|
|
88
|
-
|
|
89
|
-
### 修复(真机走查)
|
|
90
|
-
- **预设提示不再常驻、也不顶动布局**:「方案已复制到剪贴板。」这类提示以前会一直挂在卡片里,且作为新的一行把下面的分区顶下去。现在它和「选中方案后,所有改动自动存入该方案。」**共用一行**:提示出现在该行**右侧**,**2.6 秒后自动渐隐**(透明度过渡 0.24s,之后清空文本)。那一行**始终挂载**且只有一行高,提示文本用 `nowrap + ellipsis` 限宽——出现与消失都不会改变行高,因此下方内容一动不动。连续两次相同操作也不会失灵(消息带自增 id,自动隐藏的定时器会重置),超长文本(如剪贴板不可用时的回落内容)可在悬停时通过 `title` 看全文。
|
|
91
|
-
- **「改界面,动的却是对话」**:界面字号轴此前在缩放界面阶梯 token 的同时,也会缩放对话专用的官方内容字号链(`--dsh-content-font-size` / 次级字号),而 markdown 的每一级尺寸都由这条链派生——所以调界面字号看起来就是在调对话。现在界面轴被明令隔离在这条链之外(`bodyTokenNames` 排除 `--dsh-content-font-*`),并且界面字号轴本身也因「没有接口」而退役(见上)。
|
|
92
|
-
- **对话字号偏移过去只影响标题、不影响段落**:原实现只改写 delta 与字面量字号,而段落的字号取自 `var(--dsh-content-font-size,14px)`(`var()` 在自定义属性里于**声明处**求值,深层作用域覆盖无效),所以段落纹丝不动。新实现改为在源头把 `--dsh-content-font-size` 声明为「官方值 + 偏移」,段落、标题、行高一起跟随。
|
|
93
|
-
- **暗色主题下深色覆盖会被浅色值盖掉**:按主题解析时,深色映射此前是合并在**已展开**的取值上,跟随规则一改就会出现互相覆盖。现在先在原始值上合并深色覆盖、再做展开,深色设的字体不会再被浅色值顶掉。
|
|
94
|
-
- **字重读数显示 400**:未设置的字重以前读数写「未设置」,而滑块其实停在 400、提示也写「400 表示保持 DSH 原样」——三者不一致。现在未设置的读数就是 **400**(对话字重与代码字重同此)。
|
|
95
|
-
- **行高滑块拖动时 % 消失**:拖动中的待定读数没带单位,松手才出现——现在拖动读数同样显示 `%`(字号/代码行高的 `px` 前缀原本就带)。
|
|
96
|
-
- **对话分区全是英文“变量名”**:对话轴的字段标签键(`dialog.*`、`size/line/weight.dialogLabel` 等)没有进双语词典,`translate` 回退显示键名——已补齐中英两份。
|
|
97
|
-
- **手风琴展开后首行离标题太远**:字段行自带 16px 顶部内边距叠加在分区体上——分区体的首个字段收紧到 10px。
|
|
98
|
-
- **展开态箭头不在最右**:展开后摘要消失导致箭头滑到标题旁——展开时渲染一个弹性占位符,箭头两种状态下都钉在最右。
|
|
77
|
+
- **排印分成三套**:**对话**(正文、表格、标题,字体 / 字号 / 行高 / 字重全都有)、**界面**(字体一项,默认跟随对话)、**代码**(独立一套,含连字与特性开关)。
|
|
78
|
+
- **对话字号**:在 DSH 自己的对话字号之上 −3 ~ +6 px,段落、标题与行高一起跟随。
|
|
79
|
+
- **对话行高**:100% ~ 160%;代码行高是独立的加减偏移。
|
|
80
|
+
- **代码连字**:默认 / 开启 / 关闭三档,高级模式还可填 `font-feature-settings`。
|
|
81
|
+
- **拒绝合成斜体与合成粗体**:简单模式一个开关同时禁掉,高级模式分开控制。
|
|
82
|
+
- **预设方案**:卡片里的下拉框,内置五个默认方案,点选即应用;选中之后所有改动自动存入该方案;右侧可改名、导入、导出(导入按名合并,最多 20 个,跨浏览器同步)。
|
|
83
|
+
- **卡片改版**:编辑模式 + 预设条 + 对话 / 界面 / 代码三个可折叠分区,默认全部收起、一次只展开一个,展开后末尾是该分区的独立预览;行高与控件形状与 dsh-quick-toc 对齐。
|
|
99
84
|
|
|
100
85
|
### 变更
|
|
101
|
-
-
|
|
102
|
-
-
|
|
86
|
+
- **界面的字号、行高、字重三项退役**:DSH 没有界面尺寸接口(设置页与侧栏的字号是上游写死的),此前这几轴既够不到界面、又会误动对话;现在字号 / 行高 / 字重归对话独占,界面只保留实测生效的字体。老配置里的这些字段继续保留、照常解析。
|
|
87
|
+
- 字体族改由官方主题层下发,主题切换后立刻生效。
|
|
88
|
+
- 深浅色本版共用同一套数值,按主题分别设置留到以后。
|
|
89
|
+
|
|
90
|
+
### 修复
|
|
91
|
+
- **「改界面,动的却是对话」**:界面字号轴此前会连带缩放到对话的字号链,现已隔离。
|
|
92
|
+
- **对话字号偏移只影响标题、不影响段落**:改为在源头加一次偏移,段落、标题与行高一起跟随。
|
|
93
|
+
- **暗色主题下深色的值会被浅色的值盖掉**。
|
|
94
|
+
- **字重读数写「未设置」而滑块停在 400**:现在读数就是 400。
|
|
95
|
+
- **行高滑块拖动时 `%` 会消失**:拖动过程中同样显示单位。
|
|
96
|
+
- **对话分区的标签显示成英文变量名**:中英文案补齐。
|
|
97
|
+
- 展开后首行离标题太远、展开态箭头不在最右。
|
|
98
|
+
|
|
103
99
|
|
|
104
100
|
## [0.1.6] - 2026-09-15
|
|
105
101
|
|
|
106
102
|
### 修复
|
|
107
|
-
-
|
|
103
|
+
- **配置卡片的展开箭头与宿主不一致**:原先是文本字符,比宿主卡片的箭头更细、旋转时还会偏移;现在换成与宿主同款的内联箭头图标,绕自身中心翻转。
|
|
104
|
+
|
|
108
105
|
|
|
109
106
|
## [0.1.5] - 2026-09-15
|
|
110
107
|
|
|
111
108
|
### 新增
|
|
112
|
-
-
|
|
109
|
+
- **代码字重**:字重拆成「正文字重」与「代码字重」两根互不影响的滑块(各 300 ~ 600,400 表示不动),调正文不再带动代码。
|
|
113
110
|
|
|
114
111
|
### 变更
|
|
115
|
-
-
|
|
116
|
-
-
|
|
117
|
-
|
|
112
|
+
- 卡片里字重滑块移进对应的字体分组,两处文案分开。
|
|
113
|
+
- 未设置代码字重时显式写回 DSH 原值,旧配置升级后代码不会跟着正文一起变粗。
|
|
114
|
+
|
|
118
115
|
|
|
119
116
|
## [0.1.4] - 2026-09-15
|
|
120
117
|
|
|
121
118
|
### 新增
|
|
122
|
-
-
|
|
119
|
+
- **代码字号**:字号拆成「正文字号」与「代码字号」两根互不影响的滑块(各 −3 ~ +6 px,0 表示不动),调正文不再带动代码。
|
|
123
120
|
|
|
124
121
|
### 变更
|
|
125
|
-
-
|
|
126
|
-
|
|
127
|
-
- **兼容表**改列 0.1.4 为最新版本。
|
|
122
|
+
- 卡片里字号滑块移到对应字体下面,两处滑块文案分开;旧配置升级后正文行为不变、代码回到 DSH 原值。
|
|
123
|
+
|
|
128
124
|
|
|
129
125
|
## [0.1.3] - 2026-09-14
|
|
130
126
|
|
|
131
127
|
### 变更
|
|
132
|
-
-
|
|
133
|
-
-
|
|
134
|
-
-
|
|
135
|
-
|
|
128
|
+
- 开关行左侧说明改为「编辑模式」,右侧两个选项恢复为一个外框、中间一条分隔线的连体分段样式。
|
|
129
|
+
- 卡片描述补上「中西文分栏」。
|
|
130
|
+
- README 精简:去掉「松手才生效」「首帧不闪字体」「中英双语」三条实现细节(行为未变)。
|
|
131
|
+
|
|
136
132
|
|
|
137
133
|
## [0.1.2] - 2026-09-14
|
|
138
134
|
|
|
139
135
|
### 变更
|
|
140
|
-
-
|
|
141
|
-
-
|
|
142
|
-
-
|
|
143
|
-
|
|
136
|
+
- README 重写为「功能 / 安装 / 使用 / 兼容性 / 开发」,设计取舍与开发期踩坑不再写进 README(中英两份同步)。
|
|
137
|
+
- 兼容声明收紧:只列 0.1.5 线的最新补丁——同一大版本内的旧版本按语义化版本约定向上兼容,不再逐个罗列。
|
|
138
|
+
- npm 描述精简(已发布版本的元数据无法修改,故从 0.1.2 起生效);英文卡片标题改为「Font tune」,与包名一致。
|
|
139
|
+
|
|
144
140
|
|
|
145
141
|
## [0.1.1] - 2026-09-14
|
|
146
142
|
|
|
147
143
|
### 新增
|
|
148
|
-
-
|
|
149
|
-
-
|
|
144
|
+
- 英文更新日志 `CHANGELOG.en.md`,随包发布。
|
|
145
|
+
- 打完 `v*` 标签自动打包并创建 / 更新 Release,另外产出一个不带版本号的 `dsh-fonttune.tgz`(供市场条目长期引用);Release 正文取对应版本的中文段落,英文折叠在里面。
|
|
150
146
|
|
|
151
|
-
### 变更
|
|
152
|
-
- 订正 README 与更新日志里过期的离线检查数(35 → 42 项)。运行代码与 0.1.0 相同。
|
|
153
147
|
|
|
154
148
|
## [0.1.0] - 2026-09-14
|
|
155
149
|
|
|
156
|
-
|
|
150
|
+
首个版本:宿主半 + 客户端半的双半插件。客户端半负责设置卡片与样式注入,宿主半注册设置命名空间并把已保存的声明随首页下发,因此首帧就是保存的字体。
|
|
157
151
|
|
|
158
152
|
### 新增
|
|
159
|
-
-
|
|
160
|
-
-
|
|
161
|
-
-
|
|
162
|
-
-
|
|
163
|
-
-
|
|
164
|
-
-
|
|
165
|
-
-
|
|
166
|
-
- **全局字重**(300 ~ 600,任意整数):作用于 `body, body *`;400 与未设置都表示「不动」。
|
|
167
|
-
- **滑块松手才落盘**:字号偏移 / 字重滑块拖动时只更新本地待定值与读数,`pointerup` / `touchend`(窗口捕获级监听)或失焦、键盘抬起时才一次性提交——拖动过程零写入,不再每挪一格就重算字号 token 并写设置文档。**松手后保持待定值直到宿主确认值回来**:提交与设置文档回执之间若立刻清本地值,滑块会闪回旧值再跳到新值(「回弹再到位」),现在以待提交值上屏、回执到达(或外部值变化)才清除;重复 `pointerup` 以「已待确认」守卫挡住,不会重复写同一个值。
|
|
168
|
-
- **首帧不闪字体**:宿主半监听 `webserver/index-inject` 注入同款 `<style>`,客户端插件激活前首帧就是保存的字体。
|
|
169
|
-
- **中英双语文案**,缺英文回退中文;`queryLocalFonts` 不可用或被拒时静默回退到内置列表。
|
|
170
|
-
- **字体名消毒**:按白名单过滤后整体加引号(仅保留字母/数字/空格/`.` `,` `_` `-`),宿主 schema 另加 `^[^{};<>\\]*$` 与长度上限;手工构造的 CSS 注入无法闭合声明或另起规则。
|
|
153
|
+
- **插件配置卡片**:出现在 设置 → 插件 → 插件配置,读写 DSH 自己的设置文档。
|
|
154
|
+
- **正文与代码两套字体族**:各一串回退列表,留空即完全不动 DSH 的字体。
|
|
155
|
+
- **选字体面板**:内置等宽 / 中文 / 拉丁 / 通用四组,Chromium 下可列出本机已安装字体,搜不到的名字可新建,每行用自身字体渲染。
|
|
156
|
+
- **中西分家(简单模式)**:把字体栈拆成「西文字体」「中文字体」两个格子,其余回退项与顺序原样保留;高级模式是完整的 chip 编辑器,支持拖拽排序与实时预览。
|
|
157
|
+
- **全局字号偏移**(−3 ~ +6 px,与 DSH 自己的字号滑块叠加)与**全局字重**(300 ~ 600,400 表示不动)。
|
|
158
|
+
- **滑块松手才写入**:拖动过程零写入,松手后读数保持到宿主确认,不再回弹。
|
|
159
|
+
- **中英双语文案**;字体名经过消毒,无法闭合声明或另起规则。
|
|
171
160
|
|
|
172
161
|
### 修复
|
|
173
|
-
-
|
|
174
|
-
-
|
|
175
|
-
-
|
|
176
|
-
-
|
|
177
|
-
-
|
|
178
|
-
|
|
179
|
-
- **字号 token 正则漏掉 `--dsh-content-font-size`**(该名不含 `-font-` 前缀)及其 `-secondary` 变体。
|
|
180
|
-
- **计时器改走 `globalThis`**,不再依赖 `window` 上是否存在这两个方法。
|
|
162
|
+
- **卡片首次渲染就崩溃**(发布阻断):订阅方法被裸传导致 `this` 丢失,卡片在插件配置页里根本不出现。
|
|
163
|
+
- **字号偏移的三个问题**:body 自身没被缩放、刷新时把插件自己的声明当成基准越乘越大、派生字号被重复缩放。
|
|
164
|
+
- **字体族铺不进对话区与侧栏**(那些区域自己声明了字体变量)。
|
|
165
|
+
- **字重被吸附到整百档**:现在按所选整数原样生效。
|
|
166
|
+
- **字体名消毒过于宽松**。
|
|
167
|
+
|
package/README.en.md
CHANGED
|
@@ -22,23 +22,26 @@
|
|
|
22
22
|
|
|
23
23
|
## Compatibility
|
|
24
24
|
|
|
25
|
-
**One package serves
|
|
25
|
+
**One package serves three host lines** — 0.1.5-rc.3 (the floor), 0.1.7-alpha.1 / alpha.2 and 0.1.7-rc.1 — and the install is the same on any of them: all three were verified for "the settings card opens, the stylesheet really reaches the page, and a change made in the card is written through".
|
|
26
26
|
|
|
27
27
|
| Plugin version | Supported DSH versions |
|
|
28
28
|
| --- | --- |
|
|
29
|
-
| **0.2.
|
|
29
|
+
| **0.2.6** (latest) | 0.1.5-rc.3, 0.1.7-alpha.1 / alpha.2, 0.1.7-rc.1 |
|
|
30
|
+
| 0.2.5 | 0.1.5-rc.1 / rc.2 / rc.3, 0.1.7-alpha.1 / alpha.2 |
|
|
31
|
+
| 0.2.4 | 0.1.5-rc.1 / rc.2 / rc.3, 0.1.7-alpha.1 / alpha.2 |
|
|
30
32
|
| 0.2.3 | 0.1.5-rc.2 |
|
|
31
33
|
| 0.2.2 | 0.1.5-rc.2 |
|
|
32
34
|
| 0.2.1 | 0.1.5-rc.2 |
|
|
33
35
|
| 0.2.0 | 0.1.5-rc.2 |
|
|
34
36
|
|
|
35
|
-
`engines.dsh` is declared as **`>=0.1.5-rc.
|
|
37
|
+
`engines.dsh` is declared as **`>=0.1.5-rc.3 <0.1.7-0 || >=0.1.7-alpha.1 <0.2.0-0`** (a prerelease needs its own branch: node-semver admits one only when some comparator in the range sits on that version's exact `major.minor.patch` tuple and carries a prerelease tag of its own, so a plain `>=0.1.5-rc.3` never matches `0.1.7-alpha.1`). Every difference between the lines is settled at runtime rather than by version number:
|
|
36
38
|
|
|
37
|
-
- **The settings service**: up to 0.1.5-rc.x it is `settingsScope.bind({namespace})` (by namespace);
|
|
38
|
-
- **The
|
|
39
|
+
- **The settings service**: up to 0.1.5-rc.x it is `settingsScope.bind({namespace})` (by namespace); 0.1.7-alpha.x and 0.1.7-rc.x use `configForms.get(<profile entry id>)` (by entry id, which the installing profile decides — so the plugin claims the form whose served schema names its own fields). Both expose the same `getSnapshot`/`subscribe`/`set`/`unset` face, so one implementation covers them.
|
|
40
|
+
- **The loader row id IS the settings key**: from 0.1.7-rc.1 on, settings are stored per entry id, and the first start imports the removed `settings.yaml` by matching section names against it — so the row id this package ships equals its settings namespace (`dsh-fonttune`). That same id also lets the package be installed through the profile's `dsh.profile.bundles`: the plugin manager then shows it as running while the configuration page stays reachable.
|
|
41
|
+
- **The configuration card's seat**: 0.1.5-rc.x has a keyed cell under Settings → Plugins → Plugin configuration (`settings.plugin.item`); the 0.1.7 lines dropped that slot and instead contribute an entry to the Plugins page's official list (`plugins.item`, which is how the built-in settings pages are added there), plus a per-package page for a profile that installed this plugin as a bundle (`plugins.bundle.config`). All three are registered; the one a host never declares is inert. On those pages the card **starts open** — opening the entry is the expansion gesture, and asking for a second click is exactly what this release removed.
|
|
39
42
|
- **The host half's config values**: once the alpha marks the schema `.volatile()`, the fields the host half receives are cosmokit volatile references (`{get(),[write]}`) rather than plain values, which left the first-frame stylesheet row empty; the references are unwrapped before use.
|
|
40
|
-
- **`inject` declares only services
|
|
41
|
-
- **The
|
|
43
|
+
- **`inject` declares only services all three lines have** (`slots`, `locale`): declaring one a host does not provide parks the whole package — on the alpha a declared `settingsScope` kept the entire Web UI from booting. The settings service is looked up with `ctx.get(name)` instead.
|
|
44
|
+
- **The 0.1.7 form is addressed by entry id**: while the host's `describe()` view has not arrived, the plugin does not guess a name (a wrong guess means every write is refused) — it stands in with a pending scope, adopts the real form as soon as the view is served, and re-reads immediately.
|
|
42
45
|
|
|
43
46
|
The market entry also states these requirements (`engines.dsh`, `dsh.compatibility.dshReleases` and `peerDependencies` in `package.json`), so the host a version needs can be checked before installing.
|
|
44
47
|
|
package/README.md
CHANGED
|
@@ -22,23 +22,26 @@
|
|
|
22
22
|
|
|
23
23
|
## 兼容性
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
**一份包同时支持三条宿主线**——0.1.5-rc.3(下限)、0.1.7-alpha.1 / alpha.2、0.1.7-rc.1:安装方式与宿主线无关,三条线都验证过「设置卡片可用、样式真的作用到页面、卡片上的改动写得进去」。
|
|
26
26
|
|
|
27
27
|
| 插件版本 | 支持的 DSH 版本 |
|
|
28
28
|
| --- | --- |
|
|
29
|
-
| **0.2.
|
|
29
|
+
| **0.2.6**(最新) | 0.1.5-rc.3、0.1.7-alpha.1 / alpha.2、0.1.7-rc.1 |
|
|
30
|
+
| 0.2.5 | 0.1.5-rc.1 / rc.2 / rc.3、0.1.7-alpha.1 / alpha.2 |
|
|
31
|
+
| 0.2.4 | 0.1.5-rc.1 / rc.2 / rc.3、0.1.7-alpha.1 / alpha.2 |
|
|
30
32
|
| 0.2.3 | 0.1.5-rc.2 |
|
|
31
33
|
| 0.2.2 | 0.1.5-rc.2 |
|
|
32
34
|
| 0.2.1 | 0.1.5-rc.2 |
|
|
33
35
|
| 0.2.0 | 0.1.5-rc.2 |
|
|
34
36
|
|
|
35
|
-
`engines.dsh` 声明为 **`>=0.1.5-rc.
|
|
37
|
+
`engines.dsh` 声明为 **`>=0.1.5-rc.3 <0.1.7-0 || >=0.1.7-alpha.1 <0.2.0-0`**(预发布版本必须显式留分支:node-semver 只在一个范围的某个比较符与该版本落在同一个 `major.minor.patch` 元组、且自身带预发布标签时才放行,写成 `>=0.1.5-rc.3` 匹配不到 `0.1.7-alpha.1`)。三条线的差别**全部在运行时二选一,不看版本号**:
|
|
36
38
|
|
|
37
|
-
- **设置服务**:0.1.5-rc.x 是 `settingsScope.bind({namespace})
|
|
38
|
-
-
|
|
39
|
+
- **设置服务**:0.1.5-rc.x 是 `settingsScope.bind({namespace})`(按命名空间);0.1.7-alpha.x 与 0.1.7-rc.x 换成了 `configForms.get(<profile 条目 id>)`(按条目 id,id 由安装方的 profile 决定,所以插件靠「宿主服务的那份 schema 里有没有本插件自己的字段」来认领)。两者都是 `getSnapshot/subscribe/set/unset` 同一张脸,插件只写一套。
|
|
40
|
+
- **loader 行 id 就是设置键**:0.1.7-rc.1 起设置按入口 id 存档,首次启动还会按**同名**把旧的 `settings.yaml` 搬过去——本包自带的 loader 行 id 因此与设置命名空间一致(`dsh-fonttune`)。同名的行 id 也让这个包可以写进 profile 的 `dsh.profile.bundles` 安装:插件管理页会把它显示为运行中,配置页照旧可达。
|
|
41
|
+
- **配置卡片座位**:0.1.5-rc.x 是 设置 → 插件 → 插件配置 里的一个 keyed 单元(`settings.plugin.item`);0.1.7 两条线删掉了这个槽位,改成在「插件」页的官方插件列表里贡献一个条目(`plugins.item`,内置那些设置页就是这么挂的),并另外提供「已安装成 bundle 时」的每包页面(`plugins.bundle.config`)。三个座位都注册,宿主不声明的那个是惰性的;卡片在这些页面里**默认展开**——点进那个条目本身就是展开手势,不该再让人多点一次。
|
|
39
42
|
- **宿主半的配置来源**:alpha 把 schema 标成 `.volatile()` 之后,宿主半拿到的配置字段是 cosmokit 的 volatile 引用(`{get(),[write]}`)而不是普通值,首帧样式行会因此变空;插件先把引用解出来再用。
|
|
40
|
-
- **`inject`
|
|
41
|
-
- **
|
|
43
|
+
- **`inject` 只声明三条线都有的服务**(`slots`、`locale`):声明一个宿主没有的服务会把整包 park 住——alpha 上声明 `settingsScope` 会让整个 Web 界面起不来。设置服务一律用 `ctx.get(name)` 现查。
|
|
44
|
+
- **0.1.7 的表单是「条目 id + 描述视图」**:宿主 `describe()` 还没答话时,插件不会去猜一个条目名(猜错的话每次写入都会被宿主拒绝),而是先用一个等待态座位顶住,等宿主把视图发出来再接管并立刻重读。
|
|
42
45
|
|
|
43
46
|
市场条目同时声明这些兼容信息(`package.json` 的 `engines.dsh`、`dsh.compatibility.dshReleases` 与 `peerDependencies`),安装前可据此判断这一版需要的宿主版本。
|
|
44
47
|
|
package/cordis.patch.yml
CHANGED
|
@@ -5,16 +5,26 @@
|
|
|
5
5
|
# the first paint already uses them; the browser half owns the
|
|
6
6
|
# Settings -> Plugins -> Plugin configuration card.
|
|
7
7
|
#
|
|
8
|
+
# The row id is the settings key from DSH 0.1.7-rc.1 on: that line imports the
|
|
9
|
+
# sections of the removed settings.yaml by matching each section against the
|
|
10
|
+
# entry of the SAME name, and this plugin's host half registered the namespace
|
|
11
|
+
# `dsh-fonttune` (its package name). Keeping the id equal to that namespace is
|
|
12
|
+
# what carries an existing installation's saved fonts and weights over; naming
|
|
13
|
+
# it `fonttune` leaves them behind in settings.yaml.imported, which shows up as
|
|
14
|
+
# "the plugin does nothing" (measured on 0.1.7-rc.1: an empty runtime
|
|
15
|
+
# stylesheet, no font applied). On the 0.1.5-rc lines the id is only a loader
|
|
16
|
+
# key, so the same value is harmless there.
|
|
17
|
+
#
|
|
8
18
|
# A profile may pin the composition defaults here; a saved value still wins,
|
|
9
19
|
# and a field left out falls back to the schema default (empty = do not touch
|
|
10
20
|
# that axis):
|
|
11
21
|
#
|
|
12
22
|
# - insert:
|
|
13
|
-
# - id: fonttune
|
|
23
|
+
# - id: dsh-fonttune
|
|
14
24
|
# name: dsh-fonttune
|
|
15
25
|
# config:
|
|
16
26
|
# sans: '"JetBrains Mono", "Sarasa Mono SC", "Microsoft YaHei", sans-serif'
|
|
17
27
|
# mono: '"JetBrains Mono", "Cascadia Code", Consolas, monospace'
|
|
18
28
|
- insert:
|
|
19
|
-
- id: fonttune
|
|
29
|
+
- id: dsh-fonttune
|
|
20
30
|
name: dsh-fonttune
|