ReadViewSDK/Sources/RDReaderView/EPUBCore/RDEPUBParser+ReadingProfile.swift
shenlei c76beed03c feat(reader): 实现大书快速进入与增量分页路径
- PaginationCoordinator: 新增 textReflowable 快速进入路径,支持增量章节构建
  与 staged 合并策略,避免整书一次性构建的主线程阻塞
- TextBookBuilder: 重构为支持单章构建与增量合并模式
- ChapterPageCounter: 优化分页计数逻辑,支持章节级分页缓存
- PageFrameFactory: 新增 CoreText 页面帧工厂,提升排版性能
- ReaderContext/ReaderRuntime: 适配增量分页状态管理

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-02 21:16:57 +08:00

57 lines
2.5 KiB
Swift
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.

// RDEPUBParser+ReadingProfile.swift
// EPUB
// metadata layout manifest/spine
// webFixedLayoutwebInteractive/ textReflowable
import Foundation
extension RDEPUBParser {
///
/// /iframe/
public func readingProfile() -> RDEPUBReadingProfile {
if metadata.layout == .fixed {
return .webFixedLayout
}
return hasInteractiveContent() ? .webInteractive : .textReflowable
}
///
/// manifest "scripted"
/// HTML script/iframe/video/audio/canvas/svg/form
public func hasInteractiveContent() -> Bool {
let interactiveMediaTypes = [
"application/javascript",
"text/javascript",
"application/ecmascript"
]
if manifest.values.contains(where: { item in
interactiveMediaTypes.contains(item.mediaType.lowercased()) || item.properties.contains("scripted")
}) {
return true
}
for item in spine where item.linear && (item.mediaType.contains("html") || item.mediaType.contains("xhtml")) {
guard let html = htmlString(forRelativePath: item.href) else {
continue
}
if containsInteractiveMarkup(html) {
return true
}
}
return false
}
/// HTML Web
/// EPUB SVG `<svg>` interactive
private func containsInteractiveMarkup(_ html: String) -> Bool {
let interactivePattern = #"<(script|iframe|video|audio|canvas|object|embed)\b|\bon(load|click|touchstart|touchend|mouseover|submit|change|input)=|hype_generated_script|swiper|webview"#
if html.range(of: interactivePattern, options: [.regularExpression, .caseInsensitive]) != nil {
return true
}
let dynamicSVGPattern = #"<svg\b[^>]*>[\s\S]*?(<(script|foreignObject|animate|animateMotion|animateTransform|set)\b|\bon(load|click|touchstart|touchend|mouseover)=)"#
return html.range(of: dynamicSVGPattern, options: [.regularExpression, .caseInsensitive]) != nil
}
}