Add JavaScript and native message handler for getting mouseover urls from the detail view’s WKWebView.
This commit is contained in:
parent
9818278c9b
commit
3fcede7fb4
|
@ -148,10 +148,10 @@ private struct SidebarItemSpecifier {
|
|||
|
||||
func restore() {
|
||||
|
||||
if let feed = feed {
|
||||
if let _ = feed {
|
||||
restoreFeed()
|
||||
}
|
||||
else if let folder = folder {
|
||||
else if let _ = folder {
|
||||
restoreFolder()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -620,8 +620,8 @@
|
|||
849A977C1ED9EC42007D329B /* Detail */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
849A977D1ED9EC42007D329B /* ArticleRenderer.swift */,
|
||||
849A977E1ED9EC42007D329B /* DetailViewController.swift */,
|
||||
849A977D1ED9EC42007D329B /* ArticleRenderer.swift */,
|
||||
);
|
||||
path = Detail;
|
||||
sourceTree = "<group>";
|
||||
|
|
|
@ -17,6 +17,10 @@ extension Notification.Name {
|
|||
static let AppNavigationKeyPressed = Notification.Name("AppNavigationKeyPressedNotification")
|
||||
|
||||
static let UserDidAddFeed = Notification.Name("UserDidAddFeedNotification")
|
||||
|
||||
// Sent by DetailViewController when mouse hovers over link in web view.
|
||||
static let MouseDidEnterLink = Notification.Name("MouseDidEnterLinkNotification")
|
||||
static let MouseDidExitLink = Notification.Name("MouseDidExitLinkNotification")
|
||||
}
|
||||
|
||||
extension Notification {
|
||||
|
@ -42,6 +46,7 @@ final class AppInfo {
|
|||
var navigationKey: Int?
|
||||
var objects: [AnyObject]?
|
||||
var feed: Feed?
|
||||
var url: String?
|
||||
|
||||
static let appInfoKey = "appInfo"
|
||||
|
||||
|
|
|
@ -180,14 +180,40 @@ class ArticleRenderer {
|
|||
|
||||
private func renderedHTML() -> String {
|
||||
|
||||
var s = "<!DOCTYPE html><html><head>"
|
||||
var s = "<!DOCTYPE html><html><head>\n\n"
|
||||
s += textInsideTag(title, "title")
|
||||
s += textInsideTag(styleString(), "style")
|
||||
s += "</head></body>"
|
||||
|
||||
s += """
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
function startup() {
|
||||
var anchors = document.getElementsByTagName("a");
|
||||
for (var i = 0; i < anchors.length; i++) {
|
||||
anchors[i].addEventListener("mouseenter", function() { mouseDidEnterLink(this) });
|
||||
anchors[i].addEventListener("mouseleave", function() { mouseDidExitLink(this) });
|
||||
}
|
||||
}
|
||||
|
||||
function mouseDidEnterLink(anchor) {
|
||||
window.webkit.messageHandlers.mouseDidEnter.postMessage(anchor.href);
|
||||
}
|
||||
|
||||
function mouseDidExitLink(anchor) {
|
||||
window.webkit.messageHandlers.mouseDidExit.postMessage(anchor.href);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
"""
|
||||
|
||||
s += "\n\n</head><body onload='startup()'>\n\n"
|
||||
|
||||
|
||||
s += RSMacroProcessor.renderedText(withTemplate: template(), substitutions: substitutions(), macroStart: "[[", macroEnd: "]]")
|
||||
|
||||
s += "</body></html>"
|
||||
s += "\n\n</body></html>"
|
||||
|
||||
// print(s)
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ import RSCore
|
|||
import Data
|
||||
|
||||
class DetailViewController: NSViewController, WKNavigationDelegate, WKUIDelegate {
|
||||
|
||||
|
||||
var webview: WKWebView!
|
||||
|
||||
var article: Article? {
|
||||
|
@ -20,7 +20,12 @@ class DetailViewController: NSViewController, WKNavigationDelegate, WKUIDelegate
|
|||
reloadHTML()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private struct MessageName {
|
||||
static let mouseDidEnter = "mouseDidEnter"
|
||||
static let mouseDidExit = "mouseDidExit"
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(timelineSelectionDidChange(_:)), name: .TimelineSelectionDidChange, object: nil)
|
||||
|
@ -35,6 +40,11 @@ class DetailViewController: NSViewController, WKNavigationDelegate, WKUIDelegate
|
|||
let configuration = WKWebViewConfiguration()
|
||||
configuration.preferences = preferences
|
||||
|
||||
let userContentController = WKUserContentController()
|
||||
userContentController.add(self, name: MessageName.mouseDidEnter)
|
||||
userContentController.add(self, name: MessageName.mouseDidExit)
|
||||
configuration.userContentController = userContentController
|
||||
|
||||
webview = WKWebView(frame: self.view.bounds, configuration: configuration)
|
||||
webview.uiDelegate = self
|
||||
webview.navigationDelegate = self
|
||||
|
@ -97,6 +107,41 @@ class DetailViewController: NSViewController, WKNavigationDelegate, WKUIDelegate
|
|||
}
|
||||
}
|
||||
|
||||
extension DetailViewController: WKScriptMessageHandler {
|
||||
|
||||
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
|
||||
|
||||
if message.name == MessageName.mouseDidEnter, let link = message.body as? String {
|
||||
mouseDidEnter(link)
|
||||
}
|
||||
else if message.name == MessageName.mouseDidExit, let link = message.body as? String{
|
||||
mouseDidExit(link)
|
||||
}
|
||||
}
|
||||
|
||||
private func mouseDidEnter(_ link: String) {
|
||||
|
||||
if link.isEmpty {
|
||||
return
|
||||
}
|
||||
|
||||
let appInfo = AppInfo()
|
||||
appInfo.view = self.view
|
||||
appInfo.url = link
|
||||
|
||||
NotificationCenter.default.post(name: .MouseDidEnterLink, object: self, userInfo: appInfo.userInfo)
|
||||
}
|
||||
|
||||
private func mouseDidExit(_ link: String) {
|
||||
|
||||
let appInfo = AppInfo()
|
||||
appInfo.view = self.view
|
||||
appInfo.url = link
|
||||
|
||||
NotificationCenter.default.post(name: .MouseDidExitLink, object: self, userInfo: appInfo.userInfo)
|
||||
}
|
||||
}
|
||||
|
||||
class DetailBox: NSBox {
|
||||
|
||||
weak var viewController: DetailViewController?
|
||||
|
|
|
@ -40,6 +40,9 @@ final class StatusBarView: NSView {
|
|||
NotificationCenter.default.addObserver(self, selector: #selector(progressDidChange(_:)), name: .AccountRefreshProgressDidChange, object: nil)
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(timelineSelectionDidChange(_:)), name: .TimelineSelectionDidChange, object: nil)
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(mouseDidEnterLink(_:)), name: .MouseDidEnterLink, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(mouseDidExitLink(_:)), name: .MouseDidExitLink, object: nil)
|
||||
}
|
||||
|
||||
// MARK: Notifications
|
||||
|
@ -51,6 +54,34 @@ final class StatusBarView: NSView {
|
|||
updateProgressLabel(progress)
|
||||
}
|
||||
|
||||
@objc dynamic func mouseDidEnterLink(_ notification: Notification) {
|
||||
|
||||
guard let appInfo = AppInfo.pullFromUserInfo(notification.userInfo) else {
|
||||
return
|
||||
}
|
||||
guard let window = window, let notificationWindow = appInfo.view?.window, window === notificationWindow else {
|
||||
return
|
||||
}
|
||||
guard let link = appInfo.url else {
|
||||
return
|
||||
}
|
||||
print(link)
|
||||
}
|
||||
|
||||
@objc dynamic func mouseDidExitLink(_ notification: Notification) {
|
||||
|
||||
guard let appInfo = AppInfo.pullFromUserInfo(notification.userInfo) else {
|
||||
return
|
||||
}
|
||||
guard let window = window, let notificationWindow = appInfo.view?.window, window === notificationWindow else {
|
||||
return
|
||||
}
|
||||
guard let link = appInfo.url else {
|
||||
return
|
||||
}
|
||||
print(link)
|
||||
}
|
||||
|
||||
// MARK: Notifications
|
||||
|
||||
@objc dynamic func timelineSelectionDidChange(_ note: Notification) {
|
||||
|
|
Loading…
Reference in New Issue