ReadViewSDK/.planning/phases/01-current-engine-boundaries/01-refactor-entry-strategy.md

269 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Phase 1 Strategy: Direct Refactor Entry Points for the Existing Reflowable Engine
**Phase:** 01-current-engine-boundaries
**Date:** 2026-05-21
**Purpose:** 把“旧引擎直接演进”的切入点、顺序和硬边界固定下来,供 Phase 2/3 实施使用。
## 1. Strategy in One Sentence
后续实现应保留现有 `RDURLReaderController -> RDEPUBReaderController -> RDReaderView` 外层契约不变,把升级集中在 `EPUBTextRendering` 内部:先增强 typesetter / CSS 分层,再增强页面级属性与分页语义,最后回接并验证 reader 兼容能力。
## 2. Why the Strategy Is “Direct Evolution,” Not “Parallel Engine”
根据当前源码审计native `.textReflowable` 主路径已经具备以下骨架:
- `RDEPUBParser.readingProfile()` 已经把普通 reflowable EPUB 分到 `.textReflowable`
- `RDEPUBReaderController.paginatePublication()` 已经把 `.textReflowable` 接到 `RDEPUBTextBookBuilder`
- `RDEPUBDTCoreTextRenderer` 已经承担章节 HTML -> `NSAttributedString`
- `RDEPUBTextPaginationSupport.ss_pageRanges(size:)` 已经承担最小可用分页
- `RDEPUBTextContentView``RDReaderView` 已经承担原生页面展示
因此,新增第二套原生引擎只会制造双轨维护问题:
- duplicate reader integration
- duplicate location/highlight/search transport
- duplicate pagination data model
- duplicate regression matrix
正确策略是:**沿着现有 native text 路径升级内部能力,而不是复制一条新路径。**
## 3. Target Capability Map: WXRead -> Current Touchpoints
下表把 WXRead 目标能力映射到当前仓库中真正应该改动的触点。
| WXRead-style capability | Current touchpoint | Target phase | Why this file is the right entry point |
|-------------------------|-------------------|--------------|----------------------------------------|
| 五层 CSS 级联default / replace / dark / epub / user | `Sources/RDReaderView/EPUBTextRendering/RDEPUBDTCoreTextRenderer.swift` | Phase 2 | 当前 renderer 已拥有 HTML、baseURL、style 三要素,是升级 stylesheet pipeline 的最直接入口。 |
| HTML 预处理与资源引用兜底 | `Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift` 或新建 `RDEPUBWXReadHTMLPreprocessor.swift` | Phase 2 | builder 已掌握章节原始 HTML 与章节 baseURL适合做 `<link>` CSS 内联或章节级规范化。 |
| 统一 stylesheet 生成器 | 新建 `Sources/RDReaderView/EPUBTextRendering/RDEPUBWXReadStyleSheetBuilder.swift` | Phase 2 | 避免把 layered CSS 逻辑塞进 renderer使样式层可测试、可替换、可调试。 |
| 页面级 attributed string 元数据 | `Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift`、`RDEPUBTextChapter`、`RDEPUBTextPage` | Phase 3 | 当前 page model 只有范围和 offset后续页面语义需要在这里承接。 |
| 更强分页语义(块级避免断页、图片/附件边界) | `Sources/RDReaderView/EPUBTextRendering/RDEPUBTextPaginationSupport.swift` | Phase 3 | 当前 `ss_pageRanges(size:)` 是唯一分页核心,增强必须从这里开始。 |
| Layout frame / layouter 责任分离 | 新建 `EPUBTextRendering` 内部 layouter/frame 类型 | Phase 3 | 不应把复杂页面布局逻辑继续堆在 `RDEPUBReaderController` 或 content view。 |
| Reader 兼容性回接(位置、高亮、搜索、重分页) | `Sources/RDReaderView/EPUBUI/RDEPUBReaderController.swift` | Phase 4 | 这是现有 reader state 的唯一编排点,适合接回而不是承担新排版实现。 |
## 4. Phase 2 Entry Strategy: Upgrade Typesetter First
Phase 2 的目标不是“立刻实现 WXRead 全量布局器”,而是把渲染输入从“简单 DTCoreText options”升级为“WXRead 风格 typesetter”。
### 4.1 Primary code touchpoints
优先改动:
- `Sources/RDReaderView/EPUBTextRendering/RDEPUBDTCoreTextRenderer.swift`
- `Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift`
- 新建 `Sources/RDReaderView/EPUBTextRendering/RDEPUBWXReadStyleSheetBuilder.swift`
### 4.2 Concrete target state
Phase 2 应把当前 renderer 升级到以下状态:
1. 合成 layered CSS
- SDK default CSS
- SDK replace/enhancement CSS
- dark theme override
- EPUB embedded CSS
- user CSS from `RDEPUBTextRenderStyle`
2. 使用章节目录 `baseURL`
- 保留当前 baseURL 计算方式
- 确保图片与章节级 CSS 相对路径继续可解析
3. 维持 fragment marker / fragment offset 体系
- 不能破坏 `injectFragmentMarkers`
- 不能破坏 `extractFragmentOffsets`
4. 不改 reader integration surface
- `RDEPUBTextBookBuilder.build(...)` 的高层职责保持不变
- `RDEPUBReaderController.paginatePublication()` 的分支结构保持不变
### 4.3 Why Phase 2 should stop there
如果在 Phase 2 就同时引入:
- 全新分页器
- 大量新 page model
- reader compatibility 回接修复
就会把“渲染输入提升”与“分页语义重构”混为一体定位回归原因会非常困难。Phase 2 应该先把章节渲染输入变得更接近 WXRead再观察真实样本书暴露的分页问题。
## 5. Phase 3 Entry Strategy: Upgrade Pagination Semantics
Phase 3 才是“把 pageRanges 模式升级为更强页面语义”的阶段。
### 5.1 Primary code touchpoints
优先改动:
- `Sources/RDReaderView/EPUBTextRendering/RDEPUBTextPaginationSupport.swift`
- `Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift`
- `RDEPUBTextPage`
- `RDEPUBTextChapter`
- 必要时新建内部 layouter/layout-frame 类型
### 5.2 Concrete target state
Phase 3 应逐步实现:
1. 当前 range-only page model -> richer page metadata
- block boundaries
- image/attachment semantics
- page-level layout markers
- future page background or page-style metadata hooks
2. 当前 visible-range slicing -> stronger pagination semantics
- avoid page break inside for large blocks
- image and attachment boundary handling
- better page edge control than pure `CTFrameGetVisibleStringRange`
3. 保留 offset continuity
- `pageStartOffset`
- `pageEndOffset`
- chapter-level text continuity
- fragment offset compatibility
### 5.3 What not to do in Phase 3
不要把分页器升级等同于:
- 改写 `RDReaderView`
- 改写 fixed/interactive 渲染链路
- 绕开 `RDEPUBTextBook` 直接输出新的 UI 专用模型
Phase 3 的正确做法是:让更强的分页语义仍然最终落到现有 book/chapter/page 契约上,必要时是“扩展”这些模型,而不是抛弃它们。
## 6. Compatibility Surface That Must Be Preserved
以下能力必须视为后续 phase 的硬约束:
### 6.1 `WKWebView` retention boundary
保留不动:
- `webFixedLayout`
- `webInteractive`
- `RDEPUBWebView+FixedLayout.swift`
- `RDEPUBWebView+Reflowable.swift`
- `RDEPUBPaginator.swift` 所属的 WebView 测量职责
原因:
- Fixed layout 依赖 spread HTML 表示
- interactive EPUB 依赖 JS/bridge/iframe/form/multimedia 支持
- 它们不属于 native reflowable 的目标问题域
### 6.2 Stable reader container
`RDReaderView` 与现有翻页模式保持不变:
- page curl
- horizontal scroll
- vertical scroll
- page direction
- dual-page / cover page behavior
- orientation-driven container refresh
原因:
- 它是 native text 与 web content 的共同外壳
- 改它会同时扩大 regression surface
### 6.3 Reader capability continuity
以下链路必须继续通过现有 `RDEPUBReaderController` 契约工作:
- 阅读位置恢复
- `RDEPUBLocation` 映射
- 高亮 / 选区
- 搜索结果定位
- 字号/行高/主题切换后的重分页
这要求后续 phase 继续维护:
- `fragmentOffsets`
- `pageStartOffset`
- `pageEndOffset`
- `RDEPUBTextOffsetRangeInfo`
- `RDEPUBTextContentView` 所依赖的页内容语义
## 7. Recommended Implementation Sequence
建议执行顺序如下:
### Step 1: Strengthen renderer / typesetter
目标:
- layered CSS
- HTML preprocessing
- stable resource resolution
- normalized style injection
原因:
- 先把“输入质量”提升,才能判断现有分页问题到底是样式输入问题还是分页算法问题
### Step 2: Strengthen pagination semantics
目标:
- richer page metadata
- avoid-break logic
- attachment-aware page boundaries
原因:
- 在更稳定的 attributed string 输入上做分页升级,结果更可解释
### Step 3: Reconnect and validate reader capability chain
目标:
- 位置映射
- highlight/search
- repagination after settings change
原因:
- 这一步应基于已经稳定的 renderer + page model而不是把所有问题都混在一起排查
## 8. File-Level Recommendations for Next Phases
### 8.1 Files Phase 2 should read first
- `Sources/RDReaderView/EPUBTextRendering/RDEPUBDTCoreTextRenderer.swift`
- `Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift`
- `Doc/WXRead/analysis/EPUB渲染管线详解.md`
- `Doc/WXRead/analysis/DTCoreText自定义修改分析.md`
- `.planning/phases/01-current-engine-boundaries/01-reflowable-audit.md`
### 8.2 Files Phase 3 should read first
- `Sources/RDReaderView/EPUBTextRendering/RDEPUBTextPaginationSupport.swift`
- `Sources/RDReaderView/EPUBTextRendering/RDEPUBTextBookBuilder.swift`
- `Sources/RDReaderView/EPUBUI/RDEPUBTextContentView.swift`
- `.planning/phases/01-current-engine-boundaries/01-reflowable-audit.md`
- `Doc/WXRead/analysis/02_符号恢复与核心算法.md`
### 8.3 Files Phase 4 should read first
- `Sources/RDReaderView/EPUBUI/RDEPUBReaderController.swift`
- `Sources/RDReaderView/EPUBUI/RDEPUBTextContentView.swift`
- `Sources/RDReaderView/RDReaderView.swift`
- Any Phase 2/3 summaries produced from the pagination work
## 9. Non-Goals and Refusal Rules
后续 phase 默认拒绝以下方向,除非 roadmap 被显式修改:
1. 把 Fixed Layout EPUB 改成 native renderer
2. 把 interactive EPUB 改成 native renderer
3. 新建并长期维护第二套 reflowable 原生引擎
4. 修改 `RDReaderView` 的外部容器契约
5. 在还没完成 Phase 2 renderer 升级前,就全面重写 reader integration
## 10. Final Strategy Decision
最终策略决议如下:
> Phase 2 先把 `RDEPUBDTCoreTextRenderer` 从“简单 DTCoreText options”升级成“WXRead 风格 typesetter + layered CSS pipeline”Phase 3 再升级 `RDEPUBTextPaginationSupport`、`RDEPUBTextBookBuilder` 与 page model 的页面语义Phase 4 才处理 reader capability 链路的兼容回接。整个过程中,`WKWebView` 边界和 `RDReaderView` 容器契约都保持不变。