Files
ReadViewSDK/Sources/RDReaderView/EPUBCore/RDEPUBSearchModels.swift
T
shenandshen 54798ba578 refactor: 添加中文注释 + 优化模块结构
- 给全部 78 个 Swift 源文件添加详细的中文注释(文件级、类级、方法级)
- 删除 LegacyRDReaderController/ 死代码目录(16 文件 4592 行)
- 根目录翻页容器文件移入 ReaderView/ 目录
- Resources/ 移入 EPUBCore/Resources/(与使用者归属一致)
- RDEPUBTextIndexTable.swift 移入 EPUBTextRendering/(消除反向依赖)
- RDURLReaderController.swift 移入 EPUBUI/(入口控制器归入 UI 层)
- 更新 podspec 资源路径
2026-05-25 10:19:14 +08:00

131 lines
4.3 KiB
Swift

// RDEPUBSearchModels.swift
// EPUB 搜索相关数据模型
// 定义搜索匹配项(RDEPUBSearchMatch)、搜索结果(RDEPUBSearchResult)、
// 搜索状态(RDEPUBSearchState)和搜索展示(RDEPUBSearchPresentation)等数据结构。
import Foundation
/// 搜索匹配项,包含匹配位置、进度、预览文本和范围信息
public struct RDEPUBSearchMatch: Codable, Equatable {
/// 匹配所在资源的规范化 href
public var href: String
/// 匹配位置在文本中的进度比例(0.0 ~ 1.0)
public var progression: Double
/// 匹配位置前后的预览文本
public var previewText: String
/// 在当前资源内的本地匹配索引
public var localMatchIndex: Int
/// 匹配范围的起始位置(字符偏移量)
public var rangeLocation: Int?
/// 匹配范围的长度
public var rangeLength: Int
/// 文本范围锚点(用于精确定位)
public var rangeAnchor: RDEPUBTextRangeAnchor?
public init(
href: String,
progression: Double,
previewText: String,
localMatchIndex: Int,
rangeLocation: Int? = nil,
rangeLength: Int,
rangeAnchor: RDEPUBTextRangeAnchor? = nil
) {
self.href = href
self.progression = progression
self.previewText = previewText
self.localMatchIndex = localMatchIndex
self.rangeLocation = rangeLocation
self.rangeLength = rangeLength
self.rangeAnchor = rangeAnchor
}
}
/// 搜索结果摘要,包含关键词、总匹配数和当前匹配项
public struct RDEPUBSearchResult: Codable, Equatable {
/// 搜索关键词
public var keyword: String
/// 总匹配数量
public var totalMatchCount: Int
/// 当前匹配项的索引(从 1 开始)
public var currentMatchIndex: Int?
/// 当前高亮的匹配项
public var currentMatch: RDEPUBSearchMatch?
public init(
keyword: String,
totalMatchCount: Int,
currentMatchIndex: Int?,
currentMatch: RDEPUBSearchMatch?
) {
self.keyword = keyword
self.totalMatchCount = totalMatchCount
self.currentMatchIndex = currentMatchIndex
self.currentMatch = currentMatch
}
}
/// 搜索状态,管理关键词、匹配列表和当前索引
public struct RDEPUBSearchState: Codable, Equatable {
/// 搜索关键词
public var keyword: String
/// 所有匹配项列表
public var matches: [RDEPUBSearchMatch]
/// 当前匹配项索引(从 0 开始)
public var currentMatchIndex: Int?
public init(keyword: String, matches: [RDEPUBSearchMatch], currentMatchIndex: Int? = nil) {
self.keyword = keyword
self.matches = matches
self.currentMatchIndex = currentMatchIndex
}
/// 获取当前匹配项
public var currentMatch: RDEPUBSearchMatch? {
guard let currentMatchIndex,
matches.indices.contains(currentMatchIndex) else {
return nil
}
return matches[currentMatchIndex]
}
/// 转换为搜索结果摘要
public var result: RDEPUBSearchResult {
RDEPUBSearchResult(
keyword: keyword,
totalMatchCount: matches.count,
currentMatchIndex: currentMatchIndex.map { $0 + 1 },
currentMatch: currentMatch
)
}
}
/// 搜索展示的单个资源信息
public struct RDEPUBSearchPresentationResource: Codable, Equatable {
/// 资源的规范化 href
public var href: String
/// 该资源内的匹配数量
public var matchCount: Int
/// 当前活跃的本地匹配索引
public var activeLocalMatchIndex: Int?
public init(href: String, matchCount: Int, activeLocalMatchIndex: Int? = nil) {
self.href = href
self.matchCount = matchCount
self.activeLocalMatchIndex = activeLocalMatchIndex
}
}
/// 搜索展示信息,传递给 JS 桥接脚本用于渲染搜索高亮
public struct RDEPUBSearchPresentation: Codable, Equatable {
/// 搜索关键词
public var keyword: String
/// 各资源的搜索展示信息列表
public var resources: [RDEPUBSearchPresentationResource]
public init(keyword: String, resources: [RDEPUBSearchPresentationResource]) {
self.keyword = keyword
self.resources = resources
}
}