Epub阅读器0.0.1
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
import UIKit
|
||||
import WebKit
|
||||
|
||||
extension RDEPUBWebView {
|
||||
func configureWebViewIfNeeded(publication: RDEPUBPublication) {
|
||||
let parser = publication.parser
|
||||
let publicationKey = parser.opfURL?.path ?? parser.extractionRootURL?.path ?? UUID().uuidString
|
||||
if publicationKey == configuredPublicationKey, webView != nil {
|
||||
return
|
||||
}
|
||||
|
||||
teardownWebView()
|
||||
|
||||
let userContentController = WKUserContentController()
|
||||
RDEPUBJavaScriptBridge.messageNames.forEach {
|
||||
userContentController.add(self, name: $0)
|
||||
}
|
||||
userContentController.addUserScript(
|
||||
WKUserScript(
|
||||
source: RDEPUBJavaScriptBridge.userScript,
|
||||
injectionTime: .atDocumentEnd,
|
||||
forMainFrameOnly: true
|
||||
)
|
||||
)
|
||||
|
||||
let configuration = WKWebViewConfiguration()
|
||||
configuration.websiteDataStore = .nonPersistent()
|
||||
configuration.userContentController = userContentController
|
||||
let schemeHandler = RDEPUBResourceURLSchemeHandler(parser: parser)
|
||||
configuration.setURLSchemeHandler(schemeHandler, forURLScheme: RDEPUBResourceURLSchemeHandler.scheme)
|
||||
|
||||
let webView = RDEPUBAnnotationWebView(frame: bounds, configuration: configuration)
|
||||
webView.onSelectionAction = { [weak self] action in
|
||||
guard let self else { return }
|
||||
self.handleSelectionMenuAction(action)
|
||||
}
|
||||
UIMenuController.shared.menuItems = [
|
||||
UIMenuItem(title: "拷贝", action: #selector(RDEPUBAnnotationWebView.rd_copy(_:))),
|
||||
UIMenuItem(title: "高亮", action: #selector(RDEPUBAnnotationWebView.rd_highlight(_:))),
|
||||
UIMenuItem(title: "批注", action: #selector(RDEPUBAnnotationWebView.rd_annotate(_:)))
|
||||
]
|
||||
webView.navigationDelegate = self
|
||||
webView.scrollView.isScrollEnabled = false
|
||||
webView.scrollView.showsHorizontalScrollIndicator = false
|
||||
webView.scrollView.showsVerticalScrollIndicator = false
|
||||
webView.scrollView.bounces = false
|
||||
webView.scrollView.alwaysBounceHorizontal = false
|
||||
webView.scrollView.alwaysBounceVertical = false
|
||||
webView.scrollView.clipsToBounds = true
|
||||
webView.scrollView.panGestureRecognizer.isEnabled = false
|
||||
webView.scrollView.pinchGestureRecognizer?.isEnabled = false
|
||||
webView.isOpaque = false
|
||||
webView.backgroundColor = .clear
|
||||
webView.clipsToBounds = true
|
||||
if #available(iOS 16.4, *) {
|
||||
webView.isInspectable = true
|
||||
}
|
||||
|
||||
addSubview(webView)
|
||||
webView.frame = bounds
|
||||
webView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
||||
|
||||
self.schemeHandler = schemeHandler
|
||||
self.webView = webView
|
||||
self.configuredPublicationKey = publicationKey
|
||||
RDEPUBWebViewDebug.log(debugScope, message: "configured webView=\(RDEPUBWebViewDebug.webViewID(webView)) publicationKey=\(publicationKey)")
|
||||
}
|
||||
|
||||
func handleSelectionMenuAction(_ action: RDEPUBAnnotationMenuAction) {
|
||||
delegate?.epubWebView(self, didRequestSelectionAction: action)
|
||||
clearWebSelection()
|
||||
}
|
||||
|
||||
func clearWebSelection() {
|
||||
webView?.evaluateJavaScript("window.getSelection && window.getSelection().removeAllRanges();")
|
||||
}
|
||||
|
||||
func teardownWebView() {
|
||||
cancelFixedLayoutReadyFallback()
|
||||
if let webView {
|
||||
RDEPUBWebViewDebug.log(debugScope, message: "teardown webView=\(RDEPUBWebViewDebug.webViewID(webView))")
|
||||
}
|
||||
webView?.navigationDelegate = nil
|
||||
if let userContentController = webView?.configuration.userContentController {
|
||||
RDEPUBJavaScriptBridge.messageNames.forEach {
|
||||
userContentController.removeScriptMessageHandler(forName: $0)
|
||||
}
|
||||
}
|
||||
(webView as? RDEPUBAnnotationWebView)?.onSelectionAction = nil
|
||||
webView?.removeFromSuperview()
|
||||
webView = nil
|
||||
schemeHandler = nil
|
||||
configuredPublicationKey = nil
|
||||
currentLoadSignature = nil
|
||||
}
|
||||
}
|
||||
|
||||
extension UIColor {
|
||||
var ss_hexString: String {
|
||||
var red: CGFloat = 0
|
||||
var green: CGFloat = 0
|
||||
var blue: CGFloat = 0
|
||||
var alpha: CGFloat = 0
|
||||
getRed(&red, green: &green, blue: &blue, alpha: &alpha)
|
||||
return String(format: "#%02X%02X%02X", Int(red * 255), Int(green * 255), Int(blue * 255))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user