feat: 支持加密 EPUB、试读墙、工具栏定制与朝向锁定

- 新增 RDEPUBResourceDataProvider 解密钩子协议 + 访问登记表,收敛章节 HTML/
  图片/内联 CSS/脚注/封面/图片查看器/正文取图等读取点,scheme handler 对加密书
  禁用流式分支;新增 RDEPUBDecryptingImageAttachment 解密 DTCoreText 图片附件;
  RDEPUBReaderDependencies.live(resourceDataProvider:) 便捷注入。明文书零影响。
- 试读墙:configuration.trialPolicy + delegate epubReaderTrialWallView/
  DidReachTrialWall,UI 由宿主提供(RDEPUBReaderController+Trial)。
- 工具栏定制:RDEPUBReaderTop/BottomToolViewProtocol 协议 + dependencies 工厂注入,
  内置栏已 conform,configureTopToolView 改协议类型。
- 朝向锁定:RDEPUBMetadata.orientation(OPF rendition:orientation 主,
  iBooks display-options 兜底)+ RDEPUBReaderController+Orientation 重写支持朝向、
  打开后主动转向。

注:RDEPUBReaderController+LocationResolution / PaginationCoordinator 为本次改动前
即存在的工作区修改,一并纳入。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-07-10 12:25:17 +09:00
co-authored by Claude Fable 5
parent 83dfa40299
commit d5a7755702
30 changed files with 2218 additions and 1569 deletions
@@ -59,13 +59,22 @@ public final class RDEPUBNoteResolver {
guard let fragment,
!fragment.isEmpty,
let fileURL = resourceResolver.fileURL(forRelativePath: href),
let html = try? String(contentsOf: fileURL, encoding: .utf8) else {
let html = chapterHTML(at: fileURL) else {
return nil
}
return elementHTML(withID: fragment, in: html)
}
/// HTML provider
private func chapterHTML(at fileURL: URL) -> String? {
if let provided = resourceResolver.providedResourceData(at: fileURL) {
return String(data: provided, encoding: .utf8)
?? String(data: provided, encoding: .utf16)
}
return try? String(contentsOf: fileURL, encoding: .utf8)
}
private func elementHTML(withID id: String, in html: String) -> String? {
let escapedID = NSRegularExpression.escapedPattern(for: id)
let pattern = #"<([A-Za-z][A-Za-z0-9:_-]*)(?=[^>]*(?:id|xml:id)\s*=\s*(['"])"# + escapedID + #"\2)[^>]*>"#