# overflow-fallback(任务清单) > 目标:统一实现 `ELLIPSIS/CLIP/SYSTEM_DEFAULT` 的溢出与兜底语义(文档 12.x),输出稳定可解释的 meta。 ## 0. 对齐与准备 - [x] 阅读并对齐口径 - [x] 阅读 `spec_kit/Text Wrap/modules/overflow-fallback/spec.md` - [x] 阅读 `spec_kit/Text Wrap/modules/overflow-fallback/plan.md` - [x] 阅读 `设计说明文档/文档换行算法.md` 的 12.x/14 章节 - [x] 创建客户端模块目录 - [x] 新建 `client/src/features/textWrap/overflow/` ## 1. 类型与对外接口 - [x] 新建 `client/src/features/textWrap/overflow/types.ts` - [x] 定义 `OverflowMode = 'ELLIPSIS' | 'CLIP' | 'SYSTEM_DEFAULT'` - [x] 定义 `FallbackType = 'NONE' | 'RELAX_RULES' | 'SYSTEM_DEFAULT'` - [x] 定义 `OverflowType = 'NONE' | 'ELLIPSIS' | 'CLIP'` - [x] 定义 `OverflowReason`(至少包含:NO_CANDIDATE/WIDTH_UNKNOWN/TOO_LONG/WIDOW/PARTICLE) - [x] 定义 `PartialLayoutInput`:`breaks` + `lines[{start,end,text?}]` - [x] 定义 `ApplyOverflowFallbackInput/Result` - [x] 新建 `client/src/features/textWrap/overflow/index.ts` - [x] 统一导出 types 与入口 `applyOverflowFallback()` ## 2. ELLIPSIS 核心逻辑 - [x] 新建 `client/src/features/textWrap/overflow/ellipsis.ts` - [x] 实现 `cleanLineBeforeEllipsis(line, lang)`: - [x] trim 末尾空白,避免 `" …"` - [x] TC:若末尾是 `,。!?;:、`,移除该标点,避免 `",…"` - [x] 实现 `applyEllipsisToLastLine(...)`: - [x] 仅处理最后一行 - [x] EN 回退单位=整词;TC 回退单位=grapheme - [x] 若提供测量能力:加省略号后必须重新测量,超宽则循环回退再测量 - [x] 若测量不可用:直接输出(确定性) ## 3. 入口:applyOverflowFallback - [x] 新建 `client/src/features/textWrap/overflow/fallback.ts` - [x] 实现 `applyOverflowFallback(input)`: - [x] overflow 判定:partialLayout 是否覆盖到 N - [x] `SYSTEM_DEFAULT`(12.4A):返回单行原文 + meta.fallback_type=SYSTEM_DEFAULT - [x] `CLIP`:截断到 maxLines - [x] `ELLIPSIS`:调用 ellipsis 逻辑 - [x] meta 输出:`fallback_type/overflow_type/reason` ## 4. 单测(Vitest) - [x] 新建 `client/src/features/textWrap/overflow/__tests__/overflowFallback.test.ts` - [x] SYSTEM_DEFAULT 语义 - [x] CLIP 截断行为 - [x] ELLIPSIS 清理规则(不输出 `" …"`、不输出 `",…"`) - [x] ELLIPSIS 测量回退:mock measureWidthImpl,让超宽时按 token 回退直到不超宽 ## 5. 收尾 - [x] 跑测试与类型检查 - [x] `npm test` - [x] `npx tsc --noEmit` - [x] 将本 `tasks.md` 全部勾选完成 - [x] 更新 `spec_kit/overview.md` - [x] 标记 `overflow-fallback` 已完成编码(阶段性) - [x] 写入变更文件清单