更新换行算法和APP-PUSH

This commit is contained in:
吕新雨
2026-02-10 11:39:33 +08:00
parent f03d36b5e9
commit ee2d9f44ea
105 changed files with 9967 additions and 233 deletions

View File

@@ -0,0 +1,109 @@
# overflow-fallback技术计划
## 1. 计划目标
实现统一的“溢出与兜底”策略模块,用于在以下情况给出确定性且可解释的返回:
- 搜索器无法在 `<=maxLines` 覆盖到结束边界 `N`
- `lineMode=FIXED` 需要刚好 `maxLines` 但无解
- 测量不可用或失败导致无法执行宽度派约束(尤其 Widget
支持三种模式:
- `ELLIPSIS`:最后一行加省略号并保证不超宽(必要时回退移除 token 再加)
- `CLIP`:截断到 `maxLines`(不加省略号)
- `SYSTEM_DEFAULT`:算法层不插入换行,交给系统排版(仅在 meta 标记)
## 2. 对外输入/输出(与 spec 对齐)
### 2.1 输入
- `tokens: Token[]`
- `partialLayout?: { breaks: number[]; lines: Array<{ start; end; text? }> }`
- 若提供:表示搜索器的 best-effort可能未覆盖到 N
- `overflowMode: 'ELLIPSIS' | 'CLIP' | 'SYSTEM_DEFAULT'`
- `availableWidth: number`
- `maxLines: number`
- `lang: 'TC' | 'EN'`
- `context: 'APP' | 'WIDGET'`
- `ellipsisToken: string`(推荐 `"…"`,配置化)
- `measure?: { contextProfile; fontSpec; measureWidthImpl; widgetEnableMeasure? }`(用于“加省略号后再测量”)
- `reason: 'NO_CANDIDATE' | 'WIDTH_UNKNOWN' | 'TOO_LONG' | 'WIDOW' | 'PARTICLE' | string`
### 2.2 输出
统一返回:
- `result: { lines: string[]; wrappedText: string; meta: { fallback_type; overflow_type; reason } }`
其中:
- `fallback_type`: `NONE | RELAX_RULES | SYSTEM_DEFAULT`
- `overflow_type`: `NONE | ELLIPSIS | CLIP`
## 3. 核心行为细则(对应文档 12.x
### 3.1 overflow 判定
在本模块内不重新跑搜索,仅基于输入判断:
-`partialLayout` 覆盖到 `N`(即最后一行 `end==N`),则 overflow_type=NONE
- 否则为 overflow按 overflowMode 执行
### 3.2 SYSTEM_DEFAULT12.4A
- 返回 `lines=[原文单行]``wrappedText=原文`
- `meta.fallback_type='SYSTEM_DEFAULT'`
- `meta.overflow_type='NONE'`(因为不再输出算法换行;由 UI 决定是否完全交给系统)
- `meta.reason=输入 reason`
### 3.3 CLIP
-`partialLayout` 有 lines取前 `maxLines` 行,重组 `wrappedText=lines.join('\n')`
- 若无:返回单行原文
- `meta.overflow_type='CLIP'``fallback_type='NONE'``reason=输入 reason`
### 3.4 ELLIPSIS12.3/12.5
仅处理最后一行:
1. 选取 baseLines
- 优先使用 `partialLayout.lines`(若为空则把全文当单行)
- 截断到 `maxLines`(只在最后一行做 ellipsis
2. 清理规则(固定,确定性):
- 不输出 `" …"`:最后一行末尾空白先 trim
- 不输出 `",…"/"。…"`:若最后一行末尾是常见 TC 标点(`,。!?;:、`),则移除该标点再加 ellipsis
3. 宽度检查12.3
- 若提供测量能力且启用:
- 重新测量 `lastLine+ellipsisToken`
- 若超宽:按语言回退单位移除 token 再加省略号并重测
- EN按整词token
- TC按 graphemetoken
- 若测量不可用不做重测直接输出meta.reason 仍保留)
> 说明:首版不做“避免截断 emotionPhrase 的整段前移/整段省略”,该策略可在后续结合 scoring 决策升级,但必须保持确定性。
## 4. 代码落位(客户端)
- `client/src/features/textWrap/overflow/`
- `types.ts`
- `ellipsis.ts`
- `fallback.ts`入口applyOverflowFallback
- `index.ts`
- `__tests__/overflowFallback.test.ts`
## 5. 测试计划Vitest
- SYSTEM_DEFAULTlines 单行meta.fallback_type=SYSTEM_DEFAULT
- CLIP超过 maxLines 时截断行数
- ELLIPSIS
- 末尾空白去除,不输出 `" …"`
- 末尾 TC 标点去除,不输出 `",…"`
- 测量超宽时按 token 回退直到不超宽(用 mock measureWidthImpl
## 6. 完成定义DoD
- 三种 overflowMode 行为稳定且可解释
- ELLIPSIS 的清理与回退测量实现完毕(可测)
- 输出 meta 字段满足文档 12/14 的治理需求