feat: EPUB阅读器搜索、注释、CFI模块及大书远距跳转优化
- 实现EPUB阅读器搜索功能及选中注释功能 - 优化CFI模块,修复代码审查发现的11个问题 - 实现大书远距目录跳转与后台补全优化方案 - 优化设置面板与章节运行时联动 - 重构及大量改进优化
This commit is contained in:
@@ -1,54 +1,34 @@
|
||||
// RDEPUBReaderController+PublicAPI.swift
|
||||
// RDEPUBReaderController 的公开 API 扩展,提供书签、高亮、目录跳转、搜索等操作
|
||||
|
||||
import UIKit
|
||||
|
||||
// MARK: - Public Reader Commands
|
||||
|
||||
extension RDEPUBReaderController {
|
||||
/// 重新加载书籍,重置所有状态并重新解析 EPUB
|
||||
|
||||
public func reloadBook() {
|
||||
runtime.reloadBook()
|
||||
}
|
||||
|
||||
/// 跳转到指定阅读位置
|
||||
/// - Parameter location: 目标阅读位置
|
||||
public func go(to location: RDEPUBLocation) {
|
||||
guard publication != nil else { return }
|
||||
_ = runtime.go(to: location)
|
||||
}
|
||||
|
||||
/// 跳转到指定页码
|
||||
/// - Parameters:
|
||||
/// - pageNumber: 目标页码(从 1 开始)
|
||||
/// - animated: 是否动画过渡
|
||||
/// - Returns: 是否跳转成功
|
||||
@discardableResult
|
||||
public func go(toPageNumber pageNumber: Int, animated: Bool = false) -> Bool {
|
||||
runtime.go(toPageNumber: pageNumber, animated: animated)
|
||||
}
|
||||
|
||||
/// 清除当前文本选中状态
|
||||
public func clearSelection() {
|
||||
runtime.clearSelection()
|
||||
}
|
||||
|
||||
/// 根据唯一标识获取书签
|
||||
/// - Parameter id: 书签 ID
|
||||
/// - Returns: 匹配的书签对象,不存在时返回 nil
|
||||
public func bookmark(withID id: String) -> RDEPUBBookmark? {
|
||||
runtime.bookmark(withID: id)
|
||||
}
|
||||
|
||||
/// 根据唯一标识获取高亮标注
|
||||
/// - Parameter id: 高亮 ID
|
||||
/// - Returns: 匹配的高亮对象,不存在时返回 nil
|
||||
public func highlight(withID id: String) -> RDEPUBHighlight? {
|
||||
runtime.highlight(withID: id)
|
||||
}
|
||||
|
||||
/// 获取当前页的原生文本语义摘要,用于调试和可访问性
|
||||
/// - Returns: 包含页码、断行原因、块类型等信息的摘要字符串,无内容时返回 nil
|
||||
public func nativeTextSemanticSummary() -> String? {
|
||||
let resolvedPage: RDEPUBTextPage?
|
||||
if let textBook {
|
||||
@@ -79,12 +59,6 @@ extension RDEPUBReaderController {
|
||||
return parts.joined(separator: " · ")
|
||||
}
|
||||
|
||||
/// 添加高亮标注,从当前选中文本或指定选区创建
|
||||
/// - Parameters:
|
||||
/// - selection: 文本选区,默认使用 currentSelection
|
||||
/// - color: 高亮颜色(CSS 格式),默认黄色
|
||||
/// - note: 可选批注文字
|
||||
/// - Returns: 创建的高亮对象,重复时返回 nil
|
||||
@discardableResult
|
||||
public func addHighlight(
|
||||
from selection: RDEPUBSelection? = nil,
|
||||
@@ -94,13 +68,6 @@ extension RDEPUBReaderController {
|
||||
runtime.addHighlight(from: selection, color: color, note: note)
|
||||
}
|
||||
|
||||
/// 添加指定样式的标注,从当前选中文本或指定选区创建
|
||||
/// - Parameters:
|
||||
/// - selection: 文本选区,默认使用 currentSelection
|
||||
/// - style: 标注样式(下划线、高亮等)
|
||||
/// - color: 标注颜色(CSS 格式),默认黄色
|
||||
/// - note: 可选批注文字
|
||||
/// - Returns: 创建的高亮对象,重复时返回 nil
|
||||
@discardableResult
|
||||
public func addAnnotation(
|
||||
from selection: RDEPUBSelection? = nil,
|
||||
@@ -111,72 +78,40 @@ extension RDEPUBReaderController {
|
||||
runtime.addAnnotation(from: selection, style: style, color: color, note: note)
|
||||
}
|
||||
|
||||
/// 插入或更新高亮标注(存在则更新,不存在则插入)
|
||||
/// - Parameter highlight: 要写入的高亮对象
|
||||
/// - Returns: 写入后的高亮对象
|
||||
@discardableResult
|
||||
public func upsertHighlight(_ highlight: RDEPUBHighlight) -> RDEPUBHighlight? {
|
||||
runtime.upsertHighlight(highlight)
|
||||
}
|
||||
|
||||
/// 移除指定高亮标注
|
||||
/// - Parameter id: 高亮 ID
|
||||
/// - Returns: 被移除的高亮对象,不存在时返回 nil
|
||||
@discardableResult
|
||||
public func removeHighlight(id: String) -> RDEPUBHighlight? {
|
||||
runtime.removeHighlight(id: id)
|
||||
}
|
||||
|
||||
/// 更新高亮标注的批注内容
|
||||
/// - Parameters:
|
||||
/// - id: 高亮 ID
|
||||
/// - note: 新的批注文字,传 nil 清除批注
|
||||
/// - Returns: 更新后的高亮对象,不存在时返回 nil
|
||||
@discardableResult
|
||||
public func updateHighlightNote(id: String, note: String?) -> RDEPUBHighlight? {
|
||||
runtime.updateHighlightNote(id: id, note: note)
|
||||
}
|
||||
|
||||
/// 跳转到指定高亮标注所在位置
|
||||
/// - Parameters:
|
||||
/// - id: 高亮 ID
|
||||
/// - animated: 是否动画过渡
|
||||
/// - Returns: 是否跳转成功
|
||||
@discardableResult
|
||||
public func go(toHighlightID id: String, animated: Bool = true) -> Bool {
|
||||
runtime.go(toHighlightID: id, animated: animated)
|
||||
}
|
||||
|
||||
/// 移除当前书籍的所有高亮标注
|
||||
public func removeAllHighlights() {
|
||||
runtime.removeAllHighlights()
|
||||
}
|
||||
|
||||
/// 跳转到目录项对应的阅读位置
|
||||
/// - Parameters:
|
||||
/// - item: EPUB 原生目录项
|
||||
/// - animated: 是否动画过渡
|
||||
/// - Returns: 是否跳转成功
|
||||
@discardableResult
|
||||
public func go(toTableOfContentsItem item: EPUBTableOfContentsItem, animated: Bool = true) -> Bool {
|
||||
go(toTableOfContentsHref: item.href, animated: animated)
|
||||
}
|
||||
|
||||
/// 跳转到目录项对应的阅读位置
|
||||
/// - Parameters:
|
||||
/// - item: RDReader 目录项
|
||||
/// - animated: 是否动画过渡
|
||||
/// - Returns: 是否跳转成功
|
||||
@discardableResult
|
||||
public func go(toTableOfContentsItem item: RDEPUBReaderTableOfContentsItem, animated: Bool = true) -> Bool {
|
||||
go(toTableOfContentsHref: item.href, animated: animated)
|
||||
}
|
||||
|
||||
/// 通过目录 href 跳转到对应阅读位置,支持带锚点的 href
|
||||
/// - Parameters:
|
||||
/// - href: 目录资源路径(可含 #fragment)
|
||||
/// - animated: 是否动画过渡
|
||||
/// - Returns: 是否跳转成功
|
||||
@discardableResult
|
||||
public func go(toTableOfContentsHref href: String, animated: Bool = true) -> Bool {
|
||||
guard publication != nil else { return false }
|
||||
@@ -193,61 +128,40 @@ extension RDEPUBReaderController {
|
||||
return restoreReadingLocation(location, animated: animated)
|
||||
}
|
||||
|
||||
/// 在当前位置添加书签
|
||||
/// - Parameter note: 可选批注文字
|
||||
/// - Returns: 创建的书签对象,位置已存在书签时返回 nil
|
||||
@discardableResult
|
||||
public func addBookmark(note: String? = nil) -> RDEPUBBookmark? {
|
||||
runtime.addBookmark(note: note)
|
||||
}
|
||||
|
||||
/// 切换当前位置的书签状态(有则移除,无则添加)
|
||||
/// - Parameter note: 添加时可附带的批注文字
|
||||
/// - Returns: 添加时返回新书签,移除时返回被移除的书签
|
||||
@discardableResult
|
||||
public func toggleBookmark(note: String? = nil) -> RDEPUBBookmark? {
|
||||
runtime.toggleBookmark(note: note)
|
||||
}
|
||||
|
||||
/// 移除指定书签
|
||||
/// - Parameter id: 书签 ID
|
||||
/// - Returns: 被移除的书签对象,不存在时返回 nil
|
||||
@discardableResult
|
||||
public func removeBookmark(id: String) -> RDEPUBBookmark? {
|
||||
runtime.removeBookmark(id: id)
|
||||
}
|
||||
|
||||
/// 跳转到指定书签所在位置
|
||||
/// - Parameters:
|
||||
/// - id: 书签 ID
|
||||
/// - animated: 是否动画过渡
|
||||
/// - Returns: 是否跳转成功
|
||||
@discardableResult
|
||||
public func go(toBookmarkID id: String, animated: Bool = true) -> Bool {
|
||||
runtime.go(toBookmarkID: id, animated: animated)
|
||||
}
|
||||
|
||||
/// 执行全文搜索,匹配结果非空时自动跳转到第一个匹配项,无匹配时清除搜索状态
|
||||
/// - Parameter keyword: 搜索关键词,空字符串会清除搜索
|
||||
public func search(keyword: String) {
|
||||
runtime.search(keyword: keyword)
|
||||
}
|
||||
|
||||
/// 跳转到下一个搜索匹配项
|
||||
/// - Returns: 是否存在下一个匹配项并跳转成功
|
||||
@discardableResult
|
||||
public func searchNext() -> Bool {
|
||||
runtime.searchNext()
|
||||
}
|
||||
|
||||
/// 跳转到上一个搜索匹配项
|
||||
/// - Returns: 是否存在上一个匹配项并跳转成功
|
||||
@discardableResult
|
||||
public func searchPrevious() -> Bool {
|
||||
runtime.searchPrevious()
|
||||
}
|
||||
|
||||
/// 清除搜索状态和高亮
|
||||
public func clearSearch() {
|
||||
runtime.clearSearch()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user