140 lines
5.7 KiB
Swift
140 lines
5.7 KiB
Swift
import UIKit
|
|
|
|
protocol RDEPUBWebContentViewDelegate: AnyObject {
|
|
|
|
func epubWebContentView(_ contentView: RDEPUBWebContentView, didUpdateLocation location: RDEPUBLocation, spineIndex: Int)
|
|
|
|
func epubWebContentView(_ contentView: RDEPUBWebContentView, didChangeSelection selection: RDEPUBSelection?, spineIndex: Int)
|
|
|
|
func epubWebContentView(_ contentView: RDEPUBWebContentView, didRequestSelectionAction action: RDEPUBAnnotationMenuAction)
|
|
|
|
func epubWebContentView(_ contentView: RDEPUBWebContentView, didActivateInternalLink location: RDEPUBLocation, fromSpineIndex: Int)
|
|
|
|
func epubWebContentView(_ contentView: RDEPUBWebContentView, didActivateExternalLink url: URL)
|
|
|
|
func epubWebContentView(_ contentView: RDEPUBWebContentView, didLogJavaScriptError message: String)
|
|
|
|
func epubWebContentView(_ contentView: RDEPUBWebContentView, didTapImageWithSource src: String, sourceRect: CGRect?)
|
|
|
|
func epubWebContentView(_ contentView: RDEPUBWebContentView, didTapFootnoteWithAltText altText: String, sourceRect: CGRect?)
|
|
}
|
|
|
|
final class RDEPUBWebContentView: UIView, RDEpubReaderPageResourceReleasing, RDEpubReaderPageVisibilityHandling {
|
|
weak var delegate: RDEPUBWebContentViewDelegate?
|
|
|
|
/// The current href of the loaded chapter (exposed for image resolution).
|
|
var currentHref: String {
|
|
epubWebView.currentHref
|
|
}
|
|
|
|
private let epubWebView = RDEPUBWebView()
|
|
private let decorationOverlayView = RDEPUBWebDecorationOverlayView()
|
|
private let pageNumberLabel: UILabel = {
|
|
let label = UILabel()
|
|
label.font = UIFont.systemFont(ofSize: 13)
|
|
return label
|
|
}()
|
|
|
|
override init(frame: CGRect) {
|
|
super.init(frame: frame)
|
|
clipsToBounds = true
|
|
layer.masksToBounds = true
|
|
|
|
addSubview(epubWebView)
|
|
addSubview(decorationOverlayView)
|
|
addSubview(pageNumberLabel)
|
|
epubWebView.delegate = self
|
|
epubWebView.onDecorationsResolved = { [weak self] decorations in
|
|
self?.decorationOverlayView.applyDecorations(decorations)
|
|
}
|
|
}
|
|
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
override func layoutSubviews() {
|
|
super.layoutSubviews()
|
|
epubWebView.frame = bounds
|
|
decorationOverlayView.frame = bounds
|
|
|
|
let labelSize = pageNumberLabel.sizeThatFits(CGSize(width: bounds.width, height: 20))
|
|
pageNumberLabel.frame = CGRect(
|
|
x: bounds.width - labelSize.width - 24,
|
|
y: bounds.height - labelSize.height - 20,
|
|
width: labelSize.width,
|
|
height: labelSize.height
|
|
)
|
|
}
|
|
|
|
func configure(
|
|
publication: RDEPUBPublication,
|
|
request: RDEPUBRenderRequest,
|
|
pageNumber: Int,
|
|
totalPages: Int,
|
|
theme: RDEPUBReaderTheme
|
|
) {
|
|
backgroundColor = theme.contentBackgroundColor
|
|
pageNumberLabel.textColor = theme.contentTextColor
|
|
pageNumberLabel.text = "\(pageNumber) / \(totalPages)"
|
|
decorationOverlayView.applyDecorations([])
|
|
epubWebView.load(publication: publication, request: request)
|
|
setNeedsLayout()
|
|
}
|
|
|
|
func releaseResources() {
|
|
decorationOverlayView.applyDecorations([])
|
|
epubWebView.reset()
|
|
epubWebView.delegate = self
|
|
epubWebView.onDecorationsResolved = { [weak self] decorations in
|
|
self?.decorationOverlayView.applyDecorations(decorations)
|
|
}
|
|
}
|
|
|
|
func readerPageVisibilityDidChange(isVisible: Bool) {
|
|
epubWebView.setReaderPageVisible(isVisible)
|
|
}
|
|
}
|
|
|
|
extension RDEPUBWebContentView: RDEPUBWebViewDelegate {
|
|
func epubWebView(_ webView: RDEPUBWebView, didUpdateLocation location: RDEPUBLocation, spineIndex: Int) {
|
|
delegate?.epubWebContentView(self, didUpdateLocation: location, spineIndex: spineIndex)
|
|
}
|
|
|
|
func epubWebView(_ webView: RDEPUBWebView, didChangeSelection selection: RDEPUBSelection?, spineIndex: Int) {
|
|
delegate?.epubWebContentView(self, didChangeSelection: selection, spineIndex: spineIndex)
|
|
}
|
|
|
|
func epubWebView(_ webView: RDEPUBWebView, didRequestSelectionAction action: RDEPUBAnnotationMenuAction) {
|
|
delegate?.epubWebContentView(self, didRequestSelectionAction: action)
|
|
}
|
|
|
|
func epubWebView(_ webView: RDEPUBWebView, didActivateInternalLink location: RDEPUBLocation, fromSpineIndex: Int) {
|
|
delegate?.epubWebContentView(self, didActivateInternalLink: location, fromSpineIndex: fromSpineIndex)
|
|
}
|
|
|
|
func epubWebView(_ webView: RDEPUBWebView, didActivateExternalLink url: URL) {
|
|
delegate?.epubWebContentView(self, didActivateExternalLink: url)
|
|
}
|
|
|
|
func epubWebView(_ webView: RDEPUBWebView, didLogJavaScriptError message: String) {
|
|
delegate?.epubWebContentView(self, didLogJavaScriptError: message)
|
|
}
|
|
func epubWebViewDidFinishRendering(_ webView: RDEPUBWebView) {}
|
|
func epubWebView(_ webView: RDEPUBWebView, didTapImageWithSource src: String, sourceRect: CGRect?) {
|
|
delegate?.epubWebContentView(self, didTapImageWithSource: src, sourceRect: sourceRect)
|
|
}
|
|
func epubWebView(_ webView: RDEPUBWebView, didTapFootnoteWithAltText altText: String, sourceRect: CGRect?) {
|
|
delegate?.epubWebContentView(self, didTapFootnoteWithAltText: altText, sourceRect: sourceRect)
|
|
}
|
|
}
|
|
|
|
extension RDEPUBWebContentViewDelegate {
|
|
func epubWebContentView(_ contentView: RDEPUBWebContentView, didTapImageWithSource src: String, sourceRect: CGRect?) {
|
|
// Default: no-op. Implementors can present an image viewer.
|
|
}
|
|
func epubWebContentView(_ contentView: RDEPUBWebContentView, didTapFootnoteWithAltText altText: String, sourceRect: CGRect?) {
|
|
// Default: no-op. Implementors can present a footnote tooltip.
|
|
}
|
|
}
|