ReadViewSDK/Sources/RDReaderView/EPUBUI/RDEPUBReaderController+ContentDelegates.swift

188 lines
7.3 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.

// RDEPUBReaderController+ContentDelegates.swift
// EPUB
// Web RDEPUBWebContentViewDelegate Native Text
// RDEPUBTextContentViewDelegate
import UIKit
/// RDEPUBReaderController
///
/// EPUB Web Native Text
///
// MARK: - Web EPUB /Web
extension RDEPUBReaderController: RDEPUBWebContentViewDelegate {
/// Web
func epubWebContentView(_ contentView: RDEPUBWebContentView, didUpdateLocation location: RDEPUBLocation, spineIndex: Int) {
guard readerView.currentPage >= 0,
activePages.indices.contains(readerView.currentPage) else {
return
}
let currentPage = activePages[readerView.currentPage]
guard readingSession?.pageContains(spineIndex: spineIndex, in: currentPage) == true else {
return
}
persist(location: location)
readingSession?.updateReadingContext(
pageNumber: readerView.currentPage + 1,
location: location,
spineIndex: spineIndex,
chapterIndex: currentPage.chapterIndex,
bookIdentifier: currentBookIdentifier
)
}
/// Web
func epubWebContentView(_ contentView: RDEPUBWebContentView, didChangeSelection selection: RDEPUBSelection?, spineIndex: Int) {
if let selection {
updateCurrentSelection(scopedSelection(selection, relativeToSpineIndex: spineIndex))
} else {
updateCurrentSelection(nil)
}
}
/// Web
func epubWebContentView(_ contentView: RDEPUBWebContentView, didRequestSelectionAction action: RDEPUBAnnotationMenuAction) {
handleSelectionMenuAction(action, selection: currentSelection)
}
/// Web
func epubWebContentView(_ contentView: RDEPUBWebContentView, didActivateInternalLink location: RDEPUBLocation, fromSpineIndex: Int) {
guard let readingSession,
let pageNumber = readingSession.queueNavigation(
to: location,
relativeToSpineIndex: fromSpineIndex,
bookIdentifier: currentBookIdentifier
) else {
return
}
readerView.transitionToPage(pageNum: max(pageNumber - 1, 0), animated: true)
}
/// Web 使
func epubWebContentView(_ contentView: RDEPUBWebContentView, didActivateExternalLink url: URL) {
delegate?.epubReader(self, didActivateExternalLink: url)
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
/// Web JavaScript
func epubWebContentView(_ contentView: RDEPUBWebContentView, didLogJavaScriptError message: String) {
print("EPUB JS Error: \(message)")
}
}
// MARK: - Native Text
extension RDEPUBReaderController: RDEPUBTextContentViewDelegate {
///
func textContentView(_ contentView: RDEPUBTextContentView, didChangeSelection selection: RDEPUBSelection?) {
guard let selection else {
updateCurrentSelection(nil)
return
}
updateCurrentSelection(selection)
}
///
func textContentView(
_ contentView: RDEPUBTextContentView,
didRequestSelectionAction action: RDEPUBAnnotationMenuAction,
selection: RDEPUBSelection?
) {
handleSelectionMenuAction(action, selection: selection ?? currentSelection)
contentView.clearSelection()
}
func textContentView(
_ contentView: RDEPUBTextContentView,
didRequestHighlightActions highlight: RDEPUBHighlight,
sourceRect: CGRect
) {
runtime.presentHighlightActions(for: highlight, sourceView: contentView, sourceRect: sourceRect)
}
/// EPUB
func pageNumber(for location: RDEPUBLocation) -> Int? {
if let textBook, let publication {
if let anchor = location.rangeAnchor?.start {
if let page = textBook.indexTable.pageNumber(for: anchor, in: textBook) {
return page + 1
}
}
let normalizedLocation = publication.resourceResolver.normalizedLocation(
location,
relativeToSpineIndex: nil,
bookIdentifier: currentBookIdentifier
) ?? location
return textBook.pageNumber(
for: normalizedLocation,
resolver: publication.resourceResolver,
bookIdentifier: currentBookIdentifier
)
}
return readingSession?.queueNavigation(
to: location,
relativeToSpineIndex: nil,
bookIdentifier: currentBookIdentifier
)
}
///
func resolvedTextLocation(forPageNumber pageNumber: Int) -> RDEPUBLocation? {
guard let textBook,
let publication,
let page = textBook.page(at: pageNumber) else {
return nil
}
let location = textBook.chapterData(forPageNumber: pageNumber)?.location(forPage: page, bookIdentifier: currentBookIdentifier)
?? textBook.location(forPageNumber: pageNumber, bookIdentifier: currentBookIdentifier)
guard let location else { return nil }
return publication.resourceResolver.normalizedLocation(
location,
relativeToSpineIndex: nil,
bookIdentifier: currentBookIdentifier
) ?? location
}
/// spine
func synchronizeTextReadingState(pageNumber: Int, location: RDEPUBLocation) {
guard let textBook,
let page = textBook.page(at: pageNumber) else {
readingSession?.transition(to: .idle)
return
}
readingSession?.updateReadingContext(
pageNumber: pageNumber,
location: location,
spineIndex: page.spineIndex,
chapterIndex: page.chapterIndex,
bookIdentifier: currentBookIdentifier
)
}
/// +
func nativeTextSnapshot(from textBook: RDEPUBTextBook) -> RDEPUBNativeTextSnapshot {
let chapters = textBook.chapterInfos
let pages = textBook.pages.map {
EPUBPage(
spineIndex: $0.spineIndex,
chapterIndex: $0.chapterIndex,
pageIndexInChapter: $0.pageIndexInChapter,
totalPagesInChapter: $0.totalPagesInChapter,
chapterTitle: $0.chapterTitle,
fixedSpread: nil
)
}
return (pages, chapters)
}
}